diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-03-31 10:23:44 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-03-31 10:23:44 +0000 |
commit | 47f11e8447f11764c88fec0d3963c5e1e7f4c078 (patch) | |
tree | 5f692532b5bfb1559215c17e5d2b5753f7a01415 /gcc/gimplify.c | |
parent | 7af239b5581b3391731254babaa05ec512f46953 (diff) | |
download | gcc-47f11e8447f11764c88fec0d3963c5e1e7f4c078.tar.gz |
2009-03-31 Richard Guenther <rguenther@suse.de>
PR middle-end/23401
PR middle-end/27810
* tree.h (DECL_GIMPLE_FORMAL_TEMP_P): Remove.
(struct tree_decl_with_vis): Remove gimple_formal_temp member.
* tree-eh.c (lower_eh_constructs_2): Move LHS assignment to
a separate statement.
* gimplify.c (pop_gimplify_context): Remove formal temp handling.
(lookup_tmp_var): Likewise.
(is_gimple_formal_tmp_or_call_rhs): Remove.
(is_gimple_reg_or_call_rhs): Rename to ...
(is_gimple_reg_rhs_or_call): ... this.
(is_gimple_mem_or_call_rhs): Rename to ...
(is_gimple_mem_rhs_or_call): ... this.
(internal_get_tmp_var): Use is_gimple_reg_rhs_or_call. Set
DECL_GIMPLE_REG_P only if is_formal is true.
(gimplify_compound_lval): Use is_gimple_reg. Remove workaround
for non-proper post-modify expression gimplification.
(gimplify_self_mod_expr): For post-modify expressions gimplify
the lvalue to a minimal lvalue.
(rhs_predicate_for): Remove formal temp case.
(gimplify_modify_expr_rhs): Likewise.
(gimplify_addr_expr): Use is_gimple_reg.
(gimplify_expr): Remove formal temp cases.
(gimple_regimplify_operands): Likewise.
* tree-ssa-pre.c (get_or_alloc_expr_for): Treat EXC_PTR_EXPR
and FILTER_EXPR like constants.
* gimple.c (walk_gimple_op): Fix val_only initialization, use
is_gimple_reg.
(is_gimple_formal_tmp_rhs): Remove.
(is_gimple_reg_rhs): Remove special casing.
(is_gimple_mem_rhs): Fix.
(is_gimple_reg): Move DECL_GIMPLE_REG_P handling earlier.
(is_gimple_formal_tmp_var): Remove.
(is_gimple_formal_tmp_reg): Likewise.
(is_gimple_min_lval): Allow invariant component ref parts.
* gimple.h (is_gimple_formal_tmp_rhs, is_gimple_formal_tmp_var,
is_gimple_formal_tmp_reg): Remove declarations.
* tree-cfg.c (verify_expr): Verify that variables with address
taken do not have DECL_GIMPLE_REG_P set.
* tree-mudflap.c (mf_build_check_statement_for): Use
force_gimple_operand instead of gimplify_expr.
java/
* java-gimplify.c (java_gimplify_expr): Do not manually gimplify
the first operand of binary and comaprison expressions.
* gcc.dg/tree-ssa/pr23401.c: New testcase.
* gcc.dg/tree-ssa/pr27810.c: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@145338 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/gimplify.c')
-rw-r--r-- | gcc/gimplify.c | 137 |
1 files changed, 46 insertions, 91 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c index bd82051d158..515c58ed57e 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -214,16 +214,12 @@ void pop_gimplify_context (gimple body) { struct gimplify_ctx *c = gimplify_ctxp; - tree t; gcc_assert (c && (c->bind_expr_stack == NULL || VEC_empty (gimple, c->bind_expr_stack))); VEC_free (gimple, heap, c->bind_expr_stack); gimplify_ctxp = c->prev_context; - for (t = c->temps; t ; t = TREE_CHAIN (t)) - DECL_GIMPLE_FORMAL_TEMP_P (t) = 0; - if (body) declare_vars (c->temps, body, false); else @@ -609,9 +605,6 @@ lookup_tmp_var (tree val, bool is_formal) } } - if (is_formal) - DECL_GIMPLE_FORMAL_TEMP_P (ret) = 1; - return ret; } @@ -622,32 +615,10 @@ lookup_tmp_var (tree val, bool is_formal) gimplify_modify_expr. */ static bool -is_gimple_formal_tmp_or_call_rhs (tree t) +is_gimple_reg_rhs_or_call (tree t) { - return TREE_CODE (t) == CALL_EXPR || is_gimple_formal_tmp_rhs (t); -} - -/* Returns true iff T is a valid RHS for an assignment to a renamed - user -- or front-end generated artificial -- variable. */ - -static bool -is_gimple_reg_or_call_rhs (tree t) -{ - /* If the RHS of the MODIFY_EXPR may throw or make a nonlocal goto - and the LHS is a user variable, then we need to introduce a formal - temporary. This way the optimizers can determine that the user - variable is only modified if evaluation of the RHS does not throw. - - Don't force a temp of a non-renamable type; the copy could be - arbitrarily expensive. Instead we will generate a VDEF for - the assignment. */ - - if (is_gimple_reg_type (TREE_TYPE (t)) - && ((TREE_CODE (t) == CALL_EXPR && TREE_SIDE_EFFECTS (t)) - || tree_could_throw_p (t))) - return false; - - return is_gimple_formal_tmp_or_call_rhs (t); + return (get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS + || TREE_CODE (t) == CALL_EXPR); } /* Return true if T is a valid memory RHS or a CALL_EXPR. Note that @@ -655,28 +626,18 @@ is_gimple_reg_or_call_rhs (tree t) rationale for this in gimplify_modify_expr. */ static bool -is_gimple_mem_or_call_rhs (tree t) +is_gimple_mem_rhs_or_call (tree t) { /* If we're dealing with a renamable type, either source or dest must be a renamed variable. */ if (is_gimple_reg_type (TREE_TYPE (t))) return is_gimple_val (t); else - return is_gimple_formal_tmp_or_call_rhs (t); + return (is_gimple_val (t) || is_gimple_lvalue (t) + || TREE_CODE (t) == CALL_EXPR); } - -/* Returns a formal temporary variable initialized with VAL. PRE_P is as - in gimplify_expr. Only use this function if: - - 1) The value of the unfactored expression represented by VAL will not - change between the initialization and use of the temporary, and - 2) The temporary will not be otherwise modified. - - For instance, #1 means that this is inappropriate for SAVE_EXPR temps, - and #2 means it is inappropriate for && temps. - - For other cases, use get_initialized_tmp_var instead. */ +/* Helper for get_formal_tmp_var and get_initialized_tmp_var. */ static tree internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p, @@ -686,7 +647,7 @@ internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p, /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */ - gimplify_expr (&val, pre_p, post_p, is_gimple_formal_tmp_or_call_rhs, + gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call, fb_rvalue); t = lookup_tmp_var (val, is_formal); @@ -707,11 +668,11 @@ internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p, SET_DECL_RESTRICT_BASE (t, u); } } - } - if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE - || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE) - DECL_GIMPLE_REG_P (t) = 1; + if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE + || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE) + DECL_GIMPLE_REG_P (t) = 1; + } mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val)); @@ -735,9 +696,17 @@ internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p, return t; } -/* Returns a formal temporary variable initialized with VAL. PRE_P - points to a sequence where side-effects needed to compute VAL should be - stored. */ +/* Returns a formal temporary variable initialized with VAL. PRE_P is as + in gimplify_expr. Only use this function if: + + 1) The value of the unfactored expression represented by VAL will not + change between the initialization and use of the temporary, and + 2) The temporary will not be otherwise modified. + + For instance, #1 means that this is inappropriate for SAVE_EXPR temps, + and #2 means it is inappropriate for && temps. + + For other cases, use get_initialized_tmp_var instead. */ tree get_formal_tmp_var (tree val, gimple_seq *pre_p) @@ -2006,7 +1975,7 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, { TREE_OPERAND (t, 2) = low; tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, - post_p, is_gimple_formal_tmp_reg, + post_p, is_gimple_reg, fb_rvalue); ret = MIN (ret, tret); } @@ -2026,7 +1995,7 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, { TREE_OPERAND (t, 3) = elmt_size; tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, - post_p, is_gimple_formal_tmp_reg, + post_p, is_gimple_reg, fb_rvalue); ret = MIN (ret, tret); } @@ -2049,7 +2018,7 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, { TREE_OPERAND (t, 2) = offset; tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, - post_p, is_gimple_formal_tmp_reg, + post_p, is_gimple_reg, fb_rvalue); ret = MIN (ret, tret); } @@ -2072,19 +2041,11 @@ gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF) { - /* Gimplify the dimension. - Temporary fix for gcc.c-torture/execute/20040313-1.c. - Gimplify non-constant array indices into a temporary - variable. - FIXME - The real fix is to gimplify post-modify - expressions into a minimal gimple lvalue. However, that - exposes bugs in alias analysis. The alias analyzer does - not handle &PTR->FIELD very well. Will fix after the - branch is merged into mainline (dnovillo 2004-05-03). */ + /* Gimplify the dimension. */ if (!is_gimple_min_invariant (TREE_OPERAND (t, 1))) { tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p, - is_gimple_formal_tmp_reg, fb_rvalue); + is_gimple_val, fb_rvalue); ret = MIN (ret, tret); } } @@ -2176,9 +2137,18 @@ gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, rhs = TREE_OPERAND (*expr_p, 1); /* For postfix operator, we evaluate the LHS to an rvalue and then use - that as the result value and in the postqueue operation. */ + that as the result value and in the postqueue operation. We also + make sure to make lvalue a minimal lval, see + gcc.c-torture/execute/20040313-1.c for an example where this matters. */ if (postfix) { + if (!is_gimple_min_lval (lvalue)) + { + mark_addressable (lvalue); + lvalue = build_fold_addr_expr (lvalue); + gimplify_expr (&lvalue, pre_p, post_p, is_gimple_val, fb_rvalue); + lvalue = build_fold_indirect_ref (lvalue); + } ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue); if (ret == GS_ERROR) return ret; @@ -3448,12 +3418,10 @@ gimplify_init_ctor_eval (tree object, VEC(constructor_elt,gc) *elts, gimple_predicate rhs_predicate_for (tree lhs) { - if (is_gimple_formal_tmp_var (lhs)) - return is_gimple_formal_tmp_or_call_rhs; - else if (is_gimple_reg (lhs)) - return is_gimple_reg_or_call_rhs; + if (is_gimple_reg (lhs)) + return is_gimple_reg_rhs_or_call; else - return is_gimple_mem_or_call_rhs; + return is_gimple_mem_rhs_or_call; } /* Gimplify a C99 compound literal expression. This just means adding @@ -4120,11 +4088,6 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, || (DECL_P (*to_p) && DECL_REGISTER (*to_p))) /* Don't force regs into memory. */ use_target = false; - else if (TREE_CODE (*to_p) == VAR_DECL - && DECL_GIMPLE_FORMAL_TEMP_P (*to_p)) - /* Don't use the original target if it's a formal temp; we - don't want to take their addresses. */ - use_target = false; else if (TREE_CODE (*expr_p) == INIT_EXPR) /* It's OK to use the target directly if it's being initialized. */ @@ -4644,7 +4607,7 @@ gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) This mostly happens if the frontend passed us something that it could not mark addressable yet, like a fortran pass-by-reference parameter (int) floatvar. */ - if (is_gimple_formal_tmp_var (TREE_OPERAND (expr, 0))) + if (is_gimple_reg (TREE_OPERAND (expr, 0))) TREE_OPERAND (expr, 0) = get_initialized_tmp_var (TREE_OPERAND (expr, 0), pre_p, post_p); @@ -6316,16 +6279,12 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, if (gimple_test_f == is_gimple_reg) gcc_assert (fallback & (fb_rvalue | fb_lvalue)); else if (gimple_test_f == is_gimple_val - || gimple_test_f == is_gimple_formal_tmp_rhs - || gimple_test_f == is_gimple_formal_tmp_or_call_rhs - || gimple_test_f == is_gimple_formal_tmp_reg - || gimple_test_f == is_gimple_formal_tmp_var || gimple_test_f == is_gimple_call_addr || gimple_test_f == is_gimple_condexpr || gimple_test_f == is_gimple_mem_rhs - || gimple_test_f == is_gimple_mem_or_call_rhs + || gimple_test_f == is_gimple_mem_rhs_or_call || gimple_test_f == is_gimple_reg_rhs - || gimple_test_f == is_gimple_reg_or_call_rhs + || gimple_test_f == is_gimple_reg_rhs_or_call || gimple_test_f == is_gimple_asm_val) gcc_assert (fallback & fb_rvalue); else if (gimple_test_f == is_gimple_min_lval @@ -7128,7 +7087,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue); *expr_p = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (tmp)), tmp); } - else if ((fallback & fb_rvalue) && is_gimple_formal_tmp_or_call_rhs (*expr_p)) + else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p)) { /* An rvalue will do. Assign the gimplified expression into a new temporary TMP and replace the original expression with @@ -7143,9 +7102,6 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p); else *expr_p = get_formal_tmp_var (*expr_p, pre_p); - - if (TREE_CODE (*expr_p) != SSA_NAME) - DECL_GIMPLE_FORMAL_TEMP_P (*expr_p) = 1; } else { @@ -7597,7 +7553,7 @@ gimple_regimplify_operands (gimple stmt, gimple_stmt_iterator *gsi_p) lhs = gimple_get_lhs (stmt); /* If the LHS changed it in a way that requires a simple RHS, create temporary. */ - if (lhs && !is_gimple_formal_tmp_var (lhs)) + if (lhs && !is_gimple_reg (lhs)) { bool need_temp = false; @@ -7646,7 +7602,6 @@ gimple_regimplify_operands (gimple stmt, gimple_stmt_iterator *gsi_p) { tree temp = create_tmp_var (TREE_TYPE (lhs), NULL); - DECL_GIMPLE_FORMAL_TEMP_P (temp) = 1; if (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE || TREE_CODE (TREE_TYPE (lhs)) == VECTOR_TYPE) DECL_GIMPLE_REG_P (temp) = 1; |