From: Ilya Leoshkevich Date: Mon, 16 Jul 2018 14:41:57 +0000 (+0000) Subject: S/390: Implement -mnop-mcount X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=79c2f6d7de59d5580d224b491d5600d20e3101fe;p=gcc.git S/390: Implement -mnop-mcount 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 * 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 * 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 808a237604e..56e1ec3d7e3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,8 +1,14 @@ 2018-07-16 Ilya Leoshkevich - * 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 + + * 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 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/ChangeLog b/gcc/testsuite/ChangeLog index 07c87a623cf..30d4ea5cd5d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2018-07-16 Ilya Leoshkevich + + * 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 * 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 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" } } */ +}