S/390: PR82012: Implement CAN_INLINE_P target hook.
authorAndreas Krebbel <krebbel@linux.vnet.ibm.com>
Fri, 1 Sep 2017 15:58:05 +0000 (15:58 +0000)
committerAndreas Krebbel <krebbel@gcc.gnu.org>
Fri, 1 Sep 2017 15:58:05 +0000 (15:58 +0000)
TARGET_CAN_INLINE_P must be implemented when supporting target
attributes.

gcc/ChangeLog:

2017-09-01  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>

PR target/82012
* config/s390/s390.c (s390_can_inline_p): New function.

gcc/testsuite/ChangeLog:

2017-09-01  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>

PR target/82012
* gcc.target/s390/target-attribute/pr82012.c: New test.

From-SVN: r251601

gcc/ChangeLog
gcc/config/s390/s390.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/s390/target-attribute/pr82012.c [new file with mode: 0644]

index f9e49e0..e71380e 100644 (file)
@@ -1,3 +1,8 @@
+2017-09-01  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>
+
+       PR target/82012
+       * config/s390/s390.c (s390_can_inline_p): New function.
+
 2017-09-01  Jeff Law  <law@redhat.com>
 
        PR tree-optimization/82052
index d1480f4..8b6991a 100644 (file)
@@ -79,6 +79,10 @@ along with GCC; see the file COPYING3.  If not see
 #include "rtl-iter.h"
 #include "intl.h"
 #include "tm-constrs.h"
+#include "tree-vrp.h"
+#include "symbol-summary.h"
+#include "ipa-prop.h"
+#include "ipa-fnsummary.h"
 
 /* This file should be included last.  */
 #include "target-def.h"
@@ -15354,6 +15358,52 @@ s390_valid_target_attribute_p (tree fndecl,
   return ret;
 }
 
+/* Hook to determine if one function can safely inline another.  */
+
+static bool
+s390_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_tree)
+    callee_tree = target_option_default_node;
+  if (!caller_tree)
+    caller_tree = target_option_default_node;
+  if (callee_tree == caller_tree)
+    return true;
+
+  struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
+  struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
+  bool ret = true;
+
+  if ((caller_opts->x_target_flags & ~(MASK_SOFT_FLOAT | MASK_HARD_DFP))
+      != (callee_opts->x_target_flags & ~(MASK_SOFT_FLOAT | MASK_HARD_DFP)))
+    ret = false;
+
+  /* Don't inline functions to be compiled for a more recent arch into a
+     function for an older arch.  */
+  else if (caller_opts->x_s390_arch < callee_opts->x_s390_arch)
+    ret = false;
+
+  /* Inlining a hard float function into a soft float function is only
+     allowed if the hard float function doesn't actually make use of
+     floating point.
+
+     We are called from FEs for multi-versioning call optimization, so
+     beware of ipa_fn_summaries not available.  */
+  else if (((TARGET_SOFT_FLOAT_P (caller_opts->x_target_flags)
+            && !TARGET_SOFT_FLOAT_P (callee_opts->x_target_flags))
+           || (!TARGET_HARD_DFP_P (caller_opts->x_target_flags)
+               && TARGET_HARD_DFP_P (callee_opts->x_target_flags)))
+          && (! ipa_fn_summaries
+              || ipa_fn_summaries->get
+              (cgraph_node::get (callee))->fp_expressions))
+    ret = false;
+
+  return ret;
+}
+
 /* Restore targets globals from NEW_TREE and invalidate s390_previous_fndecl
    cache.  */
 
@@ -15936,6 +15986,9 @@ s390_asan_shadow_offset (void)
 
 #undef TARGET_OPTION_VALID_ATTRIBUTE_P
 #define TARGET_OPTION_VALID_ATTRIBUTE_P s390_valid_target_attribute_p
+
+#undef TARGET_CAN_INLINE_P
+#define TARGET_CAN_INLINE_P s390_can_inline_p
 #endif
 
 #undef TARGET_OPTION_RESTORE
index 9ace97b..fe6e430 100644 (file)
@@ -1,3 +1,8 @@
+2017-09-01  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>
+
+       PR target/82012
+       * gcc.target/s390/target-attribute/pr82012.c: New test.
+
 2017-09-01  Jeff Law  <law@redhat.com>
 
        PR tree-optimization/82052
diff --git a/gcc/testsuite/gcc.target/s390/target-attribute/pr82012.c b/gcc/testsuite/gcc.target/s390/target-attribute/pr82012.c
new file mode 100644 (file)
index 0000000..2e1f7ae
--- /dev/null
@@ -0,0 +1,46 @@
+/* Different target attributes in general prevent inlining.  However,
+   we make an exception for soft-float callers if the callee doesn't
+   actually use HW floating point.  This is currently required for
+   compiling libitm.  */
+
+/* { dg-options "-Wno-attributes" } */
+
+double g = 1.0;
+
+/* Inlining ok here.  foo1 doesn't use FP.  */
+
+int __attribute__ ((always_inline)) foo1 (int a)
+{
+  return 0;
+}
+
+int __attribute__ ((target ("soft-float"))) test1 (int a)
+{
+  return foo1 (a);
+}
+
+/* Inlining ok here.  FP store doesn't need HW FP.  */
+
+int __attribute__ ((always_inline)) foo2 (int a)
+{
+  g = 2.0;
+  return 0;
+}
+
+int __attribute__ ((target ("soft-float"))) test2 (int a)
+{
+  return foo2 (a);
+}
+
+/* Inlining needs to be rejected.  foo3 performs HW FP operation.  */
+
+int __attribute__ ((always_inline)) foo3 (int a) /* { dg-error "inlining failed in call to always_inline" } */
+{
+  g = (double) a / 2.0;
+  return 0;
+}
+
+int __attribute__ ((target ("soft-float"))) test3 (int a)
+{
+  return foo3 (a);
+}