/* The final value of the iv is iv1->base + MOD, assuming that this
computation does not overflow, and that
iv0->base <= iv1->base + MOD. */
- if (!iv1->no_overflow && !integer_zerop (mod))
+ if (!iv0->no_overflow && !integer_zerop (mod))
{
- bound = fold_build2 (MINUS_EXPR, type,
+ bound = fold_build2 (MINUS_EXPR, type1,
TYPE_MAX_VALUE (type1), tmod);
+ if (POINTER_TYPE_P (type))
+ bound = fold_convert (type, bound);
assumption = fold_build2 (LE_EXPR, boolean_type_node,
iv1->base, bound);
if (integer_zerop (assumption))
}
if (mpz_cmp (mmod, bnds->below) < 0)
noloop = boolean_false_node;
+ else if (POINTER_TYPE_P (type))
+ noloop = fold_build2 (GT_EXPR, boolean_type_node,
+ iv0->base,
+ fold_build2 (POINTER_PLUS_EXPR, type,
+ iv1->base, tmod));
else
noloop = fold_build2 (GT_EXPR, boolean_type_node,
iv0->base,
/* The final value of the iv is iv0->base - MOD, assuming that this
computation does not overflow, and that
iv0->base - MOD <= iv1->base. */
- if (!iv0->no_overflow && !integer_zerop (mod))
+ if (!iv1->no_overflow && !integer_zerop (mod))
{
bound = fold_build2 (PLUS_EXPR, type1,
TYPE_MIN_VALUE (type1), tmod);
+ if (POINTER_TYPE_P (type))
+ bound = fold_convert (type, bound);
assumption = fold_build2 (GE_EXPR, boolean_type_node,
iv0->base, bound);
if (integer_zerop (assumption))
}
if (mpz_cmp (mmod, bnds->below) < 0)
noloop = boolean_false_node;
+ else if (POINTER_TYPE_P (type))
+ noloop = fold_build2 (GT_EXPR, boolean_type_node,
+ fold_build2 (POINTER_PLUS_EXPR, type,
+ iv0->base,
+ fold_build1 (NEGATE_EXPR,
+ type1, tmod)),
+ iv1->base);
else
noloop = fold_build2 (GT_EXPR, boolean_type_node,
fold_build2 (MINUS_EXPR, type1,
{
if (integer_nonzerop (iv0->step))
assumption = fold_build2 (NE_EXPR, boolean_type_node,
- iv1->base, TYPE_MAX_VALUE (type1));
+ iv1->base, TYPE_MAX_VALUE (type));
else
assumption = fold_build2 (NE_EXPR, boolean_type_node,
- iv0->base, TYPE_MIN_VALUE (type1));
+ iv0->base, TYPE_MIN_VALUE (type));
if (integer_zerop (assumption))
return false;
}
if (integer_nonzerop (iv0->step))
- iv1->base = fold_build2 (PLUS_EXPR, type1,
- iv1->base, build_int_cst (type1, 1));
+ {
+ if (POINTER_TYPE_P (type))
+ iv1->base = fold_build2 (POINTER_PLUS_EXPR, type, iv1->base,
+ build_int_cst (type1, 1));
+ else
+ iv1->base = fold_build2 (PLUS_EXPR, type1, iv1->base,
+ build_int_cst (type1, 1));
+ }
+ else if (POINTER_TYPE_P (type))
+ iv0->base = fold_build2 (POINTER_PLUS_EXPR, type, iv0->base,
+ fold_build1 (NEGATE_EXPR, type1,
+ build_int_cst (type1, 1)));
else
iv0->base = fold_build2 (MINUS_EXPR, type1,
iv0->base, build_int_cst (type1, 1));
switch (code)
{
- case NOP_EXPR:
- case CONVERT_EXPR:
+ CASE_CONVERT:
/* Casts are simple. */
ee = expand_simple_operations (e);
return fold_build1 (code, TREE_TYPE (expr), ee);
&& !POINTER_TYPE_P (type))
return false;
- if (!simple_iv (loop, stmt, op0, &iv0, false))
+ if (!simple_iv (loop, loop_containing_stmt (stmt), op0, &iv0, false))
return false;
- if (!simple_iv (loop, stmt, op1, &iv1, false))
+ if (!simple_iv (loop, loop_containing_stmt (stmt), op1, &iv1, false))
return false;
/* We don't want to see undefined signed overflow warnings while
code = gimple_assign_rhs_code (stmt);
if (gimple_references_memory_p (stmt)
- /* Before alias information is computed, operand scanning marks
- statements that write memory volatile. However, the statements
- that only read memory are not marked, thus gimple_references_memory_p
- returns false for them. */
|| TREE_CODE_CLASS (code) == tcc_reference
- || TREE_CODE_CLASS (code) == tcc_declaration
- || SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_DEF) == NULL_DEF_OPERAND_P)
+ || (code == ADDR_EXPR
+ && !is_gimple_min_invariant (gimple_assign_rhs1 (stmt))))
return NULL;
use = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_USE);
- if (use == NULL_USE_OPERAND_P)
+ if (use == NULL_TREE)
return NULL;
return chain_of_csts_start (loop, use);
get_val_for (tree x, tree base)
{
gimple stmt;
- tree nx, val, retval, rhs1, rhs2;
gcc_assert (is_gimple_min_invariant (base));
/* STMT must be either an assignment of a single SSA name or an
expression involving an SSA name and a constant. Try to fold that
expression using the value for the SSA name. */
- rhs1 = gimple_assign_rhs1 (stmt);
- rhs2 = gimple_assign_rhs2 (stmt);
- if (TREE_CODE (rhs1) == SSA_NAME)
- nx = rhs1;
- else if (rhs2 && TREE_CODE (rhs2) == SSA_NAME)
- nx = rhs2;
- else
- gcc_unreachable ();
-
- /* NX is now the SSA name for which we want to discover the base value. */
- val = get_val_for (nx, base);
- if (rhs2)
- {
- /* If this is a binary expression, fold it. If folding is
- not possible, return a tree expression with the RHS of STMT. */
- rhs1 = (nx == rhs1) ? val : rhs1;
- rhs2 = (nx == rhs2) ? val : rhs2;
- retval = fold_binary (gimple_assign_rhs_code (stmt),
- gimple_expr_type (stmt), rhs1, rhs2);
- if (retval == NULL_TREE)
- retval= build2 (gimple_assign_rhs_code (stmt),
- gimple_expr_type (stmt), rhs1, rhs2);
+ if (gimple_assign_ssa_name_copy_p (stmt))
+ return get_val_for (gimple_assign_rhs1 (stmt), base);
+ else if (gimple_assign_rhs_class (stmt) == GIMPLE_UNARY_RHS
+ && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
+ {
+ return fold_build1 (gimple_assign_rhs_code (stmt),
+ gimple_expr_type (stmt),
+ get_val_for (gimple_assign_rhs1 (stmt), base));
+ }
+ else if (gimple_assign_rhs_class (stmt) == GIMPLE_BINARY_RHS)
+ {
+ tree rhs1 = gimple_assign_rhs1 (stmt);
+ tree rhs2 = gimple_assign_rhs2 (stmt);
+ if (TREE_CODE (rhs1) == SSA_NAME)
+ rhs1 = get_val_for (rhs1, base);
+ else if (TREE_CODE (rhs2) == SSA_NAME)
+ rhs2 = get_val_for (rhs2, base);
+ else
+ gcc_unreachable ();
+ return fold_build2 (gimple_assign_rhs_code (stmt),
+ gimple_expr_type (stmt), rhs1, rhs2);
}
else
- retval = val;
-
- return retval;
+ gcc_unreachable ();
}
{
gimple_stmt_iterator bsi;
+ if (gimple_code (s2) == GIMPLE_PHI)
+ return false;
+
+ if (gimple_code (s1) == GIMPLE_PHI)
+ return true;
+
for (bsi = gsi_start_bb (bb1); gsi_stmt (bsi) != s2; gsi_next (&bsi))
if (gsi_stmt (bsi) == s1)
return true;
/* If we can use the fact that signed and pointer arithmetics does not
wrap, we are done. */
- if (use_overflow_semantics && nowrap_type_p (type))
+ if (use_overflow_semantics && nowrap_type_p (TREE_TYPE (base)))
return false;
/* To be able to use estimates on number of iterations of the loop,