nonlocal goto patch

amacleod@cygnus.com amacleod@cygnus.com
Thu Jul 19 06:58:00 GMT 2001


There is a consistancy problem in the use of gen_nonlocal_goto ().
As Janis Johnson pointed out in a patch back in May, the usage in
expand_builtin_longjmp () issues the 2nd and 4th parameters in
the wrong order. There is only one other use (in expand_goto ()) which 
issues them in the documented order. Rather than trying to work around this
inconsistancy, I took a look at what was involved in correcting the
usage in expand_builtin_longjmp.   

  It appears that only a few targets actually make use of the nonlocal_goto
pattern. Of those, Im guessing the i960 and picoJava ports are probably
suffering the same problem as ia64...   It also appears that the sparc
port is the only other one which has either a builtin_longjmp or
nonlocal_goto pattern that uses the parameters are in the wrong order.

This patch cleans up both 920428-2.c and the the builtin_setjmp testcases
in c-torture on ia64. It also doesn't cause any new problems on
sparc, as well as allowing those testcases to continue working.
This patch bootstraps on sparc/solaris2.8.

I dont know if it breaks anything else, Pawing through the
config directory, it doesn't *look* like it should.  If it does, 
that port should probably be fixed to expect the proper parameter 
sequence. The nonlocal_goto pattern appears to be relatively uncommon.

The documented usage of nonlocal_goto is:
						This pattern has four
     arguments, each representing a value to be used in the jump.  The
     first argument is to be loaded into the frame pointer, the second
     is the address to branch to (code to dispatch to the actual label),
     the third is the address of a location where the stack is saved,
     and the last is the address of the label, to be placed in the
     location for the incoming static chain.

stmt.c issues it correctly:
#if HAVE_nonlocal_goto
      if (HAVE_nonlocal_goto)
        emit_insn (gen_nonlocal_goto (static_chain, handler_slot,
                                      save_area, label_ref));
      else
#endif

builtins.c has parameters 2 and 4 backwards:
#if HAVE_nonlocal_goto
      if (HAVE_nonlocal_goto)
        /* We have to pass a value to the nonlocal_goto pattern that will
           get copied into the static_chain pointer, but it does not matter
           what that value is, because builtin_setjmp does not use it.  */
        emit_insn (gen_nonlocal_goto (value, fp, stack, lab));
      else
#endif

Those are the only 2 calls to gen_nonlocal_goto () in the compiler.

Is this patch OK?

Andrew

	* stmt.c (expand_goto): A nonlocal goto can be a call too.
	* builtins.c (expand_builtin_longjmp): Reverse label and static chain
	pointer parameters to match documented usage of nonlocal_goto.
	* config/ia64/ia64.md (nonlocal_goto): Revert label and static chain
	parameters to their correct order.
	* config/sparc/sparc.md (nonlocal_goto): Revert label and static chain
	parameters to their correct order.


Index: stmt.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/stmt.c,v
retrieving revision 1.206.12.1
diff -c -p -r1.206.12.1 stmt.c
*** stmt.c	2001/06/19 04:43:11	1.206.12.1
--- stmt.c	2001/07/18 19:45:19
*************** expand_goto (label)
*** 841,852 ****
  
        /* Search backwards to the jump insn and mark it as a 
  	 non-local goto.  */
!       for (insn = get_last_insn ();
! 	   GET_CODE (insn) != JUMP_INSN; 
! 	   insn = PREV_INSN (insn))
! 	continue;
!       REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
! 					  REG_NOTES (insn));
      }
    else
      expand_goto_internal (label, label_rtx (label), NULL_RTX);
--- 841,857 ----
  
        /* Search backwards to the jump insn and mark it as a 
  	 non-local goto.  */
!       for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
! 	{
! 	  if (GET_CODE (insn) == JUMP_INSN)
! 	    {
! 	      REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
! 						  const0_rtx, REG_NOTES (insn));
! 	      break;
! 	    }
! 	  else if (GET_CODE (insn) == CALL_INSN)
! 	      break;
! 	}
      }
    else
      expand_goto_internal (label, label_rtx (label), NULL_RTX);
Index: builtins.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/builtins.c,v
retrieving revision 1.27
diff -c -p -r1.27 builtins.c
*** builtins.c	2001/05/22 20:10:18	1.27
--- builtins.c	2001/07/18 19:45:19
*************** expand_builtin_longjmp (buf_addr, value)
*** 698,704 ****
  	/* We have to pass a value to the nonlocal_goto pattern that will
  	   get copied into the static_chain pointer, but it does not matter
  	   what that value is, because builtin_setjmp does not use it.  */
! 	emit_insn (gen_nonlocal_goto (value, fp, stack, lab));
        else
  #endif
  	{
--- 698,704 ----
  	/* We have to pass a value to the nonlocal_goto pattern that will
  	   get copied into the static_chain pointer, but it does not matter
  	   what that value is, because builtin_setjmp does not use it.  */
! 	emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
        else
  #endif
  	{
Index: config/ia64/ia64.md
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/config/ia64/ia64.md,v
retrieving revision 1.99
diff -c -p -r1.99 ia64.md
*** config/ia64/ia64.md	2001/05/22 20:10:18	1.99
--- config/ia64/ia64.md	2001/07/18 19:45:19
***************
*** 4972,4980 ****
  {
    emit_library_call (gen_rtx_SYMBOL_REF (Pmode, \"__ia64_nonlocal_goto\"),
  		     LCT_NORETURN, VOIDmode, 3,
! 		     operands[3], Pmode,
  		     copy_to_reg (XEXP (operands[2], 0)), Pmode,
! 		     operands[1], Pmode);
    emit_barrier ();
    DONE;
  }")
--- 4972,4980 ----
  {
    emit_library_call (gen_rtx_SYMBOL_REF (Pmode, \"__ia64_nonlocal_goto\"),
  		     LCT_NORETURN, VOIDmode, 3,
! 		     operands[1], Pmode,
  		     copy_to_reg (XEXP (operands[2], 0)), Pmode,
! 		     operands[3], Pmode);
    emit_barrier ();
    DONE;
  }")
Index: config/sparc/sparc.md
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/config/sparc/sparc.md,v
retrieving revision 1.109
diff -c -p -r1.109 sparc.md
*** config/sparc/sparc.md	2001/04/30 22:37:40	1.109
--- config/sparc/sparc.md	2001/07/18 20:06:18
***************
*** 8982,8990 ****
  #if 0
    rtx chain = operands[0];
  #endif
!   rtx fp = operands[1];
    rtx stack = operands[2];
!   rtx lab = operands[3];
    rtx labreg;
  
    /* Trap instruction to flush all the register windows.  */
--- 8982,8990 ----
  #if 0
    rtx chain = operands[0];
  #endif
!   rtx lab = operands[1];
    rtx stack = operands[2];
!   rtx fp = operands[3];
    rtx labreg;
  
    /* Trap instruction to flush all the register windows.  */



More information about the Gcc-bugs mailing list