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]

[vta] don't introduce default SSA nodes in debug stmts


The scenario alluded to by the long comment in after 'if (failed)' is
a transformation from:

BB #1
x_1 = PHI <...>;
...

BB (#1 -...->) #2
x_2 = PHI <x_1(?), x_1(?), ...>;
...

BB (#2 -...->) #3
# DEBUG x = x_2;
...

BB (#3 -...->, ...) #4
x_3 = PHI <x_2(#3), x_1(?), ...>
...

such that #1 dominates #2 dominates #3 precedes #4.  After
jump-threading, this turned into something like:

BB #1
x_1 = PHI <...>;
...

BB (#1 -...->) #2
...

BB (#2 -...->, #5 -...->) #3
# DEBUG x = x_5(D);
...       //  ^^^^  ???

BB (#3 -...->, ...) #4
x_3 = PHI <x_1(#3), ...>;
...

BB (#1 -...->) #5
x_4 = PHI <x_1(?#1), ...>;
...
use(x_4);

i.e., a diamond pattern is introduced between #1 and #3 such that #2
no longer dominates #3.  The reason why this is done is irrelevant for
this testcase.  The problem is that the reference to x_2 in the debug
stmt now doesn't have a PHI statement to rely on, and we can't
introduce one solely for the DEBUG statement, for this would cause
codegen differences.

The current implementation decides that there's no active value to
replace x_2 and thus creates a default definition.  This is a problem
because this definition is dead, and eventually it's removed from the
debug stmt, but the dead default definition is never entirely removed,
which causes other differences in SSA version numbering down the road.
We must avoid generating this default definition at the debug insn in
the first place.

Ideally, we should be able to figure out that x_1 is the definition to
use, like the code that updates the PHI node for x_3 finds out.  I
still haven't investigated how exactly this is done.  For now, killing
the information in debug insns that would have introduced default
definitions seems simpler and appropriate.  This shouldn't cause any
harm, for in all cases I can think of, when a debug statement is to
reference a default SSA definition, it would be right after an
assignment that references it as well, or result from some
transformation that started as such.  In these cases, the default
definition is in place already, so the change won't affect it.  It
only affects situations in which the default definition would be
introduced by an SSA update.  This would in turn indicate that any
previously-assigned value was completely optimized away, so dropping
the debug value/location is the right thing to do.

I'm going to check this into the vta branch soon.

for  gcc/ChangeLog.vta
from  Alexandre Oliva  <aoliva@redhat.com>

	* tree-into-ssa.c (maybe_replace_use_in_debug_insn): New.
	(rewrite_update_stmt): Never introduce uses of a default
	definition in a debug stmt.

Index: gcc/tree-into-ssa.c
===================================================================
--- gcc/tree-into-ssa.c.orig	2007-10-01 22:49:01.000000000 -0300
+++ gcc/tree-into-ssa.c	2007-10-31 06:02:13.000000000 -0200
@@ -2079,6 +2079,30 @@ maybe_replace_use (use_operand_p use_p)
 }
 
 
+/* Same as maybe_replace_use, but without introducing default stmts,
+   returning false to indicate a need to do so.  */
+
+static inline bool
+maybe_replace_use_in_debug_insn (use_operand_p use_p)
+{
+  tree rdef = NULL_TREE;
+  tree use = USE_FROM_PTR (use_p);
+  tree sym = DECL_P (use) ? use : SSA_NAME_VAR (use);
+
+  if (symbol_marked_for_renaming (sym))
+    rdef = get_current_def (sym);
+  else if (is_old_name (use))
+    rdef = get_current_def (use);
+  else
+    return true;
+
+  if (rdef && rdef != use)
+    SET_USE (use_p, rdef);
+
+  return rdef != NULL_TREE;
+}
+
+
 /* If the operand pointed to by DEF_P is an SSA name in NEW_SSA_NAMES
    or OLD_SSA_NAMES, or if it is a symbol marked for renaming,
    register it as the current definition for the names replaced by
@@ -2153,7 +2177,7 @@ rewrite_update_stmt (struct dom_walk_dat
 
   /* Rewrite USES included in OLD_SSA_NAMES and USES whose underlying
      symbol is marked for renaming.  */
-  if (REWRITE_THIS_STMT (stmt))
+  if (REWRITE_THIS_STMT (stmt) && !IS_DEBUG_STMT (stmt))
     {
       FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
 	maybe_replace_use (use_p);
@@ -2162,6 +2186,43 @@ rewrite_update_stmt (struct dom_walk_dat
 	FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_VIRTUAL_USES)
 	  maybe_replace_use (use_p);
     }
+  else if (REWRITE_THIS_STMT (stmt) && IS_DEBUG_STMT (stmt))
+    {
+      bool failed = false;
+
+      FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
+	if (!maybe_replace_use_in_debug_insn (use_p))
+	  {
+	    failed = true;
+	    break;
+	  }
+
+      if (!failed && need_to_update_vops_p)
+	FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_VIRTUAL_USES)
+	  if (!maybe_replace_use_in_debug_insn (use_p))
+	    {
+	      failed = true;
+	      break;
+	    }
+
+      if (failed)
+	{
+	  /* DOM sometimes threads jumps in such a way that a debug
+	     stmt ends up referencing a SSA variable that no longer
+	     dominates the debug stmt, but such that all incoming
+	     definitions refer to the same definition in an earlier
+	     dominator.  We could try to recover that definition
+	     somehow, but this will have to do for now.
+
+	     Introducing a default definition, which is what
+	     maybe_replace_use() would do in such cases, may modify
+	     code generation, for the otherwise-unused default
+	     definition would never go away, modifying SSA version
+	     numbers all over.  */
+	  VAR_DEBUG_VALUE_VALUE (stmt) = VAR_DEBUG_VALUE_NOVALUE;
+	  update_stmt (stmt);
+	}
+    }
 
   /* Register definitions of names in NEW_SSA_NAMES and OLD_SSA_NAMES.
      Also register definitions for names whose underlying symbol is
-- 
Alexandre Oliva         http://www.lsd.ic.unicamp.br/~oliva/
FSF Latin America Board Member         http://www.fsfla.org/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}

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