summaryrefslogtreecommitdiff
path: root/gcc/cp/semantics.c
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2001-06-18 16:15:12 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2001-06-18 16:15:12 +0000
commit80ac742d926c6c87d9eb1648f4a501a34a3ac70a (patch)
tree70263e15f7a28d4f44a057ee1783e8a0095c5f9a /gcc/cp/semantics.c
parentf6664feec514b2e3b3f36fb59c9b1b14dc5a52fc (diff)
downloadgcc-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.c37
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);