diff options
author | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-04-08 20:16:36 +0000 |
---|---|---|
committer | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-04-08 20:16:36 +0000 |
commit | 4cd5bb613c816cf996ca11a356cff1c7870806b0 (patch) | |
tree | 3bbe3665b3ad0f65e64b4973b9c1ddee13f15d9a /gcc/function.c | |
parent | fd731bfb1dfe0d6b125b85c784f353228b242f09 (diff) | |
download | gcc-4cd5bb613c816cf996ca11a356cff1c7870806b0.tar.gz |
* tree.h (TREE_ADDRESSABLE): Document its effect for function types.
* calls.c (expand_call): Pass the function type to aggregate_value_p.
* function.c (aggregate_value_p): Do not honor DECL_BY_REFERENCE on
the target function of a CALL_EXPR. Honor TREE_ADDRESSABLE on the
function type instead. Reorder and simplify checks.
* gimplify.c (gimplify_modify_expr_rhs) <WITH_SIZE_EXPR>: New case.
ada/
* gcc-interface/ada-tree.h (TYPE_RETURNS_UNCONSTRAINED_P): Rename into.
(TYPE_RETURN_UNCONSTRAINED_P): ...this.
(TYPE_RETURNS_BY_REF_P): Rename into.
(TYPE_RETURN_BY_DIRECT_REF_P): ...this.
(TYPE_RETURNS_BY_TARGET_PTR_P): Delete.
* gcc-interface/gigi.h (create_subprog_type): Adjust parameter names.
(build_return_expr): Likewise.
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Subprogram_Type>:
Rename local variables. If the return Mechanism is By_Reference, pass
return_by_invisible_ref_p to create_subprog_type instead of toggling
TREE_ADDRESSABLE. Test return_by_invisible_ref_p in order to annotate
the mechanism. Use regular return for contrained types with non-static
size and return by invisible reference for unconstrained return types
with default discriminants. Update comment.
* gcc-interface/trans.c (Subprogram_Body_to_gnu): If the function
returns by invisible reference, turn the RESULT_DECL into a pointer.
Do not handle DECL_BY_REF_P in the CICO case here.
(call_to_gnu): Remove code handling return by target pointer. For a
function call, if the return type has non-constant size, generate the
assignment with an INIT_EXPR.
(gnat_to_gnu) <N_Return_Statement>: Remove dead code in the CICO case.
If the function returns by invisible reference, build the copy return
operation manually.
(add_decl_expr): Initialize the variable with an INIT_EXPR.
* gcc-interface/utils.c (create_subprog_type): Adjust parameter names.
Adjust for renaming of macros. Copy the node only when necessary.
(create_subprog_decl): Do not toggle TREE_ADDRESSABLE on the return
type, only change DECL_BY_REFERENCE on the RETURN_DECL.
(convert_from_reference): Delete.
(is_byref_result): Likewise.
(gnat_genericize_r): Likewise.
(gnat_genericize): Likewise.
(end_subprog_body): Do not call gnat_genericize.
* gcc-interface/utils2.c (build_binary_op) <INIT_EXPR>: New case.
(build_return_expr): Adjust parameter names, logic and comment.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158139 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/function.c')
-rw-r--r-- | gcc/function.c | 45 |
1 files changed, 19 insertions, 26 deletions
diff --git a/gcc/function.c b/gcc/function.c index 60a429dc2b5..21cbb527391 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -1853,41 +1853,36 @@ struct rtl_opt_pass pass_instantiate_virtual_regs = int aggregate_value_p (const_tree exp, const_tree fntype) { + const_tree type = (TYPE_P (exp)) ? exp : TREE_TYPE (exp); int i, regno, nregs; rtx reg; - const_tree type = (TYPE_P (exp)) ? exp : TREE_TYPE (exp); - - /* DECL node associated with FNTYPE when relevant, which we might need to - check for by-invisible-reference returns, typically for CALL_EXPR input - EXPressions. */ - const_tree fndecl = NULL_TREE; - if (fntype) switch (TREE_CODE (fntype)) { case CALL_EXPR: - fndecl = get_callee_fndecl (fntype); - fntype = (fndecl - ? TREE_TYPE (fndecl) - : TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (fntype)))); + { + tree fndecl = get_callee_fndecl (fntype); + fntype = (fndecl + ? TREE_TYPE (fndecl) + : TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (fntype)))); + } break; case FUNCTION_DECL: - fndecl = fntype; - fntype = TREE_TYPE (fndecl); + fntype = TREE_TYPE (fntype); break; case FUNCTION_TYPE: case METHOD_TYPE: break; case IDENTIFIER_NODE: - fntype = 0; + fntype = NULL_TREE; break; default: - /* We don't expect other rtl types here. */ + /* We don't expect other tree types here. */ gcc_unreachable (); } - if (TREE_CODE (type) == VOID_TYPE) + if (VOID_TYPE_P (type)) return 0; /* If a record should be passed the same as its first (and only) member @@ -1901,24 +1896,21 @@ aggregate_value_p (const_tree exp, const_tree fntype) && DECL_BY_REFERENCE (exp)) return 1; - /* If the EXPression is a CALL_EXPR, honor DECL_BY_REFERENCE set on the - called function RESULT_DECL, meaning the function returns in memory by - invisible reference. This check lets front-ends not set TREE_ADDRESSABLE - on the function type, which used to be the way to request such a return - mechanism but might now be causing troubles at gimplification time if - temporaries with the function type need to be created. */ - if (TREE_CODE (exp) == CALL_EXPR && fndecl && DECL_RESULT (fndecl) - && DECL_BY_REFERENCE (DECL_RESULT (fndecl))) + /* Function types that are TREE_ADDRESSABLE force return in memory. */ + if (fntype && TREE_ADDRESSABLE (fntype)) return 1; - if (targetm.calls.return_in_memory (type, fntype)) - return 1; /* Types that are TREE_ADDRESSABLE must be constructed in memory, and thus can't be returned in registers. */ if (TREE_ADDRESSABLE (type)) return 1; + if (flag_pcc_struct_return && AGGREGATE_TYPE_P (type)) return 1; + + if (targetm.calls.return_in_memory (type, fntype)) + return 1; + /* Make sure we have suitable call-clobbered regs to return the value in; if not, we must return it in memory. */ reg = hard_function_value (type, 0, fntype, 0); @@ -1933,6 +1925,7 @@ aggregate_value_p (const_tree exp, const_tree fntype) for (i = 0; i < nregs; i++) if (! call_used_regs[regno + i]) return 1; + return 0; } |