S/390: Add direct support for Linux kernel __fentry__ patching.
authorIlya Leoshkevich <iii@linux.ibm.com>
Mon, 16 Jul 2018 14:29:08 +0000 (14:29 +0000)
committerAndreas Krebbel <krebbel@gcc.gnu.org>
Mon, 16 Jul 2018 14:29:08 +0000 (14:29 +0000)
On i386, the difference between mcount and fentry is that fentry
comes before the prolog. On s390 mcount already comes before the
prolog, but takes 4 instructions. This patch introduces the more
efficient implementation (just 1 instruction) and puts it under
-mfentry flag.

The produced code is compatible only with newer glibc versions,
which provide the __fentry__ symbol and do not clobber %r0 when
resolving lazily bound functions. Because 31-bit PLT stubs assume
%r12 contains GOT address, which is not the case when the code runs
before the prolog, -mfentry is allowed only for 64-bit code.

Also, code compiled with -mfentry cannot be used for the nested C
functions, since they both use %r0. In this case instrumentation is
not insterted, and a new warning is issued for each affected nested
function.

2018-07-16  Ilya Leoshkevich  <iii@linux.ibm.com>

* common.opt: Add the new warning.
* config/s390/s390.c (s390_function_profiler): Emit "brasl
%r0,__fentry__" when -mfentry is specified.
(s390_option_override_internal): Disallow -mfentry for 31-bit
CPUs.
* config/s390/s390.opt: Add the new option.

2018-07-16  Ilya Leoshkevich  <iii@linux.ibm.com>

* gcc.target/s390/mfentry-m64.c: New testcase.

From-SVN: r262732

gcc/ChangeLog
gcc/common.opt
gcc/config/s390/s390.c
gcc/config/s390/s390.opt
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/s390/mfentry-m64.c [new file with mode: 0644]

index 974168cef0b0df09351e992936ac2aded236e63c..de108a529ce7148524e71aec48e48e2eb54b30a4 100644 (file)
@@ -1,3 +1,12 @@
+2018-07-16  Ilya Leoshkevich  <iii@linux.ibm.com>
+
+       * common.opt: Add the new warning.
+       * config/s390/s390.c (s390_function_profiler): Emit "brasl
+       %r0,__fentry__" when -mfentry is specified.
+       (s390_option_override_internal): Disallow -mfentry for 31-bit
+       CPUs.
+       * config/s390/s390.opt: Add the new option.
+
 2018-07-16  Richard Biener  <rguenther@suse.de>
 
        PR lto/86523
index c29abdb5cb11222b18820fab520809ab65eb0220..4d031e81b09a2d5b32aebf02e64561612dde1778 100644 (file)
@@ -571,6 +571,11 @@ Wattribute-alias
 Common Var(warn_attributes) Init(1) Warning
 Warn about type safety and similar errors in attribute alias and related.
 
+Wcannot-profile
+Common Var(warn_cannot_profile) Init(1) Warning
+Warn when profiling instrumentation was requested, but could not be applied to
+a certain function.
+
 Wcast-align
 Common Var(warn_cast_align) Warning
 Warn about pointer casts which increase alignment.
index 23c3f3db621ae7791e7c2f03cf1118378b4892e2..3a406b955a0e83a699bd8fe909f09fe033482f48 100644 (file)
@@ -13144,14 +13144,22 @@ s390_function_profiler (FILE *file, int labelno)
   op[3] = gen_rtx_SYMBOL_REF (Pmode, label);
   SYMBOL_REF_FLAGS (op[3]) = SYMBOL_FLAG_LOCAL;
 
-  op[4] = gen_rtx_SYMBOL_REF (Pmode, "_mcount");
+  op[4] = gen_rtx_SYMBOL_REF (Pmode, flag_fentry ? "__fentry__" : "_mcount");
   if (flag_pic)
     {
       op[4] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[4]), UNSPEC_PLT);
       op[4] = gen_rtx_CONST (Pmode, op[4]);
     }
 
-  if (TARGET_64BIT)
+  if (flag_fentry)
+    {
+      if (cfun->static_chain_decl)
+        warning (OPT_Wcannot_profile, "nested functions cannot be profiled "
+                 "with -mfentry on s390");
+      else
+        output_asm_insn ("brasl\t0,%4", op);
+    }
+  else if (TARGET_64BIT)
     {
       output_asm_insn ("stg\t%0,%1", op);
       output_asm_insn ("larl\t%2,%3", op);
@@ -15562,6 +15570,12 @@ s390_option_override_internal (bool main_args_p,
   /* Call target specific restore function to do post-init work.  At the moment,
      this just sets opts->x_s390_cost_pointer.  */
   s390_function_specific_restore (opts, NULL);
+
+  /* Check whether -mfentry is supported. It cannot be used in 31-bit mode,
+     because 31-bit PLT stubs assume that %r12 contains GOT address, which is
+     not the case when the code runs before the prolog. */
+  if (opts->x_flag_fentry && !TARGET_64BIT)
+    error ("-mfentry is supported only for 64-bit CPUs");
 }
 
 static void
index eb16f9c821fb05ec8b3d8cfa5cb4027d61181e09..59e97d031b49159a382cdfec462cc448eaa6f50e 100644 (file)
@@ -293,3 +293,8 @@ locations which have been patched as part of using one of the
 -mindirect-branch* or -mfunction-return* options.  The sections
 consist of an array of 32 bit elements. Each entry holds the offset
 from the entry to the patched location.
+
+mfentry
+Target Report Var(flag_fentry)
+Emit profiling counter call at function entry before prologue. The compiled
+code will require a 64-bit CPU and glibc 2.29 or newer to run.
index d1b2558a958fdbdd580be725ef452c55f92afd56..e0503f265ff7e46543d6dc14e39f94cca65c9609 100644 (file)
@@ -1,3 +1,7 @@
+2018-07-16  Ilya Leoshkevich  <iii@linux.ibm.com>
+
+       * gcc.target/s390/mfentry-m64.c: New testcase.
+
 2018-07-16  Hristian Kirtchev  <kirtchev@adacore.com>
 
        * gnat.dg/abstract_state1.adb, gnat.dg/abstract_state1.ads: New
diff --git a/gcc/testsuite/gcc.target/s390/mfentry-m64.c b/gcc/testsuite/gcc.target/s390/mfentry-m64.c
new file mode 100644 (file)
index 0000000..aa3fc81
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do compile { target { lp64 } } } */
+/* { dg-options "-pg -mfentry" } */
+
+void
+profileme (void)
+{
+  /* { dg-final { scan-assembler "brasl\t0,__fentry__" } } */
+}