This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: RFA (gimplify): PATCH to implement C++ order of evaluation paper
- From: Richard Biener <richard dot guenther at gmail dot com>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: Jason Merrill <jason at redhat dot com>, gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 28 Jun 2016 16:00:31 +0200
- Subject: Re: RFA (gimplify): PATCH to implement C++ order of evaluation paper
- Authentication-results: sourceware.org; auth=none
- References: <797c6b74-23d5-eaeb-3e48-d695356fde47 at redhat dot com> <CAFiYyc1AEANpRx+pfb-JUuvXVhzmQ4ihR_36Ne7kX4zqDW9k9w at mail dot gmail dot com> <CADzB+2mdcgwCQAsUAuynyhbzYQdNdJJ5YhKbPzJV-vEgWBFb3A at mail dot gmail dot com> <20160616161534 dot GV7387 at tucnak dot redhat dot com>
On Thu, Jun 16, 2016 at 6:15 PM, Jakub Jelinek <jakub@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.
Richard.
> static bool
> is_whatever (tree t)
> {
> /* For calls, as there are side-effects, assume lhs might not be
> is_gimple_reg. */
> if (TREE_CODE (t) == CALL_EXPR && is_gimple_reg_type (TREE_TYPE (t)))
> return is_gimple_val (t);
> /* For other side effects, also make sure those are evaluated before
> side-effects in lhs. */
> if (TREE_THIS_VOLATILE (t))
> return is_gimple_mem_rhs_or_call (t);
> /* Otherwise, optimistically assume lhs will be is_gimple_reg. */
> return is_gimple_reg_rhs_or_call (t);
> }
>
> and then do in gimplify_modify_expr:
> ret = gimplify_expr (from_p, pre_p, post_p,
> is_gimple_reg (*to_p)
> ? is_gimple_reg_rhs_or_call : is_whatever,
> 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;
>
> if (!is_gimple_reg (*to_p) && !is_gimple_mem_rhs_or_call (*from_p))
> {
> ret = gimplify_expr (from_p, pre_p, post_p, is_gimple_mem_rhs_or_call,
> fb_rvalue);
> if (ret == GS_ERROR)
> return ret;
> }
>
> Or if you want to guess if *to_p will be is_gimple_reg or not after
> gimplification, do it just very conservatively and let the more difficult
> to predict cases handled worst case by forcing something into a temporary
> with the above code.
>
> Jakub