Comments
Patch
for gcc/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
PR debug/48866
* cfgexpand.c (def_expansions): New.
(def_expansion_recent_tree, def_expansion_recent_rtx): New.
(def_expansions_init, def_expansions_fini): New.
(def_has_expansion_ptr, def_get_expansion_ptr): New.
(expand_debug_expr): Use recorded expansion if available.
(expand_gimple_basic_block): Prepare to record expansion of
replaceable defs. Change return type to void.
(gimple_expand_cfg): Initialize and finalize expansions cache.
Expand dominator blocks before dominated.
* expr.c (expand_expr_real_1): Use recorded expansion of
replaceable defs.
* expr.h (def_has_expansion_ptr): Declare.
===================================================================
@@ -2337,6 +2337,42 @@ convert_debug_memory_address (enum machi
return x;
}
+/* Map replaceable SSA_NAMEs to their RTL expansions. */
+static rtx *def_expansions;
+
+/* Initialize the def_expansions data structure. This is to be called
+ before expansion of a function starts. */
+
+static void
+def_expansions_init (void)
+{
+ gcc_checking_assert (!def_expansions);
+ def_expansions = XCNEWVEC (rtx, num_ssa_names);
+}
+
+/* Finalize the def_expansions data structure. This is to be called
+ at the end of the expansion of a function. */
+
+static void
+def_expansions_fini (void)
+{
+ gcc_checking_assert (def_expansions);
+ XDELETEVEC (def_expansions);
+ def_expansions = NULL;
+}
+
+/* Return a pointer to the rtx expanded from EXP. EXP must be a
+ replaceable SSA_NAME. */
+
+rtx *
+def_get_expansion_ptr (tree exp)
+{
+ gcc_checking_assert (def_expansions);
+ gcc_checking_assert (TREE_CODE (exp) == SSA_NAME);
+ gcc_checking_assert (bitmap_bit_p (SA.values, SSA_NAME_VERSION (exp)));
+ return &def_expansions[SSA_NAME_VERSION (exp)];
+}
+
/* Return an RTX equivalent to the value of the tree expression
EXP. */
@@ -3131,7 +3167,16 @@ expand_debug_expr (tree exp)
gimple g = get_gimple_for_ssa_name (exp);
if (g)
{
- op0 = expand_debug_expr (gimple_assign_rhs_to_tree (g));
+ rtx *xp = def_get_expansion_ptr (exp);
+
+ if (xp)
+ op0 = copy_rtx (*xp);
+ else
+ op0 = NULL;
+
+ if (!op0)
+ op0 = expand_debug_expr (gimple_assign_rhs_to_tree (g));
+
if (!op0)
return NULL;
}
@@ -3618,20 +3663,38 @@ expand_gimple_basic_block (basic_block b
}
else
{
+ rtx *xp = NULL;
def_operand_p def_p;
def_p = SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_DEF);
- if (def_p != NULL)
+ /* Ignore this stmt if it is in the list of
+ replaceable expressions. */
+ if (def_p != NULL
+ && SA.values
+ && bitmap_bit_p (SA.values,
+ SSA_NAME_VERSION (DEF_FROM_PTR (def_p))))
{
- /* Ignore this stmt if it is in the list of
- replaceable expressions. */
- if (SA.values
- && bitmap_bit_p (SA.values,
- SSA_NAME_VERSION (DEF_FROM_PTR (def_p))))
- continue;
+ tree def = DEF_FROM_PTR (def_p);
+ gimple g = get_gimple_for_ssa_name (def);
+ rtx retval;
+
+ last = get_last_insn ();
+
+ retval = expand_expr (gimple_assign_rhs_to_tree (g),
+ NULL_RTX, VOIDmode, EXPAND_SUM);
+
+ xp = def_get_expansion_ptr (def);
+ gcc_checking_assert (!*xp);
+ *xp = retval;
}
- last = expand_gimple_stmt (stmt);
+ else
+ last = expand_gimple_stmt (stmt);
maybe_dump_rtl_for_gimple_stmt (stmt, last);
+ if (xp && dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "\n=> ");
+ print_rtl (dump_file, *xp);
+ }
}
}
}
@@ -4112,11 +4175,14 @@ gimple_expand_cfg (void)
e->flags &= ~EDGE_EXECUTABLE;
lab_rtx_for_bb = pointer_map_create ();
+ def_expansions_init ();
+
FOR_BB_BETWEEN (bb, init_block->next_bb, EXIT_BLOCK_PTR, next_bb)
bb = expand_gimple_basic_block (bb);
if (MAY_HAVE_DEBUG_INSNS)
expand_debug_locations ();
+ def_expansions_fini ();
execute_free_datastructures ();
timevar_push (TV_OUT_OF_SSA);
===================================================================
@@ -8424,10 +8424,40 @@ expand_expr_real_1 (tree exp, rtx target
&& !SSA_NAME_IS_DEFAULT_DEF (exp)
&& (optimize || DECL_IGNORED_P (SSA_NAME_VAR (exp)))
&& stmt_is_replaceable_p (SSA_NAME_DEF_STMT (exp)))
- g = SSA_NAME_DEF_STMT (exp);
+ {
+ g = SSA_NAME_DEF_STMT (exp);
+ if (g)
+ return expand_expr_real (gimple_assign_rhs_to_tree (g),
+ target, tmode, modifier, NULL);
+ }
if (g)
- return expand_expr_real (gimple_assign_rhs_to_tree (g), target, tmode,
- modifier, NULL);
+ {
+ rtx retval = *def_get_expansion_ptr (exp);
+
+ gcc_assert (retval);
+
+ switch (modifier)
+ {
+ case EXPAND_SUM:
+ return retval;
+
+ case EXPAND_STACK_PARM:
+ case EXPAND_NORMAL:
+ if (!target || !REG_P (target) || GET_MODE (target) != mode
+ || !general_operand (retval, mode))
+ return force_reg (mode, retval);
+
+ emit_move_insn (target, retval);
+ return target;
+
+ case EXPAND_MEMORY:
+ case EXPAND_CONST_ADDRESS:
+ case EXPAND_INITIALIZER:
+ case EXPAND_WRITE:
+ default:
+ gcc_unreachable ();
+ }
+ }
ssa_name = exp;
decl_rtl = get_rtx_for_ssa_name (ssa_name);
===================================================================
@@ -693,4 +693,7 @@ extern tree build_libfunc_function (cons
/* Get the personality libfunc for a function decl. */
rtx get_personality_function (tree);
+/* In cfgexpand.c. */
+rtx *def_get_expansion_ptr (tree);
+
#endif /* GCC_EXPR_H */