output.h (current_function_is_leaf, [...]): Declare.

* 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.

From-SVN: r26538
This commit is contained in:
John Wehle 1999-04-18 13:09:37 +00:00 committed by John Wehle
parent fbdd002411
commit 54ff41b717
14 changed files with 96 additions and 30 deletions

View File

@ -1,3 +1,30 @@
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) Sun Apr 18 02:15:09 PDT 1999 Jeff Law (law@cygnus.com)
* version.c: Bump for snapshot. * version.c: Bump for snapshot.
@ -1150,7 +1177,7 @@ Fri Apr 2 14:12:06 1999 John Wehle (john@feith.com)
* i386.md: Delete floating point compare, add, subtract, * i386.md: Delete floating point compare, add, subtract,
multiply, and divide patterns which allowed integer multiply, and divide patterns which allowed integer
operands. operands.
* i386.c (output_386_binary_op): Delete unused code. * i386.c (output_387_binary_op): Delete unused code.
(output_float_compare): Likewise. (output_float_compare): Likewise.
Fri Apr 2 11:53:37 1999 John Wehle (john@feith.com) Fri Apr 2 11:53:37 1999 John Wehle (john@feith.com)

View File

@ -1990,6 +1990,11 @@ ix86_compute_frame_size (size, nregs_on_stack)
if (padding < (((offset + preferred_alignment - 1) if (padding < (((offset + preferred_alignment - 1)
& -preferred_alignment) - offset)) & -preferred_alignment) - offset))
padding += preferred_alignment; 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 #endif

View File

@ -2230,7 +2230,7 @@ eligible_for_epilogue_delay (trial, slot)
/* In the case of a true leaf function, anything can go into the delay slot. /* 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 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. */ 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 ()) if (leaf_return_peephole_ok ())
return ((get_attr_in_uncond_branch_delay (trial) return ((get_attr_in_uncond_branch_delay (trial)
@ -4686,7 +4686,7 @@ output_return (operands)
operands[0] = leaf_label; operands[0] = leaf_label;
return "b%* %l0%("; return "b%* %l0%(";
} }
else if (leaf_function) else if (current_function_uses_only_leaf_regs)
{ {
/* No delay slot in a leaf function. */ /* No delay slot in a leaf function. */
if (delay) if (delay)
@ -7524,7 +7524,7 @@ sparc_return_peephole_ok (dest, src)
{ {
if (! TARGET_V9) if (! TARGET_V9)
return 0; return 0;
if (leaf_function) if (current_function_uses_only_leaf_regs)
return 0; return 0;
if (GET_CODE (src) != CONST_INT if (GET_CODE (src) != CONST_INT
&& (GET_CODE (src) != REG || ! IN_OR_GLOBAL_P (src))) && (GET_CODE (src) != REG || ! IN_OR_GLOBAL_P (src)))

View File

@ -1838,10 +1838,10 @@ do { \
to do a "save" insn. The decision about whether or not to do a "save" insn. The decision about whether or not
to do this is made in regclass.c. */ to do this is made in regclass.c. */
extern int leaf_function;
#define FUNCTION_PROLOGUE(FILE, SIZE) \ #define FUNCTION_PROLOGUE(FILE, SIZE) \
(TARGET_FLAT ? sparc_flat_output_function_prologue (FILE, (int)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))
/* Output assembler code to FILE to increment profiler label # LABELNO /* Output assembler code to FILE to increment profiler label # LABELNO
for profiling a function entry. for profiling a function entry.
@ -2216,7 +2216,8 @@ extern union tree_node *current_function_decl;
#define FUNCTION_EPILOGUE(FILE, SIZE) \ #define FUNCTION_EPILOGUE(FILE, SIZE) \
(TARGET_FLAT ? sparc_flat_output_function_epilogue (FILE, (int)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 \ #define DELAY_SLOTS_FOR_EPILOGUE \
(TARGET_FLAT ? sparc_flat_epilogue_delay_slots () : 1) (TARGET_FLAT ? sparc_flat_epilogue_delay_slots () : 1)

View File

@ -159,7 +159,7 @@
[(eq_attr "in_call_delay" "true") (nil) (nil)]) [(eq_attr "in_call_delay" "true") (nil) (nil)])
(define_attr "leaf_function" "false,true" (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" (define_attr "in_return_delay" "false,true"
(if_then_else (and (and (and (eq_attr "type" "move,load,sload,store,binary,ialu") (if_then_else (and (and (and (eq_attr "type" "move,load,sload,store,binary,ialu")
@ -7618,7 +7618,8 @@
if (! TARGET_ARCH64) 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); rtx value = gen_reg_rtx (SImode);
/* Fetch the instruction where we will return to and see if it's an unimp /* Fetch the instruction where we will return to and see if it's an unimp

View File

@ -1937,7 +1937,7 @@ dbxout_symbol (decl, local)
DECL_RTL (decl) = eliminate_regs (DECL_RTL (decl), 0, NULL_RTX); DECL_RTL (decl) = eliminate_regs (DECL_RTL (decl), 0, NULL_RTX);
#ifdef LEAF_REG_REMAP #ifdef LEAF_REG_REMAP
if (leaf_function) if (current_function_uses_only_leaf_regs)
leaf_renumber_regs_insn (DECL_RTL (decl)); leaf_renumber_regs_insn (DECL_RTL (decl));
#endif #endif
@ -2259,7 +2259,7 @@ dbxout_parms (parms)
= eliminate_regs (DECL_INCOMING_RTL (parms), 0, NULL_RTX); = eliminate_regs (DECL_INCOMING_RTL (parms), 0, NULL_RTX);
DECL_RTL (parms) = eliminate_regs (DECL_RTL (parms), 0, NULL_RTX); DECL_RTL (parms) = eliminate_regs (DECL_RTL (parms), 0, NULL_RTX);
#ifdef LEAF_REG_REMAP #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_INCOMING_RTL (parms));
leaf_renumber_regs_insn (DECL_RTL (parms)); leaf_renumber_regs_insn (DECL_RTL (parms));

View File

@ -7207,7 +7207,7 @@ add_location_or_const_value_attribute (die, decl)
rtl = eliminate_regs (rtl, 0, NULL_RTX); rtl = eliminate_regs (rtl, 0, NULL_RTX);
#ifdef LEAF_REG_REMAP #ifdef LEAF_REG_REMAP
if (leaf_function) if (current_function_uses_only_leaf_regs)
leaf_renumber_regs_insn (rtl); leaf_renumber_regs_insn (rtl);
#endif #endif

View File

@ -2421,7 +2421,7 @@ location_or_const_value_attribute (decl)
rtl = eliminate_regs (rtl, 0, NULL_RTX); rtl = eliminate_regs (rtl, 0, NULL_RTX);
#ifdef LEAF_REG_REMAP #ifdef LEAF_REG_REMAP
if (leaf_function) if (current_function_uses_only_leaf_regs)
leaf_renumber_regs_insn (rtl); leaf_renumber_regs_insn (rtl);
#endif #endif

View File

@ -131,11 +131,6 @@ Boston, MA 02111-1307, USA. */
#define JUMP_TABLES_IN_TEXT_SECTION 0 #define JUMP_TABLES_IN_TEXT_SECTION 0
#endif #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. */ /* Last insn processed by final_scan_insn. */
static rtx debug_insn = 0; static rtx debug_insn = 0;
@ -1634,7 +1629,7 @@ final_start_function (first, file, optimize)
output_source_line (file, first); output_source_line (file, first);
#ifdef LEAF_REG_REMAP #ifdef LEAF_REG_REMAP
if (leaf_function) if (current_function_uses_only_leaf_regs)
leaf_renumber_regs (first); leaf_renumber_regs (first);
#endif #endif

View File

@ -140,12 +140,25 @@ int current_function_has_nonlocal_goto;
int current_function_contains_functions; 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 /* Nonzero if function being compiled doesn't modify the stack pointer
(ignoring the prologue and epilogue). This is only valid after (ignoring the prologue and epilogue). This is only valid after
life_analysis has run. */ life_analysis has run. */
int current_function_sp_is_unchanging; 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. */ /* Nonzero if the function being compiled issues a computed jump. */
int current_function_has_computed_jump; int current_function_has_computed_jump;
@ -5897,7 +5910,9 @@ init_function_start (subr, filename, line)
current_function_has_nonlocal_label = 0; current_function_has_nonlocal_label = 0;
current_function_has_nonlocal_goto = 0; current_function_has_nonlocal_goto = 0;
current_function_contains_functions = 0; current_function_contains_functions = 0;
current_function_is_leaf = 0;
current_function_sp_is_unchanging = 0; current_function_sp_is_unchanging = 0;
current_function_uses_only_leaf_regs = 0;
current_function_has_computed_jump = 0; current_function_has_computed_jump = 0;
current_function_is_thunk = 0; current_function_is_thunk = 0;

View File

@ -383,12 +383,25 @@ extern int current_function_has_nonlocal_label;
extern int current_function_contains_functions; 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 /* Nonzero if function being compiled doesn't modify the stack pointer
(ignoring the prologue and epilogue). This is only valid after (ignoring the prologue and epilogue). This is only valid after
life_analysis has run. */ life_analysis has run. */
extern int current_function_sp_is_unchanging; 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. */ /* Nonzero if the function being compiled issues a computed jump. */
extern int current_function_has_computed_jump; extern int current_function_has_computed_jump;

View File

@ -811,7 +811,7 @@ sdbout_symbol (decl, local)
DECL_RTL (decl) = eliminate_regs (DECL_RTL (decl), 0, NULL_RTX); DECL_RTL (decl) = eliminate_regs (DECL_RTL (decl), 0, NULL_RTX);
#ifdef LEAF_REG_REMAP #ifdef LEAF_REG_REMAP
if (leaf_function) if (current_function_uses_only_leaf_regs)
leaf_renumber_regs_insn (DECL_RTL (decl)); leaf_renumber_regs_insn (DECL_RTL (decl));
#endif #endif
value = DECL_RTL (decl); value = DECL_RTL (decl);

View File

@ -1642,12 +1642,17 @@ treatment of leaf functions, and registers need to be renumbered to do
this. this.
@end table @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 Normally, @code{FUNCTION_PROLOGUE} and @code{FUNCTION_EPILOGUE} must
treat leaf functions specially. It can test the C variable treat leaf functions specially. They can test the C variable
@code{leaf_function} which is nonzero for leaf functions. (The variable @code{current_function_is_leaf} which is nonzero for leaf functions.
@code{leaf_function} is defined only if @code{LEAF_REGISTERS} is @code{current_function_is_leaf} is set prior to local register allocation
defined.) 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 changed this to fix overfull. ALSO: why the "it" at the beginning
@c of the next paragraph?! --mew 2feb93 @c of the next paragraph?! --mew 2feb93
@ -3296,7 +3301,7 @@ argument lists of the function. @xref{Stack Arguments}.
Normally, it is necessary for the macros @code{FUNCTION_PROLOGUE} and Normally, it is necessary for the macros @code{FUNCTION_PROLOGUE} and
@code{FUNCTION_EPILOGUE} to treat leaf functions specially. The C @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 @findex EXIT_IGNORE_STACK
@item EXIT_IGNORE_STACK @item EXIT_IGNORE_STACK
@ -3346,8 +3351,8 @@ is wanted, the macro can refer to the variable
a function that needs a frame pointer. a function that needs a frame pointer.
Normally, @code{FUNCTION_PROLOGUE} and @code{FUNCTION_EPILOGUE} must Normally, @code{FUNCTION_PROLOGUE} and @code{FUNCTION_EPILOGUE} must
treat leaf functions specially. The C variable @code{leaf_function} is treat leaf functions specially. The C variable @code{current_function_is_leaf}
nonzero for such a function. @xref{Leaf Functions}. is nonzero for such a function. @xref{Leaf Functions}.
On some machines, some functions pop their arguments on exit while On some machines, some functions pop their arguments on exit while
others leave that for the caller to do. For example, the 68020 when others leave that for the caller to do. For example, the 68020 when

View File

@ -4089,6 +4089,11 @@ rest_of_compilation (decl)
} }
} }
/* 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, /* Unless we did stupid register allocation,
allocate pseudo-regs that are used only within 1 basic block. allocate pseudo-regs that are used only within 1 basic block.
@ -4235,9 +4240,8 @@ rest_of_compilation (decl)
} }
#ifdef LEAF_REGISTERS #ifdef LEAF_REGISTERS
leaf_function = 0;
if (optimize > 0 && only_leaf_regs_used () && leaf_function_p ()) if (optimize > 0 && only_leaf_regs_used () && leaf_function_p ())
leaf_function = 1; current_function_uses_only_leaf_regs = 1;
#endif #endif
/* One more attempt to remove jumps to .+1 /* One more attempt to remove jumps to .+1