diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-08-07 17:40:10 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-08-07 17:40:10 +0000 |
commit | 806e4c12395ae2ebbd374d91880204c498ae4c0b (patch) | |
tree | 252b73c82d55d0b8da42cb892207cf89b9b2d1bc /gcc/function.c | |
parent | 8223629e6c6c40e59d68e94e9fc2b7eca7848dd5 (diff) | |
download | gcc-806e4c12395ae2ebbd374d91880204c498ae4c0b.tar.gz |
Make return in memory explicit.
* function.c (aggregate_value_p): Check DECL_BY_REFERENCE.
(assign_parm_find_data_types): Remove code for old front end
invisible reference handling.
(assign_parms): Handle DECL_BY_REFERENCE on the RESULT_DECL.
(expand_function_end): Likewise.
* gimplify.c (gimplify_return_expr): Handle a dereferenced
RESULT_DECL.
* tree-inline.c (copy_body_r): Don't bother looking for &* anymore.
(declare_return_variable): Handle DECL_BY_REFERENCE.
* cp/cp-gimplify.c (is_invisiref_parm): Also handle RESULT_DECL.
(cp_genericize_r): Use convert_from_reference.
Don't dereference a RESULT_DECL directly inside a RETURN_EXPR.
(cp_genericize): Handle the RESULT_DECL. Unset TREE_ADDRESSABLE.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@85675 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/function.c')
-rw-r--r-- | gcc/function.c | 46 |
1 files changed, 26 insertions, 20 deletions
diff --git a/gcc/function.c b/gcc/function.c index 699a009ee03..4de748aceb8 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -1883,6 +1883,11 @@ aggregate_value_p (tree exp, tree fntype) if (TREE_CODE (type) == VOID_TYPE) return 0; + /* If the front end has decided that this needs to be passed by + reference, do so. */ + if ((TREE_CODE (exp) == PARM_DECL || TREE_CODE (exp) == RESULT_DECL) + && DECL_BY_REFERENCE (exp)) + return 1; if (targetm.calls.return_in_memory (type, fntype)) return 1; /* Types that are TREE_ADDRESSABLE must be constructed in memory, @@ -2187,15 +2192,6 @@ assign_parm_find_data_types (struct assign_parm_data_all *all, tree parm, data->passed_pointer = true; passed_mode = nominal_mode = Pmode; } - /* See if the frontend wants to pass this by invisible reference. */ - else if (passed_type != nominal_type - && POINTER_TYPE_P (passed_type) - && TREE_TYPE (passed_type) == nominal_type) - { - nominal_type = passed_type; - data->passed_pointer = 1; - passed_mode = nominal_mode = Pmode; - } /* Find mode as it is passed by the ABI. */ promoted_mode = passed_mode; @@ -3095,9 +3091,14 @@ assign_parms (tree fndecl) rtx addr = DECL_RTL (all.function_result_decl); rtx x; - addr = convert_memory_address (Pmode, addr); - x = gen_rtx_MEM (DECL_MODE (result), addr); - set_mem_attributes (x, result, 1); + if (DECL_BY_REFERENCE (result)) + x = addr; + else + { + addr = convert_memory_address (Pmode, addr); + x = gen_rtx_MEM (DECL_MODE (result), addr); + set_mem_attributes (x, result, 1); + } SET_DECL_RTL (result, x); } @@ -4385,17 +4386,22 @@ expand_function_end (void) if (current_function_returns_struct || current_function_returns_pcc_struct) { - rtx value_address - = XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0); + rtx value_address = DECL_RTL (DECL_RESULT (current_function_decl)); tree type = TREE_TYPE (DECL_RESULT (current_function_decl)); + rtx outgoing; + + if (DECL_BY_REFERENCE (DECL_RESULT (current_function_decl))) + type = TREE_TYPE (type); + else + value_address = XEXP (value_address, 0); + #ifdef FUNCTION_OUTGOING_VALUE - rtx outgoing - = FUNCTION_OUTGOING_VALUE (build_pointer_type (type), - current_function_decl); + outgoing = FUNCTION_OUTGOING_VALUE (build_pointer_type (type), + current_function_decl); #else - rtx outgoing - = FUNCTION_VALUE (build_pointer_type (type), current_function_decl); -#endif + outgoing = FUNCTION_VALUE (build_pointer_type (type), + current_function_decl); +#endif /* Mark this as a function return value so integrate will delete the assignment and USE below when inlining this function. */ |