Commit f35bcbc5 by Richard Henderson Committed by Jeff Law

expr.c (expand_builtin_setjmp): Set current_function_has_nonlocal_label.

        * 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.

From-SVN: r16492
parent 531ea24e
Fri Nov 14 07:24:20 1997 Richard Henderson <rth@cygnus.com> 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 * alpha.c (output_prolog [*]): Prefix entry labels with '$' to
keep them from being propogated to the object file. keep them from being propogated to the object file.
(alpha_write_linkage): Likewise. (alpha_write_linkage): Likewise.
......
...@@ -4683,12 +4683,15 @@ ...@@ -4683,12 +4683,15 @@
} }
}") }")
(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)] [(unspec_volatile [(const_int 0)] 2)]
"! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT" "! 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) [(unspec_volatile [(const_int 0)] 1)
(set (reg:DI 27) (mem:DI (reg:DI 29))) (set (reg:DI 27) (mem:DI (reg:DI 29)))
(unspec_volatile [(const_int 0)] 1) (unspec_volatile [(const_int 0)] 1)
...@@ -4696,6 +4699,18 @@ ...@@ -4696,6 +4699,18 @@
"TARGET_OPEN_VMS" "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" (define_insn "arg_home"
[(unspec [(const_int 0)] 0) [(unspec [(const_int 0)] 0)
(use (reg:DI 1)) (use (reg:DI 1))
......
...@@ -8213,12 +8213,7 @@ expand_builtin_setjmp (buf_addr, target) ...@@ -8213,12 +8213,7 @@ expand_builtin_setjmp (buf_addr, target)
#endif #endif
emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx); emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
/* Do we need to do something like: current_function_has_nonlocal_label = 1;
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) */
#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
if (fixed_regs[ARG_POINTER_REGNUM]) if (fixed_regs[ARG_POINTER_REGNUM])
......
...@@ -42,8 +42,8 @@ Boston, MA 02111-1307, USA. */ ...@@ -42,8 +42,8 @@ Boston, MA 02111-1307, USA. */
pseudo reg is computed. Then the pseudo regs are ordered by priority pseudo reg is computed. Then the pseudo regs are ordered by priority
and assigned hard regs in priority order. */ and assigned hard regs in priority order. */
#include <stdio.h>
#include "config.h" #include "config.h"
#include <stdio.h>
#include "rtl.h" #include "rtl.h"
#include "hard-reg-set.h" #include "hard-reg-set.h"
#include "regs.h" #include "regs.h"
...@@ -230,21 +230,34 @@ stupid_life_analysis (f, nregs, file) ...@@ -230,21 +230,34 @@ stupid_life_analysis (f, nregs, file)
&& NOTE_LINE_NUMBER (insn) == NOTE_INSN_SETJMP) && NOTE_LINE_NUMBER (insn) == NOTE_INSN_SETJMP)
last_setjmp_suid = INSN_SUID (insn); last_setjmp_suid = INSN_SUID (insn);
/* Mark all call-clobbered regs as live after each call insn /* Mark all call-clobbered regs as dead after each call insn so that
so that a pseudo whose life span includes this insn a pseudo whose life span includes this insn will not go in one of
will not go in one of them. 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 Then mark those regs as all dead for the continuing scan
of the insns before the call. */ of the insns before the call. */
if (GET_CODE (insn) == CALL_INSN) if (GET_CODE (insn) == CALL_INSN)
{ {
last_call_suid = INSN_SUID (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 (current_function_has_nonlocal_label)
if (call_used_regs[i]) {
regs_live[i] = 0; 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 /* It is important that this be done after processing the insn's
pattern because we want the function result register to still pattern because we want the function result register to still
...@@ -269,8 +282,11 @@ stupid_life_analysis (f, nregs, file) ...@@ -269,8 +282,11 @@ stupid_life_analysis (f, nregs, file)
register int r = reg_order[i]; register int r = reg_order[i];
/* Some regnos disappear from the rtl. Ignore them to avoid crash. /* Some regnos disappear from the rtl. Ignore them to avoid crash.
Also don't allocate registers that cross a setjmp. */ Also don't allocate registers that cross a setjmp, or live across
if (regno_reg_rtx[r] == 0 || regs_crosses_setjmp[r]) 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; continue;
/* Now find the best hard-register class for this pseudo register */ /* Now find the best hard-register class for this pseudo register */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment