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: merge blocks


On Thu, Apr 08, 1999 at 11:00:40PM -0600, Jeffrey A Law wrote:
> If I remember correctly we had a block where the head pointed to the
> block note, the tail pointed to a jump to the next block.
[...]
> prev_nonnote_insn (tmp) return zero because every insn before the jump was
> a note.  SO we set a->end to zero.
> 
> This caused the compiler to segfault some time later.

I've rewritten that routine to handle this more gracefully.  It
passes your hp example and bootstraps alpha with no regressions.


r~


        * flow.c (merge_blocks_nomove): Rewrite to properly handle two
        blocks that vanish entirely during merging.

Index: flow.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/flow.c,v
retrieving revision 1.114
diff -c -p -d -r1.114 flow.c
*** flow.c	1999/04/09 01:23:05	1.114
--- flow.c	1999/04/09 18:28:41
*************** merge_blocks_nomove (a, b)
*** 1847,1885 ****
       basic_block a, b;
  {
    edge e;
!   rtx insn;
!   int done = 0;
  
    /* If there was a jump out of A, delete it.  */
!   if (GET_CODE (a->end) == JUMP_INSN)
      {
!       /* If the jump was the only insn in A, turn the jump into a deleted
! 	 note, since we may yet not be able to merge the blocks.  */
!       if (a->end == a->head)
! 	{
! 	  PUT_CODE (a->head, NOTE);
! 	  NOTE_LINE_NUMBER (a->head) = NOTE_INSN_DELETED;
! 	  NOTE_SOURCE_FILE (a->head) = 0;
! 	}
!       else
! 	{
! 	  rtx tmp = a->end;
  
! 	  a->end = prev_nonnote_insn (tmp);
  
  #ifdef HAVE_cc0
! 	  /* If this was a conditional jump, we need to also delete
! 	     the insn that set cc0.  */
! 	  if (! simplejump_p (tmp) && condjump_p (tmp))
! 	    {
! 	      PUT_CODE (PREV_INSN (tmp), NOTE);
! 	      NOTE_LINE_NUMBER (PREV_INSN (tmp)) = NOTE_INSN_DELETED;
! 	      NOTE_SOURCE_FILE (PREV_INSN (tmp)) = 0;
! 	    }
! #endif
  
  	  flow_delete_insn (tmp);
  	}
      }
  
    /* By definition, there should only be one successor of A, and that is
--- 1847,1904 ----
       basic_block a, b;
  {
    edge e;
!   rtx b_head, b_end, a_end;
!   int b_empty = 0;
! 
!   /* If there was a CODE_LABEL beginning B, delete it.  */
!   b_head = b->head;
!   b_end = b->end;
!   if (GET_CODE (b_head) == CODE_LABEL)
!     {
!       /* Detect basic blocks with nothing but a label.  This can happen
! 	 in particular at the end of a function.  */
!       if (b_head == b_end)
! 	b_empty = 1;
!       b_head = flow_delete_insn (b_head);
!     }
! 
!   /* Delete the basic block note.  */
!   if (GET_CODE (b_head) == NOTE 
!       && NOTE_LINE_NUMBER (b_head) == NOTE_INSN_BASIC_BLOCK)
!     {
!       if (b_head == b_end)
! 	b_empty = 1;
!       b_head = flow_delete_insn (b_head);
!     }
  
    /* If there was a jump out of A, delete it.  */
!   a_end = a->end;
!   if (GET_CODE (a_end) == JUMP_INSN)
      {
!       rtx prev;
  
!       prev = prev_nonnote_insn (a_end);
!       if (!prev) 
! 	prev = a->head;
  
  #ifdef HAVE_cc0
!       /* If this was a conditional jump, we need to also delete
! 	 the insn that set cc0.  */
  
+       if (prev && sets_cc0_p (prev))
+ 	{
+           rtx tmp = prev;
+ 	  prev = prev_nonnote_insn (prev);
+ 	  if (!prev)
+ 	    prev = a->head;
  	  flow_delete_insn (tmp);
  	}
+ #endif
+ 
+       /* Note that a->head != a->end, since we should have at least a
+ 	 bb note plus the jump, so prev != insn.  */
+       flow_delete_insn (a_end);
+       a_end = prev;
      }
  
    /* By definition, there should only be one successor of A, and that is
*************** merge_blocks_nomove (a, b)
*** 1891,1927 ****
      e->src = a;
    a->succ = b->succ;
  
-   /* If there was a CODE_LABEL beginning B, delete it.  */
-   insn = b->head;
-   if (GET_CODE (insn) == CODE_LABEL)
-     {
-       /* Detect basic blocks with nothing but a label.  This can happen
- 	 in particular at the end of a function.  */
-       if (insn == b->end)
- 	done = 1;
-       insn = flow_delete_insn (insn);
-     }
- 
-   /* Delete the basic block note.  */
-   if (GET_CODE (insn) == NOTE 
-       && NOTE_LINE_NUMBER (insn) == NOTE_INSN_BASIC_BLOCK)
-     {
-       if (insn == b->end)
- 	done = 1;
-       insn = flow_delete_insn (insn);
-     }
- 
    /* Reassociate the insns of B with A.  */
!   if (!done)
      {
!       BLOCK_FOR_INSN (insn) = a;
!       while (insn != b->end)
  	{
! 	  insn = NEXT_INSN (insn);
! 	  BLOCK_FOR_INSN (insn) = a;
  	}
!       a->end = insn;
      }
    
    /* Compact the basic block array.  */
    expunge_block (b);
--- 1910,1927 ----
      e->src = a;
    a->succ = b->succ;
  
    /* Reassociate the insns of B with A.  */
!   if (!b_empty)
      {
!       BLOCK_FOR_INSN (b_head) = a;
!       while (b_head != b_end)
  	{
! 	  b_head = NEXT_INSN (b_head);
! 	  BLOCK_FOR_INSN (b_head) = a;
  	}
!       a_end = b_head;
      }
+   a->end = a_end;
    
    /* Compact the basic block array.  */
    expunge_block (b);


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