This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFC: PATCH to gimplify_modify_expr_rhs to make return slotexplicit


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;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]