diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-02-09 09:54:36 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-02-09 09:54:36 +0000 |
commit | cf6b103ecba3ec845e82cac95ce2693954438eec (patch) | |
tree | 2e7796711ab7dc7b1bc13550933b9b8d077c098e /gcc/gimplify.c | |
parent | f7bac623609f2c8ed2dbebebe91001b675a035e1 (diff) | |
download | gcc-cf6b103ecba3ec845e82cac95ce2693954438eec.tar.gz |
PR c++/25979
* tree.def: Elaborate on difference from MODIFY_EXPR.
* doc/c-tree.texi (INIT_EXPR): Likewise.
* gimplify.c (internal_get_tmp_var): Use INIT_EXPR.
(gimplify_decl_expr, gimplify_init_ctor_eval): Likewise.
(gimplify_target_expr): Likewise.
(gimplify_cond_expr): Remove target handling.
(gimplify_modify_expr): Don't clobber INIT_EXPR code here.
(gimplify_expr): Clobber it here.
(gimplify_modify_expr_rhs): Push assignment into COND_EXPR here.
Do return slot optimization if we have an INIT_EXPR.
PR tree-opt/24365
* tree-inline.c (declare_return_variable): Also clear
DECL_COMPLEX_GIMPLE_REG_P as needed in the modify_dest case.
PR c++/16405
* gimplify.c (gimplify_modify_expr_rhs): Re-enable *& handling.
PR middle-end/22439
* gimplify.c (gimplify_one_sizepos): Fix typo.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@110789 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/gimplify.c')
-rw-r--r-- | gcc/gimplify.c | 105 |
1 files changed, 62 insertions, 43 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c index da800bba195..710569888ec 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -606,7 +606,7 @@ internal_get_tmp_var (tree val, tree *pre_p, tree *post_p, bool is_formal) if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE) DECL_COMPLEX_GIMPLE_REG_P (t) = 1; - mod = build2 (MODIFY_EXPR, TREE_TYPE (t), t, val); + mod = build2 (INIT_EXPR, TREE_TYPE (t), t, val); if (EXPR_HAS_LOCATION (val)) SET_EXPR_LOCUS (mod, EXPR_LOCUS (val)); @@ -1204,7 +1204,7 @@ gimplify_decl_expr (tree *stmt_p) if (!TREE_STATIC (decl)) { DECL_INITIAL (decl) = NULL_TREE; - init = build2 (MODIFY_EXPR, void_type_node, decl, init); + init = build2 (INIT_EXPR, void_type_node, decl, init); gimplify_and_add (init, stmt_p); } else @@ -2341,14 +2341,10 @@ gimple_boolify (tree expr) TARGET is the tree for T1 above. PRE_P points to the list where side effects that must happen before - *EXPR_P should be stored. - - POST_P points to the list where side effects that must happen after - *EXPR_P should be stored. */ + *EXPR_P should be stored. */ static enum gimplify_status -gimplify_cond_expr (tree *expr_p, tree *pre_p, tree *post_p, tree target, - fallback_t fallback) +gimplify_cond_expr (tree *expr_p, tree *pre_p, fallback_t fallback) { tree expr = *expr_p; tree tmp, tmp2, type; @@ -2362,16 +2358,7 @@ gimplify_cond_expr (tree *expr_p, tree *pre_p, tree *post_p, tree target, { tree result; - if (target) - { - ret = gimplify_expr (&target, pre_p, post_p, - is_gimple_min_lval, fb_lvalue); - if (ret != GS_ERROR) - ret = GS_OK; - result = tmp = target; - tmp2 = unshare_expr (target); - } - else if ((fallback & fb_lvalue) == 0) + if ((fallback & fb_lvalue) == 0) { result = tmp2 = tmp = create_tmp_var (TREE_TYPE (expr), "iftmp"); ret = GS_ALL_DONE; @@ -2836,7 +2823,7 @@ gimplify_init_ctor_eval (tree object, VEC(constructor_elt,gc) *elts, pre_p, cleared); else { - init = build2 (MODIFY_EXPR, TREE_TYPE (cref), cref, value); + init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value); gimplify_and_add (init, pre_p); } } @@ -3190,7 +3177,6 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p, while (ret != GS_UNHANDLED) switch (TREE_CODE (*from_p)) { -#if 0 case INDIRECT_REF: { /* If we have code like @@ -3212,7 +3198,6 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p, ret = GS_UNHANDLED; break; } -#endif case TARGET_EXPR: { @@ -3257,9 +3242,36 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p, copy in other cases as well. */ if (!is_gimple_reg_type (TREE_TYPE (*from_p))) { - *expr_p = *from_p; - return gimplify_cond_expr (expr_p, pre_p, post_p, *to_p, - fb_rvalue); + /* This code should mirror the code in gimplify_cond_expr. */ + enum tree_code code = TREE_CODE (*expr_p); + tree cond = *from_p; + tree result = *to_p; + + ret = gimplify_expr (&result, pre_p, post_p, + is_gimple_min_lval, fb_lvalue); + if (ret != GS_ERROR) + ret = GS_OK; + + if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node) + TREE_OPERAND (cond, 1) + = build2 (code, void_type_node, result, + TREE_OPERAND (cond, 1)); + if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node) + TREE_OPERAND (cond, 2) + = build2 (code, void_type_node, unshare_expr (result), + TREE_OPERAND (cond, 2)); + + TREE_TYPE (cond) = void_type_node; + recalculate_side_effects (cond); + + if (want_value) + { + gimplify_and_add (cond, pre_p); + *expr_p = unshare_expr (result); + } + else + *expr_p = cond; + return ret; } else ret = GS_UNHANDLED; @@ -3273,11 +3285,26 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p, { bool use_target; - if (TREE_CODE (*to_p) == RESULT_DECL - && DECL_NAME (*to_p) == NULL_TREE - && needs_to_live_in_memory (*to_p)) + if (!(rhs_predicate_for (*to_p))(*from_p)) + /* If we need a temporary, *to_p isn't accurate. */ + use_target = false; + else if (TREE_CODE (*to_p) == RESULT_DECL + && DECL_NAME (*to_p) == NULL_TREE + && needs_to_live_in_memory (*to_p)) /* It's OK to use the return slot directly unless it's an NRV. */ use_target = true; + else if (is_gimple_reg_type (TREE_TYPE (*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. */ + use_target = true; else if (!is_gimple_non_addressable (*to_p)) /* Don't use the original target if it's already addressable; if its address escapes, and the called function uses the @@ -3286,14 +3313,6 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p, When optimizing, the return_slot pass marks more functions as safe after we have escape info. */ use_target = false; - else if (TREE_CODE (*to_p) != PARM_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 (is_gimple_reg_type (TREE_TYPE (*to_p))) - /* Also don't force regs into memory. */ - use_target = false; else use_target = true; @@ -3379,10 +3398,6 @@ gimplify_modify_expr (tree *expr_p, tree *pre_p, tree *post_p, bool want_value) gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR || TREE_CODE (*expr_p) == INIT_EXPR); - /* The distinction between MODIFY_EXPR and INIT_EXPR is no longer useful. */ - if (TREE_CODE (*expr_p) == INIT_EXPR) - TREE_SET_CODE (*expr_p, MODIFY_EXPR); - /* For zero sized types only gimplify the left hand side and right hand side as statements and throw away the assignment. */ if (zero_sized_type (TREE_TYPE (*from_p))) @@ -4072,7 +4087,7 @@ gimplify_target_expr (tree *expr_p, tree *pre_p, tree *post_p) gimplify_bind_expr (&init, temp, pre_p); if (init != temp) { - init = build2 (MODIFY_EXPR, void_type_node, temp, init); + init = build2 (INIT_EXPR, void_type_node, temp, init); ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none); } @@ -5216,8 +5231,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p, break; case COND_EXPR: - ret = gimplify_cond_expr (expr_p, pre_p, post_p, NULL_TREE, - fallback); + ret = gimplify_cond_expr (expr_p, pre_p, fallback); /* C99 code may assign to an array in a structure value of a conditional expression, and this has undefined behavior only on execution, so create a temporary if an lvalue is @@ -5253,6 +5267,11 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p, case INIT_EXPR: ret = gimplify_modify_expr (expr_p, pre_p, post_p, fallback != fb_none); + + /* The distinction between MODIFY_EXPR and INIT_EXPR is no longer + useful. */ + if (*expr_p && TREE_CODE (*expr_p) == INIT_EXPR) + TREE_SET_CODE (*expr_p, MODIFY_EXPR); break; case TRUTH_ANDIF_EXPR: @@ -5889,7 +5908,7 @@ gimplify_one_sizepos (tree *expr_p, tree *stmt_p) *expr_p = create_tmp_var (type, NULL); tmp = build1 (NOP_EXPR, type, expr); - tmp = build2 (MODIFY_EXPR, type, *expr_p, expr); + tmp = build2 (MODIFY_EXPR, type, *expr_p, tmp); if (EXPR_HAS_LOCATION (expr)) SET_EXPR_LOCUS (tmp, EXPR_LOCUS (expr)); else |