static tree
remap_type_1 (tree type, copy_body_data *id)
{
- tree *node;
tree new, t;
- if (type == NULL)
- return type;
-
- /* See if we have remapped this type. */
- node = (tree *) pointer_map_contains (id->decl_map, type);
- if (node)
- return *node;
-
- /* The type only needs remapping if it's variably modified. */
- if (! variably_modified_type_p (type, id->src_fn))
- {
- insert_decl_map (id, type, type);
- return type;
- }
-
/* We do need a copy. build and register it now. If this is a pointer or
reference type, remap the designated type and make a new pointer or
reference type. */
and friends are up-to-date. */
else if (TREE_CODE (*tp) == ADDR_EXPR)
{
+ int invariant = TREE_INVARIANT (*tp);
walk_tree (&TREE_OPERAND (*tp, 0), copy_body_r, id, NULL);
/* Handle the case where we substituted an INDIRECT_REF
into the operand of the ADDR_EXPR. */
*tp = TREE_OPERAND (TREE_OPERAND (*tp, 0), 0);
else
recompute_tree_invariant_for_addr_expr (*tp);
+ /* If this used to be invariant, but is not any longer,
+ then regimplification is probably needed. */
+ if (invariant && !TREE_INVARIANT (*tp))
+ id->regimplify = true;
*walk_subtrees = 0;
}
}
tree stmt = bsi_stmt (bsi);
tree orig_stmt = stmt;
+ id->regimplify = false;
walk_tree (&stmt, copy_body_r, id, NULL);
/* RETURN_EXPR might be removed,
/* With return slot optimization we can end up with
non-gimple (foo *)&this->m, fix that here. */
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == NOP_EXPR
- && !is_gimple_val (TREE_OPERAND (GIMPLE_STMT_OPERAND (stmt, 1), 0)))
+ if ((TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
+ && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == NOP_EXPR
+ && !is_gimple_val (TREE_OPERAND (GIMPLE_STMT_OPERAND (stmt, 1), 0)))
+ || id->regimplify)
gimplify_stmt (&stmt);
bsi_insert_after (©_bsi, stmt, BSI_NEW_STMT);
return;
}
+ /* If the value of argument is never used, don't care about initializing
+ it. */
+ if (gimple_in_ssa_p (cfun) && !def && is_gimple_reg (p))
+ {
+ gcc_assert (!value || !TREE_SIDE_EFFECTS (value));
+ return;
+ }
+
/* Initialize this VAR_DECL from the equivalent argument. Convert
the argument to the proper type in case it was promoted. */
if (value)
/* Walk to the last sub-block. */
for (blk_p = &BLOCK_SUBBLOCKS (current_block);
*blk_p;
- blk_p = &TREE_CHAIN (*blk_p))
+ blk_p = &BLOCK_CHAIN (*blk_p))
;
*blk_p = new_block;
BLOCK_SUPERCONTEXT (new_block) = current_block;
id->src_cfun = DECL_STRUCT_FUNCTION (fn);
id->call_expr = t;
+ gcc_assert (!id->src_cfun->after_inlining);
+
initialize_inlined_parameters (id, t, fn, bb);
if (DECL_INITIAL (fn))
id.dst_fn = current_function_decl;
id.src_cfun = cfun;
id.decl_map = pointer_map_create ();
+ id.copy_decl = copy_decl_no_change;
type = remap_type_1 (type, &id);