current_function_uses_only_leaf_regs): Declare.
* function.c (current_function_is_leaf,
current_function_uses_only_leaf_regs): Define.
(init_function_start): Initialize current_function_is_leaf
and current_function_uses_only_leaf_regs.
* final.c (leaf_function): Don't define.
(final_start_function): Replace uses of leaf_function with
current_function_uses_only_leaf_regs.
* toplev.c (rest_of_compilation): Set current_function_is_leaf
prior to invoking local register allocation.
(rest_of_compilation): Replace uses of leaf_function with
current_function_uses_only_leaf_regs.
* dbxout.c (dbxout_symbol, dbxout_parms): Likewise.
* dwarf2out.c (add_location_or_const_vaule_attribute): Likewise.
* dwarfout.c (add_location_or_const_value_attribute): Likewise.
* sdbout.c (sdbout_symbol): Likewise.
* sparc.h (FUNCTION_PROLOGUE, FUNCTION_EPILOGUE): Likewise.
* sparc.c (eligible_for_epilogue_delay, output_return,
sparc_return_peephole_ok): Likewise.
* sparc.md (leaf_function attribute, untyped_return): Likewise.
* i386.c (ix86_compute_frame_size): Don't align the stack
for leaf functions which don't allocate any stack slots.
* tm.texi: Update documentation.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@26538
138bc75d-0d04-0410-961f-
82ee72b054a4
+Sun Apr 18 15:50:33 EDT 1999 John Wehle (john@feith.com)
+
+ * output.h (current_function_is_leaf,
+ current_function_uses_only_leaf_regs): Declare.
+ * function.c (current_function_is_leaf,
+ current_function_uses_only_leaf_regs): Define.
+ (init_function_start): Initialize current_function_is_leaf
+ and current_function_uses_only_leaf_regs.
+ * final.c (leaf_function): Don't define.
+ (final_start_function): Replace uses of leaf_function with
+ current_function_uses_only_leaf_regs.
+ * toplev.c (rest_of_compilation): Set current_function_is_leaf
+ prior to invoking local register allocation.
+ (rest_of_compilation): Replace uses of leaf_function with
+ current_function_uses_only_leaf_regs.
+ * dbxout.c (dbxout_symbol, dbxout_parms): Likewise.
+ * dwarf2out.c (add_location_or_const_vaule_attribute): Likewise.
+ * dwarfout.c (add_location_or_const_value_attribute): Likewise.
+ * sdbout.c (sdbout_symbol): Likewise.
+ * sparc.h (FUNCTION_PROLOGUE, FUNCTION_EPILOGUE): Likewise.
+ * sparc.c (eligible_for_epilogue_delay, output_return,
+ sparc_return_peephole_ok): Likewise.
+ * sparc.md (leaf_function attribute, untyped_return): Likewise.
+ * i386.c (ix86_compute_frame_size): Don't align the stack
+ for leaf functions which don't allocate any stack slots.
+ * tm.texi: Update documentation.
+
Sun Apr 18 02:15:09 PDT 1999 Jeff Law (law@cygnus.com)
* version.c: Bump for snapshot.
* i386.md: Delete floating point compare, add, subtract,
multiply, and divide patterns which allowed integer
operands.
- * i386.c (output_386_binary_op): Delete unused code.
+ * i386.c (output_387_binary_op): Delete unused code.
(output_float_compare): Likewise.
Fri Apr 2 11:53:37 1999 John Wehle (john@feith.com)
if (padding < (((offset + preferred_alignment - 1)
& -preferred_alignment) - offset))
padding += preferred_alignment;
+
+ /* Don't bother aligning the stack of a leaf function
+ which doesn't allocate any stack slots. */
+ if (size == 0 && current_function_is_leaf)
+ padding = 0;
}
#endif
/* In the case of a true leaf function, anything can go into the delay slot.
A delay slot only exists however if the frame size is zero, otherwise
we will put an insn to adjust the stack after the return. */
- if (leaf_function)
+ if (current_function_uses_only_leaf_regs)
{
if (leaf_return_peephole_ok ())
return ((get_attr_in_uncond_branch_delay (trial)
operands[0] = leaf_label;
return "b%* %l0%(";
}
- else if (leaf_function)
+ else if (current_function_uses_only_leaf_regs)
{
/* No delay slot in a leaf function. */
if (delay)
{
if (! TARGET_V9)
return 0;
- if (leaf_function)
+ if (current_function_uses_only_leaf_regs)
return 0;
if (GET_CODE (src) != CONST_INT
&& (GET_CODE (src) != REG || ! IN_OR_GLOBAL_P (src)))
to do a "save" insn. The decision about whether or not
to do this is made in regclass.c. */
-extern int leaf_function;
#define FUNCTION_PROLOGUE(FILE, SIZE) \
(TARGET_FLAT ? sparc_flat_output_function_prologue (FILE, (int)SIZE) \
- : output_function_prologue (FILE, (int)SIZE, leaf_function))
+ : output_function_prologue (FILE, (int)SIZE, \
+ current_function_uses_only_leaf_regs))
\f
/* Output assembler code to FILE to increment profiler label # LABELNO
for profiling a function entry.
#define FUNCTION_EPILOGUE(FILE, SIZE) \
(TARGET_FLAT ? sparc_flat_output_function_epilogue (FILE, (int)SIZE) \
- : output_function_epilogue (FILE, (int)SIZE, leaf_function))
+ : output_function_epilogue (FILE, (int)SIZE, \
+ current_function_uses_only_leaf_regs))
#define DELAY_SLOTS_FOR_EPILOGUE \
(TARGET_FLAT ? sparc_flat_epilogue_delay_slots () : 1)
[(eq_attr "in_call_delay" "true") (nil) (nil)])
(define_attr "leaf_function" "false,true"
- (const (symbol_ref "leaf_function")))
+ (const (symbol_ref "current_function_uses_only_leaf_regs")))
(define_attr "in_return_delay" "false,true"
(if_then_else (and (and (and (eq_attr "type" "move,load,sload,store,binary,ialu")
if (! TARGET_ARCH64)
{
- rtx rtnreg = gen_rtx_REG (SImode, (leaf_function ? 15 : 31));
+ rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
+ ? 15 : 31));
rtx value = gen_reg_rtx (SImode);
/* Fetch the instruction where we will return to and see if it's an unimp
DECL_RTL (decl) = eliminate_regs (DECL_RTL (decl), 0, NULL_RTX);
#ifdef LEAF_REG_REMAP
- if (leaf_function)
+ if (current_function_uses_only_leaf_regs)
leaf_renumber_regs_insn (DECL_RTL (decl));
#endif
= eliminate_regs (DECL_INCOMING_RTL (parms), 0, NULL_RTX);
DECL_RTL (parms) = eliminate_regs (DECL_RTL (parms), 0, NULL_RTX);
#ifdef LEAF_REG_REMAP
- if (leaf_function)
+ if (current_function_uses_only_leaf_regs)
{
leaf_renumber_regs_insn (DECL_INCOMING_RTL (parms));
leaf_renumber_regs_insn (DECL_RTL (parms));
rtl = eliminate_regs (rtl, 0, NULL_RTX);
#ifdef LEAF_REG_REMAP
- if (leaf_function)
+ if (current_function_uses_only_leaf_regs)
leaf_renumber_regs_insn (rtl);
#endif
rtl = eliminate_regs (rtl, 0, NULL_RTX);
#ifdef LEAF_REG_REMAP
- if (leaf_function)
+ if (current_function_uses_only_leaf_regs)
leaf_renumber_regs_insn (rtl);
#endif
#define JUMP_TABLES_IN_TEXT_SECTION 0
#endif
-/* Nonzero means this function is a leaf function, with no function calls.
- This variable exists to be examined in FUNCTION_PROLOGUE
- and FUNCTION_EPILOGUE. Always zero, unless set by some action. */
-int leaf_function;
-
/* Last insn processed by final_scan_insn. */
static rtx debug_insn = 0;
output_source_line (file, first);
#ifdef LEAF_REG_REMAP
- if (leaf_function)
+ if (current_function_uses_only_leaf_regs)
leaf_renumber_regs (first);
#endif
int current_function_contains_functions;
+/* Nonzero if function being compiled doesn't contain any calls
+ (ignoring the prologue and epilogue). This is set prior to
+ local register allocation and is valid for the remaining
+ compiler passes. */
+
+int current_function_is_leaf;
+
/* Nonzero if function being compiled doesn't modify the stack pointer
(ignoring the prologue and epilogue). This is only valid after
life_analysis has run. */
int current_function_sp_is_unchanging;
+/* Nonzero if the function being compiled is a leaf function which only
+ uses leaf registers. This is valid after reload (specifically after
+ sched2) and is useful only if the port defines LEAF_REGISTERS. */
+
+int current_function_uses_only_leaf_regs;
+
/* Nonzero if the function being compiled issues a computed jump. */
int current_function_has_computed_jump;
current_function_has_nonlocal_label = 0;
current_function_has_nonlocal_goto = 0;
current_function_contains_functions = 0;
+ current_function_is_leaf = 0;
current_function_sp_is_unchanging = 0;
+ current_function_uses_only_leaf_regs = 0;
current_function_has_computed_jump = 0;
current_function_is_thunk = 0;
extern int current_function_contains_functions;
+/* Nonzero if function being compiled doesn't contain any calls
+ (ignoring the prologue and epilogue). This is set prior to
+ local register allocation and is valid for the remaining
+ compiler passes. */
+
+extern int current_function_is_leaf;
+
/* Nonzero if function being compiled doesn't modify the stack pointer
(ignoring the prologue and epilogue). This is only valid after
life_analysis has run. */
extern int current_function_sp_is_unchanging;
+/* Nonzero if the function being compiled is a leaf function which only
+ uses leaf registers. This is valid after reload (specifically after
+ sched2) and is useful only if the port defines LEAF_REGISTERS. */
+
+extern int current_function_uses_only_leaf_regs;
+
/* Nonzero if the function being compiled issues a computed jump. */
extern int current_function_has_computed_jump;
DECL_RTL (decl) = eliminate_regs (DECL_RTL (decl), 0, NULL_RTX);
#ifdef LEAF_REG_REMAP
- if (leaf_function)
+ if (current_function_uses_only_leaf_regs)
leaf_renumber_regs_insn (DECL_RTL (decl));
#endif
value = DECL_RTL (decl);
this.
@end table
-@findex leaf_function
+@findex current_function_is_leaf
+@findex current_function_uses_only_leaf_regs
Normally, @code{FUNCTION_PROLOGUE} and @code{FUNCTION_EPILOGUE} must
-treat leaf functions specially. It can test the C variable
-@code{leaf_function} which is nonzero for leaf functions. (The variable
-@code{leaf_function} is defined only if @code{LEAF_REGISTERS} is
-defined.)
+treat leaf functions specially. They can test the C variable
+@code{current_function_is_leaf} which is nonzero for leaf functions.
+@code{current_function_is_leaf} is set prior to local register allocation
+and is valid for the remaining compiler passes. They can also test the C
+variable @code{current_function_uses_only_leaf_regs} which is nonzero for
+leaf functions which only use leaf registers.
+@code{current_function_uses_only_leaf_regs} is valid after reload and is
+only useful if @code{LEAF_REGISTERS} is defined.
@c changed this to fix overfull. ALSO: why the "it" at the beginning
@c of the next paragraph?! --mew 2feb93
Normally, it is necessary for the macros @code{FUNCTION_PROLOGUE} and
@code{FUNCTION_EPILOGUE} to treat leaf functions specially. The C
-variable @code{leaf_function} is nonzero for such a function.
+variable @code{current_function_is_leaf} is nonzero for such a function.
@findex EXIT_IGNORE_STACK
@item EXIT_IGNORE_STACK
a function that needs a frame pointer.
Normally, @code{FUNCTION_PROLOGUE} and @code{FUNCTION_EPILOGUE} must
-treat leaf functions specially. The C variable @code{leaf_function} is
-nonzero for such a function. @xref{Leaf Functions}.
+treat leaf functions specially. The C variable @code{current_function_is_leaf}
+is nonzero for such a function. @xref{Leaf Functions}.
On some machines, some functions pop their arguments on exit while
others leave that for the caller to do. For example, the 68020 when
}
}
+ /* Determine if the current function is a leaf before running reload
+ since this can impact optimizations done by the prologue and
+ epilogue thus changing register elimination offsets. */
+ current_function_is_leaf = leaf_function_p ();
+
/* Unless we did stupid register allocation,
allocate pseudo-regs that are used only within 1 basic block.
}
#ifdef LEAF_REGISTERS
- leaf_function = 0;
if (optimize > 0 && only_leaf_regs_used () && leaf_function_p ())
- leaf_function = 1;
+ current_function_uses_only_leaf_regs = 1;
#endif
/* One more attempt to remove jumps to .+1