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
This commit is contained in:
parent
531ea24eef
commit
f35bcbc5d0
|
@ -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.
|
||||
|
|
|
@ -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)]
|
||||
"! 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)
|
||||
|
@ -4696,6 +4699,18 @@
|
|||
"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))
|
||||
|
|
|
@ -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])
|
||||
|
|
38
gcc/stupid.c
38
gcc/stupid.c
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue