aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndreas Krebbel <krebbel@linux.vnet.ibm.com>2017-09-01 15:58:05 +0000
committerAndreas Krebbel <krebbel@gcc.gnu.org>2017-09-01 15:58:05 +0000
commitdb6bb1ec036f180584d221cdc66dff7bb7180d7a (patch)
tree120d17aca1c004b77c81225c4d7db63eb76c2f29 /gcc
parent0e34f6d842f2cd7f9aecdc32bfdc14dcf6c811e5 (diff)
downloadgcc-db6bb1ec036f180584d221cdc66dff7bb7180d7a.zip
gcc-db6bb1ec036f180584d221cdc66dff7bb7180d7a.tar.gz
gcc-db6bb1ec036f180584d221cdc66dff7bb7180d7a.tar.bz2
S/390: PR82012: Implement CAN_INLINE_P target hook.
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/s390/s390.c53
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/s390/target-attribute/pr82012.c46
4 files changed, 109 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f9e49e0..e71380e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index d1480f4..8b6991a 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9ace97b..fe6e430 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..2e1f7ae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/target-attribute/pr82012.c
@@ -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);
+}