diff mbox

[ARM] Enable descriptors for nested functions in Ada

Message ID 1669782.vfRejaKWdb@polaris
State New
Headers show

Commit Message

Eric Botcazou Nov. 13, 2016, 10:31 p.m. UTC
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.

Comments

Richard Earnshaw (lists) Feb. 14, 2017, 2:50 p.m. UTC | #1
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
>
Eric Botcazou Feb. 14, 2017, 6:37 p.m. UTC | #2
> 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.
diff mbox

Patch

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