This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: RFC: PATCH to gimplify_modify_expr_rhs to make return slotexplicit
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Mark Mitchell <mark at codesourcery dot com>, "Frank Ch. Eigler" <fche at redhat dot com>, Richard Henderson <rth at redhat dot com>
- Date: Thu, 13 Jan 2005 20:57:20 -0500
- Subject: Re: RFC: PATCH to gimplify_modify_expr_rhs to make return slotexplicit
- References: <xypvfa2giqj.fsf@miranda.boston.redhat.com>
This patch fixes a couple of bugs in the earlier version.
2005-01-12 Jason Merrill <jason@redhat.com>
* gimplify.c (gimplify_modify_expr_rhs) [CALL_EXPR]: Make return
slot explicit.
*** gimplify.c.~1~ 2005-01-11 19:13:24.000000000 -0500
--- gimplify.c 2005-01-13 14:03:45.000000000 -0500
*************** gimplify_modify_expr_rhs (tree *expr_p,
*** 2883,2888 ****
--- 2884,2937 ----
ret = GS_UNHANDLED;
break;
+ case CALL_EXPR:
+ /* For calls that return in memory, give *to_p as the CALL_EXPR's
+ return slot so that we don't generate a temporary. */
+ if (aggregate_value_p (*from_p, *from_p))
+ {
+ tree init = *from_p;
+ tree fn = TREE_OPERAND (init, 0);
+ tree args = TREE_OPERAND (init, 1);
+ tree rettype = TREE_TYPE (TREE_TYPE (TREE_TYPE (fn)));
+ tree arg = *to_p;
+ tree type;
+
+ /* Only use the original target if *to_p isn't already
+ addressable; if its address escapes, and the called function
+ uses the NRV optimization, a conforming program could see
+ *to_p change before the called function returns. */
+ bool use_temp = !is_gimple_non_addressable (*to_p);
+ if (use_temp)
+ {
+ arg = create_tmp_var (rettype, "ret");
+ *from_p = arg;
+ }
+
+ type = TREE_TYPE (arg);
+ lang_hooks.mark_addressable (arg);
+ arg = build1 (ADDR_EXPR, build_pointer_type (type), arg);
+ /* The return type might have different cv-quals from arg. */
+ arg = convert (build_pointer_type (rettype), arg);
+ args = tree_cons (NULL_TREE, arg, args);
+ init = build3 (CALL_EXPR, rettype, fn, args, NULL_TREE);
+ CALL_EXPR_HAS_RETURN_SLOT_ADDR (init) = 1;
+ TREE_USED (init) = 1;
+
+ if (use_temp)
+ gimplify_and_add (init, pre_p);
+ else if (want_value)
+ {
+ gimplify_and_add (init, pre_p);
+ *expr_p = *to_p;
+ }
+ else
+ *expr_p = init;
+ ret = GS_OK;
+ }
+ else
+ ret = GS_UNHANDLED;
+ break;
+
default:
ret = GS_UNHANDLED;
break;