S/390: Hotpatch: Remove special handling of nested functions.

gcc/
2015-03-31  Dominik Vogt  <vogt@linux.vnet.ibm.com>

	    * config/s390/s390.c (s390_function_num_hotpatch_hw): Allow hotpatching
	    nested functions.
	    (s390_reorg): Adapt to new signature of s390_function_num_hotpatch_hw.
	    (s390_asm_output_function_label): Adapt to new signature of
	    s390_function_num_hotpatch_hw
	    Optimise the code generating assembler output.
	    Add comments to assembler file.

gcc/testsuite/
2015-03-31  Dominik Vogt  <vogt@linux.vnet.ibm.com>

	    * gcc.target/s390/hotpatch-25.c: New test.
	    * gcc.target/s390/hotpatch-1.c: Update test.
	    * gcc.target/s390/hotpatch-10.c: Update test.
	    * gcc.target/s390/hotpatch-11.c: Update test.
	    * gcc.target/s390/hotpatch-12.c: Update test.
	    * gcc.target/s390/hotpatch-13.c: Update test.
	    * gcc.target/s390/hotpatch-14.c: Update test.
	    * gcc.target/s390/hotpatch-15.c: Update test.
	    * gcc.target/s390/hotpatch-16.c: Update test.
	    * gcc.target/s390/hotpatch-17.c: Update test.
	    * gcc.target/s390/hotpatch-18.c: Update test.
	    * gcc.target/s390/hotpatch-19.c: Update test.
	    * gcc.target/s390/hotpatch-2.c: Update test.
	    * gcc.target/s390/hotpatch-21.c: Update test.
	    * gcc.target/s390/hotpatch-22.c: Update test.
	    * gcc.target/s390/hotpatch-23.c: Update test.
	    * gcc.target/s390/hotpatch-24.c: Update test.
	    * gcc.target/s390/hotpatch-3.c: Update test.
	    * gcc.target/s390/hotpatch-4.c: Update test.
	    * gcc.target/s390/hotpatch-5.c: Update test.
	    * gcc.target/s390/hotpatch-6.c: Update test.
	    * gcc.target/s390/hotpatch-7.c: Update test.
	    * gcc.target/s390/hotpatch-8.c: Update test.
	    * gcc.target/s390/hotpatch-9.c: Update test.
	    * gcc.target/s390/hotpatch-compile-16.c: Update test.

From-SVN: r221794
This commit is contained in:
Dominik Vogt 2015-03-31 12:07:06 +00:00 committed by Andreas Krebbel
parent bed18fbd09
commit 2d38d80934
28 changed files with 148 additions and 36 deletions

View File

@ -1,3 +1,13 @@
2015-03-31 Dominik Vogt <vogt@linux.vnet.ibm.com>
* config/s390/s390.c (s390_function_num_hotpatch_hw): Allow hotpatching
nested functions.
(s390_reorg): Adapt to new signature of s390_function_num_hotpatch_hw.
(s390_asm_output_function_label): Adapt to new signature of
s390_function_num_hotpatch_hw
Optimise the code generating assembler output.
Add comments to assembler file.
2015-03-31 Richard Biener <rguenther@suse.de>
PR middle-end/65626

View File

@ -5234,21 +5234,18 @@ print_shift_count_operand (FILE *file, rtx op)
fprintf (file, "(%s)", reg_names[REGNO (base)]);
}
/* Returns false if the function should not be made hotpatchable.
Otherwise it assigns the number of NOP halfwords to be emitted
before and after the function label to hw_before and hw_after.
Both must not be NULL. */
/* Assigns the number of NOP halfwords to be emitted before and after the
function label to *HW_BEFORE and *HW_AFTER. Both pointers must not be NULL.
If hotpatching is disabled for the function, the values are set to zero.
*/
static bool
static void
s390_function_num_hotpatch_hw (tree decl,
int *hw_before,
int *hw_after)
{
tree attr;
*hw_before = 0;
*hw_after = 0;
attr = lookup_attribute ("hotpatch", DECL_ATTRIBUTES (decl));
/* Handle the arguments of the hotpatch attribute. The values
@ -5267,18 +5264,6 @@ s390_function_num_hotpatch_hw (tree decl,
*hw_before = s390_hotpatch_hw_before_label;
*hw_after = s390_hotpatch_hw_after_label;
}
if (*hw_before == 0 && *hw_after == 0)
return false;
if (decl_function_context (decl) != NULL_TREE)
{
warning_at (DECL_SOURCE_LOCATION (decl), OPT_mhotpatch_,
"hotpatching is not compatible with nested functions");
return false;
}
return true;
}
/* Write the extra assembler code needed to declare a function properly. */
@ -5288,12 +5273,9 @@ s390_asm_output_function_label (FILE *asm_out_file, const char *fname,
tree decl)
{
int hw_before, hw_after;
bool hotpatch_p = (decl
? s390_function_num_hotpatch_hw (decl,
&hw_before, &hw_after)
: false);
if (hotpatch_p)
s390_function_num_hotpatch_hw (decl, &hw_before, &hw_after);
if (hw_before > 0)
{
unsigned int function_alignment;
int i;
@ -5301,22 +5283,35 @@ s390_asm_output_function_label (FILE *asm_out_file, const char *fname,
/* Add a trampoline code area before the function label and initialize it
with two-byte nop instructions. This area can be overwritten with code
that jumps to a patched version of the function. */
for (i = 0; i < hw_before; i++)
asm_fprintf (asm_out_file, "\tnopr\t%%r7\n");
asm_fprintf (asm_out_file, "\tnopr\t%%r7"
"\t# pre-label NOPs for hotpatch (%d halfwords)\n",
hw_before);
for (i = 1; i < hw_before; i++)
fputs ("\tnopr\t%r7\n", asm_out_file);
/* Note: The function label must be aligned so that (a) the bytes of the
following nop do not cross a cacheline boundary, and (b) a jump address
(eight bytes for 64 bit targets, 4 bytes for 32 bit targets) can be
stored directly before the label without crossing a cacheline
boundary. All this is necessary to make sure the trampoline code can
be changed atomically. */
be changed atomically.
This alignment is done automatically using the FOUNCTION_BOUNDARY, but
if there are NOPs before the function label, the alignment is placed
before them. So it is necessary to duplicate the alignment after the
NOPs. */
function_alignment = MAX (8, DECL_ALIGN (decl) / BITS_PER_UNIT);
if (! DECL_USER_ALIGN (decl))
function_alignment = MAX (function_alignment,
(unsigned int) align_functions);
fputs ("\t# alignment for hotpatch\n", asm_out_file);
ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (function_alignment));
}
ASM_OUTPUT_LABEL (asm_out_file, fname);
if (hw_after > 0)
asm_fprintf (asm_out_file,
"\t# post-label NOPs for hotpatch (%d halfwords)\n",
hw_after);
}
/* Output machine-dependent UNSPECs occurring in address constant X
@ -11491,7 +11486,7 @@ s390_reorg (void)
{
rtx_insn *insn;
/* Inject nops for hotpatching. */
/* Insert NOPs for hotpatching. */
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
{
if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_FUNCTION_BEG)

View File

@ -1,3 +1,31 @@
2015-03-31 Dominik Vogt <vogt@linux.vnet.ibm.com>
* gcc.target/s390/hotpatch-25.c: New test.
* gcc.target/s390/hotpatch-1.c: Update test.
* gcc.target/s390/hotpatch-10.c: Update test.
* gcc.target/s390/hotpatch-11.c: Update test.
* gcc.target/s390/hotpatch-12.c: Update test.
* gcc.target/s390/hotpatch-13.c: Update test.
* gcc.target/s390/hotpatch-14.c: Update test.
* gcc.target/s390/hotpatch-15.c: Update test.
* gcc.target/s390/hotpatch-16.c: Update test.
* gcc.target/s390/hotpatch-17.c: Update test.
* gcc.target/s390/hotpatch-18.c: Update test.
* gcc.target/s390/hotpatch-19.c: Update test.
* gcc.target/s390/hotpatch-2.c: Update test.
* gcc.target/s390/hotpatch-21.c: Update test.
* gcc.target/s390/hotpatch-22.c: Update test.
* gcc.target/s390/hotpatch-23.c: Update test.
* gcc.target/s390/hotpatch-24.c: Update test.
* gcc.target/s390/hotpatch-3.c: Update test.
* gcc.target/s390/hotpatch-4.c: Update test.
* gcc.target/s390/hotpatch-5.c: Update test.
* gcc.target/s390/hotpatch-6.c: Update test.
* gcc.target/s390/hotpatch-7.c: Update test.
* gcc.target/s390/hotpatch-8.c: Update test.
* gcc.target/s390/hotpatch-9.c: Update test.
* gcc.target/s390/hotpatch-compile-16.c: Update test.
2015-03-31 Richard Biener <rguenther@suse.de>
PR middle-end/65626

View File

@ -11,6 +11,9 @@ void hp1(void)
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-not "pre-label NOPs" } } */
/* { dg-final { scan-assembler-not "post-label NOPs" } } */
/* { dg-final { scan-assembler-not "nopr\t%r7" } } */
/* { dg-final { scan-assembler-not "nop\t0" } } */
/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */
/* { dg-final { scan-assembler-not "alignment for hotpatch" } } */

View File

@ -11,6 +11,9 @@ void hp1(void)
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-not "pre-label NOPs" } } */
/* { dg-final { scan-assembler-not "post-label NOPs" } } */
/* { dg-final { scan-assembler-not "nopr\t%r7" } } */
/* { dg-final { scan-assembler-not "nop\t0" } } */
/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */
/* { dg-final { scan-assembler-not "alignment for hotpatch" } } */

View File

@ -11,6 +11,8 @@ void hp1(void)
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler "pre-label.*(1 halfwords)" } } */
/* { dg-final { scan-assembler-not "post-label NOPs" } } */
/* { dg-final { scan-assembler-times "nopr\t%r7" 1 } } */
/* { dg-final { scan-assembler-not "nop\t0" } } */
/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */

View File

@ -11,6 +11,8 @@ void hp1(void)
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler "pre-label.*(999 halfwords)" } } */
/* { dg-final { scan-assembler-not "post-label NOPs" } } */
/* { dg-final { scan-assembler-times "nopr\t%r7" 999 } } */
/* { dg-final { scan-assembler-not "nop\t0" } } */
/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */

View File

@ -12,6 +12,10 @@ void hp1(void)
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler "pre-label.*(1 halfwords)" } } */
/* { dg-final { scan-assembler-not "post-label NOPs" } } */
/* { dg-final { scan-assembler-times "nopr\t%r7" 1 } } */
/* { dg-final { scan-assembler-not "nop\t0" } } */
/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */
/* { dg-final { scan-assembler "alignment for hotpatch" } } */
/* { dg-final { scan-assembler-times "\.align\t8" 2 } } */

View File

@ -12,6 +12,9 @@ void hp1(void)
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-not "pre-label NOPs" } } */
/* { dg-final { scan-assembler "post-label.*(2 halfwords)" } } */
/* { dg-final { scan-assembler-not "nopr\t%r7" } } */
/* { dg-final { scan-assembler-times "nop\t0" 1 } } */
/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */
/* { dg-final { scan-assembler-not "alignment for hotpatch" } } */

View File

@ -12,6 +12,8 @@ void hp1(void)
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler "pre-label.*(1 halfwords)" } } */
/* { dg-final { scan-assembler "post-label.*(2 halfwords)" } } */
/* { dg-final { scan-assembler-times "nopr\t%r7" 1 } } */
/* { dg-final { scan-assembler-times "nop\t0" 1 } } */
/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */

View File

@ -12,6 +12,8 @@ void hp1(void)
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler "pre-label.*(1 halfwords)" } } */
/* { dg-final { scan-assembler "post-label.*(2 halfwords)" } } */
/* { dg-final { scan-assembler-times "nopr\t%r7" 1 } } */
/* { dg-final { scan-assembler-times "nop\t0" 1 } } */
/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */

View File

@ -12,6 +12,9 @@ void hp1(void)
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-not "pre-label NOPs" } } */
/* { dg-final { scan-assembler-not "post-label NOPs" } } */
/* { dg-final { scan-assembler-not "nopr\t%r7" } } */
/* { dg-final { scan-assembler-not "nop\t0" } } */
/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */
/* { dg-final { scan-assembler-not "alignment for hotpatch" } } */

View File

@ -11,6 +11,9 @@ void hp1(void)
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-not "pre-label NOPs" } } */
/* { dg-final { scan-assembler-not "post-label NOPs" } } */
/* { dg-final { scan-assembler-not "nopr\t%r7" } } */
/* { dg-final { scan-assembler-not "nop\t0" } } */
/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */
/* { dg-final { scan-assembler-not "alignment for hotpatch" } } */

View File

@ -18,6 +18,8 @@ void hp1(void)
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler "pre-label.*(1 halfwords)" } } */
/* { dg-final { scan-assembler "post-label.*(2 halfwords)" } } */
/* { dg-final { scan-assembler-times "nopr\t%r7" 1 } } */
/* { dg-final { scan-assembler-times "nop\t0" 1 } } */
/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */

View File

@ -11,7 +11,9 @@ void hp1(void)
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-not "pre-label NOPs" } } */
/* { dg-final { scan-assembler "post-label.*(1 halfwords)" } } */
/* { dg-final { scan-assembler-times "nopr\t%r7" 1 } } */
/* { dg-final { scan-assembler-not "nop\t0" } } */
/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */
/* { dg-final { scan-assembler-times "\.align\t8" 2 } } */
/* { dg-final { scan-assembler-not "alignment for hotpatch" } } */

View File

@ -11,4 +11,4 @@ void __attribute__ ((aligned(512))) hp1(void)
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-times "\.align\t512" 2 } } */
/* { dg-final { scan-assembler-not "alignment for hotpatch" } } */

View File

@ -11,4 +11,4 @@ void hp1(void)
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-times "\.align\t1024" 2 } } */
/* { dg-final { scan-assembler-not "alignment for hotpatch" } } */

View File

@ -11,4 +11,4 @@ void __attribute__ ((aligned(2048))) hp1(void)
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-times "\.align\t2048" 2 } } */
/* { dg-final { scan-assembler-not "alignment for hotpatch" } } */

View File

@ -11,4 +11,4 @@ void __attribute__ ((aligned(4096))) hp1(void)
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-times "\.align\t4096" 2 } } */
/* { dg-final { scan-assembler-not "alignment for hotpatch" } } */

View File

@ -0,0 +1,33 @@
/* Functional tests for the function hotpatching feature. */
/* { dg-do compile } */
/* { dg-options "-O3 -mzarch" } */
typedef long (*fn_t)(void);
__attribute__ ((hotpatch(1,2)))
fn_t outer(void)
{
__attribute__ ((hotpatch(4,8)))
long nested1(void)
{
__attribute__ ((hotpatch(16,32)))
long nested2(void)
{
return 2;
}
return (long)(void *)nested2;
}
return nested1;
}
/* { dg-final { scan-assembler "pre-label.*(1 halfwords)" } } */
/* { dg-final { scan-assembler "pre-label.*(4 halfwords)" } } */
/* { dg-final { scan-assembler "pre-label.*(16 halfwords)" } } */
/* { dg-final { scan-assembler "post-label.*(2 halfwords)" } } */
/* { dg-final { scan-assembler "post-label.*(8 halfwords)" } } */
/* { dg-final { scan-assembler "post-label.*(32 halfwords)" } } */
/* { dg-final { scan-assembler-times "alignment for hotpatch" 3 } } */
/* { dg-final { scan-assembler-times "\.align\t8" 6 } } */
/* { dg-final { scan-assembler "nopr.*\n.*nopr.*\n.*nopr.*\n.*nopr.*\n.*nopr.*\n.*nopr.*\n.*nopr.*\n.*nopr.*\n.*nopr.*\n.*nopr.*\n.*nopr.*\n.*nopr.*\n.*nopr.*\n.*nopr.*\n.*nopr.*\n.*nopr" } } */

View File

@ -11,6 +11,8 @@ void hp1(void)
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-not "pre-label NOPs" } } */
/* { dg-final { scan-assembler "post-label.*(2 halfwords)" } } */
/* { dg-final { scan-assembler-not "nopr\t%r7" } } */
/* { dg-final { scan-assembler-times "nop\t0" 1 } } */
/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */

View File

@ -11,6 +11,8 @@ void hp1(void)
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-not "pre-label NOPs" } } */
/* { dg-final { scan-assembler "post-label.*(3 halfwords)" } } */
/* { dg-final { scan-assembler-not "nopr\t%r7" } } */
/* { dg-final { scan-assembler-not "nop\t0" } } */
/* { dg-final { scan-assembler-times "brcl\t0, 0" 1 } } */

View File

@ -11,6 +11,8 @@ void hp1(void)
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-not "pre-label NOPs" } } */
/* { dg-final { scan-assembler "post-label.*(4 halfwords)" } } */
/* { dg-final { scan-assembler-times "nopr\t%r7" 1 } } */
/* { dg-final { scan-assembler-not "nop\t0" } } */
/* { dg-final { scan-assembler-times "brcl\t0, 0" 1 } } */

View File

@ -11,6 +11,8 @@ void hp1(void)
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-not "pre-label NOPs" } } */
/* { dg-final { scan-assembler "post-label.*(5 halfwords)" } } */
/* { dg-final { scan-assembler-not "nopr\t%r7" } } */
/* { dg-final { scan-assembler-times "nop\t0" 1 } } */
/* { dg-final { scan-assembler-times "brcl\t0, 0" 1 } } */

View File

@ -11,6 +11,8 @@ void hp1(void)
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-not "pre-label NOPs" } } */
/* { dg-final { scan-assembler "post-label.*(6 halfwords)" } } */
/* { dg-final { scan-assembler-not "nopr\t%r7" } } */
/* { dg-final { scan-assembler-not "nop\t0" } } */
/* { dg-final { scan-assembler-times "brcl\t0, 0" 2 } } */

View File

@ -11,6 +11,9 @@ void hp1(void)
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-not "pre-label NOPs" } } */
/* { dg-final { scan-assembler "post-label.*(3 halfwords)" } } */
/* { dg-final { scan-assembler-times "nopr\t%r7" 1 } } */
/* { dg-final { scan-assembler-times "nop\t0" 1 } } */
/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */
/* { dg-final { scan-assembler-not "alignment for hotpatch" } } */

View File

@ -11,6 +11,8 @@ void hp1(void)
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-not "pre-label NOPs" } } */
/* { dg-final { scan-assembler "post-label.*(4 halfwords)" } } */
/* { dg-final { scan-assembler-not "nopr\t%r7" } } */
/* { dg-final { scan-assembler-times "nop\t0" 2 } } */
/* { dg-final { scan-assembler-not "brcl\t0, 0" } } */

View File

@ -1,4 +1,4 @@
/* A warning will be issued when requesting hotpatching on a nested function. */
/* Functional tests for the function hotpatching feature. */
/* { dg-do compile } */
/* { dg-options "-O3 -mzarch" } */
@ -17,7 +17,7 @@ fn_t hp1(void)
fn_t hp2(void)
{
__attribute__ ((hotpatch(1,2)))
int nested2(void) /* { dg-warning "hotpatching is not compatible with nested functions" } */
int nested2(void)
{ return 2; }
return nested2;