This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
ia64 prologue/epilogue rewrite 1/N
- To: gcc-patches at gcc dot gnu dot org
- Subject: ia64 prologue/epilogue rewrite 1/N
- From: Richard Henderson <rth at cygnus dot com>
- Date: Tue, 8 Aug 2000 01:33:52 -0700
I'm going to try to break this up into as distinct many pieces as
possible, especially where generic code is concerned; last I checked
the whole thing was 350k. Do note, however, that I havn't tested
each of these separately.
The following allows a target to tell flow that some registers do
not contain live data at function exit, despite being marked as
call-saved. This might have been seen on Sparc and others, had
they emitted epilogues as rtl.
This doesn't actually affect code correctness, merely code quality.
r~
* tm.texi (LOCAL_REGNO): Document.
* flow.c (LOCAL_REGNO, EPILOGUE_USES): Provide default.
(mark_regs_live_at_end): Don't mark LOCAL_REGNO registers.
* reload1.c (reload): Likewise when considering nonlocal labels.
* config/ia64/ia64.h (LOCAL_REGNO): New.
* config/sparc/sparc.h (LOCAL_REGNO): New.
Index: flow.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/flow.c,v
retrieving revision 1.319
diff -c -p -d -r1.319 flow.c
*** flow.c 2000/08/07 07:07:21 1.319
--- flow.c 2000/08/08 08:21:28
*************** Boston, MA 02111-1307, USA. */
*** 163,168 ****
--- 163,175 ----
#define HAVE_sibcall_epilogue 0
#endif
+ #ifndef LOCAL_REGNO
+ #define LOCAL_REGNO(REGNO) 0
+ #endif
+ #ifndef EPILOGUE_USES
+ #define EPILOGUE_USES(REGNO) 0
+ #endif
+
/* The contents of the current function definition are allocated
in this obstack, and all are freed at the end of the function.
For top-level functions, this is temporary_obstack.
*************** mark_regs_live_at_end (set)
*** 3051,3058 ****
{
SET_REGNO_REG_SET (set, FRAME_POINTER_REGNUM);
#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
! /* If they are different, also mark the hard frame pointer as live */
! SET_REGNO_REG_SET (set, HARD_FRAME_POINTER_REGNUM);
#endif
}
--- 3058,3066 ----
{
SET_REGNO_REG_SET (set, FRAME_POINTER_REGNUM);
#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
! /* If they are different, also mark the hard frame pointer as live. */
! if (! LOCAL_REGNO (HARD_FRAME_POINTER_REGNUM))
! SET_REGNO_REG_SET (set, HARD_FRAME_POINTER_REGNUM);
#endif
}
*************** mark_regs_live_at_end (set)
*** 3070,3087 ****
as being live at the end of the function since they may be
referenced by our caller. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! if (global_regs[i]
! #ifdef EPILOGUE_USES
! || EPILOGUE_USES (i)
! #endif
! )
SET_REGNO_REG_SET (set, i);
/* Mark all call-saved registers that we actaully used. */
if (HAVE_epilogue && reload_completed)
{
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! if (! call_used_regs[i] && regs_ever_live[i])
SET_REGNO_REG_SET (set, i);
}
--- 3078,3091 ----
as being live at the end of the function since they may be
referenced by our caller. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! if (global_regs[i] || EPILOGUE_USES (i))
SET_REGNO_REG_SET (set, i);
/* Mark all call-saved registers that we actaully used. */
if (HAVE_epilogue && reload_completed)
{
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! if (regs_ever_live[i] && ! call_used_regs[i] && ! LOCAL_REGNO (i))
SET_REGNO_REG_SET (set, i);
}
Index: reload1.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/reload1.c,v
retrieving revision 1.219
diff -c -p -d -r1.219 reload1.c
*** reload1.c 2000/08/04 20:28:05 1.219
--- reload1.c 2000/08/08 08:21:29
*************** Boston, MA 02111-1307, USA. */
*** 85,90 ****
--- 85,94 ----
#ifndef REGISTER_MOVE_COST
#define REGISTER_MOVE_COST(x, y) 2
#endif
+
+ #ifndef LOCAL_REGNO
+ #define LOCAL_REGNO(REGNO) 0
+ #endif
/* During reload_as_needed, element N contains a REG rtx for the hard reg
into which reg N has been reloaded (perhaps for a previous insn). */
*************** reload (first, global, dumpfile)
*** 654,663 ****
registers. */
if (current_function_has_nonlocal_label)
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! {
! if (! call_used_regs[i] && ! fixed_regs[i])
! regs_ever_live[i] = 1;
! }
/* Find all the pseudo registers that didn't get hard regs
but do have known equivalent constants or memory slots.
--- 658,665 ----
registers. */
if (current_function_has_nonlocal_label)
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! if (! call_used_regs[i] && ! fixed_regs[i] && ! LOCAL_REGNO (i))
! regs_ever_live[i] = 1;
/* Find all the pseudo registers that didn't get hard regs
but do have known equivalent constants or memory slots.
Index: tm.texi
===================================================================
RCS file: /cvs/gcc/egcs/gcc/tm.texi,v
retrieving revision 1.137
diff -c -p -d -r1.137 tm.texi
*** tm.texi 2000/08/06 17:50:07 1.137
--- tm.texi 2000/08/08 08:21:30
*************** corresponding to the register number @va
*** 1489,1494 ****
--- 1489,1502 ----
function. Return @var{in} if register number @var{in} is not an inbound
register.
+ @findex LOCAL_REGNO
+ @item LOCAL_REGNO (@var{regno})
+ Define this macro if the target machine has register windows. This C
+ expression returns true if the register is call-saved but is in the
+ register window. Unlike most call-saved registers, such registers
+ need not be explicitly restored on function exit or during non-local
+ gotos.
+
@ignore
@findex PC_REGNUM
@item PC_REGNUM
Index: config/ia64/ia64.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/ia64/ia64.h,v
retrieving revision 1.31
diff -c -p -d -r1.31 ia64.h
*** ia64.h 2000/07/30 23:57:59 1.31
--- ia64.h 2000/08/08 08:21:31
*************** while (0)
*** 686,691 ****
--- 686,697 ----
#define OUTGOING_REGNO(IN) \
((unsigned) ((IN) - IN_REG (0)) < 8 ? OUT_REG ((IN) - IN_REG (0)) : (IN))
+ /* Define this macro if the target machine has register windows. This
+ C expression returns true if the register is call-saved but is in the
+ register window. */
+
+ #define LOCAL_REGNO(REGNO) \
+ (IN_REGNO_P (REGNO) || LOC_REGNO_P (REGNO))
/* Order of allocation of registers */
Index: config/sparc/sparc.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/sparc/sparc.h,v
retrieving revision 1.115
diff -c -p -d -r1.115 sparc.h
*** sparc.h 2000/06/27 02:26:23 1.115
--- sparc.h 2000/08/08 08:21:33
*************** extern char leaf_reg_remap[];
*** 1711,1716 ****
--- 1711,1723 ----
#define OUTGOING_REGNO(IN) \
((TARGET_FLAT || (IN) < 24 || (IN) > 31) ? (IN) : (IN) - 16)
+ /* Define this macro if the target machine has register windows. This
+ C expression returns true if the register is call-saved but is in the
+ register window. */
+
+ #define LOCAL_REGNO(REGNO) \
+ (TARGET_FLAT ? 0 : (REGNO) >= 16 && (REGNO) <= 31)
+
/* Define how to find the value returned by a function.
VALTYPE is the data type of the value (as a tree).
If the precise function being called is known, FUNC is its FUNCTION_DECL;