Commit 6ca3c22f by Richard Henderson Committed by Richard Henderson

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