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.

-- 
Eric Botcazou

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.

-- 
Eric Botcazou
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