summaryrefslogtreecommitdiff
path: root/gcc/ipa-split.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2010-07-02 23:38:19 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2010-07-02 23:38:19 +0000
commita800589339f009a61895b240e6829079ef445681 (patch)
tree1913806125a574a453a4f91633b857b230c20a52 /gcc/ipa-split.c
parente2669ea74dd370c02edc4f1c740610024dc8fdc4 (diff)
downloadgcc-a800589339f009a61895b240e6829079ef445681.tar.gz
* ipa-split.c (split_function): For aggregate values set return_slot_opt;
when passing DECL_BY_REFERENCE produce *<retval> = fncall.part () (execute_split_functions): Do not care about DECL_BY_REFERENCE. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161756 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ipa-split.c')
-rw-r--r--gcc/ipa-split.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index 0cec0b82907..1bd9d248384 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -949,6 +949,13 @@ split_function (struct split_point *split_point)
call = gimple_build_call_vec (node->decl, args_to_pass);
gimple_set_block (call, DECL_INITIAL (current_function_decl));
+ /* We avoid address being taken on any variable used by split part,
+ so return slot optimization is always possible. Moreover this is
+ required to make DECL_BY_REFERENCE work. */
+ if (aggregate_value_p (DECL_RESULT (current_function_decl),
+ TREE_TYPE (current_function_decl)))
+ gimple_call_set_return_slot_opt (call, true);
+
/* Update return value. This is bit tricky. When we do not return,
do nothing. When we return we might need to update return_bb
or produce a new return statement. */
@@ -1002,7 +1009,10 @@ split_function (struct split_point *split_point)
update_stmt (gsi_stmt (bsi));
}
}
- gimple_call_set_lhs (call, retval);
+ if (DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))
+ gimple_call_set_lhs (call, build_simple_mem_ref (retval));
+ else
+ gimple_call_set_lhs (call, retval);
}
gsi_insert_after (&gsi, call, GSI_NEW_STMT);
}
@@ -1021,7 +1031,10 @@ split_function (struct split_point *split_point)
retval = create_tmp_reg (TREE_TYPE (retval), NULL);
if (is_gimple_reg (retval))
retval = make_ssa_name (retval, call);
- gimple_call_set_lhs (call, retval);
+ if (DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))
+ gimple_call_set_lhs (call, build_simple_mem_ref (retval));
+ else
+ gimple_call_set_lhs (call, retval);
}
gsi_insert_after (&gsi, call, GSI_NEW_STMT);
ret = gimple_build_return (retval);
@@ -1085,13 +1098,6 @@ execute_split_functions (void)
fprintf (dump_file, "Not splitting: nested function.\n");
return 0;
}
- /* FIXME: Should be easy to support. */
- if (DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))
- {
- if (dump_file)
- fprintf (dump_file, "Not splitting: returns value by reference.\n");
- return 0;
- }
/* See if it makes sense to try to split.
It makes sense to split if we inline, that is if we have direct calls to