/* Induction variable canonicalization.
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
This file is part of GCC.
}
cond = last_stmt (exit->src);
- in = exit->src->succ;
+ in = EDGE_SUCC (exit->src, 0);
if (in == exit)
- in = in->succ_next;
+ in = EDGE_SUCC (exit->src, 1);
/* Note that we do not need to worry about overflows, since
type of niter is always unsigned and all comparisons are
COND_EXPR_COND (cond) = build2 (cmp, boolean_type_node,
var,
build_int_cst (type, 0));
- modify_stmt (cond);
+ update_stmt (cond);
}
/* Computes an estimated number of insns in LOOP. */
if (n_unroll)
{
- if (!flag_unroll_loops)
- return false;
-
old_cond = COND_EXPR_COND (cond);
COND_EXPR_COND (cond) = dont_exit;
- modify_stmt (cond);
+ update_stmt (cond);
-#if 0
- /* The necessary infrastructure is not in yet. */
if (!tree_duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
loops, n_unroll, NULL,
NULL, NULL, NULL, 0))
-#endif
{
COND_EXPR_COND (cond) = old_cond;
+ update_stmt (cond);
return false;
}
}
COND_EXPR_COND (cond) = do_exit;
- modify_stmt (cond);
+ update_stmt (cond);
+
+ update_ssa (TODO_update_ssa);
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "Unrolled loop %d completely.\n", loop->num);
niter = fold (build2 (MINUS_EXPR, TREE_TYPE (niter), niter,
build_int_cst (TREE_TYPE (niter), 1)));
}
- else if (try_eval)
- niter = find_loop_niter_by_eval (loop, &exit);
-
- if (chrec_contains_undetermined (niter)
- || TREE_CODE (niter) != INTEGER_CST)
- return false;
+ else
+ {
+ /* If the loop has more than one exit, try checking all of them
+ for # of iterations determinable through scev. */
+ if (!loop->single_exit)
+ niter = find_loop_niter (loop, &exit);
+
+ /* Finally if everything else fails, try brute force evaluation. */
+ if (try_eval
+ && (chrec_contains_undetermined (niter)
+ || TREE_CODE (niter) != INTEGER_CST))
+ niter = find_loop_niter_by_eval (loop, &exit);
+
+ if (chrec_contains_undetermined (niter)
+ || TREE_CODE (niter) != INTEGER_CST)
+ return false;
+ }
if (dump_file && (dump_flags & TDF_DETAILS))
{
{
unsigned i;
struct loop *loop;
+ bool changed = false;
for (i = 1; i < loops->num; i++)
{
loop = loops->parray[i];
if (loop)
- canonicalize_loop_induction_variables (loops, loop, true, false, true);
+ changed |= canonicalize_loop_induction_variables (loops, loop,
+ true, false, true);
}
-#if 0
- /* The necessary infrastructure is not in yet. */
+ /* Clean up the information about numbers of iterations, since brute force
+ evaluation could reveal new information. */
+ scev_reset ();
+
if (changed)
cleanup_tree_cfg_loop ();
-#endif
}
/* Unroll LOOPS completely if they iterate just few times. */
changed |= canonicalize_loop_induction_variables (loops, loop,
false, true,
- !flag_ivcanon);
+ !flag_tree_loop_ivcanon);
}
-#if 0
- /* The necessary infrastructure is not in yet. */
+ /* Clean up the information about numbers of iterations, since complete
+ unrolling might have invalidated it. */
+ scev_reset ();
+
if (changed)
cleanup_tree_cfg_loop ();
-#endif
}