aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-inline.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2010-07-07 03:00:42 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2010-07-07 01:00:42 +0000
commit6938f93f2ec91e5c8f68469512593efba643caef (patch)
tree94d7441216e1549f60d0ca9d9c850b862731a503 /gcc/tree-inline.c
parent1d8f4f9171a9bf20221425decc286348bb91ab15 (diff)
downloadgcc-6938f93f2ec91e5c8f68469512593efba643caef.zip
gcc-6938f93f2ec91e5c8f68469512593efba643caef.tar.gz
gcc-6938f93f2ec91e5c8f68469512593efba643caef.tar.bz2
re PR middle-end/44813 (ipa-split causes ice in ptr_deref_may_alias_decl_p, at tree-ssa-alias.c:173)
PR middle-end/44813 * tree-ssa-uninit.c (ssa_undefined_value_p): Result decl is defined for functions passed by reference. * tree.c (needs_to_live_in_memory): RESULT_DECL don't need to live in memory when passed by reference. * tree-ssa-ccp.c (get_default_value): Only VAR_DECL is undefined at beggining. * ipa-split.c (split_function): Cleanup way return value is passed; handle SSA DECL_BY_REFERENCE retvals. * tree-ssa.c (verify_def): Verify that RESULT_DECL is read only when DECL_BY_REFERENCE is set. * tree-ssa-structalias.c (get_constraint_for_ssa_var, get_fi_for_callee, find_what_p_points_to): Handle RESULT_DECL. * tree-inline.c (declare_return_variable): Get new entry_block argument; when passing by reference ensure that RESULT_DECL is gimple_val. (remap_gimple_op_r): Remap RESULT_DECL ssa name. (remap_gimple_stmt): Handle SSA DECL_BY_REFERENCE returns. * g++.dg/torture/pr44813.C: New testcase. * g++.dg/torture/pr44826.C: New testcase. From-SVN: r161898
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r--gcc/tree-inline.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index e295a6a..98cadde 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -113,7 +113,7 @@ eni_weights eni_time_weights;
/* Prototypes. */
-static tree declare_return_variable (copy_body_data *, tree, tree);
+static tree declare_return_variable (copy_body_data *, tree, tree, basic_block);
static void remap_block (tree *, copy_body_data *);
static void copy_bind_expr (tree *, int *, copy_body_data *);
static tree mark_local_for_remap_r (tree *, int *, void *);
@@ -817,6 +817,12 @@ remap_gimple_op_r (tree *tp, int *walk_subtrees, void *data)
tree decl = TREE_OPERAND (*tp, 0);
tree *n;
+ /* See remap_ssa_name. */
+ if (TREE_CODE (decl) == SSA_NAME
+ && TREE_CODE (SSA_NAME_VAR (decl)) == RESULT_DECL
+ && id->transform_return_to_modify)
+ decl = SSA_NAME_VAR (decl);
+
n = (tree *) pointer_map_contains (id->decl_map, decl);
if (n)
{
@@ -1235,7 +1241,10 @@ remap_gimple_stmt (gimple stmt, copy_body_data *id)
If RETVAL is just the result decl, the result decl has
already been set (e.g. a recent "foo (&result_decl, ...)");
just toss the entire GIMPLE_RETURN. */
- if (retval && TREE_CODE (retval) != RESULT_DECL)
+ if (retval
+ && (TREE_CODE (retval) != RESULT_DECL
+ && (TREE_CODE (retval) != SSA_NAME
+ || TREE_CODE (SSA_NAME_VAR (retval)) != RESULT_DECL)))
{
copy = gimple_build_assign (id->retvar, retval);
/* id->retvar is already substituted. Skip it on later remapping. */
@@ -2735,7 +2744,8 @@ initialize_inlined_parameters (copy_body_data *id, gimple stmt,
as seen by the caller. */
static tree
-declare_return_variable (copy_body_data *id, tree return_slot, tree modify_dest)
+declare_return_variable (copy_body_data *id, tree return_slot, tree modify_dest,
+ basic_block entry_bb)
{
tree callee = id->src_fn;
tree caller = id->dst_fn;
@@ -2878,8 +2888,20 @@ declare_return_variable (copy_body_data *id, tree return_slot, tree modify_dest)
done:
/* Register the VAR_DECL as the equivalent for the RESULT_DECL; that
way, when the RESULT_DECL is encountered, it will be
- automatically replaced by the VAR_DECL. */
- insert_decl_map (id, result, var);
+ automatically replaced by the VAR_DECL.
+
+ When returning by reference, ensure that RESULT_DECL remaps to
+ gimple_val. */
+ if (DECL_BY_REFERENCE (result)
+ && !is_gimple_val (var))
+ {
+ tree temp = create_tmp_var (TREE_TYPE (result), "retvalptr");
+ insert_decl_map (id, result, temp);
+ temp = remap_ssa_name (gimple_default_def (id->src_cfun, result), id);
+ insert_init_stmt (id, entry_bb, gimple_build_assign (temp, var));
+ }
+ else
+ insert_decl_map (id, result, var);
/* Remember this so we can ignore it in remap_decls. */
id->retvar = var;
@@ -3983,7 +4005,7 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
}
/* Declare the return variable for the function. */
- use_retvar = declare_return_variable (id, return_slot, modify_dest);
+ use_retvar = declare_return_variable (id, return_slot, modify_dest, bb);
/* Add local vars in this inlined callee to caller. */
add_local_variables (id->src_cfun, cfun, id, true);