Index: alpha/alpha.c =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/config/alpha/alpha.c,v retrieving revision 1.272.2.3 diff -u -p -r1.272.2.3 alpha.c --- alpha/alpha.c 20 Sep 2002 01:29:08 -0000 1.272.2.3 +++ alpha/alpha.c 25 Sep 2002 03:59:03 -0000 @@ -118,6 +118,8 @@ int alpha_this_literal_sequence_number; int alpha_this_gpdisp_sequence_number; /* Declarations of static functions. */ +static int alpha_function_ok_for_sibcall + PARAMS ((tree, tree)); static int tls_symbolic_operand_1 PARAMS ((rtx, enum machine_mode, int, int)); static enum tls_model tls_symbolic_operand_type @@ -292,6 +294,9 @@ static void unicosmk_unique_section PARA #undef TARGET_EXPAND_BUILTIN #define TARGET_EXPAND_BUILTIN alpha_expand_builtin +#undef TARGET_FUNCTION_OK_FOR_SIBCALL +#define TARGET_FUNCTION_OK_FOR_SIBCALL alpha_function_ok_for_sibcall + struct gcc_target targetm = TARGET_INITIALIZER; /* Parse target option strings. */ @@ -2267,6 +2272,22 @@ alpha_legitimize_address (x, scratch, mo return plus_constant (x, low); } +} + +/* We do not allow indirect calls to be optimized into sibling calls, nor + can we allow a call to a function in a different compilation unit to + be optimized into a sibcall. */ +static int +alpha_function_ok_for_sibcall (decl, exp) + tree decl; + tree exp; +{ + if (decl + && (! TREE_PUBLIC (decl) + || (TREE_ASM_WRITTEN (decl) && (*targetm.binds_local_p) (decl)))) + return 1; + else + return 0; } /* For TARGET_EXPLICIT_RELOCS, we don't obfuscate a SYMBOL_REF to a Index: alpha/alpha.h =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/config/alpha/alpha.h,v retrieving revision 1.176.4.7 diff -u -p -r1.176.4.7 alpha.h --- alpha/alpha.h 23 Sep 2002 04:38:44 -0000 1.176.4.7 +++ alpha/alpha.h 25 Sep 2002 03:59:12 -0000 @@ -1165,14 +1165,6 @@ extern int alpha_memory_latency; } \ } -/* We do not allow indirect calls to be optimized into sibling calls, nor - can we allow a call to a function in a different compilation unit to - be optimized into a sibcall. */ -#define FUNCTION_OK_FOR_SIBCALL(DECL) \ - (DECL \ - && (! TREE_PUBLIC (DECL) \ - || (TREE_ASM_WRITTEN (DECL) && (*targetm.binds_local_p) (DECL)))) - /* Try to output insns to set TARGET equal to the constant C if it can be done in less than N insns. Do all computations in MODE. Returns the place where the output has been placed if it can be done and the insns have been Index: arm/arm-protos.h =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/config/arm/arm-protos.h,v retrieving revision 1.29.8.2 diff -u -p -r1.29.8.2 arm-protos.h --- arm/arm-protos.h 17 Sep 2002 22:58:53 -0000 1.29.8.2 +++ arm/arm-protos.h 25 Sep 2002 03:59:14 -0000 @@ -41,7 +41,6 @@ extern unsigned int arm_compute_initial #ifdef TREE_CODE extern int arm_return_in_memory PARAMS ((tree)); extern void arm_encode_call_attribute PARAMS ((tree, int)); -extern int arm_function_ok_for_sibcall PARAMS ((tree)); #endif #ifdef RTX_CODE extern int arm_hard_regno_mode_ok PARAMS ((unsigned int, enum machine_mode)); Index: arm/arm.c =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/config/arm/arm.c,v retrieving revision 1.223.2.5 diff -u -p -r1.223.2.5 arm.c --- arm/arm.c 20 Sep 2002 01:29:09 -0000 1.223.2.5 +++ arm/arm.c 25 Sep 2002 03:59:48 -0000 @@ -117,6 +117,7 @@ static void arm_set_default_type_attrib static int arm_adjust_cost PARAMS ((rtx, rtx, rtx, int)); static int count_insns_for_constant PARAMS ((HOST_WIDE_INT, int)); static int arm_get_strip_length PARAMS ((int)); +static int arm_function_ok_for_sibcall PARAMS ((tree, tree)); #ifdef OBJECT_FORMAT_ELF static void arm_elf_asm_named_section PARAMS ((const char *, unsigned int)); #endif @@ -192,6 +193,9 @@ static void arm_internal_label PARAMS #undef TARGET_ASM_INTERNAL_LABEL #define TARGET_ASM_INTERNAL_LABEL arm_internal_label +#undef TARGET_FUNCTION_OK_FOR_SIBCALL +#define TARGET_FUNCTION_OK_FOR_SIBCALL arm_function_ok_for_sibcall + struct gcc_target targetm = TARGET_INITIALIZER; /* Obstack for minipool constant handling. */ @@ -2266,9 +2270,10 @@ arm_is_longcall_p (sym_ref, call_cookie, /* Return nonzero if it is ok to make a tail-call to DECL. */ -int -arm_function_ok_for_sibcall (decl) +static int +arm_function_ok_for_sibcall (decl, exp) tree decl; + tree exp; { int call_type = TARGET_LONG_CALLS ? CALL_LONG : CALL_NORMAL; Index: arm/arm.h =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/config/arm/arm.h,v retrieving revision 1.155.4.5 diff -u -p -r1.155.4.5 arm.h --- arm/arm.h 20 Sep 2002 01:29:10 -0000 1.155.4.5 +++ arm/arm.h 25 Sep 2002 04:00:00 -0000 @@ -1502,12 +1502,6 @@ typedef struct #define FUNCTION_ARG_REGNO_P(REGNO) (IN_RANGE ((REGNO), 0, 3)) -/* Tail calling. */ - -/* A C expression that evaluates to true if it is ok to perform a sibling - call to DECL. */ -#define FUNCTION_OK_FOR_SIBCALL(DECL) arm_function_ok_for_sibcall ((DECL)) - /* Perform any actions needed for a function that is receiving a variable number of arguments. CUM is as above. MODE and TYPE are the mode and type of the current parameter. PRETEND_SIZE is a variable that should be set to Index: frv/frv.c =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/config/frv/frv.c,v retrieving revision 1.2.10.3 diff -u -p -r1.2.10.3 frv.c --- frv/frv.c 20 Sep 2002 01:29:12 -0000 1.2.10.3 +++ frv/frv.c 25 Sep 2002 04:00:30 -0000 @@ -279,6 +279,7 @@ static void frv_encode_section_info PAR static void frv_init_builtins PARAMS ((void)); static rtx frv_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int)); static bool frv_in_small_data_p PARAMS ((tree)); +static int frv_function_ok_for_sibcall PARAMS ((tree, tree)); /* Initialize the GCC target structure. */ #undef TARGET_ASM_FUNCTION_PROLOGUE @@ -297,6 +298,8 @@ static bool frv_in_small_data_p PARAMS #define TARGET_EXPAND_BUILTIN frv_expand_builtin #undef TARGET_IN_SMALL_DATA_P #define TARGET_IN_SMALL_DATA_P frv_in_small_data_p +#undef TARGET_FUNCTION_OK_FOR_SIBCALL +#define TARGET_FUNCTION_OK_FOR_SIBCALL frv_function_ok_for_sibcall struct gcc_target targetm = TARGET_INITIALIZER; @@ -9773,4 +9776,13 @@ frv_in_small_data_p (decl) return symbol_ref_small_data_p (XEXP (DECL_RTL (decl), 0)) && size > 0 && size <= g_switch_value; +} + +/* Return true if a function is ok to be called as a sibcall. */ +static int +frv_function_ok_for_sibcall (decl, exp) + tree decl; + tree exp; +{ + return 0; } Index: frv/frv.h =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/config/frv/frv.h,v retrieving revision 1.3.2.5 diff -u -p -r1.3.2.5 frv.h --- frv/frv.h 20 Sep 2002 01:29:12 -0000 1.3.2.5 +++ frv/frv.h 25 Sep 2002 04:00:48 -0000 @@ -3539,9 +3539,6 @@ frv_ifcvt_modify_multiple_tests (CE_INFO scheduling. */ #define FIRST_CYCLE_MULTIPASS_SCHEDULING_LOOKAHEAD frv_sched_lookahead -/* Return true if a function is ok to be called as a sibcall. */ -#define FUNCTION_OK_FOR_SIBCALL(DECL) 0 - enum frv_builtins { FRV_BUILTIN_MAND, Index: i386/i386.c =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/config/i386/i386.c,v retrieving revision 1.447.2.3 diff -u -p -r1.447.2.3 i386.c --- i386/i386.c 17 Sep 2002 22:58:57 -0000 1.447.2.3 +++ i386/i386.c 25 Sep 2002 04:01:35 -0000 @@ -742,6 +742,7 @@ static int ix86_save_reg PARAMS ((unsign static void ix86_compute_frame_layout PARAMS ((struct ix86_frame *)); static int ix86_comp_type_attributes PARAMS ((tree, tree)); const struct attribute_spec ix86_attribute_table[]; +static int ix86_function_ok_for_sibcall PARAMS ((tree, tree)); static tree ix86_handle_cdecl_attribute PARAMS ((tree *, tree, tree, int, bool *)); static tree ix86_handle_regparm_attribute PARAMS ((tree *, tree, tree, int, bool *)); static int ix86_value_regno PARAMS ((enum machine_mode)); @@ -843,6 +844,9 @@ static enum x86_64_reg_class merge_class #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \ ia32_multipass_dfa_lookahead +#undef TARGET_FUNCTION_OK_FOR_SIBCALL +#define TARGET_FUNCTION_OK_FOR_SIBCALL ix86_function_ok_for_sibcall + #ifdef HAVE_AS_TLS #undef TARGET_HAVE_TLS #define TARGET_HAVE_TLS true @@ -1286,6 +1290,41 @@ const struct attribute_spec ix86_attribu #endif { NULL, 0, 0, false, false, false, NULL } }; + +/* If PIC, we cannot make sibling calls to global functions + because the PLT requires %ebx live. + If we are returning floats on the register stack, we cannot make + sibling calls to functions that return floats. (The stack adjust + instruction will wind up after the sibcall jump, and not be executed.) */ + +static int +ix86_function_ok_for_sibcall (decl, exp) + tree decl; + tree exp; +{ + /* If we are generating position-independent code, we cannot sibcall + optimize any indirect call, or a direct call to a global + function, as the PLT requires %ebx be live. */ + if (flag_pic && (!decl || !TREE_PUBLIC (decl))) + return 0; + + /* If we are returning floats on the 80387 register stack, we cannot + make a sibcall from a function that doesn't return a float to a + function that does; the necessary stack adjustment will not be + executed. */ + if (TARGET_FLOAT_RETURNS_IN_80387 + && FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (exp))) + && !FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (TREE_TYPE (cfun->decl))))) + return 0; + + /* TODO: Indirect sibcalls are not yet supported by the 64-bit call + patterns. */ + if (!decl && TARGET_64BIT) + return 0; + + /* Otherwise okay. */ + return 1; +} /* Handle a "cdecl" or "stdcall" attribute; arguments as in struct attribute_spec.handler. */ Index: i386/i386.h =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/config/i386/i386.h,v retrieving revision 1.280.4.5 diff -u -p -r1.280.4.5 i386.h --- i386/i386.h 23 Sep 2002 04:38:45 -0000 1.280.4.5 +++ i386/i386.h 25 Sep 2002 04:01:49 -0000 @@ -1674,17 +1674,9 @@ typedef struct ix86_args { #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0 -/* If PIC, we cannot make sibling calls to global functions - because the PLT requires %ebx live. - If we are returning floats on the register stack, we cannot make - sibling calls to functions that return floats. (The stack adjust - instruction will wind up after the sibcall jump, and not be executed.) */ -#define FUNCTION_OK_FOR_SIBCALL(DECL) \ - ((DECL) \ - && (! flag_pic || ! TREE_PUBLIC (DECL)) \ - && (! TARGET_FLOAT_RETURNS_IN_80387 \ - || ! FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (TREE_TYPE (DECL)))) \ - || FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (TREE_TYPE (cfun->decl)))))) +/* Checks whether the call can be sibcall optimized. More information + can be found in i386.c */ +/* #define FUNCTION_OK_FOR_SIBCALL(DECL, EXP) ix86_function_ok_for_sibcall ((DECL, EXP)) */ /* Perform any needed actions needed for a function that is receiving a variable number of arguments. Index: pa/pa-linux.h =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/config/pa/pa-linux.h,v retrieving revision 1.24.2.1 diff -u -p -r1.24.2.1 pa-linux.h --- pa/pa-linux.h 2 Sep 2002 02:54:02 -0000 1.24.2.1 +++ pa/pa-linux.h 25 Sep 2002 04:01:52 -0000 @@ -81,10 +81,6 @@ Boston, MA 02111-1307, USA. */ %{!dynamic-linker:-dynamic-linker /lib/ld.so.1}} \ %{static:-static}}" -/* Sibcalls, stubs, and elf sections don't play well. */ -#undef FUNCTION_OK_FOR_SIBCALL -#define FUNCTION_OK_FOR_SIBCALL(x) 0 - /* glibc's profiling functions don't need gcc to allocate counters. */ #define NO_PROFILE_COUNTERS 1 @@ -189,3 +185,7 @@ Boston, MA 02111-1307, USA. */ /* Linux always uses gas. */ #undef TARGET_GAS #define TARGET_GAS 1 + +/* Sibcalls, stubs, and elf sections don't play well. */ +#undef TARGET_FUNCTION_OK_FOR_SIBCALL +#define TARGET_FUNCTION_OK_FOR_SIBCALL hook_tree_tree_bool_false Index: pa/pa.c =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/config/pa/pa.c,v retrieving revision 1.177.2.3 diff -u -p -r1.177.2.3 pa.c --- pa/pa.c 17 Sep 2002 22:59:03 -0000 1.177.2.3 +++ pa/pa.c 25 Sep 2002 04:02:18 -0000 @@ -116,6 +116,7 @@ static void pa_select_section PARAMS ((t ATTRIBUTE_UNUSED; static void pa_encode_section_info PARAMS ((tree, int)); static const char *pa_strip_name_encoding PARAMS ((const char *)); +static int pa_function_ok_for_sibcall PARAMS ((tree, tree)); static void pa_globalize_label PARAMS ((FILE *, const char *)) ATTRIBUTE_UNUSED; @@ -194,6 +195,9 @@ static size_t n_deferred_plabels = 0; #undef TARGET_STRIP_NAME_ENCODING #define TARGET_STRIP_NAME_ENCODING pa_strip_name_encoding +#undef TARGET_FUNCTION_OK_FOR_SIBCALL +#define TARGET_FUNCTION_OK_FOR_SIBCALL pa_function_ok_for_sibcall + struct gcc_target targetm = TARGET_INITIALIZER; void @@ -6631,6 +6635,43 @@ pa_asm_output_mi_thunk (file, thunk_fnde function_section (thunk_fndecl); } current_thunk_number++; +} + +/* Only direct calls to static functions are allowed to be sibling (tail) + call optimized. + + This restriction is necessary because some linker generated stubs will + store return pointers into rp' in some cases which might clobber a + live value already in rp'. + + In a sibcall the current function and the target function share stack + space. Thus if the path to the current function and the path to the + target function save a value in rp', they save the value into the + same stack slot, which has undesirable consequences. + + Because of the deferred binding nature of shared libraries any function + with external scope could be in a different load module and thus require + rp' to be saved when calling that function. So sibcall optimizations + can only be safe for static function. + + Note that GCC never needs return value relocations, so we don't have to + worry about static calls with return value relocations (which require + saving rp'). + + It is safe to perform a sibcall optimization when the target function + will never return. */ +static int +pa_function_ok_for_sibcall (decl, exp) + tree decl; + tree exp; +{ + if (decl + && ! TARGET_PORTABLE_RUNTIME + && ! TARGET_64BIT + && ! TREE_PUBLIC (decl)) + return 1; + else + return 0; } /* Returns 1 if the 6 operands specified in OPERANDS are suitable for Index: pa/pa.h =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/config/pa/pa.h,v retrieving revision 1.166.2.4 diff -u -p -r1.166.2.4 pa.h --- pa/pa.h 17 Sep 2002 22:59:03 -0000 1.166.2.4 +++ pa/pa.h 25 Sep 2002 04:02:26 -0000 @@ -1831,35 +1831,6 @@ do { \ /* The number of Pmode words for the setjmp buffer. */ #define JMP_BUF_SIZE 50 -/* Only direct calls to static functions are allowed to be sibling (tail) - call optimized. - - This restriction is necessary because some linker generated stubs will - store return pointers into rp' in some cases which might clobber a - live value already in rp'. - - In a sibcall the current function and the target function share stack - space. Thus if the path to the current function and the path to the - target function save a value in rp', they save the value into the - same stack slot, which has undesirable consequences. - - Because of the deferred binding nature of shared libraries any function - with external scope could be in a different load module and thus require - rp' to be saved when calling that function. So sibcall optimizations - can only be safe for static function. - - Note that GCC never needs return value relocations, so we don't have to - worry about static calls with return value relocations (which require - saving rp'). - - It is safe to perform a sibcall optimization when the target function - will never return. */ -#define FUNCTION_OK_FOR_SIBCALL(DECL) \ - (DECL \ - && ! TARGET_PORTABLE_RUNTIME \ - && ! TARGET_64BIT \ - && ! TREE_PUBLIC (DECL)) - #define PREDICATE_CODES \ {"reg_or_0_operand", {SUBREG, REG, CONST_INT}}, \ {"call_operand_address", {LABEL_REF, SYMBOL_REF, CONST_INT, \ Index: rs6000/rs6000-protos.h =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/config/rs6000/rs6000-protos.h,v retrieving revision 1.43.4.1 diff -u -p -r1.43.4.1 rs6000-protos.h --- rs6000/rs6000-protos.h 17 Sep 2002 22:59:05 -0000 1.43.4.1 +++ rs6000/rs6000-protos.h 25 Sep 2002 04:02:28 -0000 @@ -151,7 +151,6 @@ extern void setup_incoming_varargs PARAM int *, int)); extern struct rtx_def *rs6000_va_arg PARAMS ((tree, tree)); extern void output_mi_thunk PARAMS ((FILE *, tree, int, tree)); -extern int function_ok_for_sibcall PARAMS ((tree)); #ifdef ARGS_SIZE_RTX /* expr.h defines ARGS_SIZE_RTX and `enum direction' */ extern enum direction function_arg_padding PARAMS ((enum machine_mode, tree)); Index: rs6000/rs6000.c =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/config/rs6000/rs6000.c,v retrieving revision 1.366.2.5 diff -u -p -r1.366.2.5 rs6000.c --- rs6000/rs6000.c 20 Sep 2002 01:29:19 -0000 1.366.2.5 +++ rs6000/rs6000.c 25 Sep 2002 04:03:13 -0000 @@ -165,6 +165,7 @@ struct builtin_description const enum rs6000_builtins code; }; +static int rs6000_function_ok_for_sibcall PARAMS ((tree, tree)); static void rs6000_add_gc_roots PARAMS ((void)); static int num_insns_constant_wide PARAMS ((HOST_WIDE_INT)); static void validate_condition_mode @@ -376,6 +377,9 @@ static const char alt_reg_names[][8] = /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */ #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO)) +#undef TARGET_FUNCTION_OK_FOR_SIBCALL +#define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall + struct gcc_target targetm = TARGET_INITIALIZER; /* Override command line options. Mostly we process the processor @@ -9403,9 +9407,10 @@ rs6000_return_addr (count, frame) vector parameters are required to have a prototype, so the argument type info must be available here. (The tail recursion case can work with vector parameters, but there's no way to distinguish here.) */ -int -function_ok_for_sibcall (fndecl) +static int +rs6000_function_ok_for_sibcall (fndecl, exp) tree fndecl; + tree exp; { tree type; if (fndecl) Index: rs6000/rs6000.h =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/config/rs6000/rs6000.h,v retrieving revision 1.224.4.6 diff -u -p -r1.224.4.6 rs6000.h --- rs6000/rs6000.h 23 Sep 2002 04:38:47 -0000 1.224.4.6 +++ rs6000/rs6000.h 25 Sep 2002 04:03:27 -0000 @@ -1804,10 +1804,6 @@ typedef struct rs6000_args argument is passed depends on whether or not it is a named argument. */ #define STRICT_ARGUMENT_NAMING 1 -/* We do not allow indirect calls to be optimized into sibling calls, nor - do we allow calls with vector parameters. */ -#define FUNCTION_OK_FOR_SIBCALL(DECL) function_ok_for_sibcall ((DECL)) - /* Output assembler code to FILE to increment profiler label # LABELNO for profiling a function entry. */ Index: sh/sh.c =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/config/sh/sh.c,v retrieving revision 1.169.4.4 diff -u -p -r1.169.4.4 sh.c --- sh/sh.c 20 Sep 2002 01:29:21 -0000 1.169.4.4 +++ sh/sh.c 25 Sep 2002 04:03:51 -0000 @@ -199,6 +199,7 @@ static void sh_insert_attributes PARAMS static int sh_adjust_cost PARAMS ((rtx, rtx, rtx, int)); static int sh_use_dfa_interface PARAMS ((void)); static int sh_issue_rate PARAMS ((void)); +static int sh_function_ok_for_sibcall PARAMS ((tree, tree)); static bool sh_cannot_modify_jumps_p PARAMS ((void)); static bool sh_ms_bitfield_layout_p PARAMS ((tree)); @@ -259,6 +260,9 @@ static void flow_dependent_p_1 PARAMS (( #undef TARGET_EXPAND_BUILTIN #define TARGET_EXPAND_BUILTIN sh_expand_builtin +#undef TARGET_FUNCTION_OK_FOR_SIBCALL +#define TARGET_FUNCTION_OK_FOR_SIBCALL sh_function_ok_for_sibcall + struct gcc_target targetm = TARGET_INITIALIZER; /* Print the operand address in x to the stream. */ @@ -7383,6 +7387,20 @@ sh_initialize_trampoline (tramp, fnaddr, } } +/* FIXME: This is overly conservative. A SHcompact function that + receives arguments ``by reference'' will have them stored in its + own stack frame, so it must not pass pointers or references to + these arguments to other functions by means of sibling calls. */ +static int +sh_function_ok_for_sibcall (decl, exp) + tree decl; + tree exp; +{ + if (! TARGET_SHCOMPACT || current_function_args_info.stack_regs == 0) + return 1; + else + return 0; +} /* Machine specific built-in functions. */ Index: sh/sh.h =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/config/sh/sh.h,v retrieving revision 1.166.4.6 diff -u -p -r1.166.4.6 sh.h --- sh/sh.h 23 Sep 2002 04:38:48 -0000 1.166.4.6 +++ sh/sh.h 25 Sep 2002 04:04:05 -0000 @@ -1706,13 +1706,6 @@ struct sh_args { (CUM).outgoing = 0; \ } while (0) -/* FIXME: This is overly conservative. A SHcompact function that - receives arguments ``by reference'' will have them stored in its - own stack frame, so it must not pass pointers or references to - these arguments to other functions by means of sibling calls. */ -#define FUNCTION_OK_FOR_SIBCALL(DECL) \ - (! TARGET_SHCOMPACT || current_function_args_info.stack_regs == 0) - /* Update the data in CUM to advance over an argument of mode MODE and data type TYPE. (TYPE is null for libcalls where that information may not be Index: sparc/sparc.c =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/config/sparc/sparc.c,v retrieving revision 1.226.4.4 diff -u -p -r1.226.4.4 sparc.c --- sparc/sparc.c 20 Sep 2002 01:29:21 -0000 1.226.4.4 +++ sparc/sparc.c 25 Sep 2002 04:04:47 -0000 @@ -176,6 +176,8 @@ static void emit_soft_tfmode_cvt PARAMS static void emit_hard_tfmode_operation PARAMS ((enum rtx_code, rtx *)); static void sparc_encode_section_info PARAMS ((tree, int)); + +static int sparc_function_ok_for_sibcall PARAMS ((tree, tree)); /* Option handling. */ @@ -239,6 +241,9 @@ enum processor_type sparc_cpu; #undef TARGET_ENCODE_SECTION_INFO #define TARGET_ENCODE_SECTION_INFO sparc_encode_section_info +#undef TARGET_FUNCTION_OK_FOR_SIBCALL +#define TARGET_FUNCTION_OK_FOR_SIBCALL sparc_function_ok_for_sibcall + struct gcc_target targetm = TARGET_INITIALIZER; /* Validate and override various options, and do some machine dependent @@ -8021,6 +8026,35 @@ sparc_elf_asm_named_section (name, flags fputc ('\n', asm_out_file); } #endif /* OBJECT_FORMAT_ELF */ + +/* We do not allow sibling calls if -mflat, nor + we do not allow indirect calls to be optimized into sibling calls. + + Also, on sparc 32-bit we cannot emit a sibling call when the + current function returns a structure. This is because the "unimp + after call" convention would cause the callee to return to the + wrong place. The generic code already disallows cases where the + function being called returns a structure. + + It may seem strange how this last case could occur. Usually there + is code after the call which jumps to epilogue code which dumps the + return value into the struct return area. That ought to invalidate + the sibling call right? Well, in the c++ case we can end up passing + the pointer to the struct return area to a constructor (which returns + void) and then nothing else happens. Such a sibling call would look + valid without the added check here. */ +static int +sparc_function_ok_for_sibcall (decl, exp) + tree decl; + tree exp; +{ + if (decl + && ! TARGET_FLAT + && (TARGET_ARCH64 || ! current_function_returns_struct)) + return 1; + else + return 0; +} /* ??? Similar to the standard section selection, but force reloc-y-ness if SUNOS4_SHARED_LIBRARIES. Unclear why this helps (as opposed to Index: sparc/sparc.h =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/config/sparc/sparc.h,v retrieving revision 1.207.4.6 diff -u -p -r1.207.4.6 sparc.h --- sparc/sparc.h 23 Sep 2002 04:38:48 -0000 1.207.4.6 +++ sparc/sparc.h 25 Sep 2002 04:05:00 -0000 @@ -1934,27 +1934,6 @@ do { \ #define STRICT_ARGUMENT_NAMING TARGET_V9 -/* We do not allow sibling calls if -mflat, nor - we do not allow indirect calls to be optimized into sibling calls. - - Also, on sparc 32-bit we cannot emit a sibling call when the - current function returns a structure. This is because the "unimp - after call" convention would cause the callee to return to the - wrong place. The generic code already disallows cases where the - function being called returns a structure. - - It may seem strange how this last case could occur. Usually there - is code after the call which jumps to epilogue code which dumps the - return value into the struct return area. That ought to invalidate - the sibling call right? Well, in the c++ case we can end up passing - the pointer to the struct return area to a constructor (which returns - void) and then nothing else happens. Such a sibling call would look - valid without the added check here. */ -#define FUNCTION_OK_FOR_SIBCALL(DECL) \ - (DECL \ - && ! TARGET_FLAT \ - && (TARGET_ARCH64 || ! current_function_returns_struct)) - /* Generate RTL to flush the register windows so as to make arbitrary frames available. */ #define SETUP_FRAME_ADDRESSES() \ Index: xtensa/xtensa.c =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/config/xtensa/xtensa.c,v retrieving revision 1.18.4.1 diff -u -p -r1.18.4.1 xtensa.c --- xtensa/xtensa.c 5 Sep 2002 17:47:31 -0000 1.18.4.1 +++ xtensa/xtensa.c 25 Sep 2002 04:05:08 -0000 @@ -202,6 +202,7 @@ static unsigned int xtensa_multibss_sect static void xtensa_select_rtx_section PARAMS ((enum machine_mode, rtx, unsigned HOST_WIDE_INT)); static void xtensa_encode_section_info PARAMS ((tree, int)); +static int xtensa_function_ok_for_sibcall PARAMS ((tree, tree)); static rtx frame_size_const; static int current_function_arg_words; @@ -238,6 +239,9 @@ static const int reg_nonleaf_alloc_order #undef TARGET_ENCODE_SECTION_INFO #define TARGET_ENCODE_SECTION_INFO xtensa_encode_section_info +#undef TARGET_FUNCTION_OK_FOR_SIBCALL +#define TARGET_FUNCTION_OK_FOR_SIBCALL xtensa_function_ok_for_sibcall + struct gcc_target targetm = TARGET_INITIALIZER; @@ -1624,6 +1628,16 @@ xtensa_emit_loop_end (insn, operands) output_asm_insn ("# loop end for %0", operands); } +/* A C expression that evaluates to true if it is ok to perform a + sibling call to DECL. */ +/* TODO: fix this up to allow at least some sibcalls */ +static int +xtensa_function_ok_for_sibcall (decl, exp) + tree decl; + tree exp; +{ + return 0; +} char * xtensa_emit_call (callop, operands) Index: xtensa/xtensa.h =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/config/xtensa/xtensa.h,v retrieving revision 1.20.4.1 diff -u -p -r1.20.4.1 xtensa.h --- xtensa/xtensa.h 16 Sep 2002 17:38:28 -0000 1.20.4.1 +++ xtensa/xtensa.h 25 Sep 2002 04:05:15 -0000 @@ -1287,11 +1287,6 @@ typedef struct xtensa_args { indexing purposes) so give the MEM rtx a words's mode. */ #define FUNCTION_MODE SImode -/* A C expression that evaluates to true if it is ok to perform a - sibling call to DECL. */ -/* TODO: fix this up to allow at least some sibcalls */ -#define FUNCTION_OK_FOR_SIBCALL(DECL) 0 - /* Xtensa constant costs. */ #define CONST_COSTS(X, CODE, OUTER_CODE) \ case CONST_INT: \