This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: (applied) defect removal and cleanup in bb-reorder
- To: gcc-patches at gcc dot gnu dot org
- Subject: PATCH: (applied) defect removal and cleanup in bb-reorder
- From: Jason Eckhardt <jle at cygnus dot com>
- Date: Fri, 24 Mar 2000 18:46:38 -0800 (PST)
this patch removes a couple of defects (that appeared on hppa port) and perhaps
helps readability in a few places as well.
also contains some --enable-checking fixes that graham found in which notes
were referred to before checking that they were indeed notes.
Fri Mar 24 20:13:49 2000 Jason Eckhardt <jle@cygnus.com>
* bb-reorder.c (REORDER_MOVED_BLOCK_END): Removed.
(reorder_block_def): New members eff_head and eff_end.
(REORDER_BLOCK_EFF_HEAD, REORDER_BLOCK_EFF_END): New macros.
(verify_insn_chain): New function.
(skip_insns_between_block): Add code to skip deleted insns.
Check for note before using.
(chain_reorder_blocks): Replace calls to skip_insns_between_block
with references to REORDER_BLOCK_EFF_HEAD and REORDER_BLOCK_EFF_END.
Check for note before using.
(make_reorder_chain): Use INTVAL rather than XINT to get REG_BR_PROB.
(fixup_reorder_chain): Restructure, clean up, defect removal.
(reorder_basic_blocks): Remove last_insn and references to it.
Moved insn chain verification code into a new function (see above).
Delete defective code that sets last insn.
Initialize REORDER_BLOCK_EFF_HEAD and REORDER_BLOCK_EFF_END for
all blocks.
Index: bb-reorder.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/bb-reorder.c,v
retrieving revision 1.2
diff -c -3 -p -r1.2 bb-reorder.c
*** bb-reorder.c 2000/03/18 20:40:38 1.2
--- bb-reorder.c 2000/03/25 02:11:43
*************** typedef struct reorder_block_def {
*** 60,70 ****
rtx end;
int block_begin;
int block_end;
} *reorder_block_def;
#define REORDER_BLOCK_HEAD 0x1
#define REORDER_BLOCK_VISITED 0x2
- #define REORDER_MOVED_BLOCK_END 0x3
#define REORDER_BLOCK_FLAGS(bb) \
((reorder_block_def) (bb)->aux)->flags
--- 60,85 ----
rtx end;
int block_begin;
int block_end;
+ rtx eff_head;
+ rtx eff_end;
} *reorder_block_def;
+ static struct reorder_block_def rbd_init
+ = {
+ 0, /* flags */
+ 0, /* index */
+ NULL, /* add_jump */
+ NULL, /* succ */
+ NULL_RTX, /* end */
+ 0, /* block_begin */
+ 0, /* block_end */
+ NULL_RTX, /* eff_head */
+ NULL_RTX /* eff_end */
+ };
+
+
#define REORDER_BLOCK_HEAD 0x1
#define REORDER_BLOCK_VISITED 0x2
#define REORDER_BLOCK_FLAGS(bb) \
((reorder_block_def) (bb)->aux)->flags
*************** typedef struct reorder_block_def {
*** 87,93 ****
--- 102,114 ----
#define REORDER_BLOCK_END(bb) \
((reorder_block_def) (bb)->aux)->block_end
+ #define REORDER_BLOCK_EFF_HEAD(bb) \
+ ((reorder_block_def) (bb)->aux)->eff_head
+
+ #define REORDER_BLOCK_EFF_END(bb) \
+ ((reorder_block_def) (bb)->aux)->eff_end
+
static int reorder_index;
static basic_block reorder_last_visited;
*************** static basic_block get_common_dest PARAM
*** 102,107 ****
--- 123,129 ----
static basic_block chain_reorder_blocks PARAMS ((edge, basic_block));
static void make_reorder_chain PARAMS ((basic_block));
static void fixup_reorder_chain PARAMS ((void));
+ static void verify_insn_chain PARAMS ((void));
/* Skip over insns BEFORE or AFTER BB which are typically associated with
*************** skip_insns_between_block (bb, skip_type)
*** 136,142 ****
break;
}
}
-
else
{
last_insn = bb->end;
--- 158,163 ----
*************** skip_insns_between_block (bb, skip_type)
*** 153,159 ****
break;
if (GET_CODE (insn) == BARRIER
! || GET_CODE (insn) == JUMP_INSN
|| (GET_CODE (insn) == NOTE
&& (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END
|| NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)))
--- 174,180 ----
break;
if (GET_CODE (insn) == BARRIER
! || GET_CODE (insn) == JUMP_INSN
|| (GET_CODE (insn) == NOTE
&& (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END
|| NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)))
*************** skip_insns_between_block (bb, skip_type)
*** 168,173 ****
--- 189,201 ----
insn = NEXT_INSN (insn);
continue;
}
+
+ /* Skip to next non-deleted insn. */
+ if (GET_CODE (insn) == NOTE
+ && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED
+ || NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL))
+ continue;
+
break;
}
*************** skip_insns_between_block (bb, skip_type)
*** 181,198 ****
&& insn == BASIC_BLOCK (bb->index + 1)->head)
break;
! if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
{
found_block_end = 1;
continue;
}
! if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED)
continue;
if (GET_CODE (insn) == NOTE
&& NOTE_LINE_NUMBER (insn) >= 0
&& NEXT_INSN (insn)
&& (NOTE_LINE_NUMBER (NEXT_INSN (insn))
== NOTE_INSN_BLOCK_END))
continue;
--- 209,229 ----
&& insn == BASIC_BLOCK (bb->index + 1)->head)
break;
! if (GET_CODE (insn) == NOTE
! && NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
{
found_block_end = 1;
continue;
}
! if (GET_CODE (insn) == NOTE
! && NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED)
continue;
if (GET_CODE (insn) == NOTE
&& NOTE_LINE_NUMBER (insn) >= 0
&& NEXT_INSN (insn)
+ && GET_CODE (NEXT_INSN (insn)) == NOTE
&& (NOTE_LINE_NUMBER (NEXT_INSN (insn))
== NOTE_INSN_BLOCK_END))
continue;
*************** chain_reorder_blocks (e, ceb)
*** 255,262 ****
"Edge from basic block %d to basic block %d last visited %d\n",
sb->index, db->index, ceb->index);
! dbh_insn = skip_insns_between_block (db, REORDER_SKIP_BEFORE);
! cebe_insn = skip_insns_between_block (ceb, REORDER_SKIP_AFTER);
cebbe_insn = skip_insns_between_block (ceb, REORDER_SKIP_BLOCK_END);
{
--- 286,293 ----
"Edge from basic block %d to basic block %d last visited %d\n",
sb->index, db->index, ceb->index);
! dbh_insn = REORDER_BLOCK_EFF_HEAD (db);
! cebe_insn = REORDER_BLOCK_EFF_END (ceb);
cebbe_insn = skip_insns_between_block (ceb, REORDER_SKIP_BLOCK_END);
{
*************** chain_reorder_blocks (e, ceb)
*** 265,271 ****
for (insn = dbh_insn; insn && insn != db->end; insn = NEXT_INSN (insn))
{
! if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG)
{
block_begins += 1;
break;
--- 296,303 ----
for (insn = dbh_insn; insn && insn != db->end; insn = NEXT_INSN (insn))
{
! if (GET_CODE (insn) == NOTE
! && NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG)
{
block_begins += 1;
break;
*************** chain_reorder_blocks (e, ceb)
*** 283,289 ****
{
if (PREV_INSN (insn) == cebbe_insn)
break;
! if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
{
block_ends += 1;
continue;
--- 315,322 ----
{
if (PREV_INSN (insn) == cebbe_insn)
break;
! if (GET_CODE (insn) == NOTE
! && NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
{
block_ends += 1;
continue;
*************** chain_reorder_blocks (e, ceb)
*** 438,446 ****
REORDER_BLOCK_ADD_JUMP (db) = last_edge->dest;
}
! dbh_insn = skip_insns_between_block (db, REORDER_SKIP_BEFORE);
! cebe_insn = skip_insns_between_block (ceb, REORDER_SKIP_AFTER);
! dbe_insn = skip_insns_between_block (db, REORDER_SKIP_AFTER);
/* Leave behind any lexical block markers. */
if (debug_info_level > DINFO_LEVEL_TERSE
--- 471,479 ----
REORDER_BLOCK_ADD_JUMP (db) = last_edge->dest;
}
! dbh_insn = REORDER_BLOCK_EFF_HEAD (db);
! cebe_insn = REORDER_BLOCK_EFF_END (ceb);
! dbe_insn = REORDER_BLOCK_EFF_END (db);
/* Leave behind any lexical block markers. */
if (debug_info_level > DINFO_LEVEL_TERSE
*************** chain_reorder_blocks (e, ceb)
*** 484,490 ****
}
! /* Reorder blocks starting at block B. */
static void
make_reorder_chain (bb)
--- 517,523 ----
}
! /* Reorder blocks starting at block BB. */
static void
make_reorder_chain (bb)
*************** make_reorder_chain (bb)
*** 506,512 ****
rtx note = find_reg_note (block_end, REG_BR_PROB, 0);
if (note)
! probability = XINT (XEXP (note, 0), 0);
else
probability = 0;
--- 539,545 ----
rtx note = find_reg_note (block_end, REG_BR_PROB, 0);
if (note)
! probability = INTVAL (XEXP (note, 0));
else
probability = 0;
*************** fixup_reorder_chain ()
*** 577,626 ****
{
int i, j;
rtx insn;
/* Set the new last insn. */
! for (i = 0;
! i < n_basic_blocks - 1
! && REORDER_BLOCK_INDEX (BASIC_BLOCK (i)) != n_basic_blocks;
! i++)
! continue;
!
! for (insn = BASIC_BLOCK (i)->head;
! NEXT_INSN (insn) != 0;
! insn = NEXT_INSN (insn))
! continue;
!
! set_last_insn (insn);
/* Add jumps and labels to fixup blocks. */
! for (i = 0; i < n_basic_blocks - 1; i++)
{
basic_block bbi = BASIC_BLOCK (i);
if (REORDER_BLOCK_ADD_JUMP (bbi))
{
rtx label_insn, jump_insn, barrier_insn;
! if (GET_CODE (REORDER_BLOCK_ADD_JUMP (bbi)->head)
! == CODE_LABEL)
label_insn = REORDER_BLOCK_ADD_JUMP (bbi)->head;
else
{
rtx new_label = gen_label_rtx ();
label_insn = emit_label_before (new_label,
REORDER_BLOCK_ADD_JUMP (bbi)->head);
}
- REORDER_BLOCK_ADD_JUMP (bbi)->head = label_insn;
- jump_insn = emit_jump_insn_after (gen_jump (label_insn),
- bbi->end);
JUMP_LABEL (jump_insn) = label_insn;
++LABEL_NUSES (label_insn);
barrier_insn = emit_barrier_after (jump_insn);
! if (GET_CODE (bbi->end) != JUMP_INSN)
! bbi->end = jump_insn;
/* Add block for jump. Typically this is when a then is not
predicted and we are jumping to the moved then block. */
! else
{
basic_block nb;
--- 610,675 ----
{
int i, j;
rtx insn;
+ int orig_num_blocks = n_basic_blocks;
/* Set the new last insn. */
! {
! int max_val = 0;
! int max_index = 0;
! for (j = 0; j < n_basic_blocks; j++)
! {
! int val = REORDER_BLOCK_INDEX (BASIC_BLOCK (j));
! if (val > max_val)
! {
! max_val = val;
! max_index = j;
! }
! }
! insn = REORDER_BLOCK_EFF_END (BASIC_BLOCK (max_index));
! NEXT_INSN (insn) = NULL_RTX;
! set_last_insn (insn);
! }
/* Add jumps and labels to fixup blocks. */
! for (i = 0; i < orig_num_blocks; i++)
{
+ int need_block = 0;
basic_block bbi = BASIC_BLOCK (i);
if (REORDER_BLOCK_ADD_JUMP (bbi))
{
rtx label_insn, jump_insn, barrier_insn;
! if (GET_CODE (REORDER_BLOCK_ADD_JUMP (bbi)->head) == CODE_LABEL)
label_insn = REORDER_BLOCK_ADD_JUMP (bbi)->head;
else
{
rtx new_label = gen_label_rtx ();
label_insn = emit_label_before (new_label,
REORDER_BLOCK_ADD_JUMP (bbi)->head);
+ REORDER_BLOCK_ADD_JUMP (bbi)->head = label_insn;
+ }
+
+ if (GET_CODE (bbi->end) != JUMP_INSN)
+ {
+ jump_insn = emit_jump_insn_after (gen_jump (label_insn),
+ bbi->end);
+ bbi->end = jump_insn;
+ need_block = 0;
+ }
+ else
+ {
+ jump_insn = emit_jump_insn_after (gen_jump (label_insn),
+ REORDER_BLOCK_EFF_END (bbi));
+ need_block = 1;
}
JUMP_LABEL (jump_insn) = label_insn;
++LABEL_NUSES (label_insn);
barrier_insn = emit_barrier_after (jump_insn);
!
/* Add block for jump. Typically this is when a then is not
predicted and we are jumping to the moved then block. */
! if (need_block)
{
basic_block nb;
*************** fixup_reorder_chain ()
*** 664,669 ****
--- 713,782 ----
}
+ /* Perform sanity checks on the insn chain.
+ 1. Check that next/prev pointers are consistent in both the forward and
+ reverse direction.
+ 2. Count insns in chain, going both directions, and check if equal.
+ 3. Check that get_last_insn () returns the actual end of chain. */
+
+ static void
+ verify_insn_chain ()
+ {
+ rtx x,
+ prevx,
+ nextx;
+ int insn_cnt1,
+ insn_cnt2;
+
+ prevx = NULL;
+ insn_cnt1 = 1;
+ for (x = get_insns (); x; x = NEXT_INSN (x))
+ {
+ if (PREV_INSN (x) != prevx)
+ {
+ fprintf (stderr, "Forward traversal: insn chain corrupt.\n");
+ fprintf (stderr, "previous insn:\n");
+ debug_rtx (prevx);
+ fprintf (stderr, "current insn:\n");
+ debug_rtx (x);
+ abort ();
+ }
+ ++insn_cnt1;
+ prevx = x;
+ }
+
+ if (prevx != get_last_insn ())
+ {
+ fprintf (stderr, "last_insn corrupt.\n");
+ abort ();
+ }
+
+ nextx = NULL;
+ insn_cnt2 = 1;
+ for (x = get_last_insn (); x; x = PREV_INSN (x))
+ {
+ if (NEXT_INSN (x) != nextx)
+ {
+ fprintf (stderr, "Reverse traversal: insn chain corrupt.\n");
+ fprintf (stderr, "current insn:\n");
+ debug_rtx (x);
+ fprintf (stderr, "next insn:\n");
+ debug_rtx (nextx);
+ abort ();
+ }
+ ++insn_cnt2;
+ nextx = x;
+ }
+
+ if (insn_cnt1 != insn_cnt2)
+ {
+ fprintf (stderr, "insn_cnt1 (%d) not equal to insn_cnt2 (%d).\n",
+ insn_cnt1, insn_cnt2);
+ abort ();
+ }
+ }
+
+
/* Reorder basic blocks. */
void
*************** reorder_basic_blocks ()
*** 672,678 ****
int i, j;
struct loops loops_info;
int num_loops;
- rtx last_insn;
if (profile_arc_flag)
return;
--- 785,790 ----
*************** reorder_basic_blocks ()
*** 708,742 ****
reorder_last_visited = BASIC_BLOCK (0);
for (i = 0; i < n_basic_blocks; i++)
! BASIC_BLOCK (i)->aux = xcalloc (1, sizeof (struct reorder_block_def));
- last_insn
- = NEXT_INSN (skip_insns_between_block (BASIC_BLOCK (n_basic_blocks - 1),
- REORDER_SKIP_AFTER));
-
make_reorder_chain (BASIC_BLOCK (0));
fixup_reorder_chain ();
#ifdef ENABLE_CHECKING
! {
! rtx insn, last_insn;
! last_insn = get_insns ();
! for (insn = NEXT_INSN (get_insns ());
! insn && PREV_INSN (insn) == last_insn
! && NEXT_INSN (PREV_INSN (insn)) == insn;
! last_insn = insn,
! insn = NEXT_INSN (insn))
! continue;
!
! if (insn)
! {
! if (rtl_dump_file)
! fprintf (rtl_dump_file, "insn chaining error at %d\n",
! INSN_UID (last_insn));
! abort();
! }
! }
#endif
/* Put basic_block_info in new order. */
--- 820,846 ----
reorder_last_visited = BASIC_BLOCK (0);
for (i = 0; i < n_basic_blocks; i++)
! {
! basic_block bbi = BASIC_BLOCK (i);
! bbi->aux = xcalloc (1, sizeof (struct reorder_block_def));
! *((struct reorder_block_def *)bbi->aux) = rbd_init;
! REORDER_BLOCK_EFF_END (bbi)
! = skip_insns_between_block (bbi, REORDER_SKIP_AFTER);
! if (i == 0)
! REORDER_BLOCK_EFF_HEAD (bbi) = get_insns ();
! else
! {
! rtx prev_eff_end = REORDER_BLOCK_EFF_END (BASIC_BLOCK (i - 1));
! REORDER_BLOCK_EFF_HEAD (bbi) = NEXT_INSN (prev_eff_end);
! }
! }
make_reorder_chain (BASIC_BLOCK (0));
fixup_reorder_chain ();
#ifdef ENABLE_CHECKING
! verify_insn_chain ();
#endif
/* Put basic_block_info in new order. */
*************** reorder_basic_blocks ()
*** 760,784 ****
BASIC_BLOCK (j) = tempbb;
}
}
-
- {
- rtx xafter = skip_insns_between_block (BASIC_BLOCK (n_basic_blocks - 1),
- REORDER_SKIP_AFTER);
- if (xafter)
- {
- NEXT_INSN (xafter) = last_insn;
- if (last_insn)
- {
- rtx x = last_insn;
- PREV_INSN (last_insn) = xafter;
- while (NEXT_INSN (x))
- x = NEXT_INSN (x);
- set_last_insn (x);
- }
- }
- else
- abort();
- }
#ifdef ENABLE_CHECKING
verify_flow_info ();
--- 864,869 ----
*************** reorder_basic_blocks ()
*** 789,793 ****
--- 874,879 ----
/* Free loop information. */
flow_loops_free (&loops_info);
+
}