diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/lambda-code.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/ltrans-3.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr23820.c | 26 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr24309.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr33766.c | 19 | ||||
-rw-r--r-- | gcc/tree-loop-linear.c | 75 |
7 files changed, 135 insertions, 37 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f553902..57d7f6f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2007-10-19 Sebastian Pop <sebastian.pop@amd.com> + + PR tree-optimization/23820 + PR tree-optimization/24309 + PR tree-optimization/33766 + * testsuite/gcc.dg/tree-ssa/pr23820.c: New. + * testsuite/gcc.dg/tree-ssa/pr24309.c: New. + * testsuite/gcc.dg/tree-ssa/pr33766.c: New. + * testsuite/gcc.dg/tree-ssa/ltrans-3.c: XFAILed. + * tree-loop-linear.c (perfect_loop_nest_depth): New. + (linear_transform_loops): Use perfect_loop_nest_depth. + * lambda-code.c (perfect_nest_p): Outer loops in perfect nests + should have a single condition: their exit. + 2007-10-19 Richard Guenther <rguenther@suse.de> PR middle-end/33816 diff --git a/gcc/lambda-code.c b/gcc/lambda-code.c index 84ad869..db92bc9 100644 --- a/gcc/lambda-code.c +++ b/gcc/lambda-code.c @@ -1972,32 +1972,42 @@ perfect_nest_p (struct loop *loop) size_t i; tree exit_cond; + /* Loops at depth 0 are perfect nests. */ if (!loop->inner) return true; + bbs = get_loop_body (loop); exit_cond = get_loop_exit_condition (loop); + for (i = 0; i < loop->num_nodes; i++) { if (bbs[i]->loop_father == loop) { block_stmt_iterator bsi; + for (bsi = bsi_start (bbs[i]); !bsi_end_p (bsi); bsi_next (&bsi)) { tree stmt = bsi_stmt (bsi); + + if (TREE_CODE (stmt) == COND_EXPR + && exit_cond != stmt) + goto non_perfectly_nested; + if (stmt == exit_cond || not_interesting_stmt (stmt) || stmt_is_bumper_for_loop (loop, stmt)) continue; + + non_perfectly_nested: free (bbs); return false; } } } + free (bbs); - /* See if the inner loops are perfectly nested as well. */ - if (loop->inner) - return perfect_nest_p (loop->inner); - return true; + + return perfect_nest_p (loop->inner); } /* Replace the USES of X in STMT, or uses with the same step as X with Y. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ltrans-3.c b/gcc/testsuite/gcc.dg/tree-ssa/ltrans-3.c index 86424ab..5f2f5ca 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ltrans-3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ltrans-3.c @@ -17,5 +17,5 @@ int foo(int N, int *res) *res = sum + N; } -/* { dg-final { scan-tree-dump-times "transformed loop" 1 "ltrans"} } */ +/* { dg-final { scan-tree-dump-times "transformed loop" 1 "ltrans" { xfail *-*-* } } } */ /* { dg-final { cleanup-tree-dump "ltrans" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr23820.c b/gcc/testsuite/gcc.dg/tree-ssa/pr23820.c new file mode 100644 index 0000000..ee855e1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr23820.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-loop-linear" } */ + +int t [2][4]; + +void foo (void) +{ + int i, j, k, v; + float e; + for (;;) + { + v = 0; + for (j = 0; j < 2; j ++) + { + for (k = 2; k < 4; k ++) + { + e = 0.0; + for (i = 0; i < 4; i ++) + e += t [j][i]; + if (e) + v = j; + } + } + t [v][0] = 0; + } +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr24309.c b/gcc/testsuite/gcc.dg/tree-ssa/pr24309.c new file mode 100644 index 0000000..b50e7a8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr24309.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-loop-linear" } */ + +float weight[10]; +void lsp_weight_quant(float *x, char *cdbk) +{ + int i,j; + float dist; + int best_id=0; + for (i=0;i<16;i++) + { + for (j=0;j<10;j++) + dist=dist+weight[j]; + if (dist<0) + best_id=i; + } + x[j] = cdbk[best_id*10+j]; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr33766.c b/gcc/testsuite/gcc.dg/tree-ssa/pr33766.c new file mode 100644 index 0000000..f6bb506 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr33766.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-loop-linear" } */ + +float +fxt1_quantize_ALPHA1() +{ + int j1; + int i; + float *tv; + for (j1 = 1; j1; j1++) { + float e; + for (i = 1; i; i++) + e = tv[i]; + if (e) + i = j1; + } + return tv[i]; +} + diff --git a/gcc/tree-loop-linear.c b/gcc/tree-loop-linear.c index 295993f..88a77dd 100644 --- a/gcc/tree-loop-linear.c +++ b/gcc/tree-loop-linear.c @@ -244,6 +244,46 @@ try_interchange_loops (lambda_trans_matrix trans, return trans; } +/* Return the number of nested loops in LOOP_NEST, or 0 if the loops + are not perfectly nested. */ + +static unsigned int +perfect_loop_nest_depth (struct loop *loop_nest) +{ + struct loop *temp; + unsigned int depth = 1; + + /* If it's not a loop nest, we don't want it. We also don't handle + sibling loops properly, which are loops of the following form: + + | for (i = 0; i < 50; i++) + | { + | for (j = 0; j < 50; j++) + | { + | ... + | } + | for (j = 0; j < 50; j++) + | { + | ... + | } + | } + */ + + if (!loop_nest->inner || !single_exit (loop_nest)) + return 0; + + for (temp = loop_nest->inner; temp; temp = temp->inner) + { + /* If we have a sibling loop or multiple exit edges, jump ship. */ + if (temp->next || !single_exit (temp)) + return 0; + + depth++; + } + + return depth; +} + /* Perform a set of linear transforms on loops. */ void @@ -263,47 +303,18 @@ linear_transform_loops (void) unsigned int depth = 0; VEC (ddr_p, heap) *dependence_relations; VEC (data_reference_p, heap) *datarefs; - struct loop *temp; lambda_loopnest before, after; lambda_trans_matrix trans; - bool problem = false; struct obstack lambda_obstack; gcc_obstack_init (&lambda_obstack); - /* If it's not a loop nest, we don't want it. - We also don't handle sibling loops properly, - which are loops of the following form: - for (i = 0; i < 50; i++) - { - for (j = 0; j < 50; j++) - { - ... - } - for (j = 0; j < 50; j++) - { - ... - } - } */ - if (!loop_nest->inner || !single_exit (loop_nest)) + depth = perfect_loop_nest_depth (loop_nest); + if (depth == 0) continue; + VEC_truncate (tree, oldivs, 0); VEC_truncate (tree, invariants, 0); - depth = 1; - for (temp = loop_nest->inner; temp; temp = temp->inner) - { - /* If we have a sibling loop or multiple exit edges, jump ship. */ - if (temp->next || !single_exit (temp)) - { - problem = true; - break; - } - depth ++; - } - if (problem) - continue; - /* Analyze data references and dependence relations using scev. */ - datarefs = VEC_alloc (data_reference_p, heap, 10); dependence_relations = VEC_alloc (ddr_p, heap, 10 * 10); compute_data_dependences_for_loop (loop_nest, true, &datarefs, |