aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-into-ssa.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-into-ssa.c')
-rw-r--r--gcc/tree-into-ssa.c106
1 files changed, 99 insertions, 7 deletions
diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
index bdec080..9f06e8c 100644
--- a/gcc/tree-into-ssa.c
+++ b/gcc/tree-into-ssa.c
@@ -749,6 +749,9 @@ mark_def_sites (basic_block bb, gimple stmt, bitmap kills)
set_register_defs (stmt, false);
set_rewrite_uses (stmt, false);
+ if (is_gimple_debug (stmt))
+ return;
+
/* If a variable is used before being set, then the variable is live
across a block boundary, so mark it live-on-entry to BB. */
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
@@ -1051,7 +1054,6 @@ mark_phi_for_rewrite (basic_block bb, gimple phi)
VEC_replace (gimple_vec, phis_to_rewrite, idx, phis);
}
-
/* Insert PHI nodes for variable VAR using the iterated dominance
frontier given in PHI_INSERTION_POINTS. If UPDATE_P is true, this
function assumes that the caller is incrementally updating the
@@ -1118,8 +1120,17 @@ insert_phi_nodes_for (tree var, bitmap phi_insertion_points, bool update_p)
}
else
{
+ tree tracked_var;
gcc_assert (DECL_P (var));
phi = create_phi_node (var, bb);
+ if (!update_p && (tracked_var = target_for_debug_bind (var)))
+ {
+ gimple note = gimple_build_debug_bind (tracked_var,
+ PHI_RESULT (phi),
+ phi);
+ gimple_stmt_iterator si = gsi_after_labels (bb);
+ gsi_insert_before (&si, note, GSI_SAME_STMT);
+ }
}
/* Mark this PHI node as interesting for update_ssa. */
@@ -1260,11 +1271,12 @@ get_reaching_def (tree var)
definition of a variable when a new real or virtual definition is found. */
static void
-rewrite_stmt (gimple stmt)
+rewrite_stmt (gimple_stmt_iterator si)
{
use_operand_p use_p;
def_operand_p def_p;
ssa_op_iter iter;
+ gimple stmt = gsi_stmt (si);
/* If mark_def_sites decided that we don't need to rewrite this
statement, ignore it. */
@@ -1293,9 +1305,18 @@ rewrite_stmt (gimple stmt)
FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_DEF)
{
tree var = DEF_FROM_PTR (def_p);
+ tree name = make_ssa_name (var, stmt);
+ tree tracked_var;
gcc_assert (DECL_P (var));
- SET_DEF (def_p, make_ssa_name (var, stmt));
+ SET_DEF (def_p, name);
register_new_def (DEF_FROM_PTR (def_p), var);
+
+ tracked_var = target_for_debug_bind (var);
+ if (tracked_var)
+ {
+ gimple note = gimple_build_debug_bind (tracked_var, name, stmt);
+ gsi_insert_after (&si, note, GSI_SAME_STMT);
+ }
}
}
@@ -1366,7 +1387,7 @@ rewrite_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
of a variable when a new real or virtual definition is found. */
if (TEST_BIT (interesting_blocks, bb->index))
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
- rewrite_stmt (gsi_stmt (gsi));
+ rewrite_stmt (gsi);
/* Step 3. Visit all the successor blocks of BB looking for PHI nodes.
For every PHI node found, add a new argument containing the current
@@ -1759,6 +1780,38 @@ 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_stmt (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);
+ /* We can't assume that, if there's no current definition, the
+ default one should be used. It could be the case that we've
+ rearranged blocks so that the earlier definition no longer
+ dominates the use. */
+ if (!rdef && SSA_NAME_IS_DEFAULT_DEF (use))
+ rdef = use;
+ }
+ else
+ rdef = use;
+
+ 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
@@ -1825,8 +1878,42 @@ rewrite_update_stmt (gimple stmt)
/* Rewrite USES included in OLD_SSA_NAMES and USES whose underlying
symbol is marked for renaming. */
if (rewrite_uses_p (stmt))
- FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES)
- maybe_replace_use (use_p);
+ {
+ if (is_gimple_debug (stmt))
+ {
+ bool failed = false;
+
+ FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
+ if (!maybe_replace_use_in_debug_stmt (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. */
+ gimple_debug_bind_reset_value (stmt);
+ update_stmt (stmt);
+ }
+ }
+ else
+ {
+ FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES)
+ maybe_replace_use (use_p);
+ }
+ }
/* Register definitions of names in NEW_SSA_NAMES and OLD_SSA_NAMES.
Also register definitions for names whose underlying symbol is
@@ -2325,7 +2412,12 @@ mark_use_interesting (tree var, gimple stmt, basic_block bb, bool insert_phi_p)
if (gimple_code (stmt) == GIMPLE_PHI)
mark_phi_for_rewrite (def_bb, stmt);
else
- set_rewrite_uses (stmt, true);
+ {
+ set_rewrite_uses (stmt, true);
+
+ if (is_gimple_debug (stmt))
+ return;
+ }
/* If VAR has not been defined in BB, then it is live-on-entry
to BB. Note that we cannot just use the block holding VAR's