This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH 3/3] S/390: Implement -mnop-mcount
- From: Ilya Leoshkevich <iii at linux dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: krebbel at linux dot ibm dot com, Ilya Leoshkevich <iii at linux dot ibm dot com>
- Date: Mon, 16 Jul 2018 09:48:07 +0200
- Subject: [PATCH 3/3] S/390: Implement -mnop-mcount
- References: <20180716074807.43653-1-iii@linux.ibm.com>
This is the counterpart of the i386 feature introduced by
39a5a6a4: Add direct support for Linux kernel __fentry__ patching.
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.
* gcc/config/s390/s390.c (s390_function_profiler): Generate
nops instead of profiler call sequences.
* gcc/config/s390/s390.opt: Add the new option.
* gcc/testsuite/gcc.target/s390/mnop-mcount-m31-fpic.c:
New testcase.
* gcc/testsuite/gcc.target/s390/mnop-mcount-m31-mzarch.c
New testcase.
* gcc/testsuite/gcc.target/s390/mnop-mcount-m31.c
New testcase.
* gcc/testsuite/gcc.target/s390/mnop-mcount-m64-mfentry.c
New testcase.
* gcc/testsuite/gcc.target/s390/mnop-mcount-m64.c
New testcase.
---
gcc/config/s390/s390.c | 113 +++++++++++++-----
gcc/config/s390/s390.opt | 5 +
.../gcc.target/s390/mnop-mcount-m31-fpic.c | 8 ++
.../gcc.target/s390/mnop-mcount-m31-mzarch.c | 8 ++
.../gcc.target/s390/mnop-mcount-m31.c | 8 ++
.../gcc.target/s390/mnop-mcount-m64-mfentry.c | 8 ++
.../gcc.target/s390/mnop-mcount-m64.c | 8 ++
7 files changed, 129 insertions(+), 29 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/s390/mnop-mcount-m31-fpic.c
create mode 100644 gcc/testsuite/gcc.target/s390/mnop-mcount-m31-mzarch.c
create mode 100644 gcc/testsuite/gcc.target/s390/mnop-mcount-m31.c
create mode 100644 gcc/testsuite/gcc.target/s390/mnop-mcount-m64-mfentry.c
create mode 100644 gcc/testsuite/gcc.target/s390/mnop-mcount-m64.c
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 600501c1e27..ba18cb1c39a 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -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)
diff --git a/gcc/config/s390/s390.opt b/gcc/config/s390/s390.opt
index 9a3ed651450..4214b1714c2 100644
--- a/gcc/config/s390/s390.opt
+++ b/gcc/config/s390/s390.opt
@@ -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.
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
index 00000000000..5b00ab65668
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/mnop-mcount-m31-fpic.c
@@ -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
index 00000000000..b2ad9f5bced
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/mnop-mcount-m31-mzarch.c
@@ -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
index 00000000000..e64c8d7d7bc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/mnop-mcount-m31.c
@@ -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
index 00000000000..9c1504e8d63
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/mnop-mcount-m64-mfentry.c
@@ -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
index 00000000000..c0e3c4e91b1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/mnop-mcount-m64.c
@@ -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" } } */
+}
--
2.17.1