This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[vta] don't introduce default SSA nodes in debug stmts
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 05 Nov 2007 06:21:23 -0200
- Subject: [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}