> Hmm, instead of (ab-)using debug_map can we instead use sth like setting
> TREE_VISITED on the argument decl (not the value - it might be passed
> multiple tiimes)? IIRC TREE_VISITED state is undetermined thus we can
> clear it at the start of setup_one_parameter and set it when we want to
> avoid the clobber and then test for this later?
>
> In the end I'd even find using a new bitmap to record parameter decl UIDs
> cleaner ... (I'm not sure if we not end up doing tree walks that might
> clobber TREE_VISITED here).
I tried TREE_VISITED and other similar kludges but this broke in weird ways so
reusing debug_map was probably the best of them. Less kludgy version attached
though, before switching to a dedicated bitmap indeed.
* tree-inline.c (insert_debug_decl_map): Insert unconditionally.
(copy_debug_stmt): Minor tweak.
(setup_one_parameter): Do not create a variable if the value is either
a read-only DECL or a non-addressable local variable in the caller.
(expand_call_inline): Do not generate a CLOBBER for these values.
--
Eric Botcazou
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 1dcb31c0267..57d3b6ff6de 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -152,21 +152,11 @@ insert_decl_map (copy_body_data *id, tree key, tree value)
id->decl_map->put (value, value);
}
-/* Insert a tree->tree mapping for ID. This is only used for
- variables. */
+/* Insert a tree->tree mapping for ID. This is only used for parameters. */
static void
insert_debug_decl_map (copy_body_data *id, tree key, tree value)
{
- if (!gimple_in_ssa_p (id->src_cfun))
- return;
-
- if (!opt_for_fn (id->dst_fn, flag_var_tracking_assignments))
- return;
-
- if (!target_for_debug_bind (key))
- return;
-
gcc_assert (TREE_CODE (key) == PARM_DECL);
gcc_assert (VAR_P (value));
@@ -3190,7 +3180,8 @@ copy_debug_stmt (gdebug *stmt, copy_body_data *id)
else
gcc_unreachable ();
- if (TREE_CODE (t) == PARM_DECL && id->debug_map
+ if (TREE_CODE (t) == PARM_DECL
+ && id->debug_map
&& (n = id->debug_map->get (t)))
{
gcc_assert (VAR_P (*n));
@@ -3460,16 +3451,18 @@ setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn,
value. */
if (TREE_READONLY (p)
&& !TREE_ADDRESSABLE (p)
- && value && !TREE_SIDE_EFFECTS (value)
+ && value
+ && !TREE_SIDE_EFFECTS (value)
&& !def)
{
- /* We may produce non-gimple trees by adding NOPs or introduce
- invalid sharing when operand is not really constant.
- It is not big deal to prohibit constant propagation here as
- we will constant propagate in DOM1 pass anyway. */
- if (is_gimple_min_invariant (value)
- && useless_type_conversion_p (TREE_TYPE (p),
- TREE_TYPE (value))
+ /* We may produce non-gimple trees by adding NOPs or introduce invalid
+ sharing when the value is not constant or DECL. And we need to make
+ sure that it cannot be modified from another path in the callee. */
+ if ((is_gimple_min_invariant (value)
+ || (DECL_P (value) && TREE_READONLY (value))
+ || (auto_var_in_fn_p (value, id->src_fn)
+ && !TREE_ADDRESSABLE (value)))
+ && useless_type_conversion_p (TREE_TYPE (p), TREE_TYPE (value))
/* We have to be very careful about ADDR_EXPR. Make sure
the base variable isn't a local variable of the inlined
function, e.g., when doing recursive inlining, direct or
@@ -5128,8 +5121,13 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id,
for (tree p = DECL_ARGUMENTS (id->src_fn); p; p = DECL_CHAIN (p))
if (!TREE_THIS_VOLATILE (p))
{
+ /* The value associated with P is a local temporary only if
+ there is no value associated with P in the debug map. */
tree *varp = id->decl_map->get (p);
- if (varp && VAR_P (*varp) && !is_gimple_reg (*varp))
+ if (varp
+ && VAR_P (*varp)
+ && !is_gimple_reg (*varp)
+ && !(id->debug_map && id->debug_map->get (p)))
{
tree clobber = build_clobber (TREE_TYPE (*varp));
gimple *clobber_stmt;