summaryrefslogtreecommitdiff
path: root/gcc/tree-loop-linear.c
diff options
context:
space:
mode:
authorspop <spop@138bc75d-0d04-0410-961f-82ee72b054a4>2007-10-19 19:01:58 +0000
committerspop <spop@138bc75d-0d04-0410-961f-82ee72b054a4>2007-10-19 19:01:58 +0000
commit538dd0caf08b1136bd0b0f677ffc715fdd1f71f8 (patch)
tree65725d390db5c25a995bac2ec0111aaf66e74f84 /gcc/tree-loop-linear.c
parent26dfb89b89b3381b72f260af57f6bc30771b7edd (diff)
downloadgcc-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.c75
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,