/* Instruction scheduling pass.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
and currently maintained by, Jim Wilson (wilson@cygnus.com)
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, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA. */
\f
#include "config.h"
#include "system.h"
#include "rtl.h"
#include "tm_p.h"
#include "hard-reg-set.h"
-#include "basic-block.h"
#include "regs.h"
#include "function.h"
#include "flags.h"
#include "toplev.h"
#include "recog.h"
#include "cfglayout.h"
+#include "params.h"
#include "sched-int.h"
#include "target.h"
\f
{
basic_block b = BLOCK_FOR_INSN (insn);
edge e;
- for (e = b->succ; e; e = e->succ_next)
+ edge_iterator ei;
+
+ FOR_EACH_EDGE (e, ei, b->succs)
if (e->flags & EDGE_FALLTHRU)
/* The jump may be a by-product of a branch that has been merged
in the main codepath after being conditionalized. Therefore
it may guard the fallthrough block from using a value that has
conditionally overwritten that of the main codepath. So we
consider that it restores the value of the main codepath. */
- bitmap_operation (set, e->dest->global_live_at_start, cond_set,
- BITMAP_AND);
+ bitmap_and (set, e->dest->il.rtl->global_live_at_start, cond_set);
else
- bitmap_operation (used, used, e->dest->global_live_at_start,
- BITMAP_IOR);
+ bitmap_ior_into (used, e->dest->il.rtl->global_live_at_start);
}
/* Used in schedule_insns to initialize current_sched_info for scheduling
{
before = emit_note_before (NOTE_INSN_BASIC_BLOCK, before);
NOTE_BASIC_BLOCK (before) = last;
- last->head = before;
- last->end = before;
+ BB_HEAD (last) = before;
+ BB_END (last) = before;
update_bb_for_insn (last);
}
}
rtx tail)
{
rtx insn = head;
- rtx last_inside = bb->head;
+ rtx last_inside = BB_HEAD (bb);
rtx aftertail = NEXT_INSN (tail);
- head = bb->head;
+ head = BB_HEAD (bb);
for (; insn != aftertail; insn = NEXT_INSN (insn))
{
- if (GET_CODE (insn) == CODE_LABEL)
- abort ();
+ gcc_assert (!LABEL_P (insn));
/* Create new basic blocks just before first insn. */
if (inside_basic_block_p (insn))
{
rtx note;
/* Re-emit the basic block note for newly found BB header. */
- if (GET_CODE (insn) == CODE_LABEL)
+ if (LABEL_P (insn))
{
note = emit_note_after (NOTE_INSN_BASIC_BLOCK, insn);
head = insn;
{
edge f;
rtx h;
+ edge_iterator ei;
/* An obscure special case, where we do have partially dead
instruction scheduled after last control flow instruction.
A safer solution can be to bring the code into sequence,
do the split and re-emit it back in case this will ever
trigger problem. */
- f = bb->prev_bb->succ;
- while (f && !(f->flags & EDGE_FALLTHRU))
- f = f->succ_next;
+
+ FOR_EACH_EDGE (f, ei, bb->prev_bb->succs)
+ if (f->flags & EDGE_FALLTHRU)
+ break;
if (f)
{
last = curr_bb = split_edge (f);
- h = curr_bb->head;
- curr_bb->head = head;
- curr_bb->end = insn;
+ h = BB_HEAD (curr_bb);
+ BB_HEAD (curr_bb) = head;
+ BB_END (curr_bb) = insn;
/* Edge splitting created misplaced BASIC_BLOCK note, kill
it. */
delete_insn (h);
delete_insn_chain (head, insn);
/* We keep some notes in the way that may split barrier from the
jump. */
- if (GET_CODE (next) == BARRIER)
+ if (BARRIER_P (next))
{
emit_barrier_after (prev_nonnote_insn (head));
delete_insn (next);
}
else
{
- curr_bb->head = head;
- curr_bb->end = insn;
- add_missing_bbs (curr_bb->head, bb, curr_bb->prev_bb);
+ BB_HEAD (curr_bb) = head;
+ BB_END (curr_bb) = insn;
+ add_missing_bbs (BB_HEAD (curr_bb), bb, curr_bb->prev_bb);
}
- note = GET_CODE (head) == CODE_LABEL ? NEXT_INSN (head) : head;
+ note = LABEL_P (head) ? NEXT_INSN (head) : head;
NOTE_BASIC_BLOCK (note) = curr_bb;
update_bb_for_insn (curr_bb);
bb = curr_bb->next_bb;
break;
}
}
- add_missing_bbs (last->next_bb->head, bb, last);
+ add_missing_bbs (BB_HEAD (last->next_bb), bb, last);
return bb->prev_bb;
}
basic_block last_block = NULL, bb;
for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
- if (GET_CODE (insn) == JUMP_INSN)
+ if (JUMP_P (insn))
{
bb = BLOCK_FOR_INSN (insn);
bb->aux = last_block;
bb = bb->aux;
if (!bb)
break;
- prev = bb->end;
+ prev = BB_END (bb);
}
}
- /* FALLTHRU */
+ /* Fall through. */
case TRAP_RISKY:
case IRISKY:
case PRISKY_CANDIDATE:
for (note = REG_NOTES (head); note; note = XEXP (note, 1))
if (REG_NOTE_KIND (note) == REG_SAVE_NOTE)
- {
- remove_note (head, note);
- note = XEXP (note, 1);
- remove_note (head, note);
- }
+ remove_note (head, note);
}
/* Remove remaining note insns from the block, save them in
schedule_block (-1, n_insns);
/* Sanity check: verify that all region insns were scheduled. */
- if (sched_n_insns != n_insns)
- abort ();
+ gcc_assert (sched_n_insns == n_insns);
head = current_sched_info->head;
tail = current_sched_info->tail;
schedule_ebbs (FILE *dump_file)
{
basic_block bb;
+ int probability_cutoff;
+
+ if (profile_info && flag_branch_probabilities)
+ probability_cutoff = PARAM_VALUE (TRACER_MIN_BRANCH_PROBABILITY_FEEDBACK);
+ else
+ probability_cutoff = PARAM_VALUE (TRACER_MIN_BRANCH_PROBABILITY);
+ probability_cutoff = REG_BR_PROB_BASE / 100 * probability_cutoff;
/* Taking care of this degenerate case makes the rest of
this code simpler. */
current_sched_info = &ebb_sched_info;
- allocate_reg_life_data ();
compute_bb_for_insn ();
/* Schedule every region in the subroutine. */
FOR_EACH_BB (bb)
{
- rtx head = bb->head;
+ rtx head = BB_HEAD (bb);
rtx tail;
for (;;)
{
edge e;
- tail = bb->end;
+ edge_iterator ei;
+ tail = BB_END (bb);
if (bb->next_bb == EXIT_BLOCK_PTR
- || GET_CODE (bb->next_bb->head) == CODE_LABEL)
+ || LABEL_P (BB_HEAD (bb->next_bb)))
break;
- for (e = bb->succ; e; e = e->succ_next)
+ FOR_EACH_EDGE (e, ei, bb->succs)
if ((e->flags & EDGE_FALLTHRU) != 0)
break;
if (! e)
break;
- if (e->probability < REG_BR_PROB_BASE / 2)
+ if (e->probability <= probability_cutoff)
break;
bb = bb->next_bb;
}
a note or two. */
while (head != tail)
{
- if (GET_CODE (head) == NOTE)
+ if (NOTE_P (head))
head = NEXT_INSN (head);
- else if (GET_CODE (tail) == NOTE)
+ else if (NOTE_P (tail))
tail = PREV_INSN (tail);
- else if (GET_CODE (head) == CODE_LABEL)
+ else if (LABEL_P (head))
head = NEXT_INSN (head);
else
break;