GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
+Free Software Foundation; either version 3, or (at your option) any
later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
/* This pass tries to find the optimal set of induction variables for the loop.
It optimizes just the basic linear induction variables (although adding
contains_abnormal_ssa_name_p (tree expr)
{
enum tree_code code;
- enum tree_code_class class;
+ enum tree_code_class codeclass;
if (!expr)
return false;
code = TREE_CODE (expr);
- class = TREE_CODE_CLASS (code);
+ codeclass = TREE_CODE_CLASS (code);
if (code == SSA_NAME)
return SSA_NAME_OCCURS_IN_ABNORMAL_PHI (expr) != 0;
idx_contains_abnormal_ssa_name_p,
NULL);
- switch (class)
+ switch (codeclass)
{
case tcc_binary:
case tcc_comparison:
*pointer_map_insert (data->niters, exit) = niter;
}
else
- niter = *slot;
+ niter = (tree) *slot;
return niter;
}
determine_base_object (tree expr)
{
enum tree_code code = TREE_CODE (expr);
- tree base, obj, op0, op1;
+ tree base, obj;
/* If this is a pointer casted to any type, we need to determine
the base object for the pointer; so handle conversions before
return fold_convert (ptr_type_node,
build_fold_addr_expr (base));
+ case POINTER_PLUS_EXPR:
+ return determine_base_object (TREE_OPERAND (expr, 0));
+
case PLUS_EXPR:
case MINUS_EXPR:
- op0 = determine_base_object (TREE_OPERAND (expr, 0));
- op1 = determine_base_object (TREE_OPERAND (expr, 1));
-
- if (!op1)
- return op0;
-
- if (!op0)
- return (code == PLUS_EXPR
- ? op1
- : fold_build1 (NEGATE_EXPR, ptr_type_node, op1));
-
- return fold_build2 (code, ptr_type_node, op0, op1);
+ /* Pointer addition is done solely using POINTER_PLUS_EXPR. */
+ gcc_unreachable ();
default:
return fold_convert (ptr_type_node, expr);
static bool
idx_find_step (tree base, tree *idx, void *data)
{
- struct ifs_ivopts_data *dta = data;
+ struct ifs_ivopts_data *dta = (struct ifs_ivopts_data *) data;
struct iv *iv;
tree step, iv_base, iv_step, lbound, off;
struct loop *loop = dta->ivopts_data->current_loop;
static bool
idx_record_use (tree base, tree *idx,
- void *data)
+ void *vdata)
{
+ struct ivopts_data *data = (struct ivopts_data *) vdata;
find_interesting_uses_op (data, *idx);
if (TREE_CODE (base) == ARRAY_REF)
{
*offset = int_cst_value (expr);
return build_int_cst (orig_type, 0);
+ case POINTER_PLUS_EXPR:
case PLUS_EXPR:
case MINUS_EXPR:
op0 = TREE_OPERAND (expr, 0);
op0 = strip_offset_1 (op0, false, false, &off0);
op1 = strip_offset_1 (op1, false, false, &off1);
- *offset = (code == PLUS_EXPR ? off0 + off1 : off0 - off1);
+ *offset = (code == MINUS_EXPR ? off0 - off1 : off0 + off1);
if (op0 == TREE_OPERAND (expr, 0)
&& op1 == TREE_OPERAND (expr, 1))
return orig_expr;
expr = op0;
else if (integer_zerop (op0))
{
- if (code == PLUS_EXPR)
- expr = op1;
- else
+ if (code == MINUS_EXPR)
expr = fold_build1 (NEGATE_EXPR, type, op1);
+ else
+ expr = op1;
}
else
expr = fold_build2 (code, type, op0, op1);
static tree
find_depends (tree *expr_p, int *ws ATTRIBUTE_UNUSED, void *data)
{
- bitmap *depends_on = data;
+ bitmap *depends_on = (bitmap *) data;
struct version_info *info;
if (TREE_CODE (*expr_p) != SSA_NAME)
{
tree obj = NULL_TREE;
rtx x = NULL_RTX;
- int *regno = data;
+ int *regno = (int *) data;
switch (TREE_CODE (*expr_p))
{
but the bit is determined from TYPE_PRECISION, not MODE_BITSIZE. */
int
-tree_int_cst_sign_bit (tree t)
+tree_int_cst_sign_bit (const_tree t)
{
unsigned bitno = TYPE_PRECISION (TREE_TYPE (t)) - 1;
unsigned HOST_WIDE_INT w;
static hashval_t
mbc_entry_hash (const void *entry)
{
- const struct mbc_entry *e = entry;
+ const struct mbc_entry *e = (const struct mbc_entry *) entry;
return 57 * (hashval_t) e->mode + (hashval_t) (e->cst % 877);
}
static int
mbc_entry_eq (const void *entry1, const void *entry2)
{
- const struct mbc_entry *e1 = entry1;
- const struct mbc_entry *e2 = entry2;
+ const struct mbc_entry *e1 = (const struct mbc_entry *) entry1;
+ const struct mbc_entry *e2 = (const struct mbc_entry *) entry2;
return (e1->mode == e2->mode
&& e1->cst == e2->cst);
symbol_cost = computation_cost (addr) + 1;
address_cost
- = computation_cost (build2 (PLUS_EXPR, type,
+ = computation_cost (build2 (POINTER_PLUS_EXPR, type,
addr,
- build_int_cst (type, 2000))) + 1;
+ build_int_cst (sizetype, 2000))) + 1;
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "force_expr_to_var_cost:\n");
switch (TREE_CODE (expr))
{
+ case POINTER_PLUS_EXPR:
case PLUS_EXPR:
case MINUS_EXPR:
case MULT_EXPR:
mode = TYPE_MODE (TREE_TYPE (expr));
switch (TREE_CODE (expr))
{
+ case POINTER_PLUS_EXPR:
case PLUS_EXPR:
case MINUS_EXPR:
cost = add_cost (mode);
{
basic_block ex_bb;
edge exit;
- tree nit, nit_type;
- tree wider_type, period, per_type;
+ tree nit, period;
struct loop *loop = data->current_loop;
aff_tree bnd;
-
+ double_int period_value, max_niter;
+
if (TREE_CODE (cand->iv->step) != INTEGER_CST)
return false;
if (!nit)
return false;
- nit_type = TREE_TYPE (nit);
-
/* Determine whether we may use the variable to test whether niter iterations
elapsed. This is the case iff the period of the induction variable is
greater than the number of iterations. */
period = iv_period (cand->iv);
if (!period)
return false;
- per_type = TREE_TYPE (period);
-
- wider_type = TREE_TYPE (period);
- if (TYPE_PRECISION (nit_type) < TYPE_PRECISION (per_type))
- wider_type = per_type;
- else
- wider_type = nit_type;
- if (!integer_nonzerop (fold_build2 (GE_EXPR, boolean_type_node,
- fold_convert (wider_type, period),
- fold_convert (wider_type, nit))))
+ /* Compare the period with the estimate on the number of iterations of the
+ loop. */
+ if (!estimated_loop_iterations (loop, true, &max_niter))
+ return false;
+ period_value = tree_to_double_int (period);
+ if (double_int_ucmp (period_value, max_niter) <= 0)
return false;
cand_value_at (loop, cand, use->stmt, nit, &bnd);
/* Try iv elimination. */
if (may_eliminate_iv (data, use, cand, &bound))
- elim_cost = force_var_cost (data, bound, &depends_on_elim);
+ {
+ elim_cost = force_var_cost (data, bound, &depends_on_elim);
+ /* The bound is a loop invariant, so it will be only computed
+ once. */
+ elim_cost /= AVG_LOOP_NITER (data->current_loop);
+ }
else
elim_cost = INFTY;
struct iv_use *use, struct iv_cand *cand)
{
tree comp;
- tree op, stmts, tgt, ass;
+ tree op, tgt, ass;
block_stmt_iterator bsi;
/* An important special case -- if we are asked to express value of
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) == MINUS_EXPR
+ || TREE_CODE (op) == POINTER_PLUS_EXPR)
{
if (TREE_OPERAND (op, 0) == cand->var_before)
op = TREE_OPERAND (op, 1);
- else if (TREE_CODE (op) == PLUS_EXPR
+ else if (TREE_CODE (op) != MINUS_EXPR
&& TREE_OPERAND (op, 1) == cand->var_before)
op = TREE_OPERAND (op, 0);
else
gcc_unreachable ();
}
- op = force_gimple_operand (comp, &stmts, false, SSA_NAME_VAR (tgt));
- if (stmts)
- bsi_insert_before (&bsi, stmts, BSI_SAME_STMT);
+ op = force_gimple_operand_bsi (&bsi, comp, false, SSA_NAME_VAR (tgt),
+ true, BSI_SAME_STMT);
if (TREE_CODE (use->stmt) == PHI_NODE)
{
}
if (aref && SSA_VAR_P (aref) && get_subvars_for_var (aref))
- return unshare_expr (sv);
+ return aref;
if (!var)
return NULL_TREE;
compare = iv_elimination_compare (data, use);
bound = unshare_expr (fold_convert (var_type, bound));
- op = force_gimple_operand_bsi (&bsi, bound, true, NULL_TREE);
+ op = force_gimple_operand_bsi (&bsi, bound, true, NULL_TREE,
+ true, BSI_SAME_STMT);
*use->op_p = build2 (compare, boolean_type_node, var, op);
return;
ok = extract_cond_operands (data, use->op_p, &var_p, NULL, NULL, NULL);
gcc_assert (ok);
- *var_p = force_gimple_operand_bsi (&bsi, comp, true, SSA_NAME_VAR (*var_p));
+ *var_p = force_gimple_operand_bsi (&bsi, comp, true, SSA_NAME_VAR (*var_p),
+ true, BSI_SAME_STMT);
}
/* Rewrites USE using candidate CAND. */