This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PATCH: register coalescing in SSA
Richard Henderson <rth@cygnus.com> writes:
Richard> What can I say? Don't call find_basic_blocks if you want
Richard> the CFG structure to remain unchanged. Anyway, you
Richard> shouldn't have to if you're preserving the structure in the
Richard> optimization phases.
OK, I see you took the extraneous calls out already. Eliminating dead
code is OK now. I think we still need the compute_bb_for_insn though.
Richard> Probably the best thing to do is to adjust the definition
Richard> of PHI to incorporate the basic_block pointers instead of
Richard> their indices. That will keep you isolated from such
Richard> changes.
I'll look into this.
How's this patch then? It also changes some block indices into
basic_block pointers.
* ssa.c (convert_to_ssa): Eliminate dead code when calling
life_analysis.
(convert_from_ssa): Call compute_bb_for_insn before life_analysis.
(for_each_successor_phi): Change parameter to basic_block.
(coalesce_regs_in_successor_phi_nodes): Likewise.
(coalesce_regs_in_copies): Likewise.
(compute_coalesced_reg_partition): Use basic_block instead of index.
* rtl.h (convert_to_ssa): Delete.
(convert_from_ssa): Likewise.
(successor_phi_fn): Likewise.
(for_each_successor_phi): Likewise.
(in_ssa_form): Likewise.
* basic-block.h (convert_to_ssa): Moved from rtl.h.
(convert_from_ssa): Likewise.
(successor_phi_fn): Likewise.
(in_ssa_form): Likewise.
(for_each_successor_phi): Likewise. Change parameter to basic_block.
* flow.c (calculate_global_regs_live): Pass a basic_block to
for_each_successor_phi.
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtl.h,v
retrieving revision 1.187
diff -c -p -r1.187 rtl.h
*** rtl.h 2000/04/07 09:24:45 1.187
--- rtl.h 2000/04/09 00:38:19
*************** extern void replace_call_placeholder PAR
*** 1806,1820 ****
extern int stack_regs_mentioned PARAMS ((rtx insn));
#endif
- /* In ssa.c */
- extern void convert_to_ssa PARAMS ((void));
- extern void convert_from_ssa PARAMS ((void));
- typedef int (*successor_phi_fn) PARAMS ((rtx, int, int, void *));
- extern int for_each_successor_phi PARAMS ((int bb,
- successor_phi_fn,
- void *));
- extern int in_ssa_form;
-
/* In toplev.c */
extern rtx stack_limit_rtx;
--- 1806,1811 ----
Index: basic-block.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/basic-block.h,v
retrieving revision 1.60
diff -c -p -r1.60 basic-block.h
*** basic-block.h 2000/04/08 05:06:29 1.60
--- basic-block.h 2000/04/09 00:38:19
*************** extern conflict_graph conflict_graph_com
*** 491,494 ****
--- 491,503 ----
PARAMS ((regset,
partition));
+ /* In ssa.c */
+ extern void convert_to_ssa PARAMS ((void));
+ extern void convert_from_ssa PARAMS ((void));
+ typedef int (*successor_phi_fn) PARAMS ((rtx, int, int, void *));
+ extern int for_each_successor_phi PARAMS ((basic_block bb,
+ successor_phi_fn,
+ void *));
+ extern int in_ssa_form;
+
#endif /* _BASIC_BLOCK_H */
Index: ssa.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/ssa.c,v
retrieving revision 1.7
diff -c -p -r1.7 ssa.c
*** ssa.c 2000/04/07 09:23:29 1.7
--- ssa.c 2000/04/09 00:38:21
*************** static int rename_equivalent_regs_in_ins
*** 147,157 ****
static int coalesce_if_unconflicting
PARAMS ((partition p, conflict_graph conflicts, int reg1, int reg2));
static int coalesce_regs_in_copies
! PARAMS ((int bb, partition p, conflict_graph conflicts));
static int coalesce_reg_in_phi
PARAMS ((rtx, int dest_regno, int src_regno, void *data));
static int coalesce_regs_in_successor_phi_nodes
! PARAMS ((int bb, partition p, conflict_graph conflicts));
static partition compute_coalesced_reg_partition
PARAMS (());
static int mark_reg_in_phi
--- 147,157 ----
static int coalesce_if_unconflicting
PARAMS ((partition p, conflict_graph conflicts, int reg1, int reg2));
static int coalesce_regs_in_copies
! PARAMS ((basic_block bb, partition p, conflict_graph conflicts));
static int coalesce_reg_in_phi
PARAMS ((rtx, int dest_regno, int src_regno, void *data));
static int coalesce_regs_in_successor_phi_nodes
! PARAMS ((basic_block bb, partition p, conflict_graph conflicts));
static partition compute_coalesced_reg_partition
PARAMS (());
static int mark_reg_in_phi
*************** convert_to_ssa()
*** 855,864 ****
if (in_ssa_form)
abort ();
! /* Don't eliminate dead code here. The CFG we computed above must
! remain unchanged until we are finished emerging from SSA form --
! the phi node representation depends on it. */
! life_analysis (get_insns (), max_reg_num (), NULL, 0);
/* Compute dominators. */
dominators = sbitmap_vector_alloc (n_basic_blocks, n_basic_blocks);
--- 855,861 ----
if (in_ssa_form)
abort ();
! life_analysis (get_insns (), max_reg_num (), NULL, 1);
/* Compute dominators. */
dominators = sbitmap_vector_alloc (n_basic_blocks, n_basic_blocks);
*************** coalesce_if_unconflicting (p, conflicts,
*** 1454,1469 ****
static int
coalesce_regs_in_copies (bb, p, conflicts)
! int bb;
partition p;
conflict_graph conflicts;
{
int changed = 0;
rtx insn;
! rtx end = BLOCK_END (bb);
/* Scan the instruction stream of the block. */
! for (insn = BLOCK_HEAD (bb); insn != end; insn = NEXT_INSN (insn))
{
rtx pattern;
rtx src;
--- 1451,1466 ----
static int
coalesce_regs_in_copies (bb, p, conflicts)
! basic_block bb;
partition p;
conflict_graph conflicts;
{
int changed = 0;
rtx insn;
! rtx end = bb->end;
/* Scan the instruction stream of the block. */
! for (insn = bb->head; insn != end; insn = NEXT_INSN (insn))
{
rtx pattern;
rtx src;
*************** coalesce_reg_in_phi (insn, dest_regno, s
*** 1551,1557 ****
static int
coalesce_regs_in_successor_phi_nodes (bb, p, conflicts)
! int bb;
partition p;
conflict_graph conflicts;
{
--- 1548,1554 ----
static int
coalesce_regs_in_successor_phi_nodes (bb, p, conflicts)
! basic_block bb;
partition p;
conflict_graph conflicts;
{
*************** compute_coalesced_reg_partition ()
*** 1610,1617 ****
order will generate correct, if non-optimal, results. */
for (bb = n_basic_blocks; --bb >= 0; )
{
! changed += coalesce_regs_in_copies (bb, p, conflicts);
! changed += coalesce_regs_in_successor_phi_nodes (bb, p, conflicts);
}
conflict_graph_delete (conflicts);
--- 1607,1616 ----
order will generate correct, if non-optimal, results. */
for (bb = n_basic_blocks; --bb >= 0; )
{
! basic_block block = BASIC_BLOCK (bb);
! changed += coalesce_regs_in_copies (block, p, conflicts);
! changed +=
! coalesce_regs_in_successor_phi_nodes (block, p, conflicts);
}
conflict_graph_delete (conflicts);
*************** convert_from_ssa()
*** 1812,1817 ****
--- 1811,1817 ----
rtx insns = get_insns ();
/* We need up-to-date life information. */
+ compute_bb_for_insn (get_max_uid ());
life_analysis (insns, max_reg_num (), NULL, 0);
/* Figure out which regs in copies and phi nodes don't conflict and
*************** convert_from_ssa()
*** 1878,1905 ****
int
for_each_successor_phi (bb, fn, data)
! int bb;
successor_phi_fn fn;
void *data;
{
- basic_block block;
edge e;
! if (bb == EXIT_BLOCK)
return 0;
- else if (bb == ENTRY_BLOCK)
- block = ENTRY_BLOCK_PTR;
- else
- block = BASIC_BLOCK (bb);
/* Scan outgoing edges. */
! for (e = block->succ; e != NULL; e = e->succ_next)
{
rtx insn;
basic_block successor = e->dest;
! if (successor->index == ENTRY_BLOCK
! || successor->index == EXIT_BLOCK)
continue;
/* Advance to the first non-label insn of the successor block. */
--- 1878,1900 ----
int
for_each_successor_phi (bb, fn, data)
! basic_block bb;
successor_phi_fn fn;
void *data;
{
edge e;
! if (bb == EXIT_BLOCK_PTR)
return 0;
/* Scan outgoing edges. */
! for (e = bb->succ; e != NULL; e = e->succ_next)
{
rtx insn;
basic_block successor = e->dest;
! if (successor == ENTRY_BLOCK_PTR
! || successor == EXIT_BLOCK_PTR)
continue;
/* Advance to the first non-label insn of the successor block. */
*************** for_each_successor_phi (bb, fn, data)
*** 1917,1923 ****
{
int result;
rtx phi_set = PATTERN (insn);
! rtx *alternative = phi_alternative (phi_set, block->index);
rtx phi_src;
/* This phi function may not have an alternative
--- 1912,1918 ----
{
int result;
rtx phi_set = PATTERN (insn);
! rtx *alternative = phi_alternative (phi_set, bb->index);
rtx phi_src;
/* This phi function may not have an alternative
Index: flow.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/flow.c,v
retrieving revision 1.249
diff -c -p -r1.249 flow.c
*** flow.c 2000/04/08 22:38:38 1.249
--- flow.c 2000/04/09 00:38:25
*************** calculate_global_regs_live (blocks_in, b
*** 3080,3086 ****
global_live_at_start, since they are live only along a
particular edge. Set those regs that are live because of a
phi node alternative corresponding to this particular block. */
! for_each_successor_phi (bb->index, &set_phi_alternative_reg,
new_live_at_end);
if (bb == ENTRY_BLOCK_PTR)
--- 3080,3086 ----
global_live_at_start, since they are live only along a
particular edge. Set those regs that are live because of a
phi node alternative corresponding to this particular block. */
! for_each_successor_phi (bb, &set_phi_alternative_reg,
new_live_at_end);
if (bb == ENTRY_BLOCK_PTR)