This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Fix PR34017: ICE in lambda_loopnest_to_gcc_loopnest


Hi,

We used to abort when the expression to be rewritten was a PHI_NODE,
but as Jakub remarked in the PR comments, there is no reason we cannot
transform the PHI_NODE expressions.  The attached patch is fixing this
bug by implementing the translation of PHI_NODEs in function of the
new induction variables.

The patch passed tree-ssa.exp, and I'm going to regstrap it tonight.
Okay for trunk after regtest?

Sebastian
-- 
AMD - GNU Tools
2008-01-09  Sebastian Pop  <sebastian.pop@amd.com>

	PR tree-optimization/34017
	* lambda-code.c (rewrite_expr_new_ivs, rewrite_phi_new_ivs): New.
	(lambda_loopnest_to_gcc_loopnest): Use these functions.

	* gcc.dg/tree-ssa/pr34017.c: New.

email:sebpop@gmail.com
branch:trunk
revision:HEAD
configure:
make:
check:

Index: testsuite/gcc.dg/tree-ssa/pr34017.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/pr34017.c	(revision 0)
+++ testsuite/gcc.dg/tree-ssa/pr34017.c	(revision 0)
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-loop-linear" } */
+
+extern int s;
+
+void
+foo (int *x, int y, int z)
+{
+ int m, n;
+ int o;
+ int p = x[0];
+ o = s;
+ for (m = 0; m < s; m++)
+   for (n = 0; n < s; n++)
+     {
+       if (x[n] != p)
+         continue;
+       if (m > z)
+         z = m;
+       if (n < o)
+         o = n;
+     }
+ for (m = y; m <= z; m++)
+   {
+   }
+}
Index: lambda-code.c
===================================================================
--- lambda-code.c	(revision 131307)
+++ lambda-code.c	(working copy)
@@ -1675,6 +1675,61 @@ remove_iv (tree iv_stmt)
     }
 }
 
+/* Rewrite the expression with the new induction variables.  */
+
+static void
+rewrite_expr_new_ivs (imm_use_iterator *imm_iter, tree stmt, size_t iv,
+		      tree type, lambda_trans_matrix transform,
+		      VEC(tree,heap) *new_ivs, struct obstack *lambda_obstack)
+{
+  use_operand_p use_p;
+  tree newiv, stmts;
+  lambda_body_vector newlbv;
+  lambda_body_vector lbv = lambda_body_vector_new (VEC_length (tree, new_ivs),
+						   lambda_obstack);
+
+  LBV_COEFFICIENTS (lbv)[iv] = 1;
+  newlbv = lambda_body_vector_compute_new (transform, lbv, lambda_obstack);
+  newiv = lbv_to_gcc_expression (newlbv, type, new_ivs, &stmts);
+
+  if (stmts)
+    {
+      block_stmt_iterator bsi = bsi_for_stmt (stmt);
+      bsi_insert_before (&bsi, stmts, BSI_SAME_STMT);
+    }
+
+  FOR_EACH_IMM_USE_ON_STMT (use_p, *imm_iter)
+    propagate_value (use_p, newiv);
+
+  update_stmt (stmt);
+}
+
+/* Rewrite the phi node with the new induction variables.  */
+
+static void
+rewrite_phi_new_ivs (imm_use_iterator *imm_iter, tree phi, size_t iv,
+		     tree type, lambda_trans_matrix transform,
+		     VEC(tree,heap) *new_ivs, struct obstack *lambda_obstack)
+{
+  int i;
+  use_operand_p use_p;
+  tree newiv, stmts;
+  lambda_body_vector newlbv;
+  lambda_body_vector lbv = lambda_body_vector_new (VEC_length (tree, new_ivs),
+						   lambda_obstack);
+
+  LBV_COEFFICIENTS (lbv)[iv] = 1;
+  newlbv = lambda_body_vector_compute_new (transform, lbv, lambda_obstack);
+  newiv = lbv_to_gcc_expression (newlbv, type, new_ivs, &stmts);
+
+  FOR_EACH_IMM_USE_ON_STMT (use_p, *imm_iter)
+    propagate_value (use_p, newiv);
+
+  if (stmts)
+    for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+      if (PHI_ARG_DEF (phi, i) == newiv)
+	bsi_insert_on_edge (PHI_ARG_EDGE (phi, i), stmts);
+}
 
 /* Transform a lambda loopnest NEW_LOOPNEST, which had TRANSFORM applied to
    it, back into gcc code.  This changes the
@@ -1698,7 +1753,7 @@ lambda_loopnest_to_gcc_loopnest (struct 
                                  struct obstack * lambda_obstack)
 {
   struct loop *temp;
-  size_t i = 0;
+  size_t iv, i = 0;
   size_t depth = 0;
   VEC(tree,heap) *new_ivs = NULL;
   tree oldiv;
@@ -1818,10 +1873,9 @@ lambda_loopnest_to_gcc_loopnest (struct 
   /* Rewrite uses of the old ivs so that they are now specified in terms of
      the new ivs.  */
 
-  for (i = 0; VEC_iterate (tree, old_ivs, i, oldiv); i++)
+  for (iv = 0; VEC_iterate (tree, old_ivs, iv, oldiv); iv++)
     {
       imm_use_iterator imm_iter;
-      use_operand_p use_p;
       tree oldiv_def;
       tree oldiv_stmt = SSA_NAME_DEF_STMT (oldiv);
       tree stmt;
@@ -1833,33 +1887,12 @@ lambda_loopnest_to_gcc_loopnest (struct 
       gcc_assert (oldiv_def != NULL_TREE);
 
       FOR_EACH_IMM_USE_STMT (stmt, imm_iter, oldiv_def)
-        {
-	  tree newiv, stmts;
-	  lambda_body_vector lbv, newlbv;
-
-	  gcc_assert (TREE_CODE (stmt) != PHI_NODE);
-
-	  /* Compute the new expression for the induction
-	     variable.  */
-	  depth = VEC_length (tree, new_ivs);
-          lbv = lambda_body_vector_new (depth, lambda_obstack);
-	  LBV_COEFFICIENTS (lbv)[i] = 1;
-	  
-          newlbv = lambda_body_vector_compute_new (transform, lbv,
-                                                   lambda_obstack);
-
-	  newiv = lbv_to_gcc_expression (newlbv, TREE_TYPE (oldiv),
-					 new_ivs, &stmts);
-	  if (stmts)
-	    {
-	      bsi = bsi_for_stmt (stmt);
-	      bsi_insert_before (&bsi, stmts, BSI_SAME_STMT);
-	    }
-
-	  FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
-	    propagate_value (use_p, newiv);
-	  update_stmt (stmt);
-	}
+	if (TREE_CODE (stmt) != PHI_NODE)
+	  rewrite_expr_new_ivs (&imm_iter, stmt, iv, TREE_TYPE (oldiv), 
+			       transform, new_ivs, lambda_obstack);
+	else
+	  rewrite_phi_new_ivs (&imm_iter, stmt, iv, TREE_TYPE (oldiv), 
+			       transform, new_ivs, lambda_obstack);
 
       /* Remove the now unused induction variable.  */
       VEC_safe_push (tree, heap, *remove_ivs, oldiv_stmt);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]