diff options
author | Andreas Krebbel <krebbel@linux.vnet.ibm.com> | 2017-09-01 15:58:05 +0000 |
---|---|---|
committer | Andreas Krebbel <krebbel@gcc.gnu.org> | 2017-09-01 15:58:05 +0000 |
commit | db6bb1ec036f180584d221cdc66dff7bb7180d7a (patch) | |
tree | 120d17aca1c004b77c81225c4d7db63eb76c2f29 /gcc | |
parent | 0e34f6d842f2cd7f9aecdc32bfdc14dcf6c811e5 (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/s390/s390.c | 53 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/s390/target-attribute/pr82012.c | 46 |
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); +} |