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: update_life_info stuff


On Tue, Oct 19, 1999 at 09:22:35PM +0200, Franz Sirl wrote:
> This seems to cause a nice SEGV in check_live_1, while compiling _bb in 
> libgcc2.c on powerpc-linux-gnu (during stage1). It seems to me that 
> candidate_table[src].split_bbs is either not initialized or corrupted?

Neither, really -- we've got an invalid value for src.

This should fix that as well as addressing the loss of
accuracy in some of the reg info.


r~




        * basic-block.h (PROP_*): Move constants from ...
        * flow.c: ... here.
        (compute_bb_for_insn): Free the array before reallocating.
        (update_life_info): New arg PROP_FLAGS; pass on to propagate_block.
        (allocate_reg_life_data): Reset all reg variables collected by
        propagate_block.
        (get_block_head_tail): Don't convert from bb to block.
        (get_bb_head_tail): New.  Update all callers of get_block_head_tail.
        (find_insn_reg_weight): Take block not bb.
        (schedule_block): Don't set block num for moved insns.
        (schedule_region): Don't update_life_info or find_insn_reg_weight.
        (schedule_insns): Do it here instead.
        * combine.c (combine_instructions): Invoke compute_bb_for_insn
        before update_life_info.
        * recog.c (split_all_insns, peephole2_optimize): Update for
        new arg to update_life_info.
        * rtlanal.c (remove_note): Cope with NULL note.
        * toplev.c (rest_of_compilation): Don't invoke recompute_reg_usage
        if we did sched1.

Index: basic-block.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/basic-block.h,v
retrieving revision 1.34
diff -c -p -d -r1.34 basic-block.h
*** basic-block.h	1999/10/18 22:20:26	1.34
--- basic-block.h	1999/10/20 13:22:18
*************** extern void compute_dominators		PROTO ((
*** 300,305 ****
--- 300,306 ----
  extern void compute_flow_dominators	PROTO ((sbitmap *, sbitmap *));
  extern void compute_immediate_dominators	PROTO ((int *, sbitmap *));
  
+ 
  enum update_life_extent
  {
    UPDATE_LIFE_LOCAL = 0,
*************** enum update_life_extent
*** 307,313 ****
    UPDATE_LIFE_GLOBAL_RM_NOTES = 2,
  };
  
! extern void update_life_info	PROTO ((sbitmap, enum update_life_extent));
  extern int count_or_remove_death_notes	PROTO ((sbitmap, int));
  
  /* In lcm.c */
--- 308,325 ----
    UPDATE_LIFE_GLOBAL_RM_NOTES = 2,
  };
  
! /* Flags for life_analysis and update_life_info.  */
! 
! #define PROP_DEATH_NOTES	1	/* Create DEAD and UNUSED notes.  */
! #define PROP_LOG_LINKS		2	/* Create LOG_LINKS.  */
! #define PROP_REG_INFO		4	/* Update regs_ever_live et al.  */
! #define PROP_KILL_DEAD_CODE	8	/* Remove dead code.  */
! #define PROP_SCAN_DEAD_CODE	16	/* Scan for dead code.  */
! #define PROP_AUTOINC		32	/* Create autoinc mem references.  */
! #define PROP_FINAL		63	/* All of the above.  */
! 
! extern void update_life_info	PROTO ((sbitmap, enum update_life_extent,
! 					int));
  extern int count_or_remove_death_notes	PROTO ((sbitmap, int));
  
  /* In lcm.c */
Index: combine.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/combine.c,v
retrieving revision 1.85
diff -c -p -d -r1.85 combine.c
*** combine.c	1999/10/18 07:44:13	1.85
--- combine.c	1999/10/20 13:22:18
*************** combine_instructions (f, nregs)
*** 696,702 ****
      }
  
    if (need_refresh)
!     update_life_info (refresh_blocks, UPDATE_LIFE_GLOBAL_RM_NOTES);
    sbitmap_free (refresh_blocks);
  
    total_attempts += combine_attempts;
--- 696,706 ----
      }
  
    if (need_refresh)
!     {
!       compute_bb_for_insn (get_max_uid ());
!       update_life_info (refresh_blocks, UPDATE_LIFE_GLOBAL_RM_NOTES,
! 		        PROP_DEATH_NOTES);
!     }
    sbitmap_free (refresh_blocks);
  
    total_attempts += combine_attempts;
Index: flow.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/flow.c,v
retrieving revision 1.173
diff -c -p -d -r1.173 flow.c
*** flow.c	1999/10/20 12:45:22	1.173
--- flow.c	1999/10/20 13:22:19
*************** static void remove_fake_successors	PROTO
*** 371,385 ****
     it being unused. */
  void verify_flow_info			PROTO ((void));
  
- /* Flags for propagate_block.  */
- 
- #define PROP_DEATH_NOTES	1	/* Create DEAD and UNUSED notes.  */
- #define PROP_LOG_LINKS		2	/* Create LOG_LINKS.  */
- #define PROP_REG_INFO		4	/* Update regs_ever_live et al.  */
- #define PROP_KILL_DEAD_CODE	8	/* Remove dead code.  */
- #define PROP_SCAN_DEAD_CODE	16	/* Scan for dead code.  */
- #define PROP_AUTOINC		32	/* Create autoinc mem references.  */
- #define PROP_FINAL		63	/* All of the above.  */
  
  /* Find basic blocks of the current function.
     F is the first insn of the function and NREGS the number of register
--- 371,376 ----
*************** compute_bb_for_insn (max)
*** 838,843 ****
--- 829,836 ----
  {
    int i;
  
+   if (basic_block_for_insn)
+     VARRAY_FREE (basic_block_for_insn);
    VARRAY_BB_INIT (basic_block_for_insn, max, "basic_block_for_insn");
  
    for (i = 0; i < n_basic_blocks; ++i)
*************** verify_local_live_at_start (new_live_at_
*** 2567,2582 ****
     If we find registers removed from live_at_start, that means we have
     a broken peephole that is killing a register it shouldn't.
  
-    BLOCK_FOR_INSN is assumed to be correct.
- 
     ??? This is not true in one situation -- when a pre-reload splitter
     generates subregs of a multi-word pseudo, current life analysis will
!    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;
--- 2560,2580 ----
     If we find registers removed from live_at_start, that means we have
     a broken peephole that is killing a register it shouldn't.
  
     ??? This is not true in one situation -- when a pre-reload splitter
     generates subregs of a multi-word pseudo, current life analysis will
!    lose the kill.  So we _can_ have a pseudo go live.  How irritating.
! 
!    BLOCK_FOR_INSN is assumed to be correct.
  
+    ??? PROP_FLAGS should not contain PROP_LOG_LINKS.  Need to set up
+    reg_next_use for that.  Including PROP_REG_INFO does not refresh
+    regs_ever_live unless the caller resets it to zero.  */
+ 
  void
! update_life_info (blocks, extent, prop_flags)
       sbitmap blocks;
       enum update_life_extent extent;
+      int prop_flags;
  {
    regset tmp;
    int i;
*************** update_life_info (blocks, extent)
*** 2586,2592 ****
    /* 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)
--- 2584,2591 ----
    /* For a global update, we go through the relaxation process again.  */
    if (extent != UPDATE_LIFE_LOCAL)
      {
!       calculate_global_regs_live (blocks, blocks,
! 				  prop_flags & PROP_SCAN_DEAD_CODE);
  
        /* If asked, remove notes from the blocks we'll update.  */
        if (extent == UPDATE_LIFE_GLOBAL_RM_NOTES)
*************** update_life_info (blocks, extent)
*** 2599,2605 ****
  
        COPY_REG_SET (tmp, bb->global_live_at_end);
        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);
--- 2598,2604 ----
  
        COPY_REG_SET (tmp, bb->global_live_at_end);
        propagate_block (tmp, bb->head, bb->end, (regset) NULL, i,
! 		       prop_flags);
  
        if (extent == UPDATE_LIFE_LOCAL)
  	verify_local_live_at_start (tmp, bb);
*************** allocate_reg_life_data ()
*** 3194,3205 ****
       vector oriented regsets would set regset_{size,bytes} here also.  */
    allocate_reg_info (max_regno, FALSE, FALSE);
  
!   /* Because both reg_scan and flow_analysis want to set up the REG_N_SETS
!      information, explicitly reset it here.  The allocation should have
!      already happened on the previous reg_scan pass.  Make sure in case
!      some more registers were allocated.  */
    for (i = 0; i < max_regno; i++)
!     REG_N_SETS (i) = 0;
  }
  
  /* Compute the registers live at the beginning of a basic block
--- 3193,3209 ----
       vector oriented regsets would set regset_{size,bytes} here also.  */
    allocate_reg_info (max_regno, FALSE, FALSE);
  
!   /* Reset all the data we'll collect in propagate_block and its 
!      subroutines.  */
    for (i = 0; i < max_regno; i++)
!     {
!       REG_N_SETS (i) = 0;
!       REG_N_REFS (i) = 0;
!       REG_N_DEATHS (i) = 0;
!       REG_N_CALLS_CROSSED (i) = 0;
!       REG_LIVE_LENGTH (i) = 0;
!       REG_BASIC_BLOCK (i) = REG_BLOCK_UNKNOWN;
!     }
  }
  
  /* Compute the registers live at the beginning of a basic block
Index: haifa-sched.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/haifa-sched.c,v
retrieving revision 1.121
diff -c -p -d -r1.121 haifa-sched.c
*** haifa-sched.c	1999/10/18 22:37:30	1.121
--- haifa-sched.c	1999/10/20 13:22:19
*************** static void rm_other_notes PROTO ((rtx, 
*** 698,703 ****
--- 698,704 ----
  static rtx reemit_notes PROTO ((rtx, rtx));
  
  static void get_block_head_tail PROTO ((int, rtx *, rtx *));
+ static void get_bb_head_tail PROTO ((int, rtx *, rtx *));
  
  static int queue_to_ready PROTO ((rtx [], int));
  
*************** unlink_line_notes (insn, tail)
*** 4299,4315 ****
  /* Return the head and tail pointers of BB.  */
  
  HAIFA_INLINE static void
! get_block_head_tail (bb, headp, tailp)
!      int bb;
       rtx *headp;
       rtx *tailp;
  {
  
    rtx head;
    rtx tail;
-   int b;
- 
-   b = BB_TO_BLOCK (bb);
  
    /* HEAD and TAIL delimit the basic block being scheduled.  */
    head = BLOCK_HEAD (b);
--- 4300,4313 ----
  /* Return the head and tail pointers of BB.  */
  
  HAIFA_INLINE static void
! get_block_head_tail (b, headp, tailp)
!      int b;
       rtx *headp;
       rtx *tailp;
  {
  
    rtx head;
    rtx tail;
  
    /* HEAD and TAIL delimit the basic block being scheduled.  */
    head = BLOCK_HEAD (b);
*************** get_block_head_tail (bb, headp, tailp)
*** 4333,4338 ****
--- 4331,4345 ----
    *tailp = tail;
  }
  
+ HAIFA_INLINE static void
+ get_bb_head_tail (bb, headp, tailp)
+      int bb;
+      rtx *headp;
+      rtx *tailp;
+ {
+   get_block_head_tail (BB_TO_BLOCK (bb), headp, tailp);
+ }
+ 
  /* Delete line notes from bb. Save them so they can be later restored
     (in restore_line_notes ()).  */
  
*************** rm_line_notes (bb)
*** 4345,4351 ****
    rtx head;
    rtx insn;
  
!   get_block_head_tail (bb, &head, &tail);
  
    if (head == tail
        && (GET_RTX_CLASS (GET_CODE (head)) != 'i'))
--- 4352,4358 ----
    rtx head;
    rtx insn;
  
!   get_bb_head_tail (bb, &head, &tail);
  
    if (head == tail
        && (GET_RTX_CLASS (GET_CODE (head)) != 'i'))
*************** save_line_notes (bb)
*** 4391,4397 ****
    rtx line = line_note_head[BB_TO_BLOCK (bb)];
    rtx insn;
  
!   get_block_head_tail (bb, &head, &tail);
    next_tail = NEXT_INSN (tail);
  
    for (insn = BLOCK_HEAD (BB_TO_BLOCK (bb));
--- 4398,4404 ----
    rtx line = line_note_head[BB_TO_BLOCK (bb)];
    rtx insn;
  
!   get_bb_head_tail (bb, &head, &tail);
    next_tail = NEXT_INSN (tail);
  
    for (insn = BLOCK_HEAD (BB_TO_BLOCK (bb));
*************** rm_other_notes (head, tail)
*** 4562,4573 ****
  /* Calculate INSN_REG_WEIGHT for all insns of a block.  */
  
  static void
! find_insn_reg_weight (bb)
!     int bb;
  {
    rtx insn, next_tail, head, tail;
  
!   get_block_head_tail (bb, &head, &tail);
    next_tail = NEXT_INSN (tail);
  
    for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
--- 4569,4580 ----
  /* Calculate INSN_REG_WEIGHT for all insns of a block.  */
  
  static void
! find_insn_reg_weight (b)
!     int b;
  {
    rtx insn, next_tail, head, tail;
  
!   get_block_head_tail (b, &head, &tail);
    next_tail = NEXT_INSN (tail);
  
    for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
*************** schedule_block (bb, rgn_n_insns)
*** 5726,5732 ****
       However, it was removed when it proved to be of marginal benefit
       and caused problems because schedule_block and compute_forward_dependences
       had different notions of what the "head" insn was.  */
!   get_block_head_tail (bb, &head, &tail);
  
    /* Interblock scheduling could have moved the original head insn from this
       block into a proceeding block.  This may also cause schedule_block and
--- 5733,5739 ----
       However, it was removed when it proved to be of marginal benefit
       and caused problems because schedule_block and compute_forward_dependences
       had different notions of what the "head" insn was.  */
!   get_bb_head_tail (bb, &head, &tail);
  
    /* Interblock scheduling could have moved the original head insn from this
       block into a proceeding block.  This may also cause schedule_block and
*************** schedule_block (bb, rgn_n_insns)
*** 5838,5844 ****
  	rtx src_next_tail;
  	rtx tail, head;
  
! 	get_block_head_tail (bb_src, &head, &tail);
  	src_next_tail = NEXT_INSN (tail);
  	src_head = head;
  
--- 5845,5851 ----
  	rtx src_next_tail;
  	rtx tail, head;
  
! 	get_bb_head_tail (bb_src, &head, &tail);
  	src_next_tail = NEXT_INSN (tail);
  	src_head = head;
  
*************** schedule_block (bb, rgn_n_insns)
*** 5968,5982 ****
  		}
  	      nr_inter++;
  
! 	      /* Find the beginning of the scheduling group; update the
! 		 containing block number for the insns.  */
  	      temp = insn;
- 	      set_block_num (temp, target_bb);
  	      while (SCHED_GROUP_P (insn))
! 		{
! 		  temp = PREV_INSN (temp);
! 		  set_block_num (temp, target_bb);
! 		}
  
  	      /* Update source block boundaries.   */
  	      b1 = BLOCK_FOR_INSN (temp);
--- 5975,5988 ----
  		}
  	      nr_inter++;
  
! 	      /* Find the beginning of the scheduling group.  */
! 	      /* ??? Ought to update basic block here, but later bits of 
! 		 schedule_block assumes the original insn block is 
! 		 still intact.  */
! 
  	      temp = insn;
  	      while (SCHED_GROUP_P (insn))
! 		temp = PREV_INSN (temp);
  
  	      /* Update source block boundaries.   */
  	      b1 = BLOCK_FOR_INSN (temp);
*************** compute_block_forward_dependences (bb)
*** 6118,6124 ****
    rtx next_tail;
    enum reg_note dep_type;
  
!   get_block_head_tail (bb, &head, &tail);
    next_tail = NEXT_INSN (tail);
    for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
      {
--- 6124,6130 ----
    rtx next_tail;
    enum reg_note dep_type;
  
!   get_bb_head_tail (bb, &head, &tail);
    next_tail = NEXT_INSN (tail);
    for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
      {
*************** compute_block_backward_dependences (bb)
*** 6337,6343 ****
      }
  
    /* Do the analysis for this block.  */
!   get_block_head_tail (bb, &head, &tail);
    sched_analyze (head, tail);
    add_branch_dependences (head, tail);
  
--- 6343,6349 ----
      }
  
    /* Do the analysis for this block.  */
!   get_bb_head_tail (bb, &head, &tail);
    sched_analyze (head, tail);
    add_branch_dependences (head, tail);
  
*************** debug_dependencies ()
*** 6520,6526 ****
  	  rtx next_tail;
  	  rtx insn;
  
! 	  get_block_head_tail (bb, &head, &tail);
  	  next_tail = NEXT_INSN (tail);
  	  fprintf (dump, "\n;;   --- Region Dependences --- b %d bb %d \n",
  		   BB_TO_BLOCK (bb), bb);
--- 6526,6532 ----
  	  rtx next_tail;
  	  rtx insn;
  
! 	  get_bb_head_tail (bb, &head, &tail);
  	  next_tail = NEXT_INSN (tail);
  	  fprintf (dump, "\n;;   --- Region Dependences --- b %d bb %d \n",
  		   BB_TO_BLOCK (bb), bb);
*************** set_priorities (bb)
*** 6591,6597 ****
    rtx prev_head;
    rtx head;
  
!   get_block_head_tail (bb, &head, &tail);
    prev_head = PREV_INSN (head);
  
    if (head == tail
--- 6597,6603 ----
    rtx prev_head;
    rtx head;
  
!   get_bb_head_tail (bb, &head, &tail);
    prev_head = PREV_INSN (head);
  
    if (head == tail
*************** schedule_region (rgn)
*** 6647,6654 ****
    int bb;
    int rgn_n_insns = 0;
    int sched_rgn_n_insns = 0;
-   int initial_deaths;
-   sbitmap blocks;
  
    /* Set variables for the current region.  */
    current_nr_blocks = RGN_NR_BLOCKS (rgn);
--- 6653,6658 ----
*************** schedule_region (rgn)
*** 6658,6670 ****
    reg_pending_clobbers = ALLOCA_REG_SET ();
    reg_pending_sets_all = 0;
  
-   /* Create a bitmap of the blocks in this region.  */
-   blocks = sbitmap_alloc (n_basic_blocks);
-   sbitmap_zero (blocks);
- 
-   for (bb = current_nr_blocks - 1; bb >= 0; --bb)
-     SET_BIT (blocks, BB_TO_BLOCK (bb));
- 
    /* Initializations for region data dependence analyisis.  */
    if (current_nr_blocks > 1)
      {
--- 6662,6667 ----
*************** schedule_region (rgn)
*** 6714,6726 ****
    for (bb = current_nr_blocks - 1; bb >= 0; bb--)
      compute_block_forward_dependences (bb);
  
-   /* Compute INSN_REG_WEIGHT.  */
-   for (bb = current_nr_blocks - 1; bb >= 0; bb--)
-     find_insn_reg_weight (bb);
- 
-   /* Remove death notes.  */
-   initial_deaths = count_or_remove_death_notes (blocks, 1);
- 
    /* Delete line notes and set priorities.  */
    for (bb = 0; bb < current_nr_blocks; bb++)
      {
--- 6711,6716 ----
*************** schedule_region (rgn)
*** 6797,6816 ****
    if (sched_rgn_n_insns != rgn_n_insns)
      abort ();
  
-   /* Update register life and usage information.  Scheduling a multi-block
-      region requires a global update.  */
-   if (current_nr_blocks > 1)
-     update_life_info (blocks, UPDATE_LIFE_GLOBAL);
-   else
-     {
-       update_life_info (blocks, UPDATE_LIFE_LOCAL);
- 
-       /* In the single block case, the count of registers that died should
- 	 not have changed during the schedule.  */
-       if (count_or_remove_death_notes (blocks, 0) != initial_deaths)
-         abort (); 
-     }
- 
    /* Restore line notes.  */
    if (write_symbols != NO_DEBUG)
      {
--- 6787,6792 ----
*************** schedule_region (rgn)
*** 6823,6829 ****
  
    FREE_REG_SET (reg_pending_sets);
    FREE_REG_SET (reg_pending_clobbers);
-   sbitmap_free (blocks);
  }
  
  /* The one entry point in this file.  DUMP_FILE is the dump file for
--- 6799,6804 ----
*************** void
*** 6833,6845 ****
  schedule_insns (dump_file)
       FILE *dump_file;
  {
! 
    int max_uid;
    int b;
    rtx insn;
    int rgn;
- 
    int luid;
  
    /* Disable speculative loads in their presence if cc0 defined.  */
  #ifdef HAVE_cc0
--- 6808,6821 ----
  schedule_insns (dump_file)
       FILE *dump_file;
  {
!   int *deaths_in_region;
!   sbitmap blocks, large_region_blocks;
    int max_uid;
    int b;
    rtx insn;
    int rgn;
    int luid;
+   int any_large_regions;
  
    /* Disable speculative loads in their presence if cc0 defined.  */
  #ifdef HAVE_cc0
*************** schedule_insns (dump_file)
*** 6905,6910 ****
--- 6881,6889 ----
    block_to_bb = (int *) alloca ((n_basic_blocks) * sizeof (int));
    containing_rgn = (int *) alloca ((n_basic_blocks) * sizeof (int));
  
+   blocks = sbitmap_alloc (n_basic_blocks);
+   large_region_blocks = sbitmap_alloc (n_basic_blocks);
+ 
    compute_bb_for_insn (max_uid);
  
    /* Compute regions for scheduling.  */
*************** schedule_insns (dump_file)
*** 6992,6997 ****
--- 6971,6978 ----
    insn_dep_count = (int *) xcalloc (max_uid, sizeof (int));
    insn_depend = (rtx *) xcalloc (max_uid, sizeof (rtx));
  
+   deaths_in_region = (int *) alloca (sizeof(int) * nr_regions);
+ 
    init_alias_analysis ();
  
    if (write_symbols != NO_DEBUG)
*************** schedule_insns (dump_file)
*** 7034,7039 ****
--- 7015,7035 ----
  	       && GET_CODE (NEXT_INSN (insn)) == BARRIER)))
      emit_note_after (NOTE_INSN_DELETED, BLOCK_END (n_basic_blocks - 1));
  
+   /* Compute INSN_REG_WEIGHT for all blocks.  We must do this before
+      removing death notes.  */
+   for (b = n_basic_blocks - 1; b >= 0; b--)
+     find_insn_reg_weight (b);
+ 
+   /* Remove all death notes from the subroutine.  */
+   for (rgn = 0; rgn < nr_regions; rgn++)
+     {
+       sbitmap_zero (blocks);
+       for (b = RGN_NR_BLOCKS (rgn) - 1; b >= 0; --b)
+ 	SET_BIT (blocks, rgn_bb_table [RGN_BLOCKS (rgn) + b]);
+ 
+       deaths_in_region[rgn] = count_or_remove_death_notes (blocks, 1);
+     }
+ 
    /* Schedule every region in the subroutine.  */
    for (rgn = 0; rgn < nr_regions; rgn++)
      {
*************** schedule_insns (dump_file)
*** 7044,7049 ****
--- 7040,7088 ----
  #endif
      }
  
+   /* Update life analysis for the subroutine.  Do single block regions
+      first so that we can verify that live_at_start didn't change.  Then
+      do all other blocks.   */
+   /* ??? There is an outside possibility that update_life_info, or more
+      to the point propagate_block, could get called with non-zero flags
+      more than once for one basic block.  This would be kinda bad if it
+      were to happen, since REG_INFO would be accumulated twice for the
+      block, and we'd have twice the REG_DEAD notes.
+ 
+      I'm fairly certain that this _shouldn't_ happen, since I don't think
+      that live_at_start should change at region heads.  Not sure what the
+      best way to test for this kind of thing... */
+ 
+   allocate_reg_life_data ();
+   compute_bb_for_insn (max_uid);
+ 
+   any_large_regions = 0;
+   sbitmap_ones (large_region_blocks);
+ 
+   for (rgn = 0; rgn < nr_regions; rgn++)
+     if (RGN_NR_BLOCKS (rgn) > 1)
+       any_large_regions = 1;
+     else
+       {
+ 	sbitmap_zero (blocks);
+ 	SET_BIT (blocks, rgn_bb_table[RGN_BLOCKS (rgn)]);
+ 	RESET_BIT (large_region_blocks, rgn_bb_table[RGN_BLOCKS (rgn)]);
+ 
+ 	update_life_info (blocks, UPDATE_LIFE_LOCAL,
+ 			  PROP_DEATH_NOTES | PROP_REG_INFO);
+ 
+ 	/* In the single block case, the count of registers that died should
+ 	   not have changed during the schedule.  */
+ 	if (count_or_remove_death_notes (blocks, 0) != deaths_in_region[rgn])
+           abort (); 
+       }
+ 
+   if (any_large_regions)
+     {
+       update_life_info (large_region_blocks, UPDATE_LIFE_GLOBAL,
+ 		        PROP_DEATH_NOTES | PROP_REG_INFO);
+     }
+ 
    /* Reposition the prologue and epilogue notes in case we moved the
       prologue/epilogue insns.  */
    if (reload_completed)
*************** schedule_insns (dump_file)
*** 7108,7112 ****
--- 7147,7154 ----
        free (out_edges);
        out_edges = NULL;
      }
+ 
+   sbitmap_free (blocks);
+   sbitmap_free (large_region_blocks);
  }
  #endif /* INSN_SCHEDULING */
Index: recog.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/recog.c,v
retrieving revision 1.47
diff -c -p -d -r1.47 recog.c
*** recog.c	1999/10/18 22:20:27	1.47
--- recog.c	1999/10/20 13:22:19
*************** split_all_insns (upd_life)
*** 2661,2667 ****
      {
        compute_bb_for_insn (get_max_uid ());
        count_or_remove_death_notes (blocks, 1);
!       update_life_info (blocks, UPDATE_LIFE_LOCAL);
      }
  
    sbitmap_free (blocks);
--- 2661,2667 ----
      {
        compute_bb_for_insn (get_max_uid ());
        count_or_remove_death_notes (blocks, 1);
!       update_life_info (blocks, UPDATE_LIFE_LOCAL, PROP_DEATH_NOTES);
      }
  
    sbitmap_free (blocks);
*************** peephole2_optimize (dump_file)
*** 2762,2767 ****
  
    compute_bb_for_insn (get_max_uid ());
    count_or_remove_death_notes (blocks, 1);
!   update_life_info (blocks, UPDATE_LIFE_LOCAL);
  }
  #endif
--- 2762,2767 ----
  
    compute_bb_for_insn (get_max_uid ());
    count_or_remove_death_notes (blocks, 1);
!   update_life_info (blocks, UPDATE_LIFE_LOCAL, PROP_DEATH_NOTES);
  }
  #endif
Index: rtlanal.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtlanal.c,v
retrieving revision 1.42
diff -c -p -d -r1.42 rtlanal.c
*** rtlanal.c	1999/09/19 17:00:01	1.42
--- rtlanal.c	1999/10/20 13:22:19
*************** find_regno_fusage (insn, code, regno)
*** 1513,1522 ****
  
  void
  remove_note (insn, note)
-      register rtx note;
       register rtx insn;
  {
    register rtx link;
  
    if (REG_NOTES (insn) == note)
      {
--- 1513,1525 ----
  
  void
  remove_note (insn, note)
       register rtx insn;
+      register rtx note;
  {
    register rtx link;
+ 
+   if (note == NULL_RTX)
+     return;
  
    if (REG_NOTES (insn) == note)
      {
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/toplev.c,v
retrieving revision 1.242
diff -c -p -d -r1.242 toplev.c
*** toplev.c	1999/10/19 13:02:39	1.242
--- toplev.c	1999/10/20 13:22:20
*************** rest_of_compilation (decl)
*** 4112,4118 ****
    if (!obey_regdecls)
      TIMEVAR (local_alloc_time,
  	     {
! 	       recompute_reg_usage (insns, ! optimize_size);
  	       regclass (insns, max_reg_num ());
  	       rebuild_label_notes_after_reload = local_alloc ();
  	     });
--- 4112,4121 ----
    if (!obey_regdecls)
      TIMEVAR (local_alloc_time,
  	     {
! 	       /* We recomputed reg usage as part of updating the rest
! 		  of life info during sched.  */
! 	       if (! flag_schedule_insns)
! 		 recompute_reg_usage (insns, ! optimize_size);
  	       regclass (insns, max_reg_num ());
  	       rebuild_label_notes_after_reload = local_alloc ();
  	     });


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