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]

PATCH: ICE in scan_region on Alpha platforms (gcc-2.95.1)


Here is an attempted fix for the gcc-2.95.1 internal compiler error in
scan_region on alpha platforms.  I do not claim this patch is correct...
But, I believe the problem occurs during CSE optimization when a
conditional jump is converted to an unconditional jump and the resulting
dead code is removed.  After removing dead code, a barrier previously
following notes for code blocks and EH regions may be moved to preceed
those notes.  This later causes the internal compiler error in scan_region.
The attempted fix is to move the jump instruction instead of the barrier to
satisfy the requirement that no NOTEs be between a JUMP_INSN and BARRIER.

Please review and correct the patch as needed...
Thank you!

- glen


Mon Aug 23 10:44:06 HST 1999  Glen Nakamura  <glen.nakamura@usa.net>
	* cse.c (cse_insn): Try not to move barriers when removing dead code
	resulting from converting conditional jumps to unconditional jumps.


diff -Nrc3p gcc-2.95.1.orig/gcc/cse.c gcc-2.95.1/gcc/cse.c
*** gcc-2.95.1.orig/gcc/cse.c	Mon Aug  2 23:58:45 1999
--- gcc-2.95.1/gcc/cse.c	Sun Aug 22 02:18:16 1999
*************** cse_insn (insn, libcall_insn)
*** 7451,7456 ****
--- 7451,7457 ----
  	 it.  If it was a computed branch, delete it and re-emit.  */
        else if (dest == pc_rtx && GET_CODE (src) == LABEL_REF)
  	{
+ 	  int barrier_detect = 0;
  	  rtx p;
  
  	  /* If this is not in the format for a simple branch and
*************** cse_insn (insn, libcall_insn)
*** 7481,7498 ****
  
  	  while (NEXT_INSN (p) != 0
  		 && GET_CODE (NEXT_INSN (p)) != BARRIER
! 		 && GET_CODE (NEXT_INSN (p)) != CODE_LABEL)
  	    {
  	      /* Note, we must update P with the return value from
  		 delete_insn, otherwise we could get an infinite loop
  		 if NEXT_INSN (p) had INSN_DELETED_P set.  */
  	      if (GET_CODE (NEXT_INSN (p)) != NOTE
  		  || NOTE_LINE_NUMBER (NEXT_INSN (p)) == NOTE_INSN_DELETED)
! 		p = PREV_INSN (delete_insn (NEXT_INSN (p)));
  	      else
  		p = NEXT_INSN (p);
  	    }
  
  	  /* If we don't have a BARRIER immediately after INSN, put one there.
  	     Much code assumes that there are no NOTEs between a JUMP_INSN and
  	     BARRIER.  */
--- 7482,7521 ----
  
  	  while (NEXT_INSN (p) != 0
  		 && GET_CODE (NEXT_INSN (p)) != BARRIER
! 		 && GET_CODE (NEXT_INSN (p)) != CODE_LABEL
! 		 && barrier_detect == 0)
  	    {
  	      /* Note, we must update P with the return value from
  		 delete_insn, otherwise we could get an infinite loop
  		 if NEXT_INSN (p) had INSN_DELETED_P set.  */
  	      if (GET_CODE (NEXT_INSN (p)) != NOTE
  		  || NOTE_LINE_NUMBER (NEXT_INSN (p)) == NOTE_INSN_DELETED)
! 		{
! 		  /* Detect BARRIER early since delete_insn deletes it
! 		     when the instruction preceding it is deleted.  */
! 		  if (GET_CODE (NEXT_INSN (NEXT_INSN (p))) == BARRIER)
! 		    barrier_detect = 1;
! 		  p = PREV_INSN (delete_insn (NEXT_INSN (p)));
! 		}
  	      else
  		p = NEXT_INSN (p);
  	    }
  
+ 	  /* If we detect an existing BARRIER after some NOTEs, move the
+ 	     jump to immediately precede it.  Much code assumes that there
+ 	     are no NOTEs between a JUMP_INSN and BARRIER.  */
+ 
+ 	  if (p != insn && (barrier_detect || (NEXT_INSN (p) != 0
+ 	      && GET_CODE (NEXT_INSN (p)) == BARRIER)))
+             {
+ 	      NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn);
+ 	      PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn);
+ 	      NEXT_INSN (insn) = NEXT_INSN (p);
+ 	      PREV_INSN (NEXT_INSN (p)) = insn;
+ 	      NEXT_INSN (p) = insn;
+ 	      PREV_INSN (insn) = p;
+             }
+ 
  	  /* If we don't have a BARRIER immediately after INSN, put one there.
  	     Much code assumes that there are no NOTEs between a JUMP_INSN and
  	     BARRIER.  */
*************** cse_insn (insn, libcall_insn)
*** 7500,7512 ****
  	  if (NEXT_INSN (insn) == 0
  	      || GET_CODE (NEXT_INSN (insn)) != BARRIER)
  	    emit_barrier_before (NEXT_INSN (insn));
- 
- 	  /* We might have two BARRIERs separated by notes.  Delete the second
- 	     one if so.  */
- 
- 	  if (p != insn && NEXT_INSN (p) != 0
- 	      && GET_CODE (NEXT_INSN (p)) == BARRIER)
- 	    delete_insn (NEXT_INSN (p));
  
  	  cse_jumps_altered = 1;
  	  sets[i].rtl = 0;
--- 7523,7528 ----

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