[AArch64][9/14] Implement TARGET_CAN_INLINE_P
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>
Tue, 4 Aug 2015 10:17:13 +0000 (10:17 +0000)
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>
Tue, 4 Aug 2015 10:17:13 +0000 (10:17 +0000)
* config/aarch64/aarch64.c (aarch64_tribools_ok_for_inlining_p):
New function.
(aarch64_can_inline_p): Likewise.
(TARGET_CAN_INLINE_P): Define.

From-SVN: r226561

gcc/ChangeLog
gcc/config/aarch64/aarch64.c

index 6344d8571ae913094eda290192578cc3939d89ec..28a55d5529eb5d650cfa755112362dc61c4a973b 100644 (file)
@@ -1,3 +1,10 @@
+2015-08-04  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * config/aarch64/aarch64.c (aarch64_tribools_ok_for_inlining_p):
+       New function.
+       (aarch64_can_inline_p): Likewise.
+       (TARGET_CAN_INLINE_P): Define.
+
 2015-08-04  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        * common/config/aarch64/aarch64-common.c (aarch64_handle_option):
index 7a369fd47346c74fc2f4782b115981b48bb4998f..6b418a7a12993e7b375e19a520dd5420c7dc57ca 100644 (file)
@@ -8459,6 +8459,113 @@ aarch64_option_valid_attribute_p (tree fndecl, tree, tree args, int)
   return ret;
 }
 
+/* Helper for aarch64_can_inline_p.  In the case where CALLER and CALLEE are
+   tri-bool options (yes, no, don't care) and the default value is
+   DEF, determine whether to reject inlining.  */
+
+static bool
+aarch64_tribools_ok_for_inlining_p (int caller, int callee,
+                                    int dont_care, int def)
+{
+  /* If the callee doesn't care, always allow inlining.  */
+  if (callee == dont_care)
+    return true;
+
+  /* If the caller doesn't care, always allow inlining.  */
+  if (caller == dont_care)
+    return true;
+
+  /* Otherwise, allow inlining if either the callee and caller values
+     agree, or if the callee is using the default value.  */
+  return (callee == caller || callee == def);
+}
+
+/* Implement TARGET_CAN_INLINE_P.  Decide whether it is valid
+   to inline CALLEE into CALLER based on target-specific info.
+   Make sure that the caller and callee have compatible architectural
+   features.  Then go through the other possible target attributes
+   and see if they can block inlining.  Try not to reject always_inline
+   callees unless they are incompatible architecturally.  */
+
+static bool
+aarch64_can_inline_p (tree caller, tree callee)
+{
+  tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
+  tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
+
+  /* If callee has no option attributes, then it is ok to inline.  */
+  if (!callee_tree)
+    return true;
+
+  struct cl_target_option *caller_opts
+       = TREE_TARGET_OPTION (caller_tree ? caller_tree
+                                          : target_option_default_node);
+
+  struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
+
+
+  /* Callee's ISA flags should be a subset of the caller's.  */
+  if ((caller_opts->x_aarch64_isa_flags & callee_opts->x_aarch64_isa_flags)
+       != callee_opts->x_aarch64_isa_flags)
+    return false;
+
+  /* Allow non-strict aligned functions inlining into strict
+     aligned ones.  */
+  if ((TARGET_STRICT_ALIGN_P (caller_opts->x_target_flags)
+       != TARGET_STRICT_ALIGN_P (callee_opts->x_target_flags))
+      && !(!TARGET_STRICT_ALIGN_P (callee_opts->x_target_flags)
+          && TARGET_STRICT_ALIGN_P (caller_opts->x_target_flags)))
+    return false;
+
+  bool always_inline = lookup_attribute ("always_inline",
+                                         DECL_ATTRIBUTES (callee));
+
+  /* If the architectural features match up and the callee is always_inline
+     then the other attributes don't matter.  */
+  if (always_inline)
+    return true;
+
+  if (caller_opts->x_aarch64_cmodel_var
+      != callee_opts->x_aarch64_cmodel_var)
+    return false;
+
+  if (caller_opts->x_aarch64_tls_dialect
+      != callee_opts->x_aarch64_tls_dialect)
+    return false;
+
+  /* Honour explicit requests to workaround errata.  */
+  if (!aarch64_tribools_ok_for_inlining_p (
+         caller_opts->x_aarch64_fix_a53_err835769,
+         callee_opts->x_aarch64_fix_a53_err835769,
+         2, TARGET_FIX_ERR_A53_835769_DEFAULT))
+    return false;
+
+  /* If the user explicitly specified -momit-leaf-frame-pointer for the
+     caller and calle and they don't match up, reject inlining.  */
+  if (!aarch64_tribools_ok_for_inlining_p (
+         caller_opts->x_flag_omit_leaf_frame_pointer,
+         callee_opts->x_flag_omit_leaf_frame_pointer,
+         2, 1))
+    return false;
+
+  /* If the callee has specific tuning overrides, respect them.  */
+  if (callee_opts->x_aarch64_override_tune_string != NULL
+      && caller_opts->x_aarch64_override_tune_string == NULL)
+    return false;
+
+  /* If the user specified tuning override strings for the
+     caller and callee and they don't match up, reject inlining.
+     We just do a string compare here, we don't analyze the meaning
+     of the string, as it would be too costly for little gain.  */
+  if (callee_opts->x_aarch64_override_tune_string
+      && caller_opts->x_aarch64_override_tune_string
+      && (strcmp (callee_opts->x_aarch64_override_tune_string,
+                 caller_opts->x_aarch64_override_tune_string) != 0))
+    return false;
+
+  return true;
+}
+
 /* Return true if SYMBOL_REF X binds locally.  */
 
 static bool
@@ -12863,6 +12970,9 @@ aarch64_promoted_type (const_tree t)
 #undef TARGET_CAN_ELIMINATE
 #define TARGET_CAN_ELIMINATE aarch64_can_eliminate
 
+#undef TARGET_CAN_INLINE_P
+#define TARGET_CAN_INLINE_P aarch64_can_inline_p
+
 #undef TARGET_CANNOT_FORCE_CONST_MEM
 #define TARGET_CANNOT_FORCE_CONST_MEM aarch64_cannot_force_const_mem