S/390: Implement -mnop-mcount
authorIlya Leoshkevich <iii@linux.ibm.com>
Mon, 16 Jul 2018 14:41:57 +0000 (14:41 +0000)
committerAndreas Krebbel <krebbel@gcc.gnu.org>
Mon, 16 Jul 2018 14:41:57 +0000 (14:41 +0000)
On i386 the profiler call sequence always consists of 1 call
instruction, so -mnop-mcount generates a single nop with the same
length as a call. For S/390 longer sequences may be used in some
cases, so -mnop-mcount generates the corresponding amount of nops.

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

* config/s390/s390.c (s390_function_profiler): Generate nops
instead of profiler call sequences.
* config/s390/s390.opt: Add the new option.

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

* gcc.target/s390/mnop-mcount-m31-fpic.c: New testcase.
* gcc.target/s390/mnop-mcount-m31-mzarch.c: New testcase.
* gcc.target/s390/mnop-mcount-m31.c: New testcase.
* gcc.target/s390/mnop-mcount-m64-mfentry.c: New testcase.
* gcc.target/s390/mnop-mcount-m64.c: New testcase.

From-SVN: r262734

gcc/ChangeLog
gcc/config/s390/s390.c
gcc/config/s390/s390.opt
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/s390/mnop-mcount-m31-fpic.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/mnop-mcount-m31-mzarch.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/mnop-mcount-m31.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/mnop-mcount-m64-mfentry.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/mnop-mcount-m64.c [new file with mode: 0644]

index 808a237604eb18fb22698cb134a1b9ccf04174d3..56e1ec3d7e38d89603505fb08530d363ef2f5191 100644 (file)
@@ -1,8 +1,14 @@
 2018-07-16  Ilya Leoshkevich  <iii@linux.ibm.com>
 
-       * gcc/config/s390/s390.c (s390_function_profiler): Generate
+       * config/s390/s390.c (s390_function_profiler): Generate nops
+       instead of profiler call sequences.
+       * config/s390/s390.opt: Add the new option.
+
+2018-07-16  Ilya Leoshkevich  <iii@linux.ibm.com>
+
+       * config/s390/s390.c (s390_function_profiler): Generate
        __mcount_loc section.
-       * gcc/config/s390/s390.opt: Add the new option.
+       * config/s390/s390.opt: Add the new option.
 
 2018-07-16  Ilya Leoshkevich  <iii@linux.ibm.com>
 
index 600501c1e277450e1b6613100e1425b790451431..ba18cb1c39a4d7a5a7a4ee1e154b693fb1012563 100644 (file)
@@ -13123,6 +13123,30 @@ s390_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
   emit_move_insn (mem, fnaddr);
 }
 
+static void
+output_asm_nops (const char *user, int hw)
+{
+  asm_fprintf (asm_out_file, "\t# NOPs for %s (%d halfwords)\n", user, hw);
+  while (hw > 0)
+    {
+      if (TARGET_CPU_ZARCH && hw >= 3)
+        {
+          output_asm_insn ("brcl\t0,0", NULL);
+          hw -= 3;
+        }
+      else if (hw >= 2)
+        {
+          output_asm_insn ("bc\t0,0", NULL);
+          hw -= 2;
+        }
+      else
+        {
+          output_asm_insn ("bcr\t0,0", NULL);
+          hw -= 1;
+        }
+    }
+}
+
 /* Output assembler code to FILE to increment profiler label # LABELNO
    for profiling a function entry.  */
 
@@ -13156,7 +13180,9 @@ s390_function_profiler (FILE *file, int labelno)
 
   if (flag_fentry)
     {
-      if (cfun->static_chain_decl)
+      if (flag_nop_mcount)
+        output_asm_nops ("-mnop-mcount", /* brasl */ 3);
+      else if (cfun->static_chain_decl)
         warning (OPT_Wcannot_profile, "nested functions cannot be profiled "
                  "with -mfentry on s390");
       else
@@ -13164,48 +13190,77 @@ s390_function_profiler (FILE *file, int labelno)
     }
   else if (TARGET_64BIT)
     {
-      output_asm_insn ("stg\t%0,%1", op);
-      output_asm_insn ("larl\t%2,%3", op);
-      output_asm_insn ("brasl\t%0,%4", op);
-      output_asm_insn ("lg\t%0,%1", op);
+      if (flag_nop_mcount)
+        output_asm_nops ("-mnop-mcount", /* stg */ 3 + /* larl */ 3 +
+                         /* brasl */ 3 + /* lg */ 3);
+      else
+        {
+          output_asm_insn ("stg\t%0,%1", op);
+          output_asm_insn ("larl\t%2,%3", op);
+          output_asm_insn ("brasl\t%0,%4", op);
+          output_asm_insn ("lg\t%0,%1", op);
+        }
     }
   else if (TARGET_CPU_ZARCH)
     {
-      output_asm_insn ("st\t%0,%1", op);
-      output_asm_insn ("larl\t%2,%3", op);
-      output_asm_insn ("brasl\t%0,%4", op);
-      output_asm_insn ("l\t%0,%1", op);
+      if (flag_nop_mcount)
+        output_asm_nops ("-mnop-mcount", /* st */ 2 + /* larl */ 3 +
+                         /* brasl */ 3 + /* l */ 2);
+      else
+        {
+          output_asm_insn ("st\t%0,%1", op);
+          output_asm_insn ("larl\t%2,%3", op);
+          output_asm_insn ("brasl\t%0,%4", op);
+          output_asm_insn ("l\t%0,%1", op);
+        }
     }
   else if (!flag_pic)
     {
       op[6] = gen_label_rtx ();
 
-      output_asm_insn ("st\t%0,%1", op);
-      output_asm_insn ("bras\t%2,%l6", op);
-      output_asm_insn (".long\t%4", op);
-      output_asm_insn (".long\t%3", op);
-      targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
-      output_asm_insn ("l\t%0,0(%2)", op);
-      output_asm_insn ("l\t%2,4(%2)", op);
-      output_asm_insn ("basr\t%0,%0", op);
-      output_asm_insn ("l\t%0,%1", op);
+      if (flag_nop_mcount)
+        output_asm_nops ("-mnop-mcount", /* st */ 2 + /* bras */ 2 +
+                         /* .long */ 2 + /* .long */ 2 + /* l */ 2 +
+                         /* l */ 2 + /* basr */ 1 + /* l */ 2);
+      else
+        {
+          output_asm_insn ("st\t%0,%1", op);
+          output_asm_insn ("bras\t%2,%l6", op);
+          output_asm_insn (".long\t%4", op);
+          output_asm_insn (".long\t%3", op);
+          targetm.asm_out.internal_label (file, "L",
+                                          CODE_LABEL_NUMBER (op[6]));
+          output_asm_insn ("l\t%0,0(%2)", op);
+          output_asm_insn ("l\t%2,4(%2)", op);
+          output_asm_insn ("basr\t%0,%0", op);
+          output_asm_insn ("l\t%0,%1", op);
+        }
     }
   else
     {
       op[5] = gen_label_rtx ();
       op[6] = gen_label_rtx ();
 
-      output_asm_insn ("st\t%0,%1", op);
-      output_asm_insn ("bras\t%2,%l6", op);
-      targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[5]));
-      output_asm_insn (".long\t%4-%l5", op);
-      output_asm_insn (".long\t%3-%l5", op);
-      targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
-      output_asm_insn ("lr\t%0,%2", op);
-      output_asm_insn ("a\t%0,0(%2)", op);
-      output_asm_insn ("a\t%2,4(%2)", op);
-      output_asm_insn ("basr\t%0,%0", op);
-      output_asm_insn ("l\t%0,%1", op);
+      if (flag_nop_mcount)
+        output_asm_nops ("-mnop-mcount", /* st */ 2 + /* bras */ 2 +
+                         /* .long */ 2 + /* .long */ 2 + /* lr */ 1 +
+                         /* a */ 2 + /* a */ 2 + /* basr */ 1 + /* l */ 2);
+      else
+        {
+          output_asm_insn ("st\t%0,%1", op);
+          output_asm_insn ("bras\t%2,%l6", op);
+          targetm.asm_out.internal_label (file, "L",
+                                          CODE_LABEL_NUMBER (op[5]));
+          output_asm_insn (".long\t%4-%l5", op);
+          output_asm_insn (".long\t%3-%l5", op);
+          targetm.asm_out.internal_label (file, "L",
+                                          CODE_LABEL_NUMBER (op[6]));
+          output_asm_insn ("lr\t%0,%2", op);
+          output_asm_insn ("a\t%0,0(%2)", op);
+          output_asm_insn ("a\t%2,4(%2)", op);
+          output_asm_insn ("basr\t%0,%0", op);
+          output_asm_insn ("l\t%0,%1", op);
+        }
     }
 
   if (flag_record_mcount)
index 9a3ed651450bcea3b7a641ec46ac7df5bed852ef..4214b1714c2afbabc48873461d099f253925cbd0 100644 (file)
@@ -302,3 +302,8 @@ code will require a 64-bit CPU and glibc 2.29 or newer to run.
 mrecord-mcount
 Target Report Var(flag_record_mcount)
 Generate __mcount_loc section with all _mcount and __fentry__ calls.
+
+mnop-mcount
+Target Report Var(flag_nop_mcount)
+Generate mcount/__fentry__ calls as nops. To activate they need to be
+patched in.
index 07c87a623cf7c4fe7c2448d3e1e7bf19130d49b2..30d4ea5cd5d02f9e60fad1add26f47ab06ea3b61 100644 (file)
@@ -1,3 +1,11 @@
+2018-07-16  Ilya Leoshkevich  <iii@linux.ibm.com>
+
+       * gcc.target/s390/mnop-mcount-m31-fpic.c: New testcase.
+       * gcc.target/s390/mnop-mcount-m31-mzarch.c: New testcase.
+       * gcc.target/s390/mnop-mcount-m31.c: New testcase.
+       * gcc.target/s390/mnop-mcount-m64-mfentry.c: New testcase.
+       * gcc.target/s390/mnop-mcount-m64.c: New testcase.
+
 2018-07-16  Ilya Leoshkevich  <iii@linux.ibm.com>
 
        * testsuite/gcc.target/s390/mrecord-mcount.c: New testcase.
diff --git a/gcc/testsuite/gcc.target/s390/mnop-mcount-m31-fpic.c b/gcc/testsuite/gcc.target/s390/mnop-mcount-m31-fpic.c
new file mode 100644 (file)
index 0000000..5b00ab6
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-m31 -mesa -march=g5 -fPIC -pg -mnop-mcount -Wno-deprecated" } */
+
+void
+profileme (void)
+{
+  /* { dg-final { scan-assembler "NOPs for -mnop-mcount \\(16 halfwords\\)\n.*bc\t0,0\n.*bc\t0,0\n.*bc\t0,0\n.*bc\t0,0\n.*bc\t0,0\n.*bc\t0,0\n.*bc\t0,0\n.*bc\t0,0" } } */
+}
diff --git a/gcc/testsuite/gcc.target/s390/mnop-mcount-m31-mzarch.c b/gcc/testsuite/gcc.target/s390/mnop-mcount-m31-mzarch.c
new file mode 100644 (file)
index 0000000..b2ad9f5
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-m31 -mzarch -pg -mnop-mcount" } */
+
+void
+profileme (void)
+{
+  /* { dg-final { scan-assembler "NOPs for -mnop-mcount \\(10 halfwords\\)\n.*brcl\t0,0\n.*brcl\t0,0\n.*brcl\t0,0\n.*bcr\t0,0" } } */
+}
diff --git a/gcc/testsuite/gcc.target/s390/mnop-mcount-m31.c b/gcc/testsuite/gcc.target/s390/mnop-mcount-m31.c
new file mode 100644 (file)
index 0000000..e64c8d7
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-m31 -mesa -march=g5 -pg -mnop-mcount -Wno-deprecated" } */
+
+void
+profileme (void)
+{
+  /* { dg-final { scan-assembler "NOPs for -mnop-mcount \\(15 halfwords\\)\n.*bc\t0,0\n.*bc\t0,0\n.*bc\t0,0\n.*bc\t0,0\n.*bc\t0,0\n.*bc\t0,0\n.*bc\t0,0\n.*bcr\t0,0" } } */
+}
diff --git a/gcc/testsuite/gcc.target/s390/mnop-mcount-m64-mfentry.c b/gcc/testsuite/gcc.target/s390/mnop-mcount-m64-mfentry.c
new file mode 100644 (file)
index 0000000..9c1504e
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do compile { target { lp64 } } } */
+/* { dg-options "-pg -mfentry -mnop-mcount" } */
+
+void
+profileme (void)
+{
+  /* { dg-final { scan-assembler "NOPs for -mnop-mcount \\(3 halfwords\\)\n.*brcl\t0,0" } } */
+}
diff --git a/gcc/testsuite/gcc.target/s390/mnop-mcount-m64.c b/gcc/testsuite/gcc.target/s390/mnop-mcount-m64.c
new file mode 100644 (file)
index 0000000..c0e3c4e
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do compile { target { lp64 } } } */
+/* { dg-options "-pg -mnop-mcount" } */
+
+void
+profileme (void)
+{
+  /* { dg-final { scan-assembler "NOPs for -mnop-mcount \\(12 halfwords\\)\n.*brcl\t0,0\n.*brcl\t0,0\n.*brcl\t0,0\n.*brcl\t0,0" } } */
+}