summaryrefslogtreecommitdiff
path: root/gcc/gimplify.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/gimplify.c')
-rw-r--r--gcc/gimplify.c182
1 files changed, 127 insertions, 55 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index ce91852eea3..efe6b96dcdf 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -769,7 +769,8 @@ should_carry_locus_p (tree stmt)
static void
annotate_one_with_locus (tree t, location_t locus)
{
- if (EXPR_P (t) && ! EXPR_HAS_LOCATION (t) && should_carry_locus_p (t))
+ if (CAN_HAVE_LOCATION_P (t)
+ && ! EXPR_HAS_LOCATION (t) && should_carry_locus_p (t))
SET_EXPR_LOCATION (t, locus);
}
@@ -1040,7 +1041,7 @@ build_stack_save_restore (tree *save, tree *restore)
NULL_TREE);
tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
- *save = build2 (MODIFY_EXPR, ptr_type_node, tmp_var, save_call);
+ *save = build2 (GIMPLE_MODIFY_STMT, ptr_type_node, tmp_var, save_call);
*restore =
build_function_call_expr (implicit_built_in_decls[BUILT_IN_STACK_RESTORE],
tree_cons (NULL_TREE, tmp_var, NULL_TREE));
@@ -1141,12 +1142,13 @@ gimplify_return_expr (tree stmt, tree *pre_p)
result_decl = NULL_TREE;
else
{
- result_decl = TREE_OPERAND (ret_expr, 0);
+ result_decl = GENERIC_TREE_OPERAND (ret_expr, 0);
if (TREE_CODE (result_decl) == INDIRECT_REF)
/* See through a return by reference. */
result_decl = TREE_OPERAND (result_decl, 0);
gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR
+ || TREE_CODE (ret_expr) == GIMPLE_MODIFY_STMT
|| TREE_CODE (ret_expr) == INIT_EXPR)
&& TREE_CODE (result_decl) == RESULT_DECL);
}
@@ -1177,10 +1179,10 @@ gimplify_return_expr (tree stmt, tree *pre_p)
gimplify_ctxp->return_temp = result;
}
- /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
+ /* Smash the lhs of the GIMPLE_MODIFY_STMT to the temporary we plan to use.
Then gimplify the whole thing. */
if (result != result_decl)
- TREE_OPERAND (ret_expr, 0) = result;
+ GENERIC_TREE_OPERAND (ret_expr, 0) = result;
gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
@@ -1189,7 +1191,8 @@ gimplify_return_expr (tree stmt, tree *pre_p)
if (result == result_decl)
ret_expr = result;
else
- ret_expr = build2 (MODIFY_EXPR, TREE_TYPE (result), result_decl, result);
+ ret_expr = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (result), result_decl,
+ result);
TREE_OPERAND (stmt, 0) = ret_expr;
return GS_ALL_DONE;
@@ -1244,7 +1247,7 @@ gimplify_decl_expr (tree *stmt_p)
t = built_in_decls[BUILT_IN_ALLOCA];
t = build_function_call_expr (t, args);
t = fold_convert (ptr_type, t);
- t = build2 (MODIFY_EXPR, void_type_node, addr, t);
+ t = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
gimplify_and_add (t, stmt_p);
@@ -1943,7 +1946,7 @@ gimplify_self_mod_expr (tree *expr_p, tree *pre_p, tree *post_p,
}
t1 = build2 (arith_code, TREE_TYPE (*expr_p), lhs, rhs);
- t1 = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
+ t1 = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (lvalue), lvalue, t1);
if (postfix)
{
@@ -2466,12 +2469,14 @@ gimplify_cond_expr (tree *expr_p, tree *pre_p, fallback_t fallback)
if this branch is void; in C++ it can be, if it's a throw. */
if (TREE_TYPE (TREE_OPERAND (expr, 1)) != void_type_node)
TREE_OPERAND (expr, 1)
- = build2 (MODIFY_EXPR, void_type_node, tmp, TREE_OPERAND (expr, 1));
+ = build2 (GIMPLE_MODIFY_STMT, void_type_node, tmp,
+ TREE_OPERAND (expr, 1));
/* Build the else clause, 't1 = b;'. */
if (TREE_TYPE (TREE_OPERAND (expr, 2)) != void_type_node)
TREE_OPERAND (expr, 2)
- = build2 (MODIFY_EXPR, void_type_node, tmp2, TREE_OPERAND (expr, 2));
+ = build2 (GIMPLE_MODIFY_STMT, void_type_node, tmp2,
+ TREE_OPERAND (expr, 2));
TREE_TYPE (expr) = void_type_node;
recalculate_side_effects (expr);
@@ -2551,8 +2556,8 @@ gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value)
{
tree args, t, to, to_ptr, from;
- to = TREE_OPERAND (*expr_p, 0);
- from = TREE_OPERAND (*expr_p, 1);
+ to = GENERIC_TREE_OPERAND (*expr_p, 0);
+ from = GENERIC_TREE_OPERAND (*expr_p, 1);
args = tree_cons (NULL, size, NULL);
@@ -2583,7 +2588,7 @@ gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value)
{
tree args, t, to, to_ptr;
- to = TREE_OPERAND (*expr_p, 0);
+ to = GENERIC_TREE_OPERAND (*expr_p, 0);
args = tree_cons (NULL, size, NULL);
@@ -2746,7 +2751,8 @@ gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
/* Create and initialize the index variable. */
var_type = TREE_TYPE (upper);
var = create_tmp_var (var_type, NULL);
- append_to_statement_list (build2 (MODIFY_EXPR, var_type, var, lower), pre_p);
+ append_to_statement_list (build2 (GIMPLE_MODIFY_STMT, var_type, var, lower),
+ pre_p);
/* Add the loop entry label. */
append_to_statement_list (build1 (LABEL_EXPR,
@@ -2767,7 +2773,7 @@ gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
pre_p, cleared);
else
- append_to_statement_list (build2 (MODIFY_EXPR, TREE_TYPE (cref),
+ append_to_statement_list (build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (cref),
cref, value),
pre_p);
@@ -2782,7 +2788,7 @@ gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
pre_p);
/* Otherwise, increment the index var... */
- append_to_statement_list (build2 (MODIFY_EXPR, var_type, var,
+ append_to_statement_list (build2 (GIMPLE_MODIFY_STMT, var_type, var,
build2 (PLUS_EXPR, var_type, var,
fold_convert (var_type,
integer_one_node))),
@@ -2918,7 +2924,7 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
tree *post_p, bool want_value)
{
tree object;
- tree ctor = TREE_OPERAND (*expr_p, 1);
+ tree ctor = GENERIC_TREE_OPERAND (*expr_p, 1);
tree type = TREE_TYPE (ctor);
enum gimplify_status ret;
VEC(constructor_elt,gc) *elts;
@@ -2926,11 +2932,11 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
if (TREE_CODE (ctor) != CONSTRUCTOR)
return GS_UNHANDLED;
- ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
+ ret = gimplify_expr (&GENERIC_TREE_OPERAND (*expr_p, 0), pre_p, post_p,
is_gimple_lvalue, fb_lvalue);
if (ret == GS_ERROR)
return ret;
- object = TREE_OPERAND (*expr_p, 0);
+ object = GENERIC_TREE_OPERAND (*expr_p, 0);
elts = CONSTRUCTOR_ELTS (ctor);
@@ -3056,7 +3062,7 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
}
walk_tree (&DECL_INITIAL (new), force_labels_r, NULL, NULL);
- TREE_OPERAND (*expr_p, 1) = new;
+ GENERIC_TREE_OPERAND (*expr_p, 1) = new;
/* This is no longer an assignment of a CONSTRUCTOR, but
we still may have processing to do on the LHS. So
@@ -3075,7 +3081,7 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
preeval_data.lhs_base_decl = NULL;
preeval_data.lhs_alias_set = get_alias_set (object);
- gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
+ gimplify_init_ctor_preeval (&GENERIC_TREE_OPERAND (*expr_p, 1),
pre_p, post_p, &preeval_data);
}
@@ -3462,8 +3468,8 @@ gimplify_modify_expr_complex_part (tree *expr_p, tree *pre_p, bool want_value)
enum tree_code code, ocode;
tree lhs, rhs, new_rhs, other, realpart, imagpart;
- lhs = TREE_OPERAND (*expr_p, 0);
- rhs = TREE_OPERAND (*expr_p, 1);
+ lhs = GENERIC_TREE_OPERAND (*expr_p, 0);
+ rhs = GENERIC_TREE_OPERAND (*expr_p, 1);
code = TREE_CODE (lhs);
lhs = TREE_OPERAND (lhs, 0);
@@ -3479,8 +3485,8 @@ gimplify_modify_expr_complex_part (tree *expr_p, tree *pre_p, bool want_value)
else
new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
- TREE_OPERAND (*expr_p, 0) = lhs;
- TREE_OPERAND (*expr_p, 1) = new_rhs;
+ GENERIC_TREE_OPERAND (*expr_p, 0) = lhs;
+ GENERIC_TREE_OPERAND (*expr_p, 1) = new_rhs;
if (want_value)
{
@@ -3491,6 +3497,53 @@ gimplify_modify_expr_complex_part (tree *expr_p, tree *pre_p, bool want_value)
return GS_ALL_DONE;
}
+
+/* Destructively convert the TREE pointer in TP into a gimple tuple if
+ appropriate. */
+
+static void
+tree_to_gimple_tuple (tree *tp)
+{
+
+ switch (TREE_CODE (*tp))
+ {
+ case GIMPLE_MODIFY_STMT:
+ return;
+ case MODIFY_EXPR:
+ {
+ struct gimple_stmt *gs;
+ tree lhs = TREE_OPERAND (*tp, 0);
+ bool def_stmt_self_p = false;
+
+ if (TREE_CODE (lhs) == SSA_NAME)
+ {
+ if (SSA_NAME_DEF_STMT (lhs) == *tp)
+ def_stmt_self_p = true;
+ }
+
+ gs = &make_node (GIMPLE_MODIFY_STMT)->gstmt;
+ gs->base = (*tp)->base;
+ /* The set to base above overwrites the CODE. */
+ TREE_SET_CODE ((tree) gs, GIMPLE_MODIFY_STMT);
+
+ gs->locus = EXPR_LOCUS (*tp);
+ gs->operands[0] = TREE_OPERAND (*tp, 0);
+ gs->operands[1] = TREE_OPERAND (*tp, 1);
+ gs->block = TREE_BLOCK (*tp);
+ *tp = (tree)gs;
+
+ /* If we re-gimplify a set to an SSA_NAME, we must change the
+ SSA name's DEF_STMT link. */
+ if (def_stmt_self_p)
+ SSA_NAME_DEF_STMT (GIMPLE_STMT_OPERAND (*tp, 0)) = *tp;
+
+ return;
+ }
+ default:
+ break;
+ }
+}
+
/* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
modify_expr
@@ -3509,11 +3562,12 @@ gimplify_modify_expr_complex_part (tree *expr_p, tree *pre_p, bool want_value)
static enum gimplify_status
gimplify_modify_expr (tree *expr_p, tree *pre_p, tree *post_p, bool want_value)
{
- tree *from_p = &TREE_OPERAND (*expr_p, 1);
- tree *to_p = &TREE_OPERAND (*expr_p, 0);
+ tree *from_p = &GENERIC_TREE_OPERAND (*expr_p, 1);
+ tree *to_p = &GENERIC_TREE_OPERAND (*expr_p, 0);
enum gimplify_status ret = GS_UNHANDLED;
gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
+ || TREE_CODE (*expr_p) == GIMPLE_MODIFY_STMT
|| TREE_CODE (*expr_p) == INIT_EXPR);
/* For zero sized types only gimplify the left hand side and right hand side
@@ -3592,6 +3646,8 @@ gimplify_modify_expr (tree *expr_p, tree *pre_p, tree *post_p, bool want_value)
if (want_value)
{
+ tree_to_gimple_tuple (expr_p);
+
append_to_statement_list (*expr_p, pre_p);
*expr_p = *to_p;
return GS_OK;
@@ -4182,9 +4238,9 @@ gimple_push_cleanup (tree var, tree cleanup, bool eh_only, tree *pre_p)
*/
tree flag = create_tmp_var (boolean_type_node, "cleanup");
- tree ffalse = build2 (MODIFY_EXPR, void_type_node, flag,
+ tree ffalse = build2 (GIMPLE_MODIFY_STMT, void_type_node, flag,
boolean_false_node);
- tree ftrue = build2 (MODIFY_EXPR, void_type_node, flag,
+ tree ftrue = build2 (GIMPLE_MODIFY_STMT, void_type_node, flag,
boolean_true_node);
cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
wce = build1 (WITH_CLEANUP_EXPR, void_type_node, cleanup);
@@ -4883,8 +4939,9 @@ gimplify_omp_for (tree *expr_p, tree *pre_p)
gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, false, false);
t = OMP_FOR_INIT (for_stmt);
- gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
- decl = TREE_OPERAND (t, 0);
+ gcc_assert (TREE_CODE (t) == MODIFY_EXPR
+ || TREE_CODE (t) == GIMPLE_MODIFY_STMT);
+ decl = GENERIC_TREE_OPERAND (t, 0);
gcc_assert (DECL_P (decl));
gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl)));
@@ -4894,16 +4951,21 @@ gimplify_omp_for (tree *expr_p, tree *pre_p)
else
omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
- ret |= gimplify_expr (&TREE_OPERAND (t, 1), &OMP_FOR_PRE_BODY (for_stmt),
+ ret |= gimplify_expr (&GENERIC_TREE_OPERAND (t, 1),
+ &OMP_FOR_PRE_BODY (for_stmt),
NULL, is_gimple_val, fb_rvalue);
+ tree_to_gimple_tuple (&OMP_FOR_INIT (for_stmt));
+
t = OMP_FOR_COND (for_stmt);
gcc_assert (COMPARISON_CLASS_P (t));
- gcc_assert (TREE_OPERAND (t, 0) == decl);
+ gcc_assert (GENERIC_TREE_OPERAND (t, 0) == decl);
- ret |= gimplify_expr (&TREE_OPERAND (t, 1), &OMP_FOR_PRE_BODY (for_stmt),
+ ret |= gimplify_expr (&GENERIC_TREE_OPERAND (t, 1),
+ &OMP_FOR_PRE_BODY (for_stmt),
NULL, is_gimple_val, fb_rvalue);
+ tree_to_gimple_tuple (&OMP_FOR_INCR (for_stmt));
t = OMP_FOR_INCR (for_stmt);
switch (TREE_CODE (t))
{
@@ -4917,13 +4979,13 @@ gimplify_omp_for (tree *expr_p, tree *pre_p)
goto build_modify;
build_modify:
t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t);
- t = build2 (MODIFY_EXPR, void_type_node, decl, t);
+ t = build2 (GIMPLE_MODIFY_STMT, void_type_node, decl, t);
OMP_FOR_INCR (for_stmt) = t;
break;
- case MODIFY_EXPR:
- gcc_assert (TREE_OPERAND (t, 0) == decl);
- t = TREE_OPERAND (t, 1);
+ case GIMPLE_MODIFY_STMT:
+ gcc_assert (GIMPLE_STMT_OPERAND (t, 0) == decl);
+ t = GIMPLE_STMT_OPERAND (t, 1);
switch (TREE_CODE (t))
{
case PLUS_EXPR:
@@ -5133,7 +5195,7 @@ gimplify_omp_atomic_pipeline (tree *expr_p, tree *pre_p, tree addr,
return GS_ERROR;
x = build_fold_indirect_ref (addr);
- x = build2 (MODIFY_EXPR, void_type_node, oldval, x);
+ x = build2 (GIMPLE_MODIFY_STMT, void_type_node, oldval, x);
gimplify_and_add (x, pre_p);
/* For floating-point values, we'll need to view-convert them to integers
@@ -5151,7 +5213,7 @@ gimplify_omp_atomic_pipeline (tree *expr_p, tree *pre_p, tree addr,
newival = create_tmp_var (itype, NULL);
x = build1 (VIEW_CONVERT_EXPR, itype, oldval);
- x = build2 (MODIFY_EXPR, void_type_node, oldival, x);
+ x = build2 (GIMPLE_MODIFY_STMT, void_type_node, oldival, x);
gimplify_and_add (x, pre_p);
iaddr = fold_convert (build_pointer_type (itype), addr);
}
@@ -5162,17 +5224,17 @@ gimplify_omp_atomic_pipeline (tree *expr_p, tree *pre_p, tree addr,
x = build1 (LABEL_EXPR, void_type_node, label);
gimplify_and_add (x, pre_p);
- x = build2 (MODIFY_EXPR, void_type_node, newval, rhs);
+ x = build2 (GIMPLE_MODIFY_STMT, void_type_node, newval, rhs);
gimplify_and_add (x, pre_p);
if (newval != newival)
{
x = build1 (VIEW_CONVERT_EXPR, itype, newval);
- x = build2 (MODIFY_EXPR, void_type_node, newival, x);
+ x = build2 (GIMPLE_MODIFY_STMT, void_type_node, newival, x);
gimplify_and_add (x, pre_p);
}
- x = build2 (MODIFY_EXPR, void_type_node, oldival2,
+ x = build2 (GIMPLE_MODIFY_STMT, void_type_node, oldival2,
fold_convert (itype, oldival));
gimplify_and_add (x, pre_p);
@@ -5182,14 +5244,14 @@ gimplify_omp_atomic_pipeline (tree *expr_p, tree *pre_p, tree addr,
x = build_function_call_expr (cmpxchg, args);
if (oldval == oldival)
x = fold_convert (type, x);
- x = build2 (MODIFY_EXPR, void_type_node, oldival, x);
+ x = build2 (GIMPLE_MODIFY_STMT, void_type_node, oldival, x);
gimplify_and_add (x, pre_p);
/* For floating point, be prepared for the loop backedge. */
if (oldval != oldival)
{
x = build1 (VIEW_CONVERT_EXPR, type, oldival);
- x = build2 (MODIFY_EXPR, void_type_node, oldval, x);
+ x = build2 (GIMPLE_MODIFY_STMT, void_type_node, oldval, x);
gimplify_and_add (x, pre_p);
}
@@ -5227,7 +5289,7 @@ gimplify_omp_atomic_mutex (tree *expr_p, tree *pre_p, tree addr, tree rhs)
gimplify_and_add (t, pre_p);
t = build_fold_indirect_ref (addr);
- t = build2 (MODIFY_EXPR, void_type_node, t, rhs);
+ t = build2 (GIMPLE_MODIFY_STMT, void_type_node, t, rhs);
gimplify_and_add (t, pre_p);
t = built_in_decls[BUILT_IN_GOMP_ATOMIC_END];
@@ -5362,7 +5424,8 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
/* Die, die, die, my darling. */
if (save_expr == error_mark_node
- || (TREE_TYPE (save_expr)
+ || (!GIMPLE_STMT_P (save_expr)
+ && TREE_TYPE (save_expr)
&& TREE_TYPE (save_expr) == error_mark_node))
{
ret = GS_ERROR;
@@ -5438,14 +5501,23 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
break;
case MODIFY_EXPR:
+ case GIMPLE_MODIFY_STMT:
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);
+ if (*expr_p)
+ {
+ /* 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);
+
+ /* Convert MODIFY_EXPR to GIMPLE_MODIFY_STMT. */
+ if (TREE_CODE (*expr_p) == MODIFY_EXPR)
+ tree_to_gimple_tuple (expr_p);
+ }
+
break;
case TRUTH_ANDIF_EXPR:
@@ -5885,7 +5957,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
given a TREE_ADDRESSABLE type. */
tree tmp = create_tmp_var_raw (type, "vol");
gimple_add_tmp_var (tmp);
- *expr_p = build2 (MODIFY_EXPR, type, tmp, *expr_p);
+ *expr_p = build2 (GIMPLE_MODIFY_STMT, type, tmp, *expr_p);
}
else
/* We can't do anything useful with a volatile reference to
@@ -6117,7 +6189,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, tmp);
+ tmp = build2 (GIMPLE_MODIFY_STMT, type, *expr_p, tmp);
if (EXPR_HAS_LOCATION (expr))
SET_EXPR_LOCUS (tmp, EXPR_LOCUS (expr));
else
@@ -6340,10 +6412,10 @@ gimplify_function_tree (tree fndecl)
DECL_SAVED_TREE (fndecl) = bind;
}
+ cfun->gimplified = true;
current_function_decl = oldfn;
cfun = oldfn ? DECL_STRUCT_FUNCTION (oldfn) : NULL;
}
-
/* Expands EXPR to list of gimple statements STMTS. If SIMPLE is true,
force the result to be either ssa_name or an invariant, otherwise
@@ -6368,7 +6440,7 @@ force_gimple_operand (tree expr, tree *stmts, bool simple, tree var)
gimplify_ctxp->into_ssa = gimple_in_ssa_p (cfun);
if (var)
- expr = build2 (MODIFY_EXPR, TREE_TYPE (var), var, expr);
+ expr = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (var), var, expr);
ret = gimplify_expr (&expr, stmts, NULL,
gimple_test_f, fb_rvalue);