Message ID | 1669782.vfRejaKWdb@polaris |
---|---|
State | New |
Headers | show |
On 13/11/16 22:31, Eric Botcazou wrote: > Similarly to x86, PowerPC and SPARC, this enables the use of custom run-time > descriptors in Ada, thus eliminating the need for trampolines and executable > stack in presence of pointers to nested functions. > > This still uses bit 1 for the run-time identification scheme because bumping > the function alignment to 64 bits seems undesirable in Thumb mode. > > Tested on ARM/Linux, OK for the mainline? > > > 2016-11-13 Eric Botcazou <ebotcazou@adacore.com> > > PR ada/67205 > * config/arm/arm.c (TARGET_CUSTOM_FUNCTION_DESCRIPTORS): Define. > (arm_function_ok_for_sibcall): Return false for an indirect call by > descriptor if all the argument registers are used. > (arm_relayout_function): Use FUNCTION_ALIGNMENT macro to adjust the > alignment of the function. > Is this ABI, or private to a release of the compiler? If the latter, then OK. Otherwise, I don't think we should presume that the reserved bits won't get used. R. > > p.diff > > > Index: config/arm/arm.c > =================================================================== > --- config/arm/arm.c (revision 242334) > +++ config/arm/arm.c (working copy) > @@ -738,6 +738,11 @@ static const struct attribute_spec arm_a > #undef TARGET_EXPAND_DIVMOD_LIBFUNC > #define TARGET_EXPAND_DIVMOD_LIBFUNC arm_expand_divmod_libfunc > > +/* Although the architecture reserves bits 0 and 1, only the former is > + used for ARM/Thumb ISA selection in v7 and earlier versions. */ > +#undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS > +#define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 2 > + > struct gcc_target targetm = TARGET_INITIALIZER; > > /* Obstack for minipool constant handling. */ > @@ -6810,6 +6815,29 @@ arm_function_ok_for_sibcall (tree decl, > && DECL_WEAK (decl)) > return false; > > + /* We cannot do a tailcall for an indirect call by descriptor if all the > + argument registers are used because the only register left to load the > + address is IP and it will already contain the static chain. */ > + if (!decl && CALL_EXPR_BY_DESCRIPTOR (exp) && !flag_trampolines) > + { > + tree fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (exp))); > + CUMULATIVE_ARGS cum; > + cumulative_args_t cum_v; > + > + arm_init_cumulative_args (&cum, fntype, NULL_RTX, NULL_TREE); > + cum_v = pack_cumulative_args (&cum); > + > + for (tree t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t)) > + { > + tree type = TREE_VALUE (t); > + if (!VOID_TYPE_P (type)) > + arm_function_arg_advance (cum_v, TYPE_MODE (type), type, true); > + } > + > + if (!arm_function_arg (cum_v, SImode, integer_type_node, true)) > + return false; > + } > + > /* Everything else is ok. */ > return true; > } > @@ -29101,7 +29129,9 @@ arm_relayout_function (tree fndecl) > callee_tree = target_option_default_node; > > struct cl_target_option *opts = TREE_TARGET_OPTION (callee_tree); > - SET_DECL_ALIGN (fndecl, FUNCTION_BOUNDARY_P (opts->x_target_flags)); > + SET_DECL_ALIGN > + (fndecl, > + FUNCTION_ALIGNMENT (FUNCTION_BOUNDARY_P (opts->x_target_flags))); > } > > /* Inner function to process the attribute((target(...))), take an argument and >
> Is this ABI, or private to a release of the compiler? If the latter, > then OK. Otherwise, I don't think we should presume that the reserved > bits won't get used. The latter, there is no fixed ABI for Ada. -- Eric Botcazou
Index: config/arm/arm.c =================================================================== --- config/arm/arm.c (revision 242334) +++ config/arm/arm.c (working copy) @@ -738,6 +738,11 @@ static const struct attribute_spec arm_a #undef TARGET_EXPAND_DIVMOD_LIBFUNC #define TARGET_EXPAND_DIVMOD_LIBFUNC arm_expand_divmod_libfunc +/* Although the architecture reserves bits 0 and 1, only the former is + used for ARM/Thumb ISA selection in v7 and earlier versions. */ +#undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS +#define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 2 + struct gcc_target targetm = TARGET_INITIALIZER; /* Obstack for minipool constant handling. */ @@ -6810,6 +6815,29 @@ arm_function_ok_for_sibcall (tree decl, && DECL_WEAK (decl)) return false; + /* We cannot do a tailcall for an indirect call by descriptor if all the + argument registers are used because the only register left to load the + address is IP and it will already contain the static chain. */ + if (!decl && CALL_EXPR_BY_DESCRIPTOR (exp) && !flag_trampolines) + { + tree fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (exp))); + CUMULATIVE_ARGS cum; + cumulative_args_t cum_v; + + arm_init_cumulative_args (&cum, fntype, NULL_RTX, NULL_TREE); + cum_v = pack_cumulative_args (&cum); + + for (tree t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t)) + { + tree type = TREE_VALUE (t); + if (!VOID_TYPE_P (type)) + arm_function_arg_advance (cum_v, TYPE_MODE (type), type, true); + } + + if (!arm_function_arg (cum_v, SImode, integer_type_node, true)) + return false; + } + /* Everything else is ok. */ return true; } @@ -29101,7 +29129,9 @@ arm_relayout_function (tree fndecl) callee_tree = target_option_default_node; struct cl_target_option *opts = TREE_TARGET_OPTION (callee_tree); - SET_DECL_ALIGN (fndecl, FUNCTION_BOUNDARY_P (opts->x_target_flags)); + SET_DECL_ALIGN + (fndecl, + FUNCTION_ALIGNMENT (FUNCTION_BOUNDARY_P (opts->x_target_flags))); } /* Inner function to process the attribute((target(...))), take an argument and