From f93444883de1497f29370fd7f1ab5d828b9b08e9 Mon Sep 17 00:00:00 2001
From: Sebastian Pop <sebastian.pop@amd.com>
Date: Tue, 13 Jan 2009 15:33:13 +0000
Subject: [PATCH] re PR middle-end/38786 ([graphite] ICE with -floop-block in
 verify_ssa)

2009-01-13  Sebastian Pop  <sebastian.pop@amd.com>

	PR tree-optimization/38786
	* gcc.dg/graphite/pr38786.c: New.
	* graphite.c (expand_scalar_variables_ssa_name): New, outlined from
	the SSA_NAME case of expand_scalar_variables_expr.
	Set the type of an expression to the type of its assign	statement.
	(expand_scalar_variables_expr): Also gather the scalar computation
	used to index the memory access.  Do not pass loop_p.
	Fix comment.  Stop recursion on tcc_constant or tcc_declaration.
	(expand_scalar_variables_stmt): Pass to expand_scalar_variables_expr
	the gimple_stmt_iterator where it inserts new code.  Do not pass loop_p.
	(copy_bb_and_scalar_dependences): Do not pass loop_p.
	(translate_clast): Update call to copy_bb_and_scalar_dependences.

From-SVN: r143341
---
 gcc/ChangeLog                           |  14 ++
 gcc/graphite.c                          | 200 ++++++++++++++++--------
 gcc/testsuite/ChangeLog                 |   5 +
 gcc/testsuite/gcc.dg/graphite/pr38786.c |  40 +++++
 4 files changed, 190 insertions(+), 69 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/graphite/pr38786.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e97f3ba37dd5..bd96796a12da 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2009-01-13  Sebastian Pop  <sebastian.pop@amd.com>
+
+	PR tree-optimization/38786
+	* graphite.c (expand_scalar_variables_ssa_name): New, outlined from
+	the SSA_NAME case of expand_scalar_variables_expr.
+	Set the type of an expression to the type of its assign	statement.
+	(expand_scalar_variables_expr): Also gather the scalar computation
+	used to index the memory access.  Do not pass loop_p.
+	Fix comment.  Stop recursion on tcc_constant or tcc_declaration.
+	(expand_scalar_variables_stmt): Pass to expand_scalar_variables_expr
+	the gimple_stmt_iterator where it inserts new code.  Do not pass loop_p.
+	(copy_bb_and_scalar_dependences): Do not pass loop_p.
+	(translate_clast): Update call to copy_bb_and_scalar_dependences.
+
 2009-01-13  Sebastian Pop  <sebastian.pop@amd.com>
 
 	* graphite.h (debug_value): Removed.
diff --git a/gcc/graphite.c b/gcc/graphite.c
index e81a93ad018d..a9d8d450d10b 100644
--- a/gcc/graphite.c
+++ b/gcc/graphite.c
@@ -4082,31 +4082,123 @@ is_iv (tree name)
 }
 
 static void expand_scalar_variables_stmt (gimple, basic_block, scop_p,
-					  loop_p, htab_t);
+					  htab_t);
+static tree
+expand_scalar_variables_expr (tree, tree, enum tree_code, tree, basic_block,
+			      scop_p, htab_t, gimple_stmt_iterator *);
+
+/* Copies at GSI all the scalar computations on which the ssa_name OP0
+   depends on in the SCOP: these are all the scalar variables used in
+   the definition of OP0, that are defined outside BB and still in the
+   SCOP, i.e. not a parameter of the SCOP.  The expression that is
+   returned contains only induction variables from the generated code:
+   MAP contains the induction variables renaming mapping, and is used
+   to translate the names of induction variables.  */
+
+static tree
+expand_scalar_variables_ssa_name (tree op0, basic_block bb,
+				  scop_p scop, htab_t map, 
+				  gimple_stmt_iterator *gsi)
+{
+  tree var0, var1, type;
+  gimple def_stmt;
+  enum tree_code subcode;
+      
+  if (is_parameter (scop, op0)
+      || is_iv (op0))
+    return get_new_name_from_old_name (map, op0);
+      
+  def_stmt = SSA_NAME_DEF_STMT (op0);
+      
+  if (gimple_bb (def_stmt) == bb)
+    {
+      /* If the defining statement is in the basic block already
+	 we do not need to create a new expression for it, we
+	 only need to ensure its operands are expanded.  */
+      expand_scalar_variables_stmt (def_stmt, bb, scop, map);
+      return get_new_name_from_old_name (map, op0);
+    }
+  else
+    {
+      if (gimple_code (def_stmt) != GIMPLE_ASSIGN
+	  || !bb_in_scop_p (gimple_bb (def_stmt), scop))
+	return get_new_name_from_old_name (map, op0);
+
+      var0 = gimple_assign_rhs1 (def_stmt);
+      subcode = gimple_assign_rhs_code (def_stmt);
+      var1 = gimple_assign_rhs2 (def_stmt);
+      type = gimple_expr_type (def_stmt);
+
+      return expand_scalar_variables_expr (type, var0, subcode, var1, bb, scop,
+					   map, gsi);
+    }
+}
 
-/* Constructs a tree which only contains old_ivs and parameters.  Any
-   other variables that are defined outside BB will be eliminated by
-   using their definitions in the constructed tree.  OLD_LOOP_FATHER
-   is the original loop that contained BB.  */
+/* Copies at GSI all the scalar computations on which the expression
+   OP0 CODE OP1 depends on in the SCOP: these are all the scalar
+   variables used in OP0 and OP1, defined outside BB and still defined
+   in the SCOP, i.e. not a parameter of the SCOP.  The expression that
+   is returned contains only induction variables from the generated
+   code: MAP contains the induction variables renaming mapping, and is
+   used to translate the names of induction variables.  */
 
 static tree
 expand_scalar_variables_expr (tree type, tree op0, enum tree_code code, 
 			      tree op1, basic_block bb, scop_p scop, 
-			      loop_p old_loop_father, htab_t map)
+			      htab_t map, gimple_stmt_iterator *gsi)
 {
-  if ((TREE_CODE_CLASS (code) == tcc_constant
-       && code == INTEGER_CST)
-      || TREE_CODE_CLASS (code) == tcc_reference)
+  if (TREE_CODE_CLASS (code) == tcc_constant
+      || TREE_CODE_CLASS (code) == tcc_declaration)
     return op0;
 
+  /* For data references we have to duplicate also its memory
+     indexing.  */
+  if (TREE_CODE_CLASS (code) == tcc_reference)
+    {
+      switch (code)
+	{
+	case INDIRECT_REF:
+	  {
+	    tree old_name = TREE_OPERAND (op0, 0);
+	    tree expr = expand_scalar_variables_ssa_name
+	      (old_name, bb, scop, map, gsi);
+	    tree new_name = force_gimple_operand_gsi (gsi, expr, true, NULL,
+						      true, GSI_SAME_STMT);
+
+	    set_symbol_mem_tag (SSA_NAME_VAR (new_name),
+				symbol_mem_tag (SSA_NAME_VAR (old_name)));
+	    return fold_build1 (code, type, new_name);
+	  }
+
+	case ARRAY_REF:
+	  {
+	    tree op00 = TREE_OPERAND (op0, 0);
+	    tree op01 = TREE_OPERAND (op0, 1);
+	    tree op02 = TREE_OPERAND (op0, 2);
+	    tree op03 = TREE_OPERAND (op0, 3);
+	    tree base = expand_scalar_variables_expr
+	      (TREE_TYPE (op00), op00, TREE_CODE (op00), NULL, bb, scop,
+	       map, gsi);
+	    tree subscript = expand_scalar_variables_expr
+	      (TREE_TYPE (op01), op01, TREE_CODE (op01), NULL, bb, scop,
+	       map, gsi);
+
+	    return build4 (ARRAY_REF, type, base, subscript, op02, op03);
+	  }
+
+	default:
+	  /* The above cases should catch everything.  */
+	  gcc_unreachable ();
+	}
+    }
+
   if (TREE_CODE_CLASS (code) == tcc_unary)
     {
       tree op0_type = TREE_TYPE (op0);
       enum tree_code op0_code = TREE_CODE (op0);
-      tree op0_expr = 
-	expand_scalar_variables_expr (op0_type, op0, op0_code,
-				      NULL, bb, scop, old_loop_father, map);
-
+      tree op0_expr = expand_scalar_variables_expr (op0_type, op0, op0_code,
+						    NULL, bb, scop, map, gsi);
+  
       return fold_build1 (code, type, op0_expr);
     }
 
@@ -4114,68 +4206,38 @@ expand_scalar_variables_expr (tree type, tree op0, enum tree_code code,
     {
       tree op0_type = TREE_TYPE (op0);
       enum tree_code op0_code = TREE_CODE (op0);
-      tree op0_expr = 
-	expand_scalar_variables_expr (op0_type, op0, op0_code,
-				      NULL, bb, scop, old_loop_father, map);
+      tree op0_expr = expand_scalar_variables_expr (op0_type, op0, op0_code,
+						    NULL, bb, scop, map, gsi);
       tree op1_type = TREE_TYPE (op1);
       enum tree_code op1_code = TREE_CODE (op1);
-      tree op1_expr = 
-	expand_scalar_variables_expr (op1_type, op1, op1_code,
-				      NULL, bb, scop, old_loop_father, map);
+      tree op1_expr = expand_scalar_variables_expr (op1_type, op1, op1_code,
+						    NULL, bb, scop, map, gsi);
 
       return fold_build2 (code, type, op0_expr, op1_expr);
     }
 
   if (code == SSA_NAME)
-    {
-      tree var0, var1;
-      gimple def_stmt;
-      enum tree_code subcode;
-      
-      if (is_parameter (scop, op0)
-	  || is_iv (op0))
-	return get_new_name_from_old_name (map, op0);
-      
-      def_stmt = SSA_NAME_DEF_STMT (op0);
-      
-      if (gimple_bb (def_stmt) == bb)
-	{
-	  /* If the defining statement is in the basic block already
-	     we do not need to create a new expression for it, we
-	     only need to ensure its operands are expanded.  */
-	  expand_scalar_variables_stmt (def_stmt, bb, scop,
-					old_loop_father, map);
-	  return get_new_name_from_old_name (map, op0);
-	}
-      else
-	{
-	  if (gimple_code (def_stmt) != GIMPLE_ASSIGN
-	      || !bb_in_scop_p (gimple_bb (def_stmt), scop))
-	    return get_new_name_from_old_name (map, op0);
-
-	  var0 = gimple_assign_rhs1 (def_stmt);
-	  subcode = gimple_assign_rhs_code (def_stmt);
-	  var1 = gimple_assign_rhs2 (def_stmt);
-
-	  return expand_scalar_variables_expr (type, var0, subcode, var1,
-					       bb, scop, old_loop_father, map);
-	}
-    }
+    return expand_scalar_variables_ssa_name (op0, bb, scop, map, gsi);
 
   gcc_unreachable ();
   return NULL;
 }
 
-/* Replicates any uses of non-parameters and non-old-ivs variablesthat
-   are defind outside BB with code that is inserted in BB.
-   OLD_LOOP_FATHER is the original loop that contained STMT.  */
+/* Copies at the beginning of BB all the scalar computations on which
+   STMT depends on in the SCOP: these are all the scalar variables used
+   in STMT, defined outside BB and still defined in the SCOP, i.e. not a
+   parameter of the SCOP.  The expression that is returned contains
+   only induction variables from the generated code: MAP contains the
+   induction variables renaming mapping, and is used to translate the
+   names of induction variables.  */
  
 static void
 expand_scalar_variables_stmt (gimple stmt, basic_block bb, scop_p scop,
-			      loop_p old_loop_father, htab_t map)
+			      htab_t map)
 {
   ssa_op_iter iter;
   use_operand_p use_p;
+  gimple_stmt_iterator gsi = gsi_after_labels (bb);
 
   FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
     {
@@ -4183,10 +4245,9 @@ expand_scalar_variables_stmt (gimple stmt, basic_block bb, scop_p scop,
       tree type = TREE_TYPE (use);
       enum tree_code code = TREE_CODE (use);
       tree use_expr = expand_scalar_variables_expr (type, use, code, NULL, bb,
-						    scop, old_loop_father, map);
+						    scop, map, &gsi);
       if (use_expr != use)
 	{
-	  gimple_stmt_iterator gsi = gsi_after_labels (bb);
 	  tree new_use =
 	    force_gimple_operand_gsi (&gsi, use_expr, true, NULL,
 				      true, GSI_NEW_STMT);
@@ -4197,21 +4258,23 @@ expand_scalar_variables_stmt (gimple stmt, basic_block bb, scop_p scop,
   update_stmt (stmt);
 }
 
-/* Copies the definitions outside of BB of variables that are not
-   induction variables nor parameters.  BB must only contain
-   "external" references to these types of variables.  OLD_LOOP_FATHER
-   is the original loop that contained BB.  */
+/* Copies at the beginning of BB all the scalar computations on which
+   BB depends on in the SCOP: these are all the scalar variables used
+   in BB, defined outside BB and still defined in the SCOP, i.e. not a
+   parameter of the SCOP.  The expression that is returned contains
+   only induction variables from the generated code: MAP contains the
+   induction variables renaming mapping, and is used to translate the
+   names of induction variables.  */
 
 static void 
-expand_scalar_variables (basic_block bb, scop_p scop, 
-			 loop_p old_loop_father, htab_t map)
+expand_scalar_variables (basic_block bb, scop_p scop, htab_t map)
 {
   gimple_stmt_iterator gsi;
   
   for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi);)
     {
       gimple stmt = gsi_stmt (gsi);
-      expand_scalar_variables_stmt (stmt, bb, scop, old_loop_father, map);
+      expand_scalar_variables_stmt (stmt, bb, scop, map);
       gsi_next (&gsi);
     }
 }
@@ -4388,7 +4451,6 @@ register_scop_liveout_renames (scop_p scop, htab_t rename_map)
  
 static edge
 copy_bb_and_scalar_dependences (basic_block bb, scop_p scop,
-				loop_p context_loop,
 				edge next_e, htab_t map)
 {
   basic_block new_bb = split_edge (next_e);
@@ -4398,7 +4460,7 @@ copy_bb_and_scalar_dependences (basic_block bb, scop_p scop,
   remove_condition (new_bb);
   rename_variables (new_bb, map);
   remove_phi_nodes (new_bb);
-  expand_scalar_variables (new_bb, scop, context_loop, map);
+  expand_scalar_variables (new_bb, scop, map);
   register_scop_liveout_renames (scop, map);
 
   return next_e;
@@ -4570,7 +4632,7 @@ translate_clast (scop_p scop, struct loop *context_loop,
       loop_iv_stack_patch_for_consts (ivstack, (struct clast_user_stmt *) stmt);
       build_iv_mapping (ivstack, map, gbb, scop);
       next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), scop,
-					       context_loop, next_e, map);
+					       next_e, map);
       htab_delete (map);
       loop_iv_stack_remove_constants (ivstack);
       update_ssa (TODO_update_ssa);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a59c294453c0..c05a25a1203a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2009-01-13  Sebastian Pop  <sebastian.pop@amd.com>
+
+	PR tree-optimization/38786
+	* gcc.dg/graphite/pr38786.c: New.
+
 2009-01-13  Uros Bizjak  <ubizjak@gmail.com>
 
 	Revert:
diff --git a/gcc/testsuite/gcc.dg/graphite/pr38786.c b/gcc/testsuite/gcc.dg/graphite/pr38786.c
new file mode 100644
index 000000000000..2e68185ab620
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/graphite/pr38786.c
@@ -0,0 +1,40 @@
+/* { dg-options "-O2 -fgraphite-identity" } */
+
+typedef struct
+{
+  int ****cofAC;
+} ImageParameters;
+typedef struct
+{
+  int ****cofAC;
+} RD_DATA;
+extern RD_DATA *rdopt;
+extern ImageParameters *img;
+dummy_slice_too_big (int bits_slice)
+{
+  int i, j, k, l;
+  for (j = 0; j < 4; j++)
+    for (k = 0; k < 2; k++)
+      for (l = 0; l < 65; l++)
+	img->cofAC[i][j][k][l] = rdopt->cofAC[i][j][k][l];
+}
+/* { dg-options "-O2 -fgraphite-identity" } */
+
+typedef struct
+{
+  int ****cofAC;
+} ImageParameters;
+typedef struct
+{
+  int ****cofAC;
+} RD_DATA;
+extern RD_DATA *rdopt;
+extern ImageParameters *img;
+dummy_slice_too_big (int bits_slice)
+{
+  int i, j, k, l;
+  for (j = 0; j < 4; j++)
+    for (k = 0; k < 2; k++)
+      for (l = 0; l < 65; l++)
+	img->cofAC[i][j][k][l] = rdopt->cofAC[i][j][k][l];
+}
-- 
GitLab