i386.c (x86_inter_unit_moves): New variable.

* i386.c (x86_inter_unit_moves): New variable.
	(ix86_secondary_memory_needed): Fix 64bit case, honor
	TARGET_INTER_UNIT_MOVES
	* i386.h (x86_inter_unit_moves): Declare.
	(TARGET_INTER_UNIT_MOVES): New macro.
	* i386.md (movsi_1): Cleanup constraints; disable
	when not doing inter-unit moves.
	(movsi_1_nointernunit): New.
	(movdi_1_rex64): Fix constraints; deal with SSE->GPR moves.
	(movdi_1_rex64_nointerunit): New.
	(mivsf_1): disable when not doing inter-unit moves.
	(movsf_1_nointerunit): New.

	* basic-block.h (inside_basic_block_p):  Declare.
	* cfgbuild.c (inside_basic_block_p): Make global.
	* haifa-sched.c (unlink_other_notes0: Deal with NOT_INSN_BASIC_BLOCK.
	* scheudle-ebb.c  (schedule_ebb): Return last basic block of trace;
	update CFG.
	(fix_basic_block_boundaries, add_missing_bbs): New.
	(rank): Use profile.
	(scheudle_ebbs): Rely on CFG; update coments.

From-SVN: r62477
This commit is contained in:
Jan Hubicka 2003-02-06 11:03:13 +01:00 committed by Jan Hubicka
parent 6eeabb09a6
commit 8f62128d21
8 changed files with 405 additions and 37 deletions

View File

@ -1,3 +1,27 @@
Thu Feb 6 00:18:38 CET 2003 Jan Hubicka <jh@suse.cz>
* i386.c (x86_inter_unit_moves): New variable.
(ix86_secondary_memory_needed): Fix 64bit case, honor
TARGET_INTER_UNIT_MOVES
* i386.h (x86_inter_unit_moves): Declare.
(TARGET_INTER_UNIT_MOVES): New macro.
* i386.md (movsi_1): Cleanup constraints; disable
when not doing inter-unit moves.
(movsi_1_nointernunit): New.
(movdi_1_rex64): Fix constraints; deal with SSE->GPR moves.
(movdi_1_rex64_nointerunit): New.
(mivsf_1): disable when not doing inter-unit moves.
(movsf_1_nointerunit): New.
* basic-block.h (inside_basic_block_p): Declare.
* cfgbuild.c (inside_basic_block_p): Make global.
* haifa-sched.c (unlink_other_notes0: Deal with NOT_INSN_BASIC_BLOCK.
* scheudle-ebb.c (schedule_ebb): Return last basic block of trace;
update CFG.
(fix_basic_block_boundaries, add_missing_bbs): New.
(rank): Use profile.
(scheudle_ebbs): Rely on CFG; update coments.
2003-02-05 Geoffrey Keating <geoffk@apple.com>
* Makefile.in (host_hook_obj): New.

View File

@ -613,6 +613,7 @@ extern void fixup_abnormal_edges PARAMS ((void));
extern bool can_hoist_insn_p PARAMS ((rtx, rtx, regset));
extern rtx hoist_insn_after PARAMS ((rtx, rtx, rtx, rtx));
extern rtx hoist_insn_to_edge PARAMS ((rtx, edge, rtx, rtx));
extern bool inside_basic_block_p PARAMS ((rtx));
extern bool control_flow_insn_p PARAMS ((rtx));
/* In dominance.c */

View File

@ -58,12 +58,11 @@ static void make_label_edge PARAMS ((sbitmap *, basic_block,
static void make_eh_edge PARAMS ((sbitmap *, basic_block, rtx));
static void find_bb_boundaries PARAMS ((basic_block));
static void compute_outgoing_frequencies PARAMS ((basic_block));
static bool inside_basic_block_p PARAMS ((rtx));
/* Return true if insn is something that should be contained inside basic
block. */
static bool
bool
inside_basic_block_p (insn)
rtx insn;
{

View File

@ -521,6 +521,7 @@ const int x86_sse_typeless_stores = m_ATHLON_K8;
const int x86_sse_load0_by_pxor = m_PPRO | m_PENT4;
const int x86_use_ffreep = m_ATHLON_K8;
const int x86_rep_movl_optimal = m_386 | m_PENT | m_PPRO | m_K6;
const int x86_inter_unit_moves = ~(m_ATHLON_K8);
/* In case the average insn count for single function invocation is
lower than this constant, emit fast (but longer) prologue and
@ -14386,10 +14387,10 @@ ix86_secondary_memory_needed (class1, class2, mode, strict)
return 1;
}
return (FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class2)
|| (SSE_CLASS_P (class1) != SSE_CLASS_P (class2)
&& (mode) != SImode)
|| (MMX_CLASS_P (class1) != MMX_CLASS_P (class2)
&& (mode) != SImode));
|| ((SSE_CLASS_P (class1) != SSE_CLASS_P (class2)
|| MMX_CLASS_P (class1) != MMX_CLASS_P (class2))
&& ((mode != SImode && (mode != DImode || !TARGET_64BIT))
|| (!TARGET_INTER_UNIT_MOVES && !optimize_size))));
}
/* Return the cost of moving data from a register in class CLASS1 to
one in class CLASS2.

View File

@ -230,6 +230,7 @@ extern const int x86_arch_always_fancy_math_387, x86_shift1;
extern const int x86_sse_partial_reg_dependency, x86_sse_partial_regs;
extern const int x86_sse_typeless_stores, x86_sse_load0_by_pxor;
extern const int x86_use_ffreep, x86_sse_partial_regs_for_cvtsd2ss;
extern const int x86_inter_unit_moves;
extern int x86_prefetch_sse;
#define TARGET_USE_LEAVE (x86_use_leave & CPUMASK)
@ -282,6 +283,7 @@ extern int x86_prefetch_sse;
#define TARGET_SHIFT1 (x86_shift1 & CPUMASK)
#define TARGET_USE_FFREEP (x86_use_ffreep & CPUMASK)
#define TARGET_REP_MOVL_OPTIMAL (x86_rep_movl_optimal & CPUMASK)
#define TARGET_INTER_UNIT_MOVES (x86_inter_unit_moves & CPUMASK)
#define TARGET_STACK_PROBE (target_flags & MASK_STACK_PROBE)

View File

@ -1165,8 +1165,49 @@
(define_insn "*movsi_1"
[(set (match_operand:SI 0 "nonimmediate_operand" "=*?a,r,*?a,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
(match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,rm,*y,*y,rm,*Y,*Y"))]
"GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
(match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
"(TARGET_INTER_UNIT_MOVES || optimize_size)
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
{
switch (get_attr_type (insn))
{
case TYPE_SSEMOV:
if (get_attr_mode (insn) == TImode)
return "movdqa\t{%1, %0|%0, %1}";
return "movd\t{%1, %0|%0, %1}";
case TYPE_MMXMOV:
if (get_attr_mode (insn) == DImode)
return "movq\t{%1, %0|%0, %1}";
return "movd\t{%1, %0|%0, %1}";
case TYPE_LEA:
return "lea{l}\t{%1, %0|%0, %1}";
default:
if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
abort();
return "mov{l}\t{%1, %0|%0, %1}";
}
}
[(set (attr "type")
(cond [(eq_attr "alternative" "4,5,6")
(const_string "mmxmov")
(eq_attr "alternative" "7,8,9")
(const_string "ssemov")
(and (ne (symbol_ref "flag_pic") (const_int 0))
(match_operand:SI 1 "symbolic_operand" ""))
(const_string "lea")
]
(const_string "imov")))
(set_attr "modrm" "0,*,0,*,*,*,*,*,*,*")
(set_attr "mode" "SI,SI,SI,SI,DI,SI,SI,TI,SI,SI")])
(define_insn "*movsi_1_nointernunit"
[(set (match_operand:SI 0 "nonimmediate_operand" "=*?a,r,*?a,m,!*y,!m,!*y,!*Y,!m,!*Y")
(match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,*y,*y,m,*Y,*Y,m"))]
"(!TARGET_INTER_UNIT_MOVES && !optimize_size)
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
{
switch (get_attr_type (insn))
{
@ -1200,7 +1241,7 @@
]
(const_string "imov")))
(set_attr "modrm" "0,*,0,*,*,*,*,*,*,*")
(set_attr "mode" "SI,SI,SI,SI,SI,SI,DI,TI,SI,SI")])
(set_attr "mode" "SI,SI,SI,SI,DI,SI,SI,TI,SI,SI")])
;; Stores and loads of ax to arbitrary constant address.
;; We fake an second form of instruction to force reload to load address
@ -1931,16 +1972,66 @@
"ix86_split_long_move (operands); DONE;")
(define_insn "*movdi_1_rex64"
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!m*y,!*y,!*Y,!m,!*Y")
(match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,m,*Y,*Y,*m"))]
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
(match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
"TARGET_64BIT
&& (TARGET_INTER_UNIT_MOVES || optimize_size)
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
{
switch (get_attr_type (insn))
{
case TYPE_SSEMOV:
if (register_operand (operands[0], DImode)
&& register_operand (operands[1], DImode))
if (get_attr_mode (insn) == MODE_TI)
return "movdqa\t{%1, %0|%0, %1}";
/* Moves from and into integer register is done using movd opcode with
REX prefix. */
if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
return "movd\t{%1, %0|%0, %1}";
/* FALLTHRU */
case TYPE_MMXMOV:
return "movq\t{%1, %0|%0, %1}";
case TYPE_MULTI:
return "#";
case TYPE_LEA:
return "lea{q}\t{%a1, %0|%0, %a1}";
default:
if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
abort ();
if (get_attr_mode (insn) == MODE_SI)
return "mov{l}\t{%k1, %k0|%k0, %k1}";
else if (which_alternative == 2)
return "movabs{q}\t{%1, %0|%0, %1}";
else
return "mov{q}\t{%1, %0|%0, %1}";
}
}
[(set (attr "type")
(cond [(eq_attr "alternative" "5,6,7")
(const_string "mmxmov")
(eq_attr "alternative" "8,9,10")
(const_string "ssemov")
(eq_attr "alternative" "4")
(const_string "multi")
(and (ne (symbol_ref "flag_pic") (const_int 0))
(match_operand:DI 1 "symbolic_operand" ""))
(const_string "lea")
]
(const_string "imov")))
(set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
(set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
(set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
(define_insn "*movdi_1_rex64_nointerunit"
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
(match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
"TARGET_64BIT
&& (!TARGET_INTER_UNIT_MOVES && !optimize_size)
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
{
switch (get_attr_type (insn))
{
case TYPE_SSEMOV:
if (get_attr_mode (insn) == MODE_TI)
return "movdqa\t{%1, %0|%0, %1}";
/* FALLTHRU */
case TYPE_MMXMOV:
@ -1961,9 +2052,9 @@
}
}
[(set (attr "type")
(cond [(eq_attr "alternative" "5,6")
(cond [(eq_attr "alternative" "5,6,7")
(const_string "mmxmov")
(eq_attr "alternative" "7,8")
(eq_attr "alternative" "8,9,10")
(const_string "ssemov")
(eq_attr "alternative" "4")
(const_string "multi")
@ -1972,9 +2063,9 @@
(const_string "lea")
]
(const_string "imov")))
(set_attr "modrm" "*,0,0,*,*,*,*,*,*,*")
(set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*")
(set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI")])
(set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
(set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
(set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
;; Stores and loads of ax to arbitrary constant address.
;; We fake an second form of instruction to force reload to load address
@ -2129,7 +2220,109 @@
(define_insn "*movsf_1"
[(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!rm,!*y")
(match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
"(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
"(TARGET_INTER_UNIT_MOVES || optimize_size)
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
&& (reload_in_progress || reload_completed
|| (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
|| GET_CODE (operands[1]) != CONST_DOUBLE
|| memory_operand (operands[0], SFmode))"
{
switch (which_alternative)
{
case 0:
if (REG_P (operands[1])
&& find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
return "fstp\t%y0";
else if (STACK_TOP_P (operands[0]))
return "fld%z1\t%y1";
else
return "fst\t%y0";
case 1:
if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
return "fstp%z0\t%y0";
else
return "fst%z0\t%y0";
case 2:
switch (standard_80387_constant_p (operands[1]))
{
case 1:
return "fldz";
case 2:
return "fld1";
}
abort();
case 3:
case 4:
return "mov{l}\t{%1, %0|%0, %1}";
case 5:
if (get_attr_mode (insn) == MODE_TI)
return "pxor\t%0, %0";
else
return "xorps\t%0, %0";
case 6:
if (get_attr_mode (insn) == MODE_V4SF)
return "movaps\t{%1, %0|%0, %1}";
else
return "movss\t{%1, %0|%0, %1}";
case 7:
case 8:
return "movss\t{%1, %0|%0, %1}";
case 9:
case 10:
return "movd\t{%1, %0|%0, %1}";
case 11:
return "movq\t{%1, %0|%0, %1}";
default:
abort();
}
}
[(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
(set (attr "mode")
(cond [(eq_attr "alternative" "3,4,9,10")
(const_string "SI")
(eq_attr "alternative" "5")
(if_then_else
(and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
(const_int 0))
(ne (symbol_ref "TARGET_SSE2")
(const_int 0)))
(eq (symbol_ref "optimize_size")
(const_int 0)))
(const_string "TI")
(const_string "V4SF"))
/* For architectures resolving dependencies on
whole SSE registers use APS move to break dependency
chains, otherwise use short move to avoid extra work.
Do the same for architectures resolving dependencies on
the parts. While in DF mode it is better to always handle
just register parts, the SF mode is different due to lack
of instructions to load just part of the register. It is
better to maintain the whole registers in single format
to avoid problems on using packed logical operations. */
(eq_attr "alternative" "6")
(if_then_else
(ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
(const_int 0))
(ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
(const_int 0)))
(const_string "V4SF")
(const_string "SF"))
(eq_attr "alternative" "11")
(const_string "DI")]
(const_string "SF")))])
(define_insn "*movsf_1_nointerunit"
[(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!m,!*y")
(match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
"(!TARGET_INTER_UNIT_MOVES && !optimize_size)
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
&& (reload_in_progress || reload_completed
|| (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
|| GET_CODE (operands[1]) != CONST_DOUBLE

View File

@ -1246,6 +1246,7 @@ unlink_other_notes (insn, tail)
/* See sched_analyze to see how these are handled. */
if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_BEG
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_END
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_EH_REGION_BEG
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_EH_REGION_END)
{

View File

@ -56,7 +56,9 @@ static const char *ebb_print_insn PARAMS ((rtx, int));
static int rank PARAMS ((rtx, rtx));
static int contributes_to_priority PARAMS ((rtx, rtx));
static void compute_jump_reg_dependencies PARAMS ((rtx, regset));
static void schedule_ebb PARAMS ((rtx, rtx));
static basic_block schedule_ebb PARAMS ((rtx, rtx));
static basic_block fix_basic_block_boundaries PARAMS ((basic_block, basic_block, rtx, rtx));
static void add_missing_bbs PARAMS ((rtx, basic_block, basic_block));
/* Return nonzero if there are more insns that should be scheduled. */
@ -139,8 +141,17 @@ ebb_print_insn (insn, aligned)
static int
rank (insn1, insn2)
rtx insn1 ATTRIBUTE_UNUSED, insn2 ATTRIBUTE_UNUSED;
rtx insn1, insn2;
{
basic_block bb1 = BLOCK_FOR_INSN (insn1);
basic_block bb2 = BLOCK_FOR_INSN (insn2);
if (bb1->count > bb2->count
|| bb1->frequency > bb2->frequency)
return -1;
if (bb1->count < bb2->count
|| bb1->frequency < bb2->frequency)
return 1;
return 0;
}
@ -192,18 +203,157 @@ static struct sched_info ebb_sched_info =
0, 1
};
/* It is possible that ebb scheduling elliminated some blocks.
Place blocks from FIRST to LAST before BEFORE. */
static void
add_missing_bbs (before, first, last)
rtx before;
basic_block first, last;
{
for (; last != first->prev_bb; last = last->prev_bb)
{
before = emit_note_before (NOTE_INSN_BASIC_BLOCK, before);
NOTE_BASIC_BLOCK (before) = last;
last->head = before;
last->end = before;
update_bb_for_insn (last);
}
}
/* Fixup the CFG after EBB scheduling. Re-recognize the basic
block boundaries in between HEAD and TAIL and update basic block
structures between BB and LAST. */
static basic_block
fix_basic_block_boundaries (bb, last, head, tail)
basic_block bb, last;
rtx head, tail;
{
rtx insn = head;
rtx last_inside = bb->head;
rtx aftertail = NEXT_INSN (tail);
head = bb->head;
for (; insn != aftertail; insn = NEXT_INSN (insn))
{
if (GET_CODE (insn) == CODE_LABEL)
abort ();
/* Create new basic blocks just before first insn. */
if (inside_basic_block_p (insn))
{
if (!last_inside)
{
rtx note;
/* Re-emit the basic block note for newly found BB header. */
if (GET_CODE (insn) == CODE_LABEL)
{
note = emit_note_after (NOTE_INSN_BASIC_BLOCK, insn);
head = insn;
last_inside = note;
}
else
{
note = emit_note_before (NOTE_INSN_BASIC_BLOCK, insn);
head = note;
last_inside = insn;
}
}
else
last_inside = insn;
}
/* Control flow instruction terminate basic block. It is possible
that we've elliminated some basic blocks (made them empty).
Find the proper basic block using BLOCK_FOR_INSN and arrange things in
a sensible way by inserting empty basic blocks as needed. */
if (control_flow_insn_p (insn) || (insn == tail && last_inside))
{
basic_block curr_bb = BLOCK_FOR_INSN (insn);
rtx note;
if (!control_flow_insn_p (insn))
curr_bb = last;
if (bb == last->next_bb)
{
edge f;
rtx h;
/* An obscure special case, where we do have partially dead
instruction scheduled after last control flow instruction.
In this case we can create new basic block. It is
always exactly one basic block last in the sequence. Handle
it by splitting the edge and repositioning the block.
This is somewhat hackish, but at least avoid cut&paste
Safter sollution 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;
if (f)
{
last = curr_bb = split_edge (f);
h = curr_bb->head;
curr_bb->head = head;
curr_bb->end = insn;
/* Edge splitting created missplaced BASIC_BLOCK note, kill
it. */
delete_insn (h);
}
/* It may happen that code got moved past unconditional jump in
case the code is completely dead. Kill it. */
else
{
rtx next = next_nonnote_insn (insn);
delete_insn_chain (head, insn);
/* We keep some notes in the way that may split barrier from the
jump. */
if (GET_CODE (next) == BARRIER)
{
emit_barrier_after (prev_nonnote_insn (head));
delete_insn (next);
}
insn = NULL;
}
}
else
{
curr_bb->head = head;
curr_bb->end = insn;
add_missing_bbs (curr_bb->head, bb, curr_bb->prev_bb);
}
note = GET_CODE (head) == CODE_LABEL ? NEXT_INSN (head) : head;
NOTE_BASIC_BLOCK (note) = curr_bb;
update_bb_for_insn (curr_bb);
bb = curr_bb->next_bb;
last_inside = NULL;
if (!insn)
break;
}
}
add_missing_bbs (last->next_bb->head, bb, last);
return bb->prev_bb;
}
/* Schedule a single extended basic block, defined by the boundaries HEAD
and TAIL. */
static void
static basic_block
schedule_ebb (head, tail)
rtx head, tail;
{
int n_insns;
basic_block b;
struct deps tmp_deps;
basic_block first_bb = BLOCK_FOR_INSN (head);
basic_block last_bb = BLOCK_FOR_INSN (tail);
if (no_real_insns_p (head, tail))
return;
return BLOCK_FOR_INSN (tail);
init_deps_global ();
@ -266,8 +416,10 @@ schedule_ebb (head, tail)
if (write_symbols != NO_DEBUG)
restore_line_notes (head, tail);
b = fix_basic_block_boundaries (first_bb, last_bb, head, tail);
finish_deps_global ();
return b;
}
/* The one entry point in this file. DUMP_FILE is the dump file for
@ -309,17 +461,8 @@ schedule_ebbs (dump_file)
break;
if (! e)
break;
if (GET_CODE (tail) == JUMP_INSN)
{
rtx x = find_reg_note (tail, REG_BR_PROB, 0);
if (x)
{
int pred_val = INTVAL (XEXP (x, 0));
if (pred_val > REG_BR_PROB_BASE / 2)
break;
}
}
if (e->probability < REG_BR_PROB_BASE / 2)
break;
bb = bb->next_bb;
}
@ -337,11 +480,11 @@ schedule_ebbs (dump_file)
break;
}
schedule_ebb (head, tail);
bb = schedule_ebb (head, tail);
}
/* It doesn't make much sense to try and update life information here - we
probably messed up even the flow graph. */
/* Updating life info can be done by local propagation over the modified
superblocks. */
/* Reposition the prologue and epilogue notes in case we moved the
prologue/epilogue insns. */
@ -352,4 +495,8 @@ schedule_ebbs (dump_file)
rm_redundant_line_notes ();
sched_finish ();
#ifdef ENABLE_CHECKING
verify_flow_info ();
#endif
}