for gcc/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
PR debug/46931
* tree-ssa.c (insert_debug_temp_for_var_def): Handle removed
assignments.
===================================================================
@@ -305,6 +305,8 @@ insert_debug_temp_for_var_def (gimple_st
gimple def_stmt = NULL;
int usecount = 0;
tree value = NULL;
+ tree value_unshare = NULL;
+ tree temp_value = NULL;
if (!MAY_HAVE_DEBUG_STMTS)
return;
@@ -421,6 +423,30 @@ insert_debug_temp_for_var_def (gimple_st
|| is_gimple_min_invariant (value)))
|| is_gimple_reg (value))
value = unshare_expr (value);
+ else if (!gsi && !gimple_bb (def_stmt))
+ {
+ if (is_gimple_val (value))
+ value_unshare = value;
+ else if (TREE_SIDE_EFFECTS (value)
+ || TREE_THIS_VOLATILE (value)
+ || !is_gimple_assign (def_stmt))
+ value_unshare = NULL;
+ else if (!gimple_assign_single_p (def_stmt))
+ value_unshare = value;
+ else if (gimple_has_volatile_ops (def_stmt))
+ value_unshare = NULL;
+ else
+ {
+ enum tree_code_class tcc;
+ tcc = TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt));
+ if (tcc == tcc_reference || tcc == tcc_declaration)
+ value_unshare = NULL;
+ else
+ value_unshare = value;
+ }
+
+ value = NULL;
+ }
else
{
gimple def_temp;
@@ -454,13 +480,48 @@ insert_debug_temp_for_var_def (gimple_st
if (!gimple_debug_bind_p (stmt))
continue;
+ /* If we have a value that needs unsharing, unshare it. Then,
+ if the debug stmt binds to VAR, we can replace it, otherwise
+ we'll create a debug temp, bind it to the unshared value
+ right before STMT, and replace uses of VAR with the debug
+ temp. We reuse the same temp for multiple uses, but we don't
+ attempt to avoid emitting debug temps that would be dominated
+ by identical debug bind stmts. */
+ if (value_unshare)
+ {
+ value = unshare_expr (value_unshare);
+ if (gimple_debug_bind_get_value (stmt) != var)
+ {
+ gimple def_temp;
+ gimple_stmt_iterator ngsi = gsi_for_stmt (stmt);
+
+ if (!temp_value)
+ {
+ temp_value = make_node (DEBUG_EXPR_DECL);
+
+ DECL_ARTIFICIAL (temp_value) = 1;
+ TREE_TYPE (temp_value) = TREE_TYPE (value);
+ if (DECL_P (value))
+ DECL_MODE (temp_value) = DECL_MODE (value);
+ else
+ DECL_MODE (temp_value) = TYPE_MODE (TREE_TYPE (value));
+ }
+
+ def_temp = gimple_build_debug_bind (temp_value, value,
+ def_stmt);
+
+ gsi_insert_before (&ngsi, def_temp, GSI_SAME_STMT);
+
+ value = temp_value;
+ }
+ }
+
if (value)
FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
- /* unshare_expr is not needed here. vexpr is either a
+ /* unshare_expr is not needed here. value is either a
SINGLE_RHS, that can be safely shared, some other RHS
that was unshared when we found it had a single debug
- use, or a DEBUG_EXPR_DECL, that can be safely
- shared. */
+ use, or a DEBUG_EXPR_DECL, that can be safely shared. */
SET_USE (use_p, value);
else
gimple_debug_bind_reset_value (stmt);