/* Induction variable canonicalization.
- Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
This file is part of GCC.
create_canonical_iv (struct loop *loop, edge exit, tree niter)
{
edge in;
- tree cond, type, var;
- block_stmt_iterator incr_at;
+ tree type, var;
+ gimple cond;
+ gimple_stmt_iterator incr_at;
enum tree_code cmp;
if (dump_file && (dump_flags & TDF_DETAILS))
niter = fold_build2 (PLUS_EXPR, type,
niter,
build_int_cst (type, 1));
- incr_at = bsi_last (in->src);
+ incr_at = gsi_last_bb (in->src);
create_iv (niter,
build_int_cst (type, -1),
NULL_TREE, loop,
&incr_at, false, NULL, &var);
cmp = (exit->flags & EDGE_TRUE_VALUE) ? EQ_EXPR : NE_EXPR;
- COND_EXPR_COND (cond) = build2 (cmp, boolean_type_node,
- var,
- build_int_cst (type, 0));
+ gimple_cond_set_code (cond, cmp);
+ gimple_cond_set_lhs (cond, var);
+ gimple_cond_set_rhs (cond, build_int_cst (type, 0));
update_stmt (cond);
}
tree_num_loop_insns (struct loop *loop, eni_weights *weights)
{
basic_block *body = get_loop_body (loop);
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
unsigned size = 1, i;
for (i = 0; i < loop->num_nodes; i++)
- for (bsi = bsi_start (body[i]); !bsi_end_p (bsi); bsi_next (&bsi))
- size += estimate_num_insns (bsi_stmt (bsi), weights);
+ for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi); gsi_next (&gsi))
+ size += estimate_num_insns (gsi_stmt (gsi), weights);
free (body);
return size;
enum unroll_level ul)
{
unsigned HOST_WIDE_INT n_unroll, ninsns, max_unroll, unr_insns;
- tree cond;
+ gimple cond;
if (loop->inner)
return false;
ninsns = tree_num_loop_insns (loop, &eni_size_weights);
- if (n_unroll * ninsns
- > (unsigned) PARAM_VALUE (PARAM_MAX_COMPLETELY_PEELED_INSNS))
- return false;
-
unr_insns = estimated_unrolled_size (ninsns, n_unroll);
if (dump_file && (dump_flags & TDF_DETAILS))
{
(int) unr_insns);
}
+ if (unr_insns > ninsns
+ && (unr_insns
+ > (unsigned) PARAM_VALUE (PARAM_MAX_COMPLETELY_PEELED_INSNS)))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Not unrolling loop %d "
+ "(--param max-completely-peeled-insns limit reached).\n",
+ loop->num);
+ return false;
+ }
+
if (ul == UL_NO_GROWTH
&& unr_insns > ninsns)
{
sbitmap_ones (wont_exit);
RESET_BIT (wont_exit, 0);
- if (!tree_duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
- n_unroll, wont_exit,
- exit, &to_remove,
- DLTHE_FLAG_UPDATE_FREQ
- | DLTHE_FLAG_COMPLETTE_PEEL))
+ if (!gimple_duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
+ n_unroll, wont_exit,
+ exit, &to_remove,
+ DLTHE_FLAG_UPDATE_FREQ
+ | DLTHE_FLAG_COMPLETTE_PEEL))
{
free_original_copy_tables ();
free (wont_exit);
}
cond = last_stmt (exit->src);
- COND_EXPR_COND (cond) = (exit->flags & EDGE_TRUE_VALUE) ? boolean_true_node
- : boolean_false_node;
+ if (exit->flags & EDGE_TRUE_VALUE)
+ gimple_cond_make_true (cond);
+ else
+ gimple_cond_make_false (cond);
update_stmt (cond);
update_ssa (TODO_update_ssa);
FOR_EACH_LOOP (li, loop, LI_ONLY_INNERMOST)
{
- if (may_increase_size && maybe_hot_bb_p (loop->header)
+ if (may_increase_size && optimize_loop_for_speed_p (loop)
/* Unroll outermost loops only if asked to do so or they do
not cause code growth. */
&& (unroll_outer
/* This will take care of removing completely unrolled loops
from the loop structures so we can continue unrolling now
innermost loops. */
- cleanup_tree_cfg ();
+ if (cleanup_tree_cfg ())
+ update_ssa (TODO_update_ssa_only_virtuals);
/* Clean up the information about numbers of iterations, since
complete unrolling might have invalidated it. */
{
edge exit;
struct tree_niter_desc niter;
- tree phi, def;
basic_block *body;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
unsigned i;
- tree stmt;
/* If the loop has multiple exits, it is too hard for us to handle.
Similarly, if the exit is not dominating, we cannot determine
return false;
/* Values of all loop exit phi nodes must be invariants. */
- for (phi = phi_nodes (exit->dest); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start(phi_nodes (exit->dest)); !gsi_end_p (gsi); gsi_next (&gsi))
{
+ gimple phi = gsi_stmt (gsi);
+ tree def;
+
if (!is_gimple_reg (PHI_RESULT (phi)))
continue;
return false;
}
- for (bsi = bsi_start (body[i]); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi); gsi_next (&gsi))
{
- stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (gsi);
+
if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS)
- || stmt_ann (stmt)->has_volatile_ops)
+ || gimple_has_volatile_ops (stmt))
{
free (body);
return false;
/* Also, asm statements and calls may have side effects and we
cannot change the number of times they are executed. */
- switch (TREE_CODE (stmt))
+ switch (gimple_code (stmt))
{
- case RETURN_EXPR:
- case GIMPLE_MODIFY_STMT:
- stmt = get_call_expr_in (stmt);
- if (!stmt)
- break;
-
- case CALL_EXPR:
- if (TREE_SIDE_EFFECTS (stmt))
+ case GIMPLE_CALL:
+ if (gimple_has_side_effects (stmt))
{
free (body);
return false;
}
break;
- case ASM_EXPR:
+ case GIMPLE_ASM:
/* We cannot remove volatile assembler. */
- if (ASM_VOLATILE_P (stmt))
+ if (gimple_asm_volatile_p (stmt))
{
free (body);
return false;
remove_empty_loop (struct loop *loop)
{
edge exit = single_dom_exit (loop), non_exit;
- tree cond_stmt = last_stmt (exit->src);
- tree do_exit;
+ gimple cond_stmt = last_stmt (exit->src);
basic_block *body;
unsigned n_before, freq_in, freq_h;
gcov_type exit_count = exit->count;
non_exit = EDGE_SUCC (exit->src, 1);
if (exit->flags & EDGE_TRUE_VALUE)
- do_exit = boolean_true_node;
+ gimple_cond_make_true (cond_stmt);
else
- do_exit = boolean_false_node;
-
- COND_EXPR_COND (cond_stmt) = do_exit;
+ gimple_cond_make_false (cond_stmt);
update_stmt (cond_stmt);
/* Let us set the probabilities of the edges coming from the exit block. */
}
return 0;
}
+