combine life update

Richard Henderson rth@cygnus.com
Sun Oct 10 16:36:00 GMT 1999


Removes one of the fixme's I just added.  Namely, there are certain
circumstances in combine that want a global life update afterward.


r~

        * combine.c (refresh_blocks, need_refresh): New.
        (combine_instructions): Allocate refresh_blocks.  Invoke
        update_life_info if needed.
        (distribute_notes): Mark refresh_blocks instead of installing
        USE insns.
        * flow.c (update_life_info): Remove notes if GLOBAL_RM_NOTES.
        * basic_block.h (enum update_life_extent): Add GLOBAL_RM_NOTES.

        * Makefile.in (recog.o): Depend on basic-block.h.

Index: basic-block.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/basic-block.h,v
retrieving revision 1.31
diff -c -p -d -r1.31 basic-block.h
*** basic-block.h	1999/10/09 19:47:17	1.31
--- basic-block.h	1999/10/10 23:32:37
*************** extern void compute_immediate_dominators
*** 301,308 ****
  
  enum update_life_extent
  {
!   UPDATE_LIFE_GLOBAL = 0,
!   UPDATE_LIFE_LOCAL = 1
  };
  
  extern void update_life_info	PROTO ((sbitmap, enum update_life_extent));
--- 301,309 ----
  
  enum update_life_extent
  {
!   UPDATE_LIFE_LOCAL = 0,
!   UPDATE_LIFE_GLOBAL = 1,
!   UPDATE_LIFE_GLOBAL_RM_NOTES = 2,
  };
  
  extern void update_life_info	PROTO ((sbitmap, enum update_life_extent));
Index: flow.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/flow.c,v
retrieving revision 1.167
diff -c -p -d -r1.167 flow.c
*** flow.c	1999/10/09 19:47:17	1.167
--- flow.c	1999/10/10 23:32:38
*************** verify_local_live_at_start (new_live_at_
*** 2554,2562 ****
     lose the kill.  So we _can_ have a pseudo go live.  How irritating.  */
  
  void
! update_life_info (blocks, local_only)
       sbitmap blocks;
!      enum update_life_extent local_only;
  {
    regset tmp;
    int i;
--- 2554,2562 ----
     lose the kill.  So we _can_ have a pseudo go live.  How irritating.  */
  
  void
! update_life_info (blocks, extent)
       sbitmap blocks;
!      enum update_life_extent extent;
  {
    regset tmp;
    int i;
*************** update_life_info (blocks, local_only)
*** 2565,2572 ****
    tmp = ALLOCA_REG_SET ();
  
    /* For a global update, we go through the relaxation process again.  */
!   if (! local_only)
!     calculate_global_regs_live (blocks, blocks, 0);
  
    EXECUTE_IF_SET_IN_SBITMAP (blocks, 0, i,
      {
--- 2565,2578 ----
    tmp = ALLOCA_REG_SET ();
  
    /* For a global update, we go through the relaxation process again.  */
!   if (extent != UPDATE_LIFE_LOCAL)
!     {
!       calculate_global_regs_live (blocks, blocks, 0);
! 
!       /* If asked, remove notes from the blocks we'll update.  */
!       if (extent == UPDATE_LIFE_GLOBAL_RM_NOTES)
! 	count_or_remove_death_notes (blocks, 1);
!     }
  
    EXECUTE_IF_SET_IN_SBITMAP (blocks, 0, i,
      {
*************** update_life_info (blocks, local_only)
*** 2576,2582 ****
        propagate_block (tmp, bb->head, bb->end, (regset) NULL, i,
  		       PROP_DEATH_NOTES);
  
!       if (local_only)
  	verify_local_live_at_start (tmp, bb);
  
        CLEAN_ALLOCA;
--- 2582,2588 ----
        propagate_block (tmp, bb->head, bb->end, (regset) NULL, i,
  		       PROP_DEATH_NOTES);
  
!       if (extent == UPDATE_LIFE_LOCAL)
  	verify_local_live_at_start (tmp, bb);
  
        CLEAN_ALLOCA;
Index: combine.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/combine.c,v
retrieving revision 1.81
diff -c -p -d -r1.81 combine.c
*** combine.c	1999/10/09 19:47:17	1.81
--- combine.c	1999/10/10 23:32:38
*************** static rtx added_links_insn;
*** 196,201 ****
--- 196,207 ----
  
  /* Basic block number of the block in which we are performing combines.  */
  static int this_basic_block;
+ 
+ /* A bitmap indicating which blocks had registers go dead at entry.  
+    After combine, we'll need to re-do global life analysis with 
+    those blocks as starting points.  */
+ static sbitmap refresh_blocks;
+ static int need_refresh;
  
  /* The next group of arrays allows the recording of the last value assigned
     to (hard or pseudo) register n.  We use this information to see if a
*************** combine_instructions (f, nregs)
*** 551,556 ****
--- 557,566 ----
  
    setup_incoming_promotions ();
  
+   refresh_blocks = sbitmap_alloc (n_basic_blocks);
+   sbitmap_zero (refresh_blocks);
+   need_refresh = 0;
+ 
    for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
      {
        uid_cuid[INSN_UID (insn)] = ++i;
*************** combine_instructions (f, nregs)
*** 685,690 ****
--- 695,704 ----
  	}
      }
  
+   if (need_refresh)
+     update_life_info (refresh_blocks, UPDATE_LIFE_GLOBAL_RM_NOTES);
+   sbitmap_free (refresh_blocks);
+ 
    total_attempts += combine_attempts;
    total_merges += combine_merges;
    total_extras += combine_extras;
*************** distribute_notes (notes, from_insn, i3, 
*** 11858,11887 ****
  	      /* We haven't found an insn for the death note and it
  		 is still a REG_DEAD note, but we have hit the beginning
  		 of the block.  If the existing life info says the reg
! 		 was dead, there's nothing left to do.
! 
! 		 ??? If the register was live, we ought to mark for later
! 		 global life update.  Cop out like the previous code and
! 		 just add a hook for the death note to live on.  */
  	      if (REG_NOTE_KIND (note) == REG_DEAD && place == 0)
  		{
  		  int regno = REGNO (XEXP (note, 0));
- 
  		  if (REGNO_REG_SET_P (bb->global_live_at_start, regno))
  		    {
! 		      rtx die = gen_rtx_USE (VOIDmode, XEXP (note, 0));
! 
! 		      place = bb->head;
! 		      if (GET_CODE (place) != CODE_LABEL
! 			  && GET_CODE (place) != NOTE)
! 			{
! 			  place = emit_insn_before (die, place);
! 			  bb->head = place;
! 			}
! 		      else
! 			{
! 			  place = emit_insn_after (die, place);
! 			}
  		    }
  		}
  	    }
--- 11872,11886 ----
  	      /* We haven't found an insn for the death note and it
  		 is still a REG_DEAD note, but we have hit the beginning
  		 of the block.  If the existing life info says the reg
! 		 was dead, there's nothing left to do.  Otherwise, we'll
! 		 need to do a global life update after combine.  */
  	      if (REG_NOTE_KIND (note) == REG_DEAD && place == 0)
  		{
  		  int regno = REGNO (XEXP (note, 0));
  		  if (REGNO_REG_SET_P (bb->global_live_at_start, regno))
  		    {
! 		      SET_BIT (refresh_blocks, this_basic_block);
! 		      need_refresh = 1;
  		    }
  		}
  	    }
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/egcs/gcc/Makefile.in,v
retrieving revision 1.320
diff -c -p -d -r1.320 Makefile.in
*** Makefile.in	1999/10/09 19:47:17	1.320
--- Makefile.in	1999/10/10 23:33:02
*************** final.o : final.c $(CONFIG_H) system.h $
*** 1593,1599 ****
     dbxout.h
  recog.o : recog.c $(CONFIG_H) system.h $(RTL_H) function.h \
     $(REGS_H) $(RECOG_H) hard-reg-set.h flags.h insn-config.h insn-attr.h \
!    insn-flags.h insn-codes.h real.h toplev.h output.h resource.h
  reg-stack.o : reg-stack.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) recog.h \
     $(REGS_H) hard-reg-set.h flags.h insn-config.h insn-flags.h toplev.h \
     varray.h function.h
--- 1593,1599 ----
     dbxout.h
  recog.o : recog.c $(CONFIG_H) system.h $(RTL_H) function.h \
     $(REGS_H) $(RECOG_H) hard-reg-set.h flags.h insn-config.h insn-attr.h \
!    insn-flags.h insn-codes.h real.h toplev.h output.h resource.h basic-block.h
  reg-stack.o : reg-stack.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) recog.h \
     $(REGS_H) hard-reg-set.h flags.h insn-config.h insn-flags.h toplev.h \
     varray.h function.h


More information about the Gcc-patches mailing list