Minor performance improvements. Minor EH/unwind bug fix.
* config/ia64/ia64.c (ia64_expand_prologue): Don't abort if leaf function uses output registers. Don't save RP for leaf functions. Do save RP even if no epilogue. * config/ia64/ia64.h (FIXED_REGISTERS): Unmark in/out registers. (CALL_USED_REGISTERS): Unmark in registers. (REG_ALLOC_ORDER): Move out regs up, to near the top. Move in regs up, to near the middle. From-SVN: r32661
This commit is contained in:
parent
c1f6390295
commit
1ff5b671b6
|
@ -1,3 +1,13 @@
|
|||
Mon Mar 20 19:53:53 2000 Jim Wilson <wilson@cygnus.com>
|
||||
|
||||
* config/ia64/ia64.c (ia64_expand_prologue): Don't abort if leaf
|
||||
function uses output registers. Don't save RP for leaf functions.
|
||||
Do save RP even if no epilogue.
|
||||
* config/ia64/ia64.h (FIXED_REGISTERS): Unmark in/out registers.
|
||||
(CALL_USED_REGISTERS): Unmark in registers.
|
||||
(REG_ALLOC_ORDER): Move out regs up, to near the top. Move in regs up,
|
||||
to near the middle.
|
||||
|
||||
2000-03-20 Geoff Keating <geoffk@cygnus.com>
|
||||
|
||||
* config/rs6000/rs6000.md (bunordered): New expander.
|
||||
|
|
|
@ -775,12 +775,6 @@ save_restore_insns (save_p)
|
|||
/* ??? Get inefficient code when the frame size is larger than can fit in an
|
||||
adds instruction. */
|
||||
|
||||
/* ??? Add support for allocating temporaries from the output registers if
|
||||
they do not need to live past call instructions. */
|
||||
|
||||
/* ??? If the function does not return, then we don't need to save the rp
|
||||
and ar.pfs registers. */
|
||||
|
||||
/* ??? If this is a leaf function, then fp/rp/ar.pfs should be put in the
|
||||
low 32 regs. */
|
||||
|
||||
|
@ -807,7 +801,7 @@ ia64_expand_prologue ()
|
|||
leaf_function = leaf_function_p ();
|
||||
pop_topmost_sequence ();
|
||||
|
||||
/* ??? If there is no epilogue, then we don't need some prologue insns. We
|
||||
/* If there is no epilogue, then we don't need some prologue insns. We
|
||||
need to avoid emitting the dead prologue insns, because flow will complain
|
||||
about them. */
|
||||
if (optimize)
|
||||
|
@ -863,10 +857,6 @@ ia64_expand_prologue ()
|
|||
else if (profile_block_flag == 2)
|
||||
outputs = MAX (outputs, 2);
|
||||
|
||||
/* Leaf functions should not use any output registers. */
|
||||
if (leaf_function && outputs != 0)
|
||||
abort ();
|
||||
|
||||
/* No rotating register support as yet. */
|
||||
|
||||
rotates = 0;
|
||||
|
@ -874,6 +864,8 @@ ia64_expand_prologue ()
|
|||
/* Allocate two extra locals for saving/restoring rp and ar.pfs. Also
|
||||
allocate one local for use as the frame pointer if frame_pointer_needed
|
||||
is true. */
|
||||
/* ??? If this is a leaf function, then we aren't using one of these local
|
||||
registers for the RP anymore. */
|
||||
locals += 2 + frame_pointer_needed;
|
||||
|
||||
/* Save these values in global registers for debugging info. */
|
||||
|
@ -925,6 +917,7 @@ ia64_expand_prologue ()
|
|||
/* We don't need an alloc instruction if this is a leaf function, and the
|
||||
locals and outputs are both zero sized. Since we have already allocated
|
||||
two locals for rp and ar.pfs, we check for two locals. */
|
||||
/* Leaf functions can use output registers as call-clobbered temporaries. */
|
||||
if (locals == 2 && outputs == 0 && leaf_function)
|
||||
{
|
||||
/* If there is no alloc, but there are input registers used, then we
|
||||
|
@ -940,21 +933,36 @@ ia64_expand_prologue ()
|
|||
else
|
||||
{
|
||||
ia64_need_regstk = 0;
|
||||
|
||||
ia64_arpfs_regno = LOC_REG (locals - 1);
|
||||
ia64_rp_regno = LOC_REG (locals - 2);
|
||||
reg_names[RETURN_ADDRESS_REGNUM] = reg_names[ia64_rp_regno];
|
||||
|
||||
emit_insn (gen_alloc (gen_rtx_REG (DImode, ia64_arpfs_regno),
|
||||
GEN_INT (inputs), GEN_INT (locals),
|
||||
GEN_INT (outputs), GEN_INT (rotates)));
|
||||
|
||||
/* ??? FIXME ??? We don't need to save BR_REG (0) if this is a leaf
|
||||
function. We also don't need to allocate a local reg for it then. */
|
||||
/* ??? Likewise if there is no epilogue. */
|
||||
if (epilogue_p)
|
||||
emit_move_insn (gen_rtx_REG (DImode, ia64_rp_regno),
|
||||
gen_rtx_REG (DImode, BR_REG (0)));
|
||||
/* Emit a save of BR_REG (0) if we call other functions.
|
||||
Do this even if this function doesn't return, as EH
|
||||
depends on this to be able to unwind the stack. */
|
||||
if (! leaf_function)
|
||||
{
|
||||
rtx ia64_rp_reg;
|
||||
|
||||
ia64_rp_regno = LOC_REG (locals - 2);
|
||||
reg_names[RETURN_ADDRESS_REGNUM] = reg_names[ia64_rp_regno];
|
||||
|
||||
ia64_rp_reg = gen_rtx_REG (DImode, ia64_rp_regno);
|
||||
insn = emit_move_insn (ia64_rp_reg, gen_rtx_REG (DImode,
|
||||
BR_REG (0)));
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
if (! epilogue_p)
|
||||
{
|
||||
/* If we don't have an epilogue, then the return value
|
||||
doesn't appear to be needed and the above store will
|
||||
appear dead and will elicit a warning from flow. */
|
||||
emit_insn (gen_rtx_USE (VOIDmode, ia64_rp_reg));
|
||||
}
|
||||
}
|
||||
else
|
||||
ia64_rp_regno = 0;
|
||||
}
|
||||
|
||||
/* Set up frame pointer and stack pointer. */
|
||||
|
|
|
@ -577,16 +577,14 @@ while (0)
|
|||
p0: constant true
|
||||
fp: eliminable frame pointer */
|
||||
|
||||
/* The last 16 stacked regs are fixed, because they are reserved for the 8
|
||||
input and 8 output registers. */
|
||||
/* The last 16 stacked regs are reserved for the 8 input and 8 output
|
||||
registers. */
|
||||
|
||||
/* ??? Must mark the next 3 stacked regs as fixed, because ia64_expand_prologue
|
||||
assumes that three locals are available for fp, b0, and ar.pfs. */
|
||||
|
||||
/* ??? Should mark b0 as fixed? */
|
||||
|
||||
/* ??? input and output registers do not have to be marked as fixed. */
|
||||
|
||||
#define FIXED_REGISTERS \
|
||||
{ /* General registers. */ \
|
||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, \
|
||||
|
@ -596,7 +594,7 @@ while (0)
|
|||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, \
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
/* Floating-point registers. */ \
|
||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
|
@ -622,8 +620,6 @@ while (0)
|
|||
therefore identifies the registers that are not available for general
|
||||
allocation of values that must live across function calls. */
|
||||
|
||||
/* ??? If inputs are not marked as fixed, then they are not call clobbered. */
|
||||
|
||||
#define CALL_USED_REGISTERS \
|
||||
{ /* General registers. */ \
|
||||
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, \
|
||||
|
@ -633,7 +629,7 @@ while (0)
|
|||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, \
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, \
|
||||
/* Floating-point registers. */ \
|
||||
1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||
|
@ -689,11 +685,6 @@ while (0)
|
|||
/* ??? Should the GR return value registers come before or after the rest
|
||||
of the caller-save GRs? */
|
||||
|
||||
/* ??? Output registers are cheap, because they will be not be saved
|
||||
by the register engine. They probably should be early in the list.
|
||||
We need to make them not fixed first though. Similarly, input registers
|
||||
are callee-saved (RSE) like the stacked locals. */
|
||||
|
||||
#define REG_ALLOC_ORDER \
|
||||
{ \
|
||||
/* Caller-saved general registers. */ \
|
||||
|
@ -701,6 +692,9 @@ while (0)
|
|||
R_GR (18), R_GR (19), R_GR (20), R_GR (21), R_GR (22), R_GR (23), \
|
||||
R_GR (24), R_GR (25), R_GR (26), R_GR (27), R_GR (28), R_GR (29), \
|
||||
R_GR (30), R_GR (31), \
|
||||
/* Output registers. */ \
|
||||
R_GR (120), R_GR (121), R_GR (122), R_GR (123), R_GR (124), R_GR (125), \
|
||||
R_GR (126), R_GR (127), \
|
||||
/* Caller-saved general registers, also used for return values. */ \
|
||||
R_GR (8), R_GR (9), R_GR (10), R_GR (11), \
|
||||
/* addl caller-saved general registers. */ \
|
||||
|
@ -759,6 +753,9 @@ while (0)
|
|||
R_GR (96), R_GR (97), R_GR (98), R_GR (99), R_GR (100), R_GR (101), \
|
||||
R_GR (102), R_GR (103), R_GR (104), R_GR (105), R_GR (106), R_GR (107), \
|
||||
R_GR (108), \
|
||||
/* Input registers. */ \
|
||||
R_GR (112), R_GR (113), R_GR (114), R_GR (115), R_GR (116), R_GR (117), \
|
||||
R_GR (118), R_GR (119), \
|
||||
/* Callee-saved general registers. */ \
|
||||
R_GR (4), R_GR (5), R_GR (6), R_GR (7), \
|
||||
/* Callee-saved FP registers. */ \
|
||||
|
@ -773,12 +770,6 @@ while (0)
|
|||
\
|
||||
/* ??? Stacked registers reserved for fp, rp, and ar.pfs. */ \
|
||||
R_GR (109), R_GR (110), R_GR (111), \
|
||||
/* Input registers. */ \
|
||||
R_GR (112), R_GR (113), R_GR (114), R_GR (115), R_GR (116), R_GR (117), \
|
||||
R_GR (118), R_GR (119), \
|
||||
/* Output registers. */ \
|
||||
R_GR (120), R_GR (121), R_GR (122), R_GR (123), R_GR (124), R_GR (125), \
|
||||
R_GR (126), R_GR (127), \
|
||||
\
|
||||
/* Special general registers. */ \
|
||||
R_GR (0), R_GR (1), R_GR (12), R_GR (13), \
|
||||
|
|
Loading…
Reference in New Issue