On Tue, Jun 28, 2016 at 10:00 AM, Richard Biener
<richard.guent...@gmail.com> wrote:
> On Thu, Jun 16, 2016 at 6:15 PM, Jakub Jelinek <ja...@redhat.com> wrote:
>> On Thu, Jun 16, 2016 at 11:28:48AM -0400, Jason Merrill wrote:
>>>  gimple_predicate
>>>  rhs_predicate_for (tree lhs)
>>>  {
>>> -  if (is_gimple_reg (lhs))
>>> +  if (will_be_gimple_reg (lhs))
>>>      return is_gimple_reg_rhs_or_call;
>>>    else
>>>      return is_gimple_mem_rhs_or_call;
>>> @@ -4778,10 +4811,6 @@ gimplify_modify_expr (tree *expr_p, gimple_seq 
>>> *pre_p, gimple_seq *post_p,
>>>       that is what we must do here.  */
>>>    maybe_with_size_expr (from_p);
>>>
>>> -  ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
>>> -  if (ret == GS_ERROR)
>>> -    return ret;
>>> -
>>>    /* As a special case, we have to temporarily allow for assignments
>>>       with a CALL_EXPR on the RHS.  Since in GIMPLE a function call is
>>>       a toplevel statement, when gimplifying the GENERIC expression
>>> @@ -4799,6 +4828,10 @@ gimplify_modify_expr (tree *expr_p, gimple_seq 
>>> *pre_p, gimple_seq *post_p,
>>>    if (ret == GS_ERROR)
>>>      return ret;
>>>
>>> +  ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
>>> +  if (ret == GS_ERROR)
>>> +    return ret;
>>> +
>>>    /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the 
>>> type
>>>       size as argument to the call.  */
>>>    if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
>>
>> I wonder if instead of trying to guess early what we'll gimplify into it
>> wouldn't be better to gimplify *from_p twice, first time with a predicate
>> that would assume *to_p could be gimplified into is_gimple_ref, but
>> guarantee there are no side-effects (so that those aren't evaluated
>> after lhs side-effects), and second time if needed (if *to_p didn't end up
>> being is_gimple_reg).  So something like a new predicate like:
>
> Yes, that is what I was suggesting.

How about this?  I also have a patch to handle assignment order
entirely in the front end, but my impression has been that you wanted
to make this change for other reasons as well.

In other news, I convinced the committee to drop function arguments
from the order of evaluation paper, so we don't have to worry about
that hit on PUSH_ARGS_REVERSED targets.

Jason
commit 8dac319f5647d31568ad9278edeff3607aa1b3cc
Author: Jason Merrill <ja...@redhat.com>
Date:   Sat Jun 25 19:12:42 2016 +0300

        P0145: Refining Expression Order for C++ (assignment)
    
        * gimplify.c (initial_rhs_predicate_for): New.
        (gimplfy_modify_expr): Gimplify RHS before LHS.

diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 47c4d25..0276588 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -3813,6 +3813,18 @@ rhs_predicate_for (tree lhs)
     return is_gimple_mem_rhs_or_call;
 }
 
+/* Return the initial guess for an appropriate RHS predicate for this LHS,
+   before the LHS has been gimplified.  */
+
+static gimple_predicate
+initial_rhs_predicate_for (tree lhs)
+{
+  if (is_gimple_reg_type (TREE_TYPE (lhs)))
+    return is_gimple_reg_rhs_or_call;
+  else
+    return is_gimple_mem_rhs_or_call;
+}
+
 /* Gimplify a C99 compound literal expression.  This just means adding
    the DECL_EXPR before the current statement and using its anonymous
    decl instead.  */
@@ -4778,10 +4790,6 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, 
gimple_seq *post_p,
      that is what we must do here.  */
   maybe_with_size_expr (from_p);
 
-  ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
-  if (ret == GS_ERROR)
-    return ret;
-
   /* As a special case, we have to temporarily allow for assignments
      with a CALL_EXPR on the RHS.  Since in GIMPLE a function call is
      a toplevel statement, when gimplifying the GENERIC expression
@@ -4794,6 +4802,16 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, 
gimple_seq *post_p,
      reaches the CALL_EXPR.  On return from gimplify_expr, the newly
      created GIMPLE_CALL <foo> will be the last statement in *PRE_P
      and all we need to do here is set 'a' to be its LHS.  */
+  ret = gimplify_expr (from_p, pre_p, post_p,
+                      initial_rhs_predicate_for (*to_p), fb_rvalue);
+  if (ret == GS_ERROR)
+    return ret;
+
+  ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
+  if (ret == GS_ERROR)
+    return ret;
+
+  /* Now that the LHS is gimplified, we know what to use for the RHS.  */
   ret = gimplify_expr (from_p, pre_p, post_p, rhs_predicate_for (*to_p),
                       fb_rvalue);
   if (ret == GS_ERROR)

Reply via email to