diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-07-02 23:38:19 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-07-02 23:38:19 +0000 |
commit | a800589339f009a61895b240e6829079ef445681 (patch) | |
tree | 1913806125a574a453a4f91633b857b230c20a52 /gcc/ipa-split.c | |
parent | e2669ea74dd370c02edc4f1c740610024dc8fdc4 (diff) | |
download | gcc-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.c | 24 |
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 |