re PR ada/67205 (eliminate No_Implicit_Dynamic_Code restriction violations)
authorEric Botcazou <ebotcazou@adacore.com>
Tue, 21 Feb 2017 08:42:54 +0000 (08:42 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 21 Feb 2017 08:42:54 +0000 (08:42 +0000)
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.

From-SVN: r245621

gcc/ChangeLog
gcc/config/arm/arm.c

index 26a3864ad090380bfbe7e015e8fed209989b8052..d23fcbf925d975b21a1cbad199c5ef91a3d7cb8c 100644 (file)
@@ -1,3 +1,12 @@
+2017-02-21  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.
+
 2017-02-21  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/61441
index 3e482b55e7487648994397c8dc75366df31ff5ee..b397a73052dcfb2e356884c929fdeee9356c5cc6 100644 (file)
@@ -760,6 +760,11 @@ static const struct attribute_spec arm_attribute_table[] =
 #undef TARGET_C_EXCESS_PRECISION
 #define TARGET_C_EXCESS_PRECISION arm_excess_precision
 
+/* 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;
 \f
 /* Obstack for minipool constant handling.  */
@@ -7173,6 +7178,29 @@ arm_function_ok_for_sibcall (tree decl, tree exp)
       && 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;
 }
@@ -30310,7 +30338,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