This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
cvs merge part 7 - cfglayout cleanup
- From: Jan Hubicka <jh at suse dot cz>
- To: gcc-patches at gcc dot gnu dot org, gcc-pdo at atrey dot karlin dot mff dot cuni dot cz
- Date: Thu, 28 Feb 2002 17:59:47 +0100
- Subject: cvs merge part 7 - cfglayout cleanup
Hi,
this patch makes cfglayout to unlink the interblock notes and jumptables
to make insn chain look like what algorithms reordering cfg expect.
It also makes possible to emit instruction into the stream w/o having
to update eff_head/eff_end pointers so we can use almost the standard way.
Tue Feb 19 12:48:17 CET 2002 Jan Hubicka <jh@suse.cz>
* cfglayout.c (function_tail_eff_head): Rename to ...
(function_footer): ... this one.
(unlink_insn_chain): New functions.
(label_for_bb): Only call block_label and emit debug message.
(record_effective_endpoints): Actually unlink the headers and footers.
(fixup_reorder_cahin): Re-insert the unlinked sequences.
(cfg_layout_duplicate_bb): Use duplicate_insn_chain.
* cfglayout.h (struct reorder_block_def): New fields footer/header;
remove eff_head/eff_end.
* rtl.h (set_first_insn): Declare.
* emit-rtl.c (set_first_insn): New function.
Index: cfglayout.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cfglayout.c,v
retrieving revision 1.9
diff -c -3 -p -r1.9 cfglayout.c
*** cfglayout.c 2002/01/10 20:37:42 1.9
--- cfglayout.c 2002/02/28 13:59:33
*************** Software Foundation, 59 Temple Place - S
*** 35,41 ****
extern struct obstack flow_obstack;
/* Holds the interesting trailing notes for the function. */
! static rtx function_tail_eff_head;
static rtx skip_insns_after_block PARAMS ((basic_block));
static void record_effective_endpoints PARAMS ((void));
--- 35,41 ----
extern struct obstack flow_obstack;
/* Holds the interesting trailing notes for the function. */
! static rtx function_footer;
static rtx skip_insns_after_block PARAMS ((basic_block));
static void record_effective_endpoints PARAMS ((void));
*************** static void change_scope PARAMS ((rtx,
*** 47,56 ****
--- 47,79 ----
void verify_insn_chain PARAMS ((void));
static void fixup_fallthru_exit_predecessor PARAMS ((void));
+ static rtx unlink_insn_chain PARAMS ((rtx, rtx));
+ static rtx duplicate_insn_chain PARAMS ((rtx, rtx));
/* Map insn uid to lexical block. */
static varray_type insn_scopes;
+ static rtx
+ unlink_insn_chain (first, last)
+ rtx first;
+ rtx last;
+ {
+ rtx prevfirst = PREV_INSN (first);
+ rtx nextlast = NEXT_INSN (last);
+
+ PREV_INSN (first) = NULL;
+ NEXT_INSN (last) = NULL;
+ if (prevfirst)
+ NEXT_INSN (prevfirst) = nextlast;
+ if (nextlast)
+ PREV_INSN (nextlast) = prevfirst;
+ else
+ set_last_insn (prevfirst);
+ if (!prevfirst)
+ set_first_insn (nextlast);
+ return first;
+ }
+
/* Skip over inter-block insns occurring after BB which are typically
associated with BB (e.g., barriers). If there are any such insns,
we return the last one. Otherwise, we return the end of BB. */
*************** label_for_bb (bb)
*** 155,162 ****
fprintf (rtl_dump_file, "Emitting label for block %d\n", bb->index);
label = block_label (bb);
- if (bb->head == PREV_INSN (RBI (bb)->eff_head))
- RBI (bb)->eff_head = label;
}
return label;
--- 178,183 ----
*************** record_effective_endpoints ()
*** 176,188 ****
basic_block bb = BASIC_BLOCK (i);
rtx end;
! RBI (bb)->eff_head = next_insn;
end = skip_insns_after_block (bb);
! RBI (bb)->eff_end = end;
! next_insn = NEXT_INSN (end);
}
! function_tail_eff_head = next_insn;
}
/* Build a varray mapping INSN_UID to lexical block. Return it. */
--- 197,214 ----
basic_block bb = BASIC_BLOCK (i);
rtx end;
! if (PREV_INSN (bb->head) && next_insn != bb->head)
! RBI (bb)->header = unlink_insn_chain (next_insn,
! PREV_INSN (bb->head));
end = skip_insns_after_block (bb);
! if (NEXT_INSN (bb->end) && bb->end != end)
! RBI (bb)->footer = unlink_insn_chain (NEXT_INSN (bb->end), end);
! next_insn = NEXT_INSN (bb->end);
}
! function_footer = next_insn;
! if (function_footer)
! function_footer = unlink_insn_chain (function_footer, get_last_insn ());
}
/* Build a varray mapping INSN_UID to lexical block. Return it. */
*************** set_block_levels (block, level)
*** 237,243 ****
block = BLOCK_CHAIN (block);
}
}
!
/* Emit lexical block notes needed to change scope from S1 to S2. */
static void
--- 263,269 ----
block = BLOCK_CHAIN (block);
}
}
!
/* Emit lexical block notes needed to change scope from S1 to S2. */
static void
*************** scope_to_insns_finalize ()
*** 330,361 ****
static void
fixup_reorder_chain ()
{
! basic_block bb, last_bb;
int index;
! rtx insn;
! int old_n_basic_blocks = n_basic_blocks;
/* First do the bulk reordering -- rechain the blocks without regard to
the needed changes to jumps and labels. */
! for (last_bb = BASIC_BLOCK (0), bb = RBI (last_bb)->next, index = 1;
bb != 0;
! last_bb = bb, bb = RBI (bb)->next, index++)
{
! rtx last_e = RBI (last_bb)->eff_end;
! rtx curr_h = RBI (bb)->eff_head;
!
! NEXT_INSN (last_e) = curr_h;
! PREV_INSN (curr_h) = last_e;
}
if (index != n_basic_blocks)
abort ();
! insn = RBI (last_bb)->eff_end;
! NEXT_INSN (insn) = function_tail_eff_head;
! if (function_tail_eff_head)
! PREV_INSN (function_tail_eff_head) = insn;
while (NEXT_INSN (insn))
insn = NEXT_INSN (insn);
--- 356,404 ----
static void
fixup_reorder_chain ()
{
! basic_block bb;
int index;
! rtx insn = NULL;
/* First do the bulk reordering -- rechain the blocks without regard to
the needed changes to jumps and labels. */
! for (bb = BASIC_BLOCK (0), index = 0;
bb != 0;
! bb = RBI (bb)->next, index++)
{
! if (RBI (bb)->header)
! {
! if (insn)
! NEXT_INSN (insn) = RBI (bb)->header;
! else
! set_first_insn (RBI (bb)->header);
! PREV_INSN (RBI (bb)->header) = insn;
! insn = RBI (bb)->header;
! while (NEXT_INSN (insn))
! insn = NEXT_INSN (insn);
! }
! if (insn)
! NEXT_INSN (insn) = bb->head;
! else
! set_first_insn (bb->head);
! PREV_INSN (bb->head) = insn;
! insn = bb->end;
! if (RBI (bb)->footer)
! {
! NEXT_INSN (insn) = RBI (bb)->footer;
! PREV_INSN (RBI (bb)->footer) = insn;
! while (NEXT_INSN (insn))
! insn = NEXT_INSN (insn);
! }
}
if (index != n_basic_blocks)
abort ();
! NEXT_INSN (insn) = function_footer;
! if (function_footer)
! PREV_INSN (function_footer) = insn;
while (NEXT_INSN (insn))
insn = NEXT_INSN (insn);
*************** fixup_reorder_chain ()
*** 470,477 ****
if (nb)
{
alloc_aux_for_block (nb, sizeof (struct reorder_block_def));
- RBI (nb)->eff_head = nb->head;
- RBI (nb)->eff_end = NEXT_INSN (nb->end);
RBI (nb)->visited = 1;
RBI (nb)->next = RBI (bb)->next;
RBI (bb)->next = nb;
--- 513,518 ----
*************** fixup_reorder_chain ()
*** 481,500 ****
}
/* Put basic_block_info in the new order. */
- bb = BASIC_BLOCK (0);
- index = 0;
if (rtl_dump_file)
- fprintf (rtl_dump_file, "Reordered sequence:\n");
-
- for (; bb; bb = RBI (bb)->next, index++)
{
! if (rtl_dump_file)
! fprintf (rtl_dump_file, " %i %sbb %i freq %i\n", index,
! bb->index >= old_n_basic_blocks ? "compensation " : "",
! bb->index,
! bb->frequency);
bb->index = index;
BASIC_BLOCK (index) = bb;
}
--- 522,544 ----
}
/* Put basic_block_info in the new order. */
if (rtl_dump_file)
{
! fprintf (rtl_dump_file, "Reordered sequence:\n");
! for (bb = BASIC_BLOCK (0), index = 0; bb; bb = RBI (bb)->next, index ++)
! {
! fprintf (rtl_dump_file, " %i ", index);
! if (forwarder_block_p (bb) && GET_CODE (bb->head) != CODE_LABEL)
! fprintf (rtl_dump_file, "compensation ");
! else
! fprintf (rtl_dump_file, "bb %i ", bb->index);
! fprintf (rtl_dump_file, " [%i]\n", bb->frequency);
! }
! }
+ for (bb = BASIC_BLOCK (0), index = 0; bb; bb = RBI (bb)->next, index ++)
+ {
bb->index = index;
BASIC_BLOCK (index) = bb;
}
*************** verify_insn_chain ()
*** 530,539 ****
if (insn_cnt1 != insn_cnt2)
abort ();
}
!
! /* The block falling through to exit must be the last one in the reordered
! chain. Ensure it is. */
!
static void
fixup_fallthru_exit_predecessor ()
{
--- 574,582 ----
if (insn_cnt1 != insn_cnt2)
abort ();
}
!
! /* The block falling through to exit must be the last one in the
! reordered chain. Ensure that this condition is met. */
static void
fixup_fallthru_exit_predecessor ()
{
*************** fixup_fallthru_exit_predecessor ()
*** 560,571 ****
}
}
! /* Main entry point to this module: initialize the datastructures for CFG
! layout changes. */
void
cfg_layout_initialize ()
{
alloc_aux_for_blocks (sizeof (struct reorder_block_def));
scope_to_insns_initialize ();
--- 603,616 ----
}
}
! /* Main entry point to this module - initialize the datastructures for
! CFG layout changes. It keeps LOOPS up-to-date if not null. */
void
cfg_layout_initialize ()
{
+ /* Our algorithm depends on fact that there are now dead jumptables
+ around the code. */
alloc_aux_for_blocks (sizeof (struct reorder_block_def));
scope_to_insns_initialize ();
Index: cfglayout.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cfglayout.h,v
retrieving revision 1.2
diff -c -3 -p -r1.2 cfglayout.h
*** cfglayout.h 2001/12/31 04:19:34 1.2
--- cfglayout.h 2002/02/28 13:59:33
***************
*** 21,28 ****
/* Structure to hold information about the blocks during reordering. */
typedef struct reorder_block_def
{
! rtx eff_head;
! rtx eff_end;
basic_block next;
int visited;
} *reorder_block_def;
--- 21,28 ----
/* Structure to hold information about the blocks during reordering. */
typedef struct reorder_block_def
{
! rtx header;
! rtx footer;
basic_block next;
int visited;
} *reorder_block_def;
*************** typedef struct reorder_block_def
*** 31,36 ****
extern void cfg_layout_initialize PARAMS ((void));
extern void cfg_layout_finalize PARAMS ((void));
-
extern void scope_to_insns_initialize PARAMS ((void));
extern void scope_to_insns_finalize PARAMS ((void));
--- 31,35 ----
Index: emit-rtl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/emit-rtl.c,v
retrieving revision 1.251
diff -c -3 -p -r1.251 emit-rtl.c
*** emit-rtl.c 2002/02/28 10:10:57 1.251
--- emit-rtl.c 2002/02/28 13:59:34
*************** get_insns ()
*** 2612,2617 ****
--- 2612,2628 ----
return first_insn;
}
+ /* Specify a new insn as the first in the chain. */
+
+ void
+ set_first_insn (insn)
+ rtx insn;
+ {
+ if (PREV_INSN (insn) != 0)
+ abort ();
+ first_insn = insn;
+ }
+
/* Return the last insn emitted in current sequence or current function. */
rtx
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtl.h,v
retrieving revision 1.331
diff -c -3 -p -r1.331 rtl.h
*** rtl.h 2002/02/20 23:19:19 1.331
--- rtl.h 2002/02/28 13:59:36
*************** extern void set_new_first_and_last_insn
*** 1844,1849 ****
--- 1844,1850 ----
extern void set_new_first_and_last_label_num PARAMS ((int, int));
extern void set_new_last_label_num PARAMS ((int));
extern void unshare_all_rtl_again PARAMS ((rtx));
+ extern void set_first_insn PARAMS ((rtx));
extern void set_last_insn PARAMS ((rtx));
extern void link_cc0_insns PARAMS ((rtx));
extern void add_insn PARAMS ((rtx));