Commit 2925cd9d by Richard Biener Committed by Richard Biener

re PR tree-optimization/28364 (poor optimization choices when iterating over a…

re PR tree-optimization/28364 (poor optimization choices when iterating over a std::string (probably not c++-specific))

2018-04-30  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/28364
	PR tree-optimization/85275
	* tree-ssa-loop-ch.c (ch_base::copy_headers): Stop after
	copying first exit test.

	* gcc.dg/tree-ssa/copy-headers-5.c: New testcase.
	* gcc.dg/tree-ssa/predcom-8.c: Likewise.
	* gcc.dg/tree-ssa/cunroll-13.c: Rewrite to gimple testcase.
	* gcc.dg/tree-ssa/ivopt_mult_1.c: XFAIL.
	* gcc.dg/tree-ssa/ivopt_mult_1g.c: Add gimple variant that
	still passes.
	* gcc.dg/tree-ssa/ivopt_mult_2.c: XFAIL.
	* gcc.dg/tree-ssa/ivopt_mult_2g.c: Add gimple variant that
	still passes.
	* gcc.dg/tree-ssa/ssa-dom-thread-7.c: Adjust.
	* gcc.dg/tree-ssa/20030710-1.c: Likewise.
	* gcc.dg/tree-ssa/20030711-1.c: Likewise.

From-SVN: r259754
parent 03b42a71
2018-04-30 Richard Biener <rguenther@suse.de>
PR tree-optimization/28364
PR tree-optimization/85275
* tree-ssa-loop-ch.c (ch_base::copy_headers): Stop after
copying first exit test.
2018-04-28 Mark Wielaard <mark@klomp.org>
* dwarf2out.c (dwarf2out_finish): Add .debug_addr table header for
......
2018-04-30 Richard Biener <rguenther@suse.de>
PR tree-optimization/28364
PR tree-optimization/85275
* gcc.dg/tree-ssa/copy-headers-5.c: New testcase.
* gcc.dg/tree-ssa/predcom-8.c: Likewise.
* gcc.dg/tree-ssa/cunroll-13.c: Rewrite to gimple testcase.
* gcc.dg/tree-ssa/ivopt_mult_1.c: XFAIL.
* gcc.dg/tree-ssa/ivopt_mult_1g.c: Add gimple variant that
still passes.
* gcc.dg/tree-ssa/ivopt_mult_2.c: XFAIL.
* gcc.dg/tree-ssa/ivopt_mult_2g.c: Add gimple variant that
still passes.
* gcc.dg/tree-ssa/ssa-dom-thread-7.c: Adjust.
* gcc.dg/tree-ssa/20030710-1.c: Likewise.
* gcc.dg/tree-ssa/20030711-1.c: Likewise.
2018-04-28 Uros Bizjak <ubizjak@gmail.com>
PR target/84431
......
/* { dg-do compile } */
/* { dg-options "-O1 -fdump-tree-dom2" } */
/* { dg-options "-O1 -fdump-tree-phicprop1" } */
extern void abort (void);
extern void blah (void);
......@@ -42,14 +42,14 @@ record_component_aliases (type)
/* The call to blah should have been eliminated. If the call is not
eliminated, then dominator optimizations failed and it'll be
impossible to delete other unnecessary code. */
/* { dg-final { scan-tree-dump-not "blah \\(\\)" "dom2" } } */
/* { dg-final { scan-tree-dump-not "blah \\(\\)" "phicprop1" } } */
/* There should be two IF conditionals. */
/* { dg-final { scan-tree-dump-times "if " 2 "dom2"} } */
/* { dg-final { scan-tree-dump-times "if " 2 "phicprop1"} } */
/* There should be a single load of type.binfo. */
/* { dg-final { scan-tree-dump-times "type\\.binfo" 1 "dom2"} } */
/* { dg-final { scan-tree-dump-times "type\\.binfo" 1 "phicprop1"} } */
/* There should be two loads of vec.length. */
/* { dg-final { scan-tree-dump-times "vec.length" 2 "dom2"} } */
/* { dg-final { scan-tree-dump-times "vec.length" 2 "phicprop1"} } */
......@@ -44,12 +44,12 @@ record_component_aliases (type)
/* The call to blah can not be eliminated. */
/* { dg-final { scan-tree-dump-times "blah \\(\\)" 1 "dom2" } } */
/* There should be four IF conditionals. */
/* { dg-final { scan-tree-dump-times "if " 4 "dom2"} } */
/* There should be three IF conditionals. */
/* { dg-final { scan-tree-dump-times "if " 3 "dom2"} } */
/* There should be two loads of type.binfo. */
/* { dg-final { scan-tree-dump-times "type\\.binfo" 2 "dom2"} } */
/* There should be four loads of vec.length. */
/* { dg-final { scan-tree-dump-times "vec.length" 4 "dom2"} } */
/* There should be three loads of vec.length. */
/* { dg-final { scan-tree-dump-times "vec.length" 3 "dom2"} } */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-ch2-details" } */
int is_sorted(int *a, int n)
{
for (int i = 0; i < n - 1; i++)
if (a[i] > a[i + 1])
return 0;
return 1;
}
/* Verify we apply loop header copying but only copy the IV test and
not the alternate exit test. */
/* { dg-final { scan-tree-dump "is now do-while loop" "ch2" } } */
/* { dg-final { scan-tree-dump-times " if " 3 "ch2" } } */
/* { dg-do compile } */
/* { dg-options "-O3 -fdisable-tree-evrp -fdisable-tree-cunrolli -fdisable-tree-vrp1 -fdump-tree-cunroll-blocks-details" } */
/* { dg-options "-O3 -fgimple -fdump-tree-cunroll-blocks-details" } */
#if __SIZEOF_INT__ < 4
__extension__ typedef __INT32_TYPE__ i32;
......@@ -7,15 +7,53 @@ __extension__ typedef __INT32_TYPE__ i32;
typedef int i32;
#endif
struct a {int a[8];int b;};
void
t(struct a *a)
struct a {i32 a[8];i32 b;};
void __GIMPLE (startwith("fix_loops"))
t (struct a * a)
{
for (i32 i=0;i<123456 && a->a[i];i++)
a->a[i]++;
i32 i;
i32 _1;
i32 _2;
i32 _9;
i32 _11;
bb_2:
_11 = a_6(D)->a[0];
if (_11 != _Literal (i32) 0)
goto bb_6;
else
goto bb_3;
bb_3:
return;
bb_4:
_1 = _2 + 1;
a_6(D)->a[i_19] = _1;
i_8 = i_19 + _Literal (i32) 1;
if (i_8 <= _Literal (i32) 123455)
goto bb_5;
else
goto bb_3;
bb_5:
i_19 = __PHI (bb_6: _Literal (i32) 1, bb_4: i_8);
_2 = a_6(D)->a[i_19];
if (_2 != _Literal (i32) 0)
goto bb_4;
else
goto bb_3;
bb_6:
_9 = _11 + _Literal (i32) 1;
a_6(D)->a[0] = _9;
goto bb_5;
}
/* This pass relies on the fact that we do not eliminate the redundant test for i early.
It is necessary to disable all passes that do so. At the moment it is evrp, vrp1 and cunrolli. */
/* This testcase relies on the fact that we do not eliminate the redundant test
for i early. It is necessary to disable all passes that do so, for the
moment starting with the loop pipeline is good enough. */
/* { dg-final { scan-tree-dump-times "Loop 1 iterates 123454 times" 1 "cunroll" } } */
/* { dg-final { scan-tree-dump-times "Last iteration exit edge was proved true" 1 "cunroll" } } */
/* { dg-final { scan-tree-dump-times "Exit condition of peeled iterations was eliminated" 1 "cunroll" } } */
......
......@@ -20,4 +20,4 @@ long foo(long* p, long* p2, int N1, int N2)
return s;
}
/* { dg-final { scan-tree-dump-times "Replacing" 1 "ivopts"} } */
/* { dg-final { scan-tree-dump-times "Replacing" 1 "ivopts" { xfail *-*-* } } } */
/* { dg-do compile { target {{ i?86-*-* x86_64-*-* } && lp64 } } } */
/* { dg-options "-O2 -fgimple -m64 -fdump-tree-ivopts-details" } */
/* The test 'if (p2 > p_limit2)' can be replaced, so iv p2 can be
* eliminated. */
long int __GIMPLE (startwith("fix_loops"))
foo (long int * p, long int * p2, int N1, int N2)
{
long int s;
long int * p_limit2;
long int * p_limit;
long unsigned int _1;
long unsigned int _2;
long unsigned int _3;
long unsigned int _4;
long int _5;
bb_2:
_1 = (long unsigned int) N1_10(D);
_2 = _1 * 8ul;
p_limit_12 = p_11(D) + _2;
_3 = (long unsigned int) N2_13(D);
_4 = _3 * 8ul;
p_limit2_15 = p2_14(D) + _4;
if (p_11(D) <= p_limit_12)
goto bb_3;
else
goto bb_13;
bb_13:
bb_9:
goto bb_6;
bb_3:
p_20 = p_11(D) + 8ul;
p2_23 = p2_14(D) + 8ul;
if (p_limit2_15 < p2_23)
goto bb_14;
else
goto bb_7;
bb_14:
goto bb_9;
bb_7:
goto bb_5;
bb_4:
p_16 = p_26 + 8ul;
p2_17 = p2_27 + 8ul;
if (p_limit2_15 < p2_17)
goto bb_11;
else
goto bb_8;
bb_11:
goto bb_6;
bb_8:
;
bb_5:
s_24 = __PHI (bb_7: 0l, bb_8: s_19);
p_26 = __PHI (bb_7: p_20, bb_8: p_16);
p2_27 = __PHI (bb_7: p2_23, bb_8: p2_17);
_5 = __MEM <long int> (p_26);
s_19 = _5 + s_24;
if (p_limit_12 >= p_26)
goto bb_4;
else
goto bb_12;
bb_12:
;
bb_6:
s_25 = __PHI (bb_12: s_19, bb_11: s_19, bb_9: 0l);
return s_25;
}
/* { dg-final { scan-tree-dump-times "Replacing" 1 "ivopts" } } */
......@@ -21,4 +21,4 @@ long foo(long* p, long* p2, int N1, int N2)
return s;
}
/* { dg-final { scan-tree-dump-times "Replacing" 2 "ivopts"} } */
/* { dg-final { scan-tree-dump-times "Replacing" 2 "ivopts" { xfail *-*-* } } } */
/* { dg-do compile { target {{ i?86-*-* x86_64-*-* } && lp64 } } } */
/* { dg-options "-O2 -fgimple -m64 -fdump-tree-ivopts-details" } */
/* Exit tests 'i < N1' and 'p2 > p_limit2' can be replaced, so
* two ivs i and p2 can be eliminate. */
long int __GIMPLE (startwith("fix_loops"))
foo (long int * p, long int * p2, int N1, int N2)
{
long int s;
long int * p_limit2;
int i;
long unsigned int _1;
long unsigned int _2;
long int _3;
bb_2:
_1 = (long unsigned int) N2_9(D);
_2 = _1 * 8ul;
p_limit2_11 = p2_10(D) + _2;
if (N1_13(D) > 0)
goto bb_3;
else
goto bb_13;
bb_13:
bb_9:
goto bb_6;
bb_3:
p_22 = p_12(D) + 8ul;
p2_23 = p2_10(D) + 8ul;
if (p_limit2_11 < p2_23)
goto bb_14;
else
goto bb_7;
bb_14:
goto bb_9;
bb_7:
goto bb_5;
bb_4:
p_14 = p_27 + 8ul;
p2_15 = p2_28 + 8ul;
i_16 = i_29 + 1;
if (p_limit2_11 < p2_15)
goto bb_11;
else
goto bb_8;
bb_11:
goto bb_6;
bb_8:
;
bb_5:
s_25 = __PHI (bb_7: 0l, bb_8: s_18);
p_27 = __PHI (bb_7: p_22, bb_8: p_14);
p2_28 = __PHI (bb_7: p2_23, bb_8: p2_15);
i_29 = __PHI (bb_7: 1, bb_8: i_16);
_3 = __MEM <long int> (p_27);
s_18 = _3 + s_25;
if (N1_13(D) > i_29)
goto bb_4;
else
goto bb_12;
bb_12:
;
bb_6:
s_26 = __PHI (bb_12: s_18, bb_11: s_18, bb_9: 0l);
return s_26;
}
/* { dg-final { scan-tree-dump-times "Replacing" 2 "ivopts"} } */
/* { dg-do compile } */
/* { dg-options "-O3 -fdump-tree-pcom-details" } */
int is_sorted(int *a, int n)
{
for (int i = 0; i < n - 1; i++)
if (a[i] > a[i + 1])
return 0;
return 1;
}
/* { dg-final { scan-tree-dump "Executing predictive commoning without unrolling" "pcom" } } */
......@@ -3,7 +3,7 @@
/* { dg-final { scan-tree-dump "Jumps threaded: 16" "thread1" } } */
/* { dg-final { scan-tree-dump "Jumps threaded: 9" "thread2" } } */
/* { dg-final { scan-tree-dump "Jumps threaded: 3" "thread3" } } */
/* { dg-final { scan-tree-dump-not "Jumps threaded" "dom2" } } */
/* { dg-final { scan-tree-dump "Jumps threaded: 1" "dom2" } } */
/* { dg-final { scan-tree-dump-not "Jumps threaded" "dom3" } } */
/* { dg-final { scan-tree-dump-not "Jumps threaded" "vrp2" } } */
......
......@@ -340,6 +340,11 @@ ch_base::copy_headers (function *fun)
bbs[n_bbs++] = header;
gcc_assert (bbs_size > n_bbs);
header = exit->dest;
/* Make sure to stop copying after we copied the first exit test.
Without further heuristics we do not want to rotate the loop
any further. */
if (loop_exits_from_bb_p (loop, exit->src))
break;
}
if (!exit)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment