mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-18 08:23:50 +08:00
flow.c (mark_regs_live_at_end): Use regs_invalidated_by_call.
* flow.c (mark_regs_live_at_end): Use regs_invalidated_by_call. * regclass.c (init_reg_sets_1): Fix typo. * config/ia64/ia64.c (ar_pfs_reg_operand): New. (ia64_expand_call): Pass ar.pfs to sibcall expanders. (ia64_compute_frame_size): Make ar.unat live when in use. (ia64_epilogue_uses): Reformat; do not check current_function_is_leaf for ar.pfs; remove ar.unat handling. * config/ia64/ia64.h (CALL_REALLY_USED_REGISTERS): ar.unat is call-saved. (PREDICATE_CODES): Add ar_pfs_reg_operand. * config/ia64/ia64-protos.h: Update decls. * config/ia64/ia64.md (sibcall_nopic): Use ar.pfs. (sibcall_pic): Likewise. From-SVN: r45021
This commit is contained in:
parent
8e8de25448
commit
6ca3c22fd1
@ -1,3 +1,19 @@
|
||||
2001-08-18 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* flow.c (mark_regs_live_at_end): Use regs_invalidated_by_call.
|
||||
* regclass.c (init_reg_sets_1): Fix typo.
|
||||
* config/ia64/ia64.c (ar_pfs_reg_operand): New.
|
||||
(ia64_expand_call): Pass ar.pfs to sibcall expanders.
|
||||
(ia64_compute_frame_size): Make ar.unat live when in use.
|
||||
(ia64_epilogue_uses): Reformat; do not check current_function_is_leaf
|
||||
for ar.pfs; remove ar.unat handling.
|
||||
* config/ia64/ia64.h (CALL_REALLY_USED_REGISTERS): ar.unat is
|
||||
call-saved.
|
||||
(PREDICATE_CODES): Add ar_pfs_reg_operand.
|
||||
* config/ia64/ia64-protos.h: Update decls.
|
||||
* config/ia64/ia64.md (sibcall_nopic): Use ar.pfs.
|
||||
(sibcall_pic): Likewise.
|
||||
|
||||
2001-08-18 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* config/ia64/ia64.c (ia64_sched_reorder2): Also skip past
|
||||
|
@ -62,6 +62,7 @@ extern int not_postinc_memory_operand PARAMS((rtx, enum machine_mode));
|
||||
extern int predicate_operator PARAMS((rtx, enum machine_mode));
|
||||
extern int ar_lc_reg_operand PARAMS((rtx, enum machine_mode));
|
||||
extern int ar_ccv_reg_operand PARAMS((rtx, enum machine_mode));
|
||||
extern int ar_pfs_reg_operand PARAMS((rtx, enum machine_mode));
|
||||
extern int general_tfmode_operand PARAMS((rtx, enum machine_mode));
|
||||
extern int destination_tfmode_operand PARAMS((rtx, enum machine_mode));
|
||||
extern int tfreg_or_fp01_operand PARAMS((rtx, enum machine_mode));
|
||||
|
@ -788,6 +788,18 @@ ar_ccv_reg_operand (op, mode)
|
||||
&& REGNO (op) == AR_CCV_REGNUM);
|
||||
}
|
||||
|
||||
/* Return 1 if this is the ar.pfs register. */
|
||||
|
||||
int
|
||||
ar_pfs_reg_operand (op, mode)
|
||||
register rtx op;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
return ((GET_MODE (op) == mode || mode == VOIDmode)
|
||||
&& GET_CODE (op) == REG
|
||||
&& REGNO (op) == AR_PFS_REGNUM);
|
||||
}
|
||||
|
||||
/* Like general_operand, but don't allow (mem (addressof)). */
|
||||
|
||||
int
|
||||
@ -1107,11 +1119,12 @@ ia64_expand_call (retval, addr, nextarg, sibcall_p)
|
||||
rtx nextarg;
|
||||
int sibcall_p;
|
||||
{
|
||||
rtx insn, b0, gp_save, narg_rtx;
|
||||
rtx insn, b0, pfs, gp_save, narg_rtx;
|
||||
int narg;
|
||||
|
||||
addr = XEXP (addr, 0);
|
||||
b0 = gen_rtx_REG (DImode, R_BR (0));
|
||||
pfs = gen_rtx_REG (DImode, AR_PFS_REGNUM);
|
||||
|
||||
if (! nextarg)
|
||||
narg = 0;
|
||||
@ -1124,7 +1137,7 @@ ia64_expand_call (retval, addr, nextarg, sibcall_p)
|
||||
if (TARGET_NO_PIC || TARGET_AUTO_PIC)
|
||||
{
|
||||
if (sibcall_p)
|
||||
insn = gen_sibcall_nopic (addr, narg_rtx, b0);
|
||||
insn = gen_sibcall_nopic (addr, narg_rtx, b0, pfs);
|
||||
else if (! retval)
|
||||
insn = gen_call_nopic (addr, narg_rtx, b0);
|
||||
else
|
||||
@ -1151,7 +1164,7 @@ ia64_expand_call (retval, addr, nextarg, sibcall_p)
|
||||
gen_rtx_MEM (DImode, plus_constant (addr, 8)));
|
||||
|
||||
if (sibcall_p)
|
||||
insn = gen_sibcall_pic (dest, narg_rtx, b0);
|
||||
insn = gen_sibcall_pic (dest, narg_rtx, b0, pfs);
|
||||
else if (! retval)
|
||||
insn = gen_call_pic (dest, narg_rtx, b0);
|
||||
else
|
||||
@ -1164,7 +1177,7 @@ ia64_expand_call (retval, addr, nextarg, sibcall_p)
|
||||
else if (TARGET_CONST_GP)
|
||||
{
|
||||
if (sibcall_p)
|
||||
insn = gen_sibcall_nopic (addr, narg_rtx, b0);
|
||||
insn = gen_sibcall_nopic (addr, narg_rtx, b0, pfs);
|
||||
else if (! retval)
|
||||
insn = gen_call_nopic (addr, narg_rtx, b0);
|
||||
else
|
||||
@ -1174,7 +1187,7 @@ ia64_expand_call (retval, addr, nextarg, sibcall_p)
|
||||
else
|
||||
{
|
||||
if (sibcall_p)
|
||||
emit_call_insn (gen_sibcall_pic (addr, narg_rtx, b0));
|
||||
emit_call_insn (gen_sibcall_pic (addr, narg_rtx, b0, pfs));
|
||||
else
|
||||
{
|
||||
emit_move_insn (gp_save, pic_offset_table_rtx);
|
||||
@ -1548,6 +1561,7 @@ ia64_compute_frame_size (size)
|
||||
ar.unat as well. */
|
||||
if (spilled_gr_p || cfun->machine->n_varargs)
|
||||
{
|
||||
regs_ever_live[AR_UNAT_REGNUM] = 1;
|
||||
SET_HARD_REG_BIT (mask, AR_UNAT_REGNUM);
|
||||
current_frame_info.reg_save_ar_unat = find_gr_spill (spill_size == 0);
|
||||
if (current_frame_info.reg_save_ar_unat == 0)
|
||||
@ -6633,42 +6647,39 @@ int
|
||||
ia64_epilogue_uses (regno)
|
||||
int regno;
|
||||
{
|
||||
/* When a function makes a call through a function descriptor, we
|
||||
will write a (potentially) new value to "gp". After returning
|
||||
from such a call, we need to make sure the function restores the
|
||||
original gp-value, even if the function itself does not use the
|
||||
gp anymore. */
|
||||
if (regno == R_GR (1)
|
||||
&& TARGET_CONST_GP
|
||||
&& !(TARGET_AUTO_PIC || TARGET_NO_PIC))
|
||||
return 1;
|
||||
switch (regno)
|
||||
{
|
||||
case R_GR (1):
|
||||
/* When a function makes a call through a function descriptor, we
|
||||
will write a (potentially) new value to "gp". After returning
|
||||
from such a call, we need to make sure the function restores the
|
||||
original gp-value, even if the function itself does not use the
|
||||
gp anymore. */
|
||||
return (TARGET_CONST_GP && !(TARGET_AUTO_PIC || TARGET_NO_PIC));
|
||||
|
||||
/* For functions defined with the syscall_linkage attribute, all input
|
||||
registers are marked as live at all function exits. This prevents the
|
||||
register allocator from using the input registers, which in turn makes it
|
||||
possible to restart a system call after an interrupt without having to
|
||||
save/restore the input registers. This also prevents kernel data from
|
||||
leaking to application code. */
|
||||
case IN_REG (0): case IN_REG (1): case IN_REG (2): case IN_REG (3):
|
||||
case IN_REG (4): case IN_REG (5): case IN_REG (6): case IN_REG (7):
|
||||
/* For functions defined with the syscall_linkage attribute, all
|
||||
input registers are marked as live at all function exits. This
|
||||
prevents the register allocator from using the input registers,
|
||||
which in turn makes it possible to restart a system call after
|
||||
an interrupt without having to save/restore the input registers.
|
||||
This also prevents kernel data from leaking to application code. */
|
||||
return lookup_attribute ("syscall_linkage",
|
||||
TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))) != NULL;
|
||||
|
||||
if (IN_REGNO_P (regno)
|
||||
&& lookup_attribute ("syscall_linkage",
|
||||
TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
|
||||
return 1;
|
||||
case R_BR (0):
|
||||
/* Conditional return patterns can't represent the use of `b0' as
|
||||
the return address, so we force the value live this way. */
|
||||
return 1;
|
||||
|
||||
/* Conditional return patterns can't represent the use of `b0' as
|
||||
the return address, so we force the value live this way. */
|
||||
if (regno == R_BR (0))
|
||||
return 1;
|
||||
case AR_PFS_REGNUM:
|
||||
/* Likewise for ar.pfs, which is used by br.ret. */
|
||||
return 1;
|
||||
|
||||
if (regs_ever_live[AR_LC_REGNUM] && regno == AR_LC_REGNUM)
|
||||
return 1;
|
||||
if (! current_function_is_leaf && regno == AR_PFS_REGNUM)
|
||||
return 1;
|
||||
if (TEST_HARD_REG_BIT (current_frame_info.mask, AR_UNAT_REGNUM)
|
||||
&& regno == AR_UNAT_REGNUM)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return true if IDENTIFIER is a valid attribute for TYPE. */
|
||||
|
@ -635,11 +635,11 @@ while (0)
|
||||
|
||||
/* Like `CALL_USED_REGISTERS' but used to overcome a historical
|
||||
problem which makes CALL_USED_REGISTERS *always* include
|
||||
all the FIXED_REGISTERS. Until this problem has been
|
||||
all the FIXED_REGISTERS. Until this problem has been
|
||||
resolved this macro can be used to overcome this situation.
|
||||
In particular, block_propagate() requires this list
|
||||
be acurate, or we can remove registers which should be live.
|
||||
This macro is used in regs_invalidated_by_call ()*/
|
||||
This macro is used in regs_invalidated_by_call. */
|
||||
|
||||
#define CALL_REALLY_USED_REGISTERS \
|
||||
{ /* General registers. */ \
|
||||
@ -668,7 +668,7 @@ while (0)
|
||||
/* Branch registers. */ \
|
||||
1, 0, 0, 0, 0, 0, 1, 1, \
|
||||
/*FP RA CCV UNAT PFS LC EC */ \
|
||||
0, 0, 1, 1, 1, 0, 0 \
|
||||
0, 0, 1, 0, 1, 0, 0 \
|
||||
}
|
||||
|
||||
|
||||
@ -2667,6 +2667,7 @@ do { \
|
||||
{ "condop_operator", {PLUS, MINUS, IOR, XOR, AND}}, \
|
||||
{ "ar_lc_reg_operand", {REG}}, \
|
||||
{ "ar_ccv_reg_operand", {REG}}, \
|
||||
{ "ar_pfs_reg_operand", {REG}}, \
|
||||
{ "general_tfmode_operand", {SUBREG, REG, CONST_DOUBLE, MEM}}, \
|
||||
{ "destination_tfmode_operand", {SUBREG, REG, MEM}}, \
|
||||
{ "tfreg_or_fp01_operand", {REG, CONST_DOUBLE}},
|
||||
|
@ -4673,7 +4673,8 @@
|
||||
(define_insn "sibcall_nopic"
|
||||
[(call (mem:DI (match_operand:DI 0 "call_operand" "b,i"))
|
||||
(match_operand 1 "" ""))
|
||||
(use (match_operand:DI 2 "register_operand" "=b,b"))]
|
||||
(use (match_operand:DI 2 "register_operand" "=b,b"))
|
||||
(use (match_operand:DI 3 "ar_pfs_reg_operand" ""))]
|
||||
""
|
||||
"br%+.many %0"
|
||||
[(set_attr "itanium_class" "br,scall")])
|
||||
@ -4701,7 +4702,8 @@
|
||||
[(call (mem:DI (match_operand:DI 0 "call_operand" "bi"))
|
||||
(match_operand 1 "" ""))
|
||||
(use (unspec [(reg:DI 1)] 9))
|
||||
(use (match_operand:DI 2 "register_operand" "=b"))]
|
||||
(use (match_operand:DI 2 "register_operand" "=b"))
|
||||
(use (match_operand:DI 3 "ar_pfs_reg_operand" ""))]
|
||||
""
|
||||
"br%+.many %0"
|
||||
[(set_attr "itanium_class" "br")])
|
||||
|
@ -4814,7 +4814,8 @@ mark_regs_live_at_end (set)
|
||||
{
|
||||
/* Mark all call-saved registers that we actually used. */
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
if (regs_ever_live[i] && ! call_used_regs[i] && ! LOCAL_REGNO (i))
|
||||
if (regs_ever_live[i] && ! LOCAL_REGNO (i)
|
||||
&& ! TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
|
||||
SET_REGNO_REG_SET (set, i);
|
||||
}
|
||||
|
||||
|
@ -474,7 +474,7 @@ init_reg_sets_1 ()
|
||||
;
|
||||
#endif
|
||||
else if (0
|
||||
#ifdef CALL_REALLY_USED_REGS
|
||||
#ifdef CALL_REALLY_USED_REGISTERS
|
||||
|| call_really_used_regs[i]
|
||||
#else
|
||||
|| call_used_regs[i]
|
||||
|
Loading…
Reference in New Issue
Block a user