OSDN Git Service

2007-10-19 Sebastian Pop <sebastian.pop@amd.com>
authorspop <spop@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 19 Oct 2007 19:01:58 +0000 (19:01 +0000)
committerspop <spop@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 19 Oct 2007 19:01:58 +0000 (19:01 +0000)
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

gcc/ChangeLog
gcc/lambda-code.c
gcc/testsuite/gcc.dg/tree-ssa/ltrans-3.c
gcc/testsuite/gcc.dg/tree-ssa/pr23820.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/pr24309.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/pr33766.c [new file with mode: 0644]
gcc/tree-loop-linear.c

index f553902..57d7f6f 100644 (file)
@@ -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
index 84ad869..db92bc9 100644 (file)
@@ -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.
index 86424ab..5f2f5ca 100644 (file)
@@ -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 (file)
index 0000000..ee855e1
--- /dev/null
@@ -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 (file)
index 0000000..b50e7a8
--- /dev/null
@@ -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 (file)
index 0000000..f6bb506
--- /dev/null
@@ -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];
+}
+
index 295993f..88a77dd 100644 (file)
@@ -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,