diff options
author | spop <spop@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-10-19 19:01:58 +0000 |
---|---|---|
committer | spop <spop@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-10-19 19:01:58 +0000 |
commit | 538dd0caf08b1136bd0b0f677ffc715fdd1f71f8 (patch) | |
tree | 65725d390db5c25a995bac2ec0111aaf66e74f84 /gcc/tree-loop-linear.c | |
parent | 26dfb89b89b3381b72f260af57f6bc30771b7edd (diff) | |
download | gcc-538dd0caf08b1136bd0b0f677ffc715fdd1f71f8.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@129494 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-loop-linear.c')
-rw-r--r-- | gcc/tree-loop-linear.c | 75 |
1 files changed, 43 insertions, 32 deletions
diff --git a/gcc/tree-loop-linear.c b/gcc/tree-loop-linear.c index 295993f1bf9..88a77dd228c 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, |