The following patch moves LIM before PRE to allow it to cleanup CSE (and copyprop) opportunities LIM exposes. It also moves the DCE done in loop before the loop pipeline as otherwise it is no longer executed uncoditionally at this point (since we have the no_loop pipeline).
The patch requires some testsuite adjustments such as cope with LIM now running before PRE and thus disabling the former and to adjust for better optimization we now do in the two testcases with redundant stores where store motion enables sinking to sink all interesting code out of the innermost loop. It also requires the LIM PHI hoisting cost adjustment patch I am testing separately. Bootstrapped and tested on x86_64-unknown-linux-gnu (with testsuite fallout resulting in the following adjustments). I'm going to re-test before committing. Richard. 2016-05-18 Richard Biener <rguent...@suse.de> PR tree-optimization/70729 * passes.def: Move LIM pass before PRE. Remove no longer required copyprop and move first DCE out of the loop pipeline. * gcc.dg/autopar/outer-6.c: Adjust to avoid redundant store. * gcc.dg/graphite/scop-18.c: Likewise. * gcc.dg/pr41783.c: Disable LIM. * gcc.dg/tree-ssa/loadpre10.c: Likewise. * gcc.dg/tree-ssa/loadpre23.c: Likewise. * gcc.dg/tree-ssa/loadpre24.c: Likewise. * gcc.dg/tree-ssa/loadpre25.c: Likewise. * gcc.dg/tree-ssa/loadpre4.c: Likewise. * gcc.dg/tree-ssa/loadpre8.c: Likewise. * gcc.dg/tree-ssa/ssa-pre-16.c: Likewise. * gcc.dg/tree-ssa/ssa-pre-18.c: Likewise. * gcc.dg/tree-ssa/ssa-pre-20.c: Likewise. * gcc.dg/tree-ssa/ssa-pre-3.c: Likewise. * gfortran.dg/pr42108.f90: Likewise. Index: trunk/gcc/passes.def =================================================================== --- trunk.orig/gcc/passes.def 2016-05-18 11:46:56.518134310 +0200 +++ trunk/gcc/passes.def 2016-05-18 11:47:16.006355920 +0200 @@ -243,12 +243,14 @@ along with GCC; see the file COPYING3. NEXT_PASS (pass_cse_sincos); NEXT_PASS (pass_optimize_bswap); NEXT_PASS (pass_laddress); + NEXT_PASS (pass_lim); NEXT_PASS (pass_split_crit_edges); NEXT_PASS (pass_pre); NEXT_PASS (pass_sink_code); NEXT_PASS (pass_sancov); NEXT_PASS (pass_asan); NEXT_PASS (pass_tsan); + NEXT_PASS (pass_dce); /* Pass group that runs when 1) enabled, 2) there are loops in the function. Make sure to run pass_fix_loops before to discover/remove loops before running the gate function @@ -257,9 +259,6 @@ along with GCC; see the file COPYING3. NEXT_PASS (pass_tree_loop); PUSH_INSERT_PASSES_WITHIN (pass_tree_loop) NEXT_PASS (pass_tree_loop_init); - NEXT_PASS (pass_lim); - NEXT_PASS (pass_copy_prop); - NEXT_PASS (pass_dce); NEXT_PASS (pass_tree_unswitch); NEXT_PASS (pass_scev_cprop); NEXT_PASS (pass_record_bounds); Index: trunk/gcc/testsuite/gcc.dg/autopar/outer-6.c =================================================================== --- trunk.orig/gcc/testsuite/gcc.dg/autopar/outer-6.c 2016-01-20 15:36:51.477802338 +0100 +++ trunk/gcc/testsuite/gcc.dg/autopar/outer-6.c 2016-05-18 12:40:29.342665450 +0200 @@ -24,7 +24,7 @@ void parloop (int N) for (i = 0; i < N; i++) { for (j = 0; j < N; j++) - y[i]=x[i][j]; + y[i]+=x[i][j]; sum += y[i]; } g_sum = sum; Index: trunk/gcc/testsuite/gcc.dg/graphite/scop-18.c =================================================================== --- trunk.orig/gcc/testsuite/gcc.dg/graphite/scop-18.c 2015-09-14 10:21:31.364089947 +0200 +++ trunk/gcc/testsuite/gcc.dg/graphite/scop-18.c 2016-05-18 12:38:35.673369299 +0200 @@ -13,13 +13,13 @@ void test (void) for (i = 0; i < 24; i++) for (j = 0; j < 24; j++) for (k = 0; k < 24; k++) - A[i][j] = B[i][k] * C[k][j]; + A[i][j] += B[i][k] * C[k][j]; /* These loops should still be strip mined. */ for (i = 0; i < 1000; i++) for (j = 0; j < 1000; j++) for (k = 0; k < 1000; k++) - A[i][j] = B[i][k] * C[k][j]; + A[i][j] += B[i][k] * C[k][j]; } /* { dg-final { scan-tree-dump-times "number of SCoPs: 1" 1 "graphite"} } */ Index: trunk/gcc/testsuite/gcc.dg/pr41783.c =================================================================== --- trunk.orig/gcc/testsuite/gcc.dg/pr41783.c 2015-06-09 15:45:14.092224446 +0200 +++ trunk/gcc/testsuite/gcc.dg/pr41783.c 2016-05-18 11:47:31.454531583 +0200 @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O3 -fdump-tree-pre" } */ +/* { dg-options "-O3 -fdump-tree-pre -fno-tree-loop-im" } */ int db[100]; int a_global_var, fact; int main() Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/loadpre10.c =================================================================== --- trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/loadpre10.c 2015-06-09 15:45:27.104343935 +0200 +++ trunk/gcc/testsuite/gcc.dg/tree-ssa/loadpre10.c 2016-05-18 11:48:23.031118053 +0200 @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-pre-stats" } */ +/* { dg-options "-O2 -fdump-tree-pre-stats -fno-tree-loop-im" } */ struct tree_common { int code; Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/loadpre23.c =================================================================== --- trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/loadpre23.c 2015-11-05 09:52:40.426667086 +0100 +++ trunk/gcc/testsuite/gcc.dg/tree-ssa/loadpre23.c 2016-05-18 11:48:36.795274560 +0200 @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-pre-stats" } */ +/* { dg-options "-O2 -fdump-tree-pre-stats -fno-tree-loop-im" } */ struct { int a; Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/loadpre24.c =================================================================== --- trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/loadpre24.c 2015-11-05 09:52:40.425667074 +0100 +++ trunk/gcc/testsuite/gcc.dg/tree-ssa/loadpre24.c 2016-05-18 11:48:51.159437887 +0200 @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-pre-stats" } */ +/* { dg-options "-O2 -fdump-tree-pre-stats -fno-tree-loop-im" } */ int a; Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/loadpre25.c =================================================================== --- trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/loadpre25.c 2015-11-05 09:52:40.426667086 +0100 +++ trunk/gcc/testsuite/gcc.dg/tree-ssa/loadpre25.c 2016-05-18 11:49:02.815570421 +0200 @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-pre-stats" } */ +/* { dg-options "-O2 -fdump-tree-pre-stats -fno-tree-loop-im" } */ struct X { int i; }; int foo(struct X *a, int argc) { Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/loadpre4.c =================================================================== --- trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/loadpre4.c 2015-11-05 09:52:40.426667086 +0100 +++ trunk/gcc/testsuite/gcc.dg/tree-ssa/loadpre4.c 2016-05-18 11:49:16.363724467 +0200 @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-pre-stats" } */ +/* { dg-options "-O2 -fdump-tree-pre-stats -fno-tree-loop-im" } */ int main(int *a, int argc) { int i; Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/loadpre8.c =================================================================== --- trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/loadpre8.c 2015-06-09 15:45:27.003343009 +0200 +++ trunk/gcc/testsuite/gcc.dg/tree-ssa/loadpre8.c 2016-05-18 11:49:28.355860820 +0200 @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-pre-stats -std=gnu89" } */ +/* { dg-options "-O2 -fdump-tree-pre-stats -std=gnu89 -fno-tree-loop-im" } */ typedef union tree_node *tree; struct tree_common { Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-16.c =================================================================== --- trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-16.c 2015-06-09 15:45:26.659339850 +0200 +++ trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-16.c 2016-05-18 11:50:17.428418769 +0200 @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-pre-stats -std=c99" } */ +/* { dg-options "-O2 -fdump-tree-pre-stats -std=c99 -fno-tree-loop-im" } */ int foo(int k, int *x) { int j=0; Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-18.c =================================================================== --- trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-18.c 2015-06-09 15:45:26.681340051 +0200 +++ trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-18.c 2016-05-18 11:50:30.372565939 +0200 @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-pre-details" } */ +/* { dg-options "-O2 -fdump-tree-pre-details -fno-tree-loop-im" } */ struct Bar { int a; int b; }; struct Foo { int x; struct Bar y; }; Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-20.c =================================================================== --- trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-20.c 2015-06-09 15:45:27.045343392 +0200 +++ trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-20.c 2016-05-18 11:50:59.072892246 +0200 @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-pre-stats" } */ +/* { dg-options "-O2 -fdump-tree-pre-stats -fno-tree-loop-im" } */ double pcheck; Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-3.c =================================================================== --- trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-3.c 2015-11-05 09:41:27.166224870 +0100 +++ trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-3.c 2016-05-18 11:51:13.045051099 +0200 @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-pre-stats" } */ +/* { dg-options "-O2 -fdump-tree-pre-stats -fno-tree-loop-im" } */ unsigned foo1 (unsigned a, unsigned b, unsigned j, unsigned k) { unsigned i; Index: trunk/gcc/testsuite/gfortran.dg/pr42108.f90 =================================================================== --- trunk.orig/gcc/testsuite/gfortran.dg/pr42108.f90 2015-06-09 15:45:08.686174805 +0200 +++ trunk/gcc/testsuite/gfortran.dg/pr42108.f90 2016-05-18 11:53:12.382407812 +0200 @@ -1,5 +1,5 @@ ! { dg-do compile } -! { dg-options "-O2 -fdump-tree-fre1 -fdump-tree-pre-details" } +! { dg-options "-O2 -fdump-tree-fre1 -fdump-tree-pre-details -fno-tree-loop-im" } subroutine eval(foo1,foo2,foo3,foo4,x,n,nnd) implicit real*8 (a-h,o-z)