summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-loop-ivopts.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-loop-ivopts.c')
-rw-r--r--gcc/tree-ssa-loop-ivopts.c377
1 files changed, 201 insertions, 176 deletions
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index ce5c05cd88f..c314da49f94 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -163,7 +163,7 @@ struct iv_use
unsigned id; /* The id of the use. */
enum use_type type; /* Type of the use. */
struct iv *iv; /* The induction variable it is based on. */
- tree stmt; /* Statement in that it occurs. */
+ gimple stmt; /* Statement in that it occurs. */
tree *op_p; /* The place where it occurs. */
bitmap related_cands; /* The set of "related" iv candidates, plus the common
important ones. */
@@ -191,7 +191,7 @@ struct iv_cand
bool important; /* Whether this is an "important" candidate, i.e. such
that it should be considered by all uses. */
enum iv_position pos; /* Where it is computed. */
- tree incremented_at; /* For original biv, the statement where it is
+ gimple incremented_at;/* For original biv, the statement where it is
incremented. */
tree var_before; /* The variable used for it before increment. */
tree var_after; /* The variable used for it after increment. */
@@ -448,7 +448,7 @@ dump_use (FILE *file, struct iv_use *use)
}
fprintf (file, " in statement ");
- print_generic_expr (file, use->stmt, TDF_SLIM);
+ print_gimple_stmt (file, use->stmt, 0, 0);
fprintf (file, "\n");
fprintf (file, " at position ");
@@ -544,9 +544,9 @@ name_info (struct ivopts_data *data, tree name)
emitted in LOOP. */
static bool
-stmt_after_ip_normal_pos (struct loop *loop, tree stmt)
+stmt_after_ip_normal_pos (struct loop *loop, gimple stmt)
{
- basic_block bb = ip_normal_pos (loop), sbb = bb_for_stmt (stmt);
+ basic_block bb = ip_normal_pos (loop), sbb = gimple_bb (stmt);
gcc_assert (bb);
@@ -563,11 +563,11 @@ stmt_after_ip_normal_pos (struct loop *loop, tree stmt)
variable CAND is incremented. */
static bool
-stmt_after_ip_original_pos (struct iv_cand *cand, tree stmt)
+stmt_after_ip_original_pos (struct iv_cand *cand, gimple stmt)
{
- basic_block cand_bb = bb_for_stmt (cand->incremented_at);
- basic_block stmt_bb = bb_for_stmt (stmt);
- block_stmt_iterator bsi;
+ basic_block cand_bb = gimple_bb (cand->incremented_at);
+ basic_block stmt_bb = gimple_bb (stmt);
+ gimple_stmt_iterator bsi;
if (!dominated_by_p (CDI_DOMINATORS, stmt_bb, cand_bb))
return false;
@@ -577,11 +577,11 @@ stmt_after_ip_original_pos (struct iv_cand *cand, tree stmt)
/* Scan the block from the end, since the original ivs are usually
incremented at the end of the loop body. */
- for (bsi = bsi_last (stmt_bb); ; bsi_prev (&bsi))
+ for (bsi = gsi_last_bb (stmt_bb); ; gsi_prev (&bsi))
{
- if (bsi_stmt (bsi) == cand->incremented_at)
+ if (gsi_stmt (bsi) == cand->incremented_at)
return false;
- if (bsi_stmt (bsi) == stmt)
+ if (gsi_stmt (bsi) == stmt)
return true;
}
}
@@ -590,7 +590,7 @@ stmt_after_ip_original_pos (struct iv_cand *cand, tree stmt)
CAND is incremented in LOOP. */
static bool
-stmt_after_increment (struct loop *loop, struct iv_cand *cand, tree stmt)
+stmt_after_increment (struct loop *loop, struct iv_cand *cand, gimple stmt)
{
switch (cand->pos)
{
@@ -858,7 +858,7 @@ get_iv (struct ivopts_data *data, tree var)
if (!name_info (data, var)->iv)
{
- bb = bb_for_stmt (SSA_NAME_DEF_STMT (var));
+ bb = gimple_bb (SSA_NAME_DEF_STMT (var));
if (!bb
|| !flow_bb_inside_loop_p (data->current_loop, bb))
@@ -872,9 +872,9 @@ get_iv (struct ivopts_data *data, tree var)
not define a simple affine biv with nonzero step. */
static tree
-determine_biv_step (tree phi)
+determine_biv_step (gimple phi)
{
- struct loop *loop = bb_for_stmt (phi)->loop_father;
+ struct loop *loop = gimple_bb (phi)->loop_father;
tree name = PHI_RESULT (phi);
affine_iv iv;
@@ -892,12 +892,16 @@ determine_biv_step (tree phi)
static bool
find_bivs (struct ivopts_data *data)
{
- tree phi, step, type, base;
+ gimple phi;
+ tree step, type, base;
bool found = false;
struct loop *loop = data->current_loop;
+ gimple_stmt_iterator psi;
- for (phi = phi_nodes (loop->header); phi; phi = PHI_CHAIN (phi))
+ for (psi = gsi_start_phis (loop->header); !gsi_end_p (psi); gsi_next (&psi))
{
+ phi = gsi_stmt (psi);
+
if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi)))
continue;
@@ -933,13 +937,17 @@ find_bivs (struct ivopts_data *data)
static void
mark_bivs (struct ivopts_data *data)
{
- tree phi, var;
+ gimple phi;
+ tree var;
struct iv *iv, *incr_iv;
struct loop *loop = data->current_loop;
basic_block incr_bb;
+ gimple_stmt_iterator psi;
- for (phi = phi_nodes (loop->header); phi; phi = PHI_CHAIN (phi))
+ for (psi = gsi_start_phis (loop->header); !gsi_end_p (psi); gsi_next (&psi))
{
+ phi = gsi_stmt (psi);
+
iv = get_iv (data, PHI_RESULT (phi));
if (!iv)
continue;
@@ -950,7 +958,7 @@ mark_bivs (struct ivopts_data *data)
continue;
/* If the increment is in the subloop, ignore it. */
- incr_bb = bb_for_stmt (SSA_NAME_DEF_STMT (var));
+ incr_bb = gimple_bb (SSA_NAME_DEF_STMT (var));
if (incr_bb->loop_father != data->current_loop
|| (incr_bb->flags & BB_IRREDUCIBLE_LOOP))
continue;
@@ -964,7 +972,7 @@ mark_bivs (struct ivopts_data *data)
parameters to IV. */
static bool
-find_givs_in_stmt_scev (struct ivopts_data *data, tree stmt, affine_iv *iv)
+find_givs_in_stmt_scev (struct ivopts_data *data, gimple stmt, affine_iv *iv)
{
tree lhs;
struct loop *loop = data->current_loop;
@@ -972,14 +980,14 @@ find_givs_in_stmt_scev (struct ivopts_data *data, tree stmt, affine_iv *iv)
iv->base = NULL_TREE;
iv->step = NULL_TREE;
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (gimple_code (stmt) != GIMPLE_ASSIGN)
return false;
- lhs = GIMPLE_STMT_OPERAND (stmt, 0);
+ lhs = gimple_assign_lhs (stmt);
if (TREE_CODE (lhs) != SSA_NAME)
return false;
- if (!simple_iv (loop, stmt, GIMPLE_STMT_OPERAND (stmt, 1), iv, true))
+ if (!simple_iv (loop, stmt, lhs, iv, true))
return false;
iv->base = expand_simple_operations (iv->base);
@@ -993,14 +1001,14 @@ find_givs_in_stmt_scev (struct ivopts_data *data, tree stmt, affine_iv *iv)
/* Finds general ivs in statement STMT. */
static void
-find_givs_in_stmt (struct ivopts_data *data, tree stmt)
+find_givs_in_stmt (struct ivopts_data *data, gimple stmt)
{
affine_iv iv;
if (!find_givs_in_stmt_scev (data, stmt, &iv))
return;
- set_iv (data, GIMPLE_STMT_OPERAND (stmt, 0), iv.base, iv.step);
+ set_iv (data, gimple_assign_lhs (stmt), iv.base, iv.step);
}
/* Finds general ivs in basic block BB. */
@@ -1008,10 +1016,10 @@ find_givs_in_stmt (struct ivopts_data *data, tree stmt)
static void
find_givs_in_bb (struct ivopts_data *data, basic_block bb)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator bsi;
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- find_givs_in_stmt (data, bsi_stmt (bsi));
+ for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
+ find_givs_in_stmt (data, gsi_stmt (bsi));
}
/* Finds general ivs. */
@@ -1070,7 +1078,7 @@ find_induction_variables (struct ivopts_data *data)
static struct iv_use *
record_use (struct ivopts_data *data, tree *use_p, struct iv *iv,
- tree stmt, enum use_type use_type)
+ gimple stmt, enum use_type use_type)
{
struct iv_use *use = XCNEW (struct iv_use);
@@ -1107,7 +1115,7 @@ record_invariant (struct ivopts_data *data, tree op, bool nonlinear_use)
|| !is_gimple_reg (op))
return;
- bb = bb_for_stmt (SSA_NAME_DEF_STMT (op));
+ bb = gimple_bb (SSA_NAME_DEF_STMT (op));
if (bb
&& flow_bb_inside_loop_p (data->current_loop, bb))
return;
@@ -1127,7 +1135,7 @@ find_interesting_uses_op (struct ivopts_data *data, tree op)
{
struct iv *iv;
struct iv *civ;
- tree stmt;
+ gimple stmt;
struct iv_use *use;
if (TREE_CODE (op) != SSA_NAME)
@@ -1156,8 +1164,8 @@ find_interesting_uses_op (struct ivopts_data *data, tree op)
*civ = *iv;
stmt = SSA_NAME_DEF_STMT (op);
- gcc_assert (TREE_CODE (stmt) == PHI_NODE
- || TREE_CODE (stmt) == GIMPLE_MODIFY_STMT);
+ gcc_assert (gimple_code (stmt) == GIMPLE_PHI
+ || is_gimple_assign (stmt));
use = record_use (data, NULL, civ, stmt, USE_NONLINEAR_EXPR);
iv->use_id = use->id;
@@ -1165,47 +1173,40 @@ find_interesting_uses_op (struct ivopts_data *data, tree op)
return use;
}
-/* Given a condition *COND_P, checks whether it is a compare of an induction
- variable and an invariant. If this is the case, CONTROL_VAR is set
- to location of the iv, BOUND to the location of the invariant,
- IV_VAR and IV_BOUND are set to the corresponding induction variable
- descriptions, and true is returned. If this is not the case,
- CONTROL_VAR and BOUND are set to the arguments of the condition and
- false is returned. */
+/* Given a condition in statement STMT, checks whether it is a compare
+ of an induction variable and an invariant. If this is the case,
+ CONTROL_VAR is set to location of the iv, BOUND to the location of
+ the invariant, IV_VAR and IV_BOUND are set to the corresponding
+ induction variable descriptions, and true is returned. If this is not
+ the case, CONTROL_VAR and BOUND are set to the arguments of the
+ condition and false is returned. */
static bool
-extract_cond_operands (struct ivopts_data *data, tree *cond_p,
+extract_cond_operands (struct ivopts_data *data, gimple stmt,
tree **control_var, tree **bound,
struct iv **iv_var, struct iv **iv_bound)
{
- /* The nodes returned when COND has just one operand. Note that you should
- not modify anything in BOUND or IV_BOUND because of this. */
+ /* The objects returned when COND has constant operands. */
static struct iv const_iv;
static tree zero;
- tree cond = *cond_p;
tree *op0 = &zero, *op1 = &zero, *tmp_op;
struct iv *iv0 = &const_iv, *iv1 = &const_iv, *tmp_iv;
bool ret = false;
- zero = integer_zero_node;
- const_iv.step = integer_zero_node;
-
- if (TREE_CODE (cond) == SSA_NAME)
+ if (gimple_code (stmt) == GIMPLE_COND)
{
- op0 = cond_p;
- iv0 = get_iv (data, cond);
- ret = (iv0 && !integer_zerop (iv0->step));
- goto end;
+ op0 = gimple_cond_lhs_ptr (stmt);
+ op1 = gimple_cond_rhs_ptr (stmt);
}
-
- if (!COMPARISON_CLASS_P (cond))
+ else
{
- op0 = cond_p;
- goto end;
+ op0 = gimple_assign_rhs1_ptr (stmt);
+ op1 = gimple_assign_rhs2_ptr (stmt);
}
- op0 = &TREE_OPERAND (cond, 0);
- op1 = &TREE_OPERAND (cond, 1);
+ zero = integer_zero_node;
+ const_iv.step = integer_zero_node;
+
if (TREE_CODE (*op0) == SSA_NAME)
iv0 = get_iv (data, *op0);
if (TREE_CODE (*op1) == SSA_NAME)
@@ -1237,16 +1238,16 @@ end:
return ret;
}
-/* Checks whether the condition *COND_P in STMT is interesting
- and if so, records it. */
+/* Checks whether the condition in STMT is interesting and if so,
+ records it. */
static void
-find_interesting_uses_cond (struct ivopts_data *data, tree stmt, tree *cond_p)
+find_interesting_uses_cond (struct ivopts_data *data, gimple stmt)
{
tree *var_p, *bound_p;
struct iv *var_iv, *civ;
- if (!extract_cond_operands (data, cond_p, &var_p, &bound_p, &var_iv, NULL))
+ if (!extract_cond_operands (data, stmt, &var_p, &bound_p, &var_iv, NULL))
{
find_interesting_uses_op (data, *var_p);
find_interesting_uses_op (data, *bound_p);
@@ -1255,7 +1256,7 @@ find_interesting_uses_cond (struct ivopts_data *data, tree stmt, tree *cond_p)
civ = XNEW (struct iv);
*civ = *var_iv;
- record_use (data, cond_p, civ, stmt, USE_COMPARE);
+ record_use (data, NULL, civ, stmt, USE_COMPARE);
}
/* Returns true if expression EXPR is obviously invariant in LOOP,
@@ -1275,7 +1276,7 @@ expr_invariant_in_loop_p (struct loop *loop, tree expr)
if (TREE_CODE (expr) == SSA_NAME)
{
- def_bb = bb_for_stmt (SSA_NAME_DEF_STMT (expr));
+ def_bb = gimple_bb (SSA_NAME_DEF_STMT (expr));
if (def_bb
&& flow_bb_inside_loop_p (loop, def_bb))
return false;
@@ -1283,7 +1284,7 @@ expr_invariant_in_loop_p (struct loop *loop, tree expr)
return true;
}
- if (!EXPR_P (expr) && !GIMPLE_STMT_P (expr))
+ if (!EXPR_P (expr))
return false;
len = TREE_OPERAND_LENGTH (expr);
@@ -1294,6 +1295,29 @@ expr_invariant_in_loop_p (struct loop *loop, tree expr)
return true;
}
+/* Returns true if statement STMT is obviously invariant in LOOP,
+ i.e. if all its operands on the RHS are defined outside of the LOOP.
+ LOOP should not be the function body. */
+
+bool
+stmt_invariant_in_loop_p (struct loop *loop, gimple stmt)
+{
+ unsigned i;
+ tree lhs;
+
+ gcc_assert (loop_depth (loop) > 0);
+
+ lhs = gimple_get_lhs (stmt);
+ for (i = 0; i < gimple_num_ops (stmt); i++)
+ {
+ tree op = gimple_op (stmt, i);
+ if (op != lhs && !expr_invariant_in_loop_p (loop, op))
+ return false;
+ }
+
+ return true;
+}
+
/* Cumulates the steps of indices into DATA and replaces their values with the
initial ones. Returns false when the value of the index cannot be determined.
Callback for for_each_index. */
@@ -1301,7 +1325,7 @@ expr_invariant_in_loop_p (struct loop *loop, tree expr)
struct ifs_ivopts_data
{
struct ivopts_data *ivopts_data;
- tree stmt;
+ gimple stmt;
tree step;
};
@@ -1553,7 +1577,7 @@ may_be_nonaddressable_p (tree expr)
/* Finds addresses in *OP_P inside STMT. */
static void
-find_interesting_uses_address (struct ivopts_data *data, tree stmt, tree *op_p)
+find_interesting_uses_address (struct ivopts_data *data, gimple stmt, tree *op_p)
{
tree base = *op_p, step = build_int_cst (sizetype, 0);
struct iv *civ;
@@ -1561,7 +1585,7 @@ find_interesting_uses_address (struct ivopts_data *data, tree stmt, tree *op_p)
/* Do not play with volatile memory references. A bit too conservative,
perhaps, but safe. */
- if (stmt_ann (stmt)->has_volatile_ops)
+ if (gimple_has_volatile_ops (stmt))
goto fail;
/* Ignore bitfields for now. Not really something terribly complicated
@@ -1657,7 +1681,7 @@ fail:
/* Finds and records invariants used in STMT. */
static void
-find_invariants_stmt (struct ivopts_data *data, tree stmt)
+find_invariants_stmt (struct ivopts_data *data, gimple stmt)
{
ssa_op_iter iter;
use_operand_p use_p;
@@ -1673,61 +1697,55 @@ find_invariants_stmt (struct ivopts_data *data, tree stmt)
/* Finds interesting uses of induction variables in the statement STMT. */
static void
-find_interesting_uses_stmt (struct ivopts_data *data, tree stmt)
+find_interesting_uses_stmt (struct ivopts_data *data, gimple stmt)
{
struct iv *iv;
- tree op, lhs, rhs;
+ tree op, *lhs, *rhs;
ssa_op_iter iter;
use_operand_p use_p;
+ enum tree_code code;
find_invariants_stmt (data, stmt);
- if (TREE_CODE (stmt) == COND_EXPR)
+ if (gimple_code (stmt) == GIMPLE_COND)
{
- find_interesting_uses_cond (data, stmt, &COND_EXPR_COND (stmt));
+ find_interesting_uses_cond (data, stmt);
return;
}
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+ if (is_gimple_assign (stmt))
{
- lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+ lhs = gimple_assign_lhs_ptr (stmt);
+ rhs = gimple_assign_rhs1_ptr (stmt);
- if (TREE_CODE (lhs) == SSA_NAME)
+ if (TREE_CODE (*lhs) == SSA_NAME)
{
/* If the statement defines an induction variable, the uses are not
interesting by themselves. */
- iv = get_iv (data, lhs);
+ iv = get_iv (data, *lhs);
if (iv && !integer_zerop (iv->step))
return;
}
- switch (TREE_CODE_CLASS (TREE_CODE (rhs)))
+ code = gimple_assign_rhs_code (stmt);
+ if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS
+ && (REFERENCE_CLASS_P (*rhs)
+ || is_gimple_val (*rhs)))
{
- case tcc_comparison:
- find_interesting_uses_cond (data, stmt,
- &GIMPLE_STMT_OPERAND (stmt, 1));
- return;
+ if (REFERENCE_CLASS_P (*rhs))
+ find_interesting_uses_address (data, stmt, rhs);
+ else
+ find_interesting_uses_op (data, *rhs);
- case tcc_reference:
- find_interesting_uses_address (data, stmt,
- &GIMPLE_STMT_OPERAND (stmt, 1));
- if (REFERENCE_CLASS_P (lhs))
- find_interesting_uses_address (data, stmt,
- &GIMPLE_STMT_OPERAND (stmt, 0));
+ if (REFERENCE_CLASS_P (*lhs))
+ find_interesting_uses_address (data, stmt, lhs);
return;
-
- default: ;
}
-
- if (REFERENCE_CLASS_P (lhs)
- && is_gimple_val (rhs))
+ else if (TREE_CODE_CLASS (code) == tcc_comparison)
{
- find_interesting_uses_address (data, stmt,
- &GIMPLE_STMT_OPERAND (stmt, 0));
- find_interesting_uses_op (data, rhs);
+ find_interesting_uses_cond (data, stmt);
return;
}
@@ -1740,11 +1758,10 @@ find_interesting_uses_stmt (struct ivopts_data *data, tree stmt)
call (memory). */
}
- if (TREE_CODE (stmt) == PHI_NODE
- && bb_for_stmt (stmt) == data->current_loop->header)
+ if (gimple_code (stmt) == GIMPLE_PHI
+ && gimple_bb (stmt) == data->current_loop->header)
{
- lhs = PHI_RESULT (stmt);
- iv = get_iv (data, lhs);
+ iv = get_iv (data, PHI_RESULT (stmt));
if (iv && !integer_zerop (iv->step))
return;
@@ -1771,10 +1788,13 @@ find_interesting_uses_stmt (struct ivopts_data *data, tree stmt)
static void
find_interesting_uses_outside (struct ivopts_data *data, edge exit)
{
- tree phi, def;
+ gimple phi;
+ gimple_stmt_iterator psi;
+ tree def;
- for (phi = phi_nodes (exit->dest); phi; phi = PHI_CHAIN (phi))
+ for (psi = gsi_start_phis (exit->dest); !gsi_end_p (psi); gsi_next (&psi))
{
+ phi = gsi_stmt (psi);
def = PHI_ARG_DEF_FROM_EDGE (phi, exit);
if (is_gimple_reg (def))
find_interesting_uses_op (data, def);
@@ -1787,8 +1807,7 @@ static void
find_interesting_uses (struct ivopts_data *data)
{
basic_block bb;
- block_stmt_iterator bsi;
- tree phi;
+ gimple_stmt_iterator bsi;
basic_block *body = get_loop_body (data->current_loop);
unsigned i;
struct version_info *info;
@@ -1807,10 +1826,10 @@ find_interesting_uses (struct ivopts_data *data)
&& !flow_bb_inside_loop_p (data->current_loop, e->dest))
find_interesting_uses_outside (data, e);
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
- find_interesting_uses_stmt (data, phi);
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- find_interesting_uses_stmt (data, bsi_stmt (bsi));
+ for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi))
+ find_interesting_uses_stmt (data, gsi_stmt (bsi));
+ for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
+ find_interesting_uses_stmt (data, gsi_stmt (bsi));
}
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -2033,7 +2052,7 @@ find_depends (tree *expr_p, int *ws ATTRIBUTE_UNUSED, void *data)
static struct iv_cand *
add_candidate_1 (struct ivopts_data *data,
tree base, tree step, bool important, enum iv_position pos,
- struct iv_use *use, tree incremented_at)
+ struct iv_use *use, gimple incremented_at)
{
unsigned i;
struct iv_cand *cand = NULL;
@@ -2157,10 +2176,10 @@ add_candidate (struct ivopts_data *data,
tree base, tree step, bool important, struct iv_use *use)
{
if (ip_normal_pos (data->current_loop))
- add_candidate_1 (data, base, step, important, IP_NORMAL, use, NULL_TREE);
+ add_candidate_1 (data, base, step, important, IP_NORMAL, use, NULL);
if (ip_end_pos (data->current_loop)
&& allow_ip_end_pos_p (data->current_loop))
- add_candidate_1 (data, base, step, important, IP_END, use, NULL_TREE);
+ add_candidate_1 (data, base, step, important, IP_END, use, NULL);
}
/* Add a standard "0 + 1 * iteration" iv candidate for a
@@ -2193,7 +2212,8 @@ add_standard_iv_candidates (struct ivopts_data *data)
static void
add_old_iv_candidates (struct ivopts_data *data, struct iv *iv)
{
- tree phi, def;
+ gimple phi;
+ tree def;
struct iv_cand *cand;
add_candidate (data, iv->base, iv->step, true, NULL);
@@ -2204,7 +2224,7 @@ add_old_iv_candidates (struct ivopts_data *data, struct iv *iv)
iv->step, true, NULL);
phi = SSA_NAME_DEF_STMT (iv->ssa_name);
- if (TREE_CODE (phi) == PHI_NODE)
+ if (gimple_code (phi) == GIMPLE_PHI)
{
/* Additionally record the possibility of leaving the original iv
untouched. */
@@ -2643,7 +2663,7 @@ computation_cost (tree expr)
/* Returns variable containing the value of candidate CAND at statement AT. */
static tree
-var_at_stmt (struct loop *loop, struct iv_cand *cand, tree stmt)
+var_at_stmt (struct loop *loop, struct iv_cand *cand, gimple stmt)
{
if (stmt_after_increment (loop, cand, stmt))
return cand->var_after;
@@ -2713,7 +2733,7 @@ determine_common_wider_type (tree *a, tree *b)
static bool
get_computation_aff (struct loop *loop,
- struct iv_use *use, struct iv_cand *cand, tree at,
+ struct iv_use *use, struct iv_cand *cand, gimple at,
struct affine_tree_combination *aff)
{
tree ubase = use->iv->base;
@@ -2788,7 +2808,7 @@ get_computation_aff (struct loop *loop,
static tree
get_computation_at (struct loop *loop,
- struct iv_use *use, struct iv_cand *cand, tree at)
+ struct iv_use *use, struct iv_cand *cand, gimple at)
{
aff_tree aff;
tree type = TREE_TYPE (use->iv->base);
@@ -3458,7 +3478,7 @@ difference_cost (struct ivopts_data *data,
static comp_cost
get_computation_cost_at (struct ivopts_data *data,
struct iv_use *use, struct iv_cand *cand,
- bool address_p, bitmap *depends_on, tree at)
+ bool address_p, bitmap *depends_on, gimple at)
{
tree ubase = use->iv->base, ustep = use->iv->step;
tree cbase, cstep;
@@ -3672,7 +3692,7 @@ determine_use_iv_cost_address (struct ivopts_data *data,
stores it to VAL. */
static void
-cand_value_at (struct loop *loop, struct iv_cand *cand, tree at, tree niter,
+cand_value_at (struct loop *loop, struct iv_cand *cand, gimple at, tree niter,
aff_tree *val)
{
aff_tree step, delta, nit;
@@ -3725,7 +3745,7 @@ iv_elimination_compare (struct ivopts_data *data, struct iv_use *use)
basic_block ex_bb;
edge exit;
- ex_bb = bb_for_stmt (use->stmt);
+ ex_bb = gimple_bb (use->stmt);
exit = EDGE_SUCC (ex_bb, 0);
if (flow_bb_inside_loop_p (loop, exit->dest))
exit = EDGE_SUCC (ex_bb, 1);
@@ -3751,11 +3771,10 @@ may_eliminate_iv (struct ivopts_data *data,
/* For now works only for exits that dominate the loop latch.
TODO: extend to other conditions inside loop body. */
- ex_bb = bb_for_stmt (use->stmt);
+ ex_bb = gimple_bb (use->stmt);
if (use->stmt != last_stmt (ex_bb)
- || TREE_CODE (use->stmt) != COND_EXPR)
- return false;
- if (!dominated_by_p (CDI_DOMINATORS, loop->latch, ex_bb))
+ || gimple_code (use->stmt) != GIMPLE_COND
+ || !dominated_by_p (CDI_DOMINATORS, loop->latch, ex_bb))
return false;
exit = EDGE_SUCC (ex_bb, 0);
@@ -3834,7 +3853,7 @@ determine_use_iv_cost_condition (struct ivopts_data *data,
/* Try expressing the original giv. If it is compared with an invariant,
note that we cannot get rid of it. */
- ok = extract_cond_operands (data, use->op_p, NULL, NULL, NULL, &cmp_iv);
+ ok = extract_cond_operands (data, use->stmt, NULL, NULL, NULL, &cmp_iv);
gcc_assert (ok);
express_cost = get_computation_cost (data, use, cand, false,
@@ -4050,7 +4069,9 @@ static void
determine_set_costs (struct ivopts_data *data)
{
unsigned j, n;
- tree phi, op;
+ gimple phi;
+ gimple_stmt_iterator psi;
+ tree op;
struct loop *loop = data->current_loop;
bitmap_iterator bi;
@@ -4083,8 +4104,9 @@ determine_set_costs (struct ivopts_data *data)
}
n = 0;
- for (phi = phi_nodes (loop->header); phi; phi = PHI_CHAIN (phi))
+ for (psi = gsi_start_phis (loop->header); !gsi_end_p (psi); gsi_next (&psi))
{
+ phi = gsi_stmt (psi);
op = PHI_RESULT (phi);
if (!is_gimple_reg (op))
@@ -4925,7 +4947,7 @@ find_optimal_iv_set (struct ivopts_data *data)
static void
create_new_iv (struct ivopts_data *data, struct iv_cand *cand)
{
- block_stmt_iterator incr_pos;
+ gimple_stmt_iterator incr_pos;
tree base;
bool after = false;
@@ -4935,11 +4957,11 @@ create_new_iv (struct ivopts_data *data, struct iv_cand *cand)
switch (cand->pos)
{
case IP_NORMAL:
- incr_pos = bsi_last (ip_normal_pos (data->current_loop));
+ incr_pos = gsi_last_bb (ip_normal_pos (data->current_loop));
break;
case IP_END:
- incr_pos = bsi_last (ip_end_pos (data->current_loop));
+ incr_pos = gsi_last_bb (ip_end_pos (data->current_loop));
after = true;
break;
@@ -4984,17 +5006,15 @@ create_new_ivs (struct ivopts_data *data, struct iv_ca *set)
is true, remove also the ssa name defined by the statement. */
static void
-remove_statement (tree stmt, bool including_defined_name)
+remove_statement (gimple stmt, bool including_defined_name)
{
- if (TREE_CODE (stmt) == PHI_NODE)
- {
- remove_phi_node (stmt, NULL_TREE, including_defined_name);
- }
+ gimple_stmt_iterator bsi = gsi_for_stmt (stmt);
+
+ if (gimple_code (stmt) == GIMPLE_PHI)
+ remove_phi_node (&bsi, including_defined_name);
else
{
- block_stmt_iterator bsi = bsi_for_stmt (stmt);
-
- bsi_remove (&bsi, true);
+ gsi_remove (&bsi, true);
release_defs (stmt);
}
}
@@ -5007,8 +5027,9 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data,
struct iv_use *use, struct iv_cand *cand)
{
tree comp;
- tree op, tgt, ass;
- block_stmt_iterator bsi;
+ tree op, tgt;
+ gimple ass;
+ gimple_stmt_iterator bsi;
/* An important special case -- if we are asked to express value of
the original iv by itself, just exit; there is no need to
@@ -5018,10 +5039,10 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data,
&& cand->incremented_at == use->stmt)
{
tree step, ctype, utype;
- enum tree_code incr_code = PLUS_EXPR;
+ enum tree_code incr_code = PLUS_EXPR, old_code;
- gcc_assert (TREE_CODE (use->stmt) == GIMPLE_MODIFY_STMT);
- gcc_assert (GIMPLE_STMT_OPERAND (use->stmt, 0) == cand->var_after);
+ gcc_assert (is_gimple_assign (use->stmt));
+ gcc_assert (gimple_assign_lhs (use->stmt) == cand->var_after);
step = cand->iv->step;
ctype = TREE_TYPE (step);
@@ -5037,16 +5058,16 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data,
computations in the loop -- otherwise, the computation
we rely upon may be removed in remove_unused_ivs,
thus leading to ICE. */
- op = GIMPLE_STMT_OPERAND (use->stmt, 1);
- if (TREE_CODE (op) == PLUS_EXPR
- || TREE_CODE (op) == MINUS_EXPR
- || TREE_CODE (op) == POINTER_PLUS_EXPR)
+ old_code = gimple_assign_rhs_code (use->stmt);
+ if (old_code == PLUS_EXPR
+ || old_code == MINUS_EXPR
+ || old_code == POINTER_PLUS_EXPR)
{
- if (TREE_OPERAND (op, 0) == cand->var_before)
- op = TREE_OPERAND (op, 1);
- else if (TREE_CODE (op) != MINUS_EXPR
- && TREE_OPERAND (op, 1) == cand->var_before)
- op = TREE_OPERAND (op, 0);
+ if (gimple_assign_rhs1 (use->stmt) == cand->var_before)
+ op = gimple_assign_rhs2 (use->stmt);
+ else if (old_code != MINUS_EXPR
+ && gimple_assign_rhs2 (use->stmt) == cand->var_before)
+ op = gimple_assign_rhs1 (use->stmt);
else
op = NULL_TREE;
}
@@ -5071,39 +5092,41 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data,
gcc_assert (comp != NULL_TREE);
}
- switch (TREE_CODE (use->stmt))
+ switch (gimple_code (use->stmt))
{
- case PHI_NODE:
+ case GIMPLE_PHI:
tgt = PHI_RESULT (use->stmt);
/* If we should keep the biv, do not replace it. */
if (name_info (data, tgt)->preserve_biv)
return;
- bsi = bsi_after_labels (bb_for_stmt (use->stmt));
+ bsi = gsi_after_labels (gimple_bb (use->stmt));
break;
- case GIMPLE_MODIFY_STMT:
- tgt = GIMPLE_STMT_OPERAND (use->stmt, 0);
- bsi = bsi_for_stmt (use->stmt);
+ case GIMPLE_ASSIGN:
+ tgt = gimple_assign_lhs (use->stmt);
+ bsi = gsi_for_stmt (use->stmt);
break;
default:
gcc_unreachable ();
}
- op = force_gimple_operand_bsi (&bsi, comp, false, SSA_NAME_VAR (tgt),
- true, BSI_SAME_STMT);
+ op = force_gimple_operand_gsi (&bsi, comp, false, SSA_NAME_VAR (tgt),
+ true, GSI_SAME_STMT);
- if (TREE_CODE (use->stmt) == PHI_NODE)
+ if (gimple_code (use->stmt) == GIMPLE_PHI)
{
- ass = build_gimple_modify_stmt (tgt, op);
- bsi_insert_before (&bsi, ass, BSI_SAME_STMT);
+ ass = gimple_build_assign (tgt, op);
+ gsi_insert_before (&bsi, ass, GSI_SAME_STMT);
remove_statement (use->stmt, false);
- SSA_NAME_DEF_STMT (tgt) = ass;
}
else
- GIMPLE_STMT_OPERAND (use->stmt, 1) = op;
+ {
+ gimple_assign_set_rhs_from_tree (&bsi, op);
+ use->stmt = gsi_stmt (bsi);
+ }
}
/* Replaces ssa name in index IDX by its basic variable. Callback for
@@ -5222,7 +5245,7 @@ rewrite_use_address (struct ivopts_data *data,
struct iv_use *use, struct iv_cand *cand)
{
aff_tree aff;
- block_stmt_iterator bsi = bsi_for_stmt (use->stmt);
+ gimple_stmt_iterator bsi = gsi_for_stmt (use->stmt);
tree ref;
bool ok;
@@ -5243,7 +5266,7 @@ rewrite_use_compare (struct ivopts_data *data,
struct iv_use *use, struct iv_cand *cand)
{
tree comp, *var_p, op, bound;
- block_stmt_iterator bsi = bsi_for_stmt (use->stmt);
+ gimple_stmt_iterator bsi = gsi_for_stmt (use->stmt);
enum tree_code compare;
struct cost_pair *cp = get_use_iv_cost (data, use, cand);
bool ok;
@@ -5256,10 +5279,12 @@ rewrite_use_compare (struct ivopts_data *data,
compare = iv_elimination_compare (data, use);
bound = unshare_expr (fold_convert (var_type, bound));
- op = force_gimple_operand_bsi (&bsi, bound, true, NULL_TREE,
- true, BSI_SAME_STMT);
+ op = force_gimple_operand_gsi (&bsi, bound, true, NULL_TREE,
+ true, GSI_SAME_STMT);
- *use->op_p = build2 (compare, boolean_type_node, var, op);
+ gimple_cond_set_lhs (use->stmt, var);
+ gimple_cond_set_code (use->stmt, compare);
+ gimple_cond_set_rhs (use->stmt, op);
return;
}
@@ -5268,11 +5293,11 @@ rewrite_use_compare (struct ivopts_data *data,
comp = get_computation (data->current_loop, use, cand);
gcc_assert (comp != NULL_TREE);
- ok = extract_cond_operands (data, use->op_p, &var_p, NULL, NULL, NULL);
+ ok = extract_cond_operands (data, use->stmt, &var_p, NULL, NULL, NULL);
gcc_assert (ok);
- *var_p = force_gimple_operand_bsi (&bsi, comp, true, SSA_NAME_VAR (*var_p),
- true, BSI_SAME_STMT);
+ *var_p = force_gimple_operand_gsi (&bsi, comp, true, SSA_NAME_VAR (*var_p),
+ true, GSI_SAME_STMT);
}
/* Rewrites USE using candidate CAND. */
@@ -5452,7 +5477,7 @@ tree_ssa_iv_optimize_loop (struct ivopts_data *data, struct loop *loop)
{
fprintf (dump_file, " single exit %d -> %d, exit condition ",
exit->src->index, exit->dest->index);
- print_generic_expr (dump_file, last_stmt (exit->src), TDF_SLIM);
+ print_gimple_stmt (dump_file, last_stmt (exit->src), 0, TDF_SLIM);
fprintf (dump_file, "\n");
}