/* Loop unswitching for GNU compiler.
- Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
+ Free Software Foundation, Inc.
This file is part of GCC.
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 later
+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 ANY
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/>. */
#include "config.h"
#include "system.h"
op0 = force_operand (op0, NULL_RTX);
op1 = force_operand (op1, NULL_RTX);
do_compare_rtx_and_jump (op0, op1, comp, 0,
- mode, NULL_RTX, NULL_RTX, label);
+ mode, NULL_RTX, NULL_RTX, label, -1);
jump = get_last_insn ();
JUMP_LABEL (jump) = label;
LABEL_NUSES (label)++;
}
- REG_NOTES (jump) = gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob),
- REG_NOTES (jump));
+ add_reg_note (jump, REG_BR_PROB, GEN_INT (prob));
+
seq = get_insns ();
end_sequence ();
void
unswitch_loops (void)
{
- int i, num;
+ loop_iterator li;
struct loop *loop;
/* Go through inner loops (only original ones). */
- num = current_loops->num;
- for (i = 1; i < num; i++)
+ FOR_EACH_LOOP (li, loop, LI_ONLY_INNERMOST)
{
- /* Removed loop? */
- loop = current_loops->parray[i];
- if (!loop)
- continue;
-
- if (loop->inner)
- continue;
-
unswitch_single_loop (loop, NULL_RTX, 0);
#ifdef ENABLE_CHECKING
verify_dominators (CDI_DOMINATORS);
}
/* Do not unswitch in cold areas. */
- if (!maybe_hot_bb_p (loop->header))
+ if (optimize_loop_for_size_p (loop))
{
if (dump_file)
fprintf (dump_file, ";; Not unswitching, not hot area\n");
edge entry, latch_edge, true_edge, false_edge, e;
basic_block switch_bb, unswitch_on_alt;
struct loop *nloop;
- sbitmap zero_bitmap;
int irred_flag, prob;
rtx seq;
/* Make a copy. */
irred_flag = entry->flags & EDGE_IRREDUCIBLE_LOOP;
entry->flags &= ~EDGE_IRREDUCIBLE_LOOP;
- zero_bitmap = sbitmap_alloc (2);
- sbitmap_zero (zero_bitmap);
if (!duplicate_loop_to_header_edge (loop, entry, 1,
- zero_bitmap, NULL, NULL, NULL, 0))
- {
- sbitmap_free (zero_bitmap);
- return NULL;
- }
- sbitmap_free (zero_bitmap);
+ NULL, NULL, NULL, 0))
+ return NULL;
entry->flags |= irred_flag;
/* Record the block with condition we unswitch on. */
/* Loopify from the copy of LOOP body, constructing the new loop. */
nloop = loopify (latch_edge,
single_pred_edge (get_bb_copy (loop->header)), switch_bb,
- BRANCH_EDGE (switch_bb), FALLTHRU_EDGE (switch_bb), true);
+ BRANCH_EDGE (switch_bb), FALLTHRU_EDGE (switch_bb), true,
+ prob, REG_BR_PROB_BASE - prob);
/* Remove branches that are now unreachable in new loops. */
remove_path (true_edge);
remove_path (false_edge);
- /* One of created loops do not have to be subloop of the outer loop now,
- so fix its placement in loop data structure. */
- fix_loop_placement (loop);
- fix_loop_placement (nloop);
-
/* Preserve the simple loop preheaders. */
split_edge (loop_preheader_edge (loop));
split_edge (loop_preheader_edge (nloop));