PR42917 (make lambda-code VTA aware)

Aldy Hernandez aldyh@redhat.com
Wed Mar 10 14:52:00 GMT 2010


Howdy.

-ftree-loop-linear is causing comparison debug failures because
lambda-code.c doesn't deal with debug statements.

There are two places that need to learn about debug statements in
lambda-code: loop interchange for (already) perfectly nested loops, and
perfect_nestify() where we make the loops perfectly nested if possible.
I have fixed the first one (loop interchange), and would like to fix the
other one on a follow-up patch, since the whole thing wasn't working at
all, and at least now we have a couple dozen testcases fixed.

The patch below moves the debug statement for the induction variable
into the inner loop since the induction variable willl also be moved
into the inner loop.  Without this, the debug statement would reference
an induction variable that hasn't been defined yet and we get a use that
is not dominated by the definition.

There are no regressions on a regular test run, and I have also tested with:

	RUNTESTFLAGS=--target_board=unix/-ftree-loop-linear/-fcompare-debug

and found a couple dozen testcases fixed that previously failed.  The PR
is also fixed.

Next I will work on the rest of the -ftree-loop-linear failures.

OK for trunk?

p.s.  I have a "??" below where I'm wondering if we should remove the
DEBUG statement altogether as opposed to resetting it's value.  What is
proper form here?

	PR tree-optimization/42917
	* lambda-code.c (lbv_to_gcc_expression): Avoid new temporaries if
	requested.
	(remove_iv): Handle debug statements.
	(lambda_loopnest_to_gcc_loopnest): Move induction variable DEBUG
	statement into the inner loop.
	Add new argument to lbv_to_gcc_expression.
	(not_interesting_stmt): Debug statements are not interesting.

Index: lambda-code.c
===================================================================
--- lambda-code.c	(revision 157277)
+++ lambda-code.c	(working copy)
@@ -1540,12 +1540,17 @@ gcc_loopnest_to_lambda_loopnest (struct 
    STMTS_TO_INSERT is a pointer to a tree where the statements we need to be
    inserted for us are stored.  INDUCTION_VARS is the array of induction
    variables for the loop this LBV is from.  TYPE is the tree type to use for
-   the variables and trees involved.  */
+   the variables and trees involved.
+
+   AVOID_NEW_TMPS is true if we should avoid making new SSA names
+   while performing the conversion.  This should be true when
+   converting debug statements.  */
 
 static tree
 lbv_to_gcc_expression (lambda_body_vector lbv,
 		       tree type, VEC(tree,heap) *induction_vars,
-		       gimple_seq *stmts_to_insert)
+		       gimple_seq *stmts_to_insert,
+		       bool avoid_new_tmps)
 {
   int k;
   tree resvar;
@@ -1556,8 +1561,13 @@ lbv_to_gcc_expression (lambda_body_vecto
   if (k != 1)
     expr = fold_build2 (CEIL_DIV_EXPR, type, expr, build_int_cst (type, k));
 
-  resvar = create_tmp_var (type, "lbvtmp");
-  add_referenced_var (resvar);
+  if (avoid_new_tmps)
+    resvar = NULL;
+  else
+    {
+      resvar = create_tmp_var (type, "lbvtmp");
+      add_referenced_var (resvar);
+    }
   return force_gimple_operand (fold (expr), stmts_to_insert, true, resvar);
 }
 
@@ -1657,8 +1667,15 @@ remove_iv (gimple iv_stmt)
 	    continue;
 
 	  FOR_EACH_IMM_USE_STMT (stmt, imm_iter, arg)
-	    if (stmt != iv_stmt)
-	      used = true;
+	    {
+	      if (is_gimple_debug (stmt))
+		{
+		  gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
+		  gsi_remove (&gsi, true);
+		}
+	      else if (stmt != iv_stmt)
+		used = true;
+	    }
 
 	  if (!used)
 	    remove_iv (SSA_NAME_DEF_STMT (arg));
@@ -1775,6 +1792,45 @@ lambda_loopnest_to_gcc_loopnest (struct 
       if (stmts)
 	gsi_insert_seq_before (&bsi, stmts, GSI_NEW_STMT);
 
+      /* Move oldiv DEBUG statement from the outer loop into the inner
+	 loop.  */
+      if (MAY_HAVE_DEBUG_STMTS && temp->inner)
+	{
+	  gimple_stmt_iterator outer_gsi, inner_gsi;
+	  gimple stmt, ivdebug = NULL;
+
+	  /* Find oldiv's DEBUG statement if available.  */
+	  outer_gsi = gsi_after_labels (temp->header);
+	  for (; !gsi_end_p (outer_gsi); gsi_next (&outer_gsi))
+	    {
+	      stmt = gsi_stmt (outer_gsi);
+	      if (is_gimple_debug (stmt))
+		{
+		  tree val;
+		  gcc_assert (gimple_debug_bind_p (stmt));
+		  val = gimple_debug_bind_get_value (stmt);
+		  if (val == oldiv)
+		    {
+		      /* Avoid doing a deep copy.  */
+		      tree var = gimple_debug_bind_get_var (stmt);
+		      ivdebug = gimple_build_debug_bind (var, val, stmt);
+		      /* ?? Perhaps remove instead of a reset ??  */
+		      gimple_debug_bind_reset_value (stmt);
+		      update_stmt (stmt);
+		    }
+		}
+	    }
+
+	  if (ivdebug)
+	    {
+	      inner_gsi = gsi_after_labels (temp->inner->header);
+	      for (; !gsi_end_p (inner_gsi); gsi_next (&inner_gsi))
+		if (gimple_code (gsi_stmt (inner_gsi)) != GIMPLE_PHI)
+		  break;
+	      gsi_insert_before (&inner_gsi, ivdebug, GSI_SAME_STMT);
+	    }
+	}
+
       /* Create the new iv.  */
 
       standard_iv_increment_position (temp, &bsi, &insert_after);
@@ -1850,7 +1906,8 @@ lambda_loopnest_to_gcc_loopnest (struct 
 
 	  stmts = NULL;
 	  newiv = lbv_to_gcc_expression (newlbv, TREE_TYPE (oldiv),
-					 new_ivs, &stmts);
+					 new_ivs, &stmts,
+					 is_gimple_debug (stmt));
 
 	  if (stmts && gimple_code (stmt) != GIMPLE_PHI)
 	    {
@@ -1885,7 +1942,8 @@ not_interesting_stmt (gimple stmt)
      loop, we would have already failed the number of exits tests.  */
   if (gimple_code (stmt) == GIMPLE_LABEL
       || gimple_code (stmt) == GIMPLE_GOTO
-      || gimple_code (stmt) == GIMPLE_COND)
+      || gimple_code (stmt) == GIMPLE_COND
+      || is_gimple_debug (stmt))
     return true;
   return false;
 }



More information about the Gcc-patches mailing list