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)