Commit 79c2f6d7 by Ilya Leoshkevich Committed by Andreas Krebbel

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  <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
parent 605090dc
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>
......
......@@ -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)
......
......@@ -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.
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.
2018-07-16 Ilya Leoshkevich <iii@linux.ibm.com>
......
/* { 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" } } */
}
/* { 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" } } */
}
/* { 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" } } */
}
/* { 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" } } */
}
/* { 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" } } */
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment