OSDN Git Service

* expr.c (expand_builtin_setjmp): Set
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 14 Nov 1997 14:51:00 +0000 (14:51 +0000)
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 14 Nov 1997 14:51:00 +0000 (14:51 +0000)
        current_function_has_nonlocal_label.
        * stupid.c (stupid_life_analysis): If has_nonlocal_label, kill
        call-saved registers across calls.

        * alpha.md (exception_receiver): Remove.
        (nonlocal_goto_receiver_osf): New
        (nonlocal_goto_receiver_vms): Renamed from nonlocal_goto_receiver.
        (nonlocal_goto_receiver): New, select _osf or _vms.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@16492 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/alpha/alpha.md
gcc/expr.c
gcc/stupid.c

index 61e6835..c7d4a41 100644 (file)
@@ -1,5 +1,15 @@
 Fri Nov 14 07:24:20 1997  Richard Henderson  <rth@cygnus.com>
 
+       * expr.c (expand_builtin_setjmp): Set
+       current_function_has_nonlocal_label.
+       * stupid.c (stupid_life_analysis): If has_nonlocal_label, kill
+       call-saved registers across calls.
+
+       * alpha.md (exception_receiver): Remove.
+       (nonlocal_goto_receiver_osf): New
+       (nonlocal_goto_receiver_vms): Renamed from nonlocal_goto_receiver.
+       (nonlocal_goto_receiver): New, select _osf or _vms.
+
        * alpha.c (output_prolog [*]): Prefix entry labels with '$' to
        keep them from being propogated to the object file.
        (alpha_write_linkage): Likewise.
index bd4f43d..5a7218d 100644 (file)
     }
 }")
 
-(define_insn "exception_receiver"
+;; Ideally we should be able to define nonlocal_goto and arrange
+;; for the pc to be in a known place.  Or perhaps branch back via
+;; br instead of jmp.
+(define_insn "nonlocal_goto_receiver_osf"
   [(unspec_volatile [(const_int 0)] 2)]
   "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
-  ".long 0xc3a00000\;ldgp $29,0($29)")
+  "br $29,$LGOTO%=\\n$LGOTO%=:\;ldgp $29,0($29)")
 
-(define_expand "nonlocal_goto_receiver"
+(define_expand "nonlocal_goto_receiver_vms"
   [(unspec_volatile [(const_int 0)] 1)
    (set (reg:DI 27) (mem:DI (reg:DI 29)))
    (unspec_volatile [(const_int 0)] 1)
   "TARGET_OPEN_VMS"
   "")
 
+(define_expand "nonlocal_goto_receiver"
+  [(unspec_volatile [(const_int 0)] 2)]
+  ""
+  "
+{
+  if (TARGET_OPEN_VMS)
+    emit_insn(gen_nonlocal_goto_receiver_vms ());
+  else if (!TARGET_WINDOWS_NT)
+    emit_insn(gen_nonlocal_goto_receiver_osf ());
+  DONE;
+}")
+
 (define_insn "arg_home"
   [(unspec [(const_int 0)] 0)
    (use (reg:DI 1))
index a18b09e..7545c43 100644 (file)
@@ -8213,12 +8213,7 @@ expand_builtin_setjmp (buf_addr, target)
 #endif
     emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
 
-  /* Do we need to do something like:
-     
-     current_function_has_nonlocal_label = 1;
-
-     here?  It seems like we might have to, or some subset of that
-     functionality, but I am unsure.  (mrs) */
+  current_function_has_nonlocal_label = 1;
 
 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
   if (fixed_regs[ARG_POINTER_REGNUM])
index b68b196..028539a 100644 (file)
@@ -42,8 +42,8 @@ Boston, MA 02111-1307, USA.  */
    pseudo reg is computed.  Then the pseudo regs are ordered by priority
    and assigned hard regs in priority order.  */
 
-#include <stdio.h>
 #include "config.h"
+#include <stdio.h>
 #include "rtl.h"
 #include "hard-reg-set.h"
 #include "regs.h"
@@ -230,21 +230,34 @@ stupid_life_analysis (f, nregs, file)
          && NOTE_LINE_NUMBER (insn) == NOTE_INSN_SETJMP)
        last_setjmp_suid = INSN_SUID (insn);
 
-      /* Mark all call-clobbered regs as live after each call insn
-        so that a pseudo whose life span includes this insn
-        will not go in one of them.
+      /* Mark all call-clobbered regs as dead after each call insn so that
+        a pseudo whose life span includes this insn will not go in one of
+        them.  If the function contains a non-local goto, mark all hard
+        registers dead (except for stack related bits).
+
         Then mark those regs as all dead for the continuing scan
         of the insns before the call.  */
 
       if (GET_CODE (insn) == CALL_INSN)
        {
          last_call_suid = INSN_SUID (insn);
-         IOR_HARD_REG_SET (after_insn_hard_regs[last_call_suid],
-                           call_used_reg_set);
 
-         for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-           if (call_used_regs[i])
-             regs_live[i] = 0;
+         if (current_function_has_nonlocal_label)
+           {
+             IOR_COMPL_HARD_REG_SET (after_insn_hard_regs[last_call_suid],
+                                     fixed_reg_set);
+             for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+               if (! fixed_regs[i])
+                 regs_live[i] = 0;
+           }
+         else
+           {
+             IOR_HARD_REG_SET (after_insn_hard_regs[last_call_suid],
+                               call_used_reg_set);
+             for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+               if (call_used_regs[i])
+                 regs_live[i] = 0;
+           }
 
          /* It is important that this be done after processing the insn's
             pattern because we want the function result register to still
@@ -269,8 +282,11 @@ stupid_life_analysis (f, nregs, file)
       register int r = reg_order[i];
 
       /* Some regnos disappear from the rtl.  Ignore them to avoid crash. 
-        Also don't allocate registers that cross a setjmp.  */
-      if (regno_reg_rtx[r] == 0 || regs_crosses_setjmp[r])
+        Also don't allocate registers that cross a setjmp, or live across
+        a call if this function receives a nonlocal goto.  */
+      if (regno_reg_rtx[r] == 0 || regs_crosses_setjmp[r]
+         || (REG_N_CALLS_CROSSED (r) > 0 
+             && current_function_has_nonlocal_label))
        continue;
 
       /* Now find the best hard-register class for this pseudo register */