diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-06-18 16:15:12 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-06-18 16:15:12 +0000 |
commit | 80ac742d926c6c87d9eb1648f4a501a34a3ac70a (patch) | |
tree | 70263e15f7a28d4f44a057ee1783e8a0095c5f9a /gcc/cp/semantics.c | |
parent | f6664feec514b2e3b3f36fb59c9b1b14dc5a52fc (diff) | |
download | gcc-80ac742d926c6c87d9eb1648f4a501a34a3ac70a.tar.gz |
Implement the Named Return Value optimization.
* c-common.h (RETURN_NULLIFIED_P): New macro.
* c-semantics.c (genrtl_return_stmt): Check it.
* cp-tree.h (struct cp_language_function): Add x_return_value.
(current_function_return_value): Now a macro.
* decl.c: Don't define it.
(define_label, finish_case_label): Don't clear it.
(init_decl_processing): Don't register it with GC.
* semantics.c (genrtl_finish_function): Don't check it for
no_return_label. Copy the RTL from the return value to
current_function_return_value and walk, calling...
(nullify_returns_r): ...this new fn.
* typeck.c (check_return_expr): Set current_function_return_value.
* expr.c (clear_storage): Set TREE_NOTHROW on the decl for memset.
(emit_block_move): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@43445 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/semantics.c')
-rw-r--r-- | gcc/cp/semantics.c | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 9dddf230ddd..0dc392a9a89 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -49,6 +49,7 @@ static tree maybe_convert_cond PARAMS ((tree)); static tree simplify_aggr_init_exprs_r PARAMS ((tree *, int *, void *)); +static tree nullify_returns_r PARAMS ((tree *, int *, void *)); static void deferred_type_access_control PARAMS ((void)); static void emit_associated_thunks PARAMS ((tree)); static void genrtl_try_block PARAMS ((tree)); @@ -2464,6 +2465,25 @@ expand_body (fn) timevar_pop (TV_EXPAND); } +/* Helper function for walk_tree, used by genrtl_start_function to override + all the RETURN_STMTs for the named return value optimization. */ + +static tree +nullify_returns_r (tp, walk_subtrees, data) + tree *tp; + int *walk_subtrees; + void *data ATTRIBUTE_UNUSED; +{ + /* No need to walk into types. */ + if (TYPE_P (*tp)) + *walk_subtrees = 0; + else if (TREE_CODE (*tp) == RETURN_STMT) + RETURN_NULLIFIED_P (*tp) = 1; + + /* Keep iterating. */ + return NULL_TREE; +} + /* Start generating the RTL for FN. */ static void @@ -2541,6 +2561,22 @@ genrtl_start_function (fn) /* Create a binding contour which can be used to catch cleanup-generated temporaries. */ expand_start_bindings (2); + + /* Set up the named return value optimization, if we can. */ + if (current_function_return_value + && current_function_return_value != error_mark_node) + { + tree r = current_function_return_value; + /* This is only worth doing for fns that return in memory--and + simpler, since we don't have to worry about promoted modes. */ + if (aggregate_value_p (TREE_TYPE (TREE_TYPE (fn)))) + { + COPY_DECL_RTL (DECL_RESULT (fn), r); + DECL_ALIGN (r) = DECL_ALIGN (DECL_RESULT (fn)); + walk_tree_without_duplicates (&DECL_SAVED_TREE (fn), + nullify_returns_r, NULL_TREE); + } + } } /* Finish generating the RTL for FN. */ @@ -2579,7 +2615,6 @@ genrtl_finish_function (fn) if (!dtor_label && !DECL_CONSTRUCTOR_P (fn) && return_label != NULL_RTX - && current_function_return_value == NULL_TREE && ! DECL_NAME (DECL_RESULT (current_function_decl))) no_return_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); |