[gcc r12-7081] Check always_inline flag in s390_can_inline_p [PR104327]

Andreas Krebbel krebbel@gcc.gnu.org
Mon Feb 7 10:18:16 GMT 2022


https://gcc.gnu.org/g:db95441cf5399aabc46ca83df19f7290c3e23cb1

commit r12-7081-gdb95441cf5399aabc46ca83df19f7290c3e23cb1
Author: Andreas Krebbel <krebbel@linux.ibm.com>
Date:   Sun Feb 6 09:07:41 2022 +0100

    Check always_inline flag in s390_can_inline_p [PR104327]
    
    MASK_MVCLE is set for -Os but not for other optimization levels. In
    general it should not make much sense to inline across calls where the
    flag is different but we have to allow it for always_inline.
    
    The patch also rearranges the hook implementation a bit based on the
    recommendations from Jakub und Martin in the PR.
    
    Bootstrapped and regression tested on s390x with various arch flags.
    Will commit after giving a few days for comments.
    
    gcc/ChangeLog:
    
            PR target/104327
            * config/s390/s390.cc (s390_can_inline_p): Accept a few more flags
            if always_inline is set. Don't inline when tune differs without
            always_inline.
    
    gcc/testsuite/ChangeLog:
    
            PR target/104327
            * gcc.c-torture/compile/pr104327.c: New test.

Diff:
---
 gcc/config/s390/s390.cc                        | 64 +++++++++++++++++++-------
 gcc/testsuite/gcc.c-torture/compile/pr104327.c | 15 ++++++
 2 files changed, 62 insertions(+), 17 deletions(-)

diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
index 5c2a830f9f0..c6cfe41ad7b 100644
--- a/gcc/config/s390/s390.cc
+++ b/gcc/config/s390/s390.cc
@@ -16091,6 +16091,23 @@ s390_valid_target_attribute_p (tree fndecl,
 static bool
 s390_can_inline_p (tree caller, tree callee)
 {
+  /* Flags which if present in the callee are required in the caller as well.  */
+  const unsigned HOST_WIDE_INT caller_required_masks = MASK_OPT_HTM;
+
+  /* Flags which affect the ABI and in general prevent inlining.  */
+  unsigned HOST_WIDE_INT must_match_masks
+    = (MASK_64BIT | MASK_ZARCH | MASK_HARD_DFP | MASK_SOFT_FLOAT
+       | MASK_LONG_DOUBLE_128 | MASK_OPT_VX);
+
+  /* Flags which we in general want to prevent inlining but accept for
+     always_inline.  */
+  const unsigned HOST_WIDE_INT always_inline_safe_masks
+    = MASK_MVCLE | MASK_BACKCHAIN | MASK_SMALL_EXEC;
+
+  const HOST_WIDE_INT all_masks
+     = (caller_required_masks | must_match_masks | always_inline_safe_masks
+	| MASK_DEBUG_ARG | MASK_PACKED_STACK | MASK_ZVECTOR);
+
   tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
   tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
 
@@ -16103,16 +16120,18 @@ s390_can_inline_p (tree caller, tree callee)
 
   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;
+  /* If one of these triggers make sure to add proper handling of your
+     new flag to this hook.  */
+  gcc_assert (!(caller_opts->x_target_flags & ~all_masks));
+  gcc_assert (!(callee_opts->x_target_flags & ~all_masks));
 
-  /* 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;
+  bool always_inline
+    = (DECL_DISREGARD_INLINE_LIMITS (callee)
+       && lookup_attribute ("always_inline", DECL_ATTRIBUTES (callee)));
+
+  if (!always_inline)
+    must_match_masks |= always_inline_safe_masks;
 
   /* Inlining a hard float function into a soft float function is only
      allowed if the hard float function doesn't actually make use of
@@ -16120,16 +16139,27 @@ s390_can_inline_p (tree caller, tree callee)
 
      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;
+  if (always_inline && ipa_fn_summaries
+      && !ipa_fn_summaries->get(cgraph_node::get (callee))->fp_expressions)
+    must_match_masks &= ~(MASK_HARD_DFP | MASK_SOFT_FLOAT);
 
-  return ret;
+  if ((caller_opts->x_target_flags & must_match_masks)
+      != (callee_opts->x_target_flags & must_match_masks))
+    return false;
+
+  if (~(caller_opts->x_target_flags & caller_required_masks)
+      & (callee_opts->x_target_flags & caller_required_masks))
+    return false;
+
+  /* Don't inline functions to be compiled for a more recent arch into a
+     function for an older arch.  */
+  if (caller_opts->x_s390_arch < callee_opts->x_s390_arch)
+    return false;
+
+  if (!always_inline && caller_opts->x_s390_tune != callee_opts->x_s390_tune)
+    return false;
+
+  return true;
 }
 #endif
 
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr104327.c b/gcc/testsuite/gcc.c-torture/compile/pr104327.c
new file mode 100644
index 00000000000..d54e5d58cc4
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr104327.c
@@ -0,0 +1,15 @@
+/* PR target/104327 */
+
+void foo (int *);
+
+static inline __attribute__((always_inline)) void
+bar (int *x)
+{
+  foo (x);
+}
+
+__attribute__((cold, optimize("Os"))) void
+baz (int *x)
+{
+  bar (x);
+}


More information about the Gcc-cvs mailing list