This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

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)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]