From 54ff41b717adbdea60052aaf1ae686b518acbffb Mon Sep 17 00:00:00 2001 From: John Wehle Date: Sun, 18 Apr 1999 13:09:37 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 29 ++++++++++++++++++++++++++++- gcc/config/i386/i386.c | 5 +++++ gcc/config/sparc/sparc.c | 6 +++--- gcc/config/sparc/sparc.h | 7 ++++--- gcc/config/sparc/sparc.md | 5 +++-- gcc/dbxout.c | 4 ++-- gcc/dwarf2out.c | 2 +- gcc/dwarfout.c | 2 +- gcc/final.c | 7 +------ gcc/function.c | 15 +++++++++++++++ gcc/output.h | 13 +++++++++++++ gcc/sdbout.c | 2 +- gcc/tm.texi | 21 +++++++++++++-------- gcc/toplev.c | 8 ++++++-- 14 files changed, 96 insertions(+), 30 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a092483e99c..37cb3f08a9e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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) * 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, 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) diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index dab03008ac2..4faff7b9d14 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -1990,6 +1990,11 @@ ix86_compute_frame_size (size, nregs_on_stack) 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 diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 05affdd5289..49502422031 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -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. 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) @@ -4686,7 +4686,7 @@ output_return (operands) 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) @@ -7524,7 +7524,7 @@ sparc_return_peephole_ok (dest, src) { 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))) diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index b37b5e9eef5..a220ce741f8 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -1838,10 +1838,10 @@ do { \ 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)) /* Output assembler code to FILE to increment profiler label # LABELNO for profiling a function entry. @@ -2216,7 +2216,8 @@ extern union tree_node *current_function_decl; #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) diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index c1adf93bbda..025992a354c 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -159,7 +159,7 @@ [(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") @@ -7618,7 +7618,8 @@ 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 diff --git a/gcc/dbxout.c b/gcc/dbxout.c index 07122ecb97f..bc15a4d5411 100644 --- a/gcc/dbxout.c +++ b/gcc/dbxout.c @@ -1937,7 +1937,7 @@ dbxout_symbol (decl, local) 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 @@ -2259,7 +2259,7 @@ dbxout_parms (parms) = 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)); diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 393dbc54323..659b119f4bd 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -7207,7 +7207,7 @@ add_location_or_const_value_attribute (die, decl) 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 diff --git a/gcc/dwarfout.c b/gcc/dwarfout.c index 388c4a40081..ac17f7fb196 100644 --- a/gcc/dwarfout.c +++ b/gcc/dwarfout.c @@ -2421,7 +2421,7 @@ location_or_const_value_attribute (decl) 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 diff --git a/gcc/final.c b/gcc/final.c index 3cd2e0cb989..bacc0932249 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -131,11 +131,6 @@ Boston, MA 02111-1307, USA. */ #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; @@ -1634,7 +1629,7 @@ final_start_function (first, file, optimize) output_source_line (file, first); #ifdef LEAF_REG_REMAP - if (leaf_function) + if (current_function_uses_only_leaf_regs) leaf_renumber_regs (first); #endif diff --git a/gcc/function.c b/gcc/function.c index ac55f3a0c8b..30357865d73 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -140,12 +140,25 @@ int current_function_has_nonlocal_goto; 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; @@ -5897,7 +5910,9 @@ init_function_start (subr, filename, line) 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; diff --git a/gcc/output.h b/gcc/output.h index 7e1c28bd7e5..e1cf6d82950 100644 --- a/gcc/output.h +++ b/gcc/output.h @@ -383,12 +383,25 @@ extern int current_function_has_nonlocal_label; 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; diff --git a/gcc/sdbout.c b/gcc/sdbout.c index 1f13899cfe8..0aebd834d23 100644 --- a/gcc/sdbout.c +++ b/gcc/sdbout.c @@ -811,7 +811,7 @@ sdbout_symbol (decl, local) 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); diff --git a/gcc/tm.texi b/gcc/tm.texi index 8e6797a9e7f..ac6e6beae53 100644 --- a/gcc/tm.texi +++ b/gcc/tm.texi @@ -1642,12 +1642,17 @@ treatment of leaf functions, and registers need to be renumbered to do 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 @@ -3296,7 +3301,7 @@ argument lists of the function. @xref{Stack Arguments}. 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 @@ -3346,8 +3351,8 @@ is wanted, the macro can refer to the variable 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 diff --git a/gcc/toplev.c b/gcc/toplev.c index 482b956795c..7b3c31c92bd 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -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, allocate pseudo-regs that are used only within 1 basic block. @@ -4235,9 +4240,8 @@ rest_of_compilation (decl) } #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 -- 2.30.2