s390.c (s390_hotpatch_trampoline_halfwords_default): New constant

2013-12-19  Dominik Vogt  <vogt@linux.vnet.ibm.com>
	    Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>

	* config/s390/s390.c (s390_hotpatch_trampoline_halfwords_default): New
	constant
	(s390_hotpatch_trampoline_halfwords_max): New constant
	(s390_hotpatch_trampoline_halfwords): New static variable
	(get_hotpatch_attribute): New function
	(s390_handle_hotpatch_attribute): New function
	(s390_attribute_table): New target specific attribute table to implement
	the hotpatch attribute
	(s390_option_override): Parse hotpatch options
	(s390_function_num_hotpatch_trampoline_halfwords): New function
	(s390_can_inline_p): Implement target hook to
	suppress hotpatching for explicitly inlined functions
	(s390_asm_output_function_label): Generate hotpatch prologue
	(TARGET_ATTRIBUTE_TABLE): Define to implement target attribute table
	(TARGET_CAN_INLINE_P): Define to implement target hook
	* config/s390/s390.opt (mhotpatch): New options -mhotpatch, -mhotpatch=
	* config/s390/s390-protos.h (s390_asm_output_function_label): Add
	prototype
	* config/s390/s390.h (ASM_OUTPUT_FUNCTION_LABEL): Target specific
	function label generation for hotpatching
	(FUNCTION_BOUNDARY): Align functions to eight bytes
	* doc/extend.texi: Document hotpatch attribute
	* doc/invoke.texi: Document -mhotpatch option

2013-12-19  Dominik Vogt  <vogt@linux.vnet.ibm.com>
	    Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>

	* gcc/testsuite/gcc.target/s390/hotpatch-1.c: New test
	* gcc/testsuite/gcc.target/s390/hotpatch-2.c: New test
	* gcc/testsuite/gcc.target/s390/hotpatch-3.c: New test
	* gcc/testsuite/gcc.target/s390/hotpatch-4.c: New test
	* gcc/testsuite/gcc.target/s390/hotpatch-5.c: New test
	* gcc/testsuite/gcc.target/s390/hotpatch-6.c: New test
	* gcc/testsuite/gcc.target/s390/hotpatch-7.c: New test
	* gcc/testsuite/gcc.target/s390/hotpatch-8.c: New test
	* gcc/testsuite/gcc.target/s390/hotpatch-9.c: New test
	* gcc/testsuite/gcc.target/s390/hotpatch-10.c: New test
	* gcc/testsuite/gcc.target/s390/hotpatch-11.c: New test
	* gcc/testsuite/gcc.target/s390/hotpatch-12.c: New test
	* gcc/testsuite/gcc.target/s390/hotpatch-compile-1.c: New test
	* gcc/testsuite/gcc.target/s390/hotpatch-compile-2.c: New test
	* gcc/testsuite/gcc.target/s390/hotpatch-compile-3.c: New test
	* gcc/testsuite/gcc.target/s390/hotpatch-compile-4.c: New test
	* gcc/testsuite/gcc.target/s390/hotpatch-compile-5.c: New test
	* gcc/testsuite/gcc.target/s390/hotpatch-compile-6.c: New test
	* gcc/testsuite/gcc.target/s390/hotpatch-compile-7.c: New test



Co-Authored-By: Andreas Krebbel <Andreas.Krebbel@de.ibm.com>

From-SVN: r206111
This commit is contained in:
Dominik Vogt 2013-12-19 12:00:43 +00:00 committed by Andreas Krebbel
parent 2f62165dce
commit d0de9e136f
27 changed files with 750 additions and 2 deletions

View File

@ -1,3 +1,30 @@
2013-12-19 Dominik Vogt <vogt@linux.vnet.ibm.com>
Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
* config/s390/s390.c (s390_hotpatch_trampoline_halfwords_default): New
constant
(s390_hotpatch_trampoline_halfwords_max): New constant
(s390_hotpatch_trampoline_halfwords): New static variable
(get_hotpatch_attribute): New function
(s390_handle_hotpatch_attribute): New function
(s390_attribute_table): New target specific attribute table to implement
the hotpatch attribute
(s390_option_override): Parse hotpatch options
(s390_function_num_hotpatch_trampoline_halfwords): New function
(s390_can_inline_p): Implement target hook to
suppress hotpatching for explicitly inlined functions
(s390_asm_output_function_label): Generate hotpatch prologue
(TARGET_ATTRIBUTE_TABLE): Define to implement target attribute table
(TARGET_CAN_INLINE_P): Define to implement target hook
* config/s390/s390.opt (mhotpatch): New options -mhotpatch, -mhotpatch=
* config/s390/s390-protos.h (s390_asm_output_function_label): Add
prototype
* config/s390/s390.h (ASM_OUTPUT_FUNCTION_LABEL): Target specific
function label generation for hotpatching
(FUNCTION_BOUNDARY): Align functions to eight bytes
* doc/extend.texi: Document hotpatch attribute
* doc/invoke.texi: Document -mhotpatch option
2013-12-19 Ganesh Gopalasubramanian <Ganesh.Gopalasubramanian@amd.com> 2013-12-19 Ganesh Gopalasubramanian <Ganesh.Gopalasubramanian@amd.com>
* config/i386/i386.c: Include cfgloop.h. * config/i386/i386.c: Include cfgloop.h.

View File

@ -110,5 +110,6 @@ extern bool s390_decompose_shift_count (rtx, rtx *, HOST_WIDE_INT *);
extern int s390_branch_condition_mask (rtx); extern int s390_branch_condition_mask (rtx);
extern int s390_compare_and_branch_condition_mask (rtx); extern int s390_compare_and_branch_condition_mask (rtx);
extern bool s390_extzv_shift_ok (int, int, unsigned HOST_WIDE_INT); extern bool s390_extzv_shift_ok (int, int, unsigned HOST_WIDE_INT);
extern void s390_asm_output_function_label (FILE *, const char *, tree);
#endif /* RTX_CODE */ #endif /* RTX_CODE */

View File

@ -434,6 +434,65 @@ struct GTY(()) machine_function
bytes on a z10 (or higher) CPU. */ bytes on a z10 (or higher) CPU. */
#define PREDICT_DISTANCE (TARGET_Z10 ? 384 : 2048) #define PREDICT_DISTANCE (TARGET_Z10 ? 384 : 2048)
static const int s390_hotpatch_trampoline_halfwords_default = 12;
static const int s390_hotpatch_trampoline_halfwords_max = 1000000;
static int s390_hotpatch_trampoline_halfwords = -1;
/* Return the argument of the given hotpatch attribute or the default value if
no argument is present. */
static inline int
get_hotpatch_attribute (tree hotpatch_attr)
{
const_tree args;
args = TREE_VALUE (hotpatch_attr);
return (args) ?
TREE_INT_CST_LOW (TREE_VALUE (args)):
s390_hotpatch_trampoline_halfwords_default;
}
/* Check whether the hotpatch attribute is applied to a function and, if it has
an argument, the argument is valid. */
static tree
s390_handle_hotpatch_attribute (tree *node, tree name, tree args,
int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
if (TREE_CODE (*node) != FUNCTION_DECL)
{
warning (OPT_Wattributes, "%qE attribute only applies to functions",
name);
*no_add_attrs = true;
}
else if (args)
{
tree expr = TREE_VALUE (args);
if (TREE_CODE (expr) != INTEGER_CST
|| !INTEGRAL_TYPE_P (TREE_TYPE (expr))
|| TREE_INT_CST_HIGH (expr) != 0
|| TREE_INT_CST_LOW (expr) > (unsigned int)
s390_hotpatch_trampoline_halfwords_max)
{
error ("requested %qE attribute is not a non-negative integer"
" constant or too large (max. %d)", name,
s390_hotpatch_trampoline_halfwords_max);
*no_add_attrs = true;
}
}
return NULL_TREE;
}
static const struct attribute_spec s390_attribute_table[] = {
{ "hotpatch", 0, 1, true, false, false, s390_handle_hotpatch_attribute, false
},
/* End element. */
{ NULL, 0, 0, false, false, false, NULL, false }
};
/* Return the alignment for LABEL. We default to the -falign-labels /* Return the alignment for LABEL. We default to the -falign-labels
value except for the literal pool base label. */ value except for the literal pool base label. */
int int
@ -1622,6 +1681,46 @@ s390_init_machine_status (void)
static void static void
s390_option_override (void) s390_option_override (void)
{ {
unsigned int i;
cl_deferred_option *opt;
vec<cl_deferred_option> *v =
(vec<cl_deferred_option> *) s390_deferred_options;
if (v)
FOR_EACH_VEC_ELT (*v, i, opt)
{
switch (opt->opt_index)
{
case OPT_mhotpatch:
s390_hotpatch_trampoline_halfwords = (opt->value) ?
s390_hotpatch_trampoline_halfwords_default : -1;
break;
case OPT_mhotpatch_:
{
int val;
val = integral_argument (opt->arg);
if (val == -1)
{
/* argument is not a plain number */
error ("argument to %qs should be a non-negative integer",
"-mhotpatch=");
break;
}
else if (val > s390_hotpatch_trampoline_halfwords_max)
{
error ("argument to %qs is too large (max. %d)",
"-mhotpatch=", s390_hotpatch_trampoline_halfwords_max);
break;
}
s390_hotpatch_trampoline_halfwords = val;
break;
}
default:
gcc_unreachable ();
}
}
/* Set up function hooks. */ /* Set up function hooks. */
init_machine_status = s390_init_machine_status; init_machine_status = s390_init_machine_status;
@ -5347,6 +5446,102 @@ get_some_local_dynamic_name (void)
gcc_unreachable (); gcc_unreachable ();
} }
/* Returns -1 if the function should not be made hotpatchable. Otherwise it
returns a number >= 0 that is the desired size of the hotpatch trampoline
in halfwords. */
static int s390_function_num_hotpatch_trampoline_halfwords (tree decl,
bool do_warn)
{
tree attr;
if (DECL_DECLARED_INLINE_P (decl)
|| DECL_ARTIFICIAL (decl)
|| MAIN_NAME_P (DECL_NAME (decl)))
{
/* - Explicitly inlined functions cannot be hotpatched.
- Artificial functions need not be hotpatched.
- Making the main function hotpatchable is useless. */
return -1;
}
attr = lookup_attribute ("hotpatch", DECL_ATTRIBUTES (decl));
if (attr || s390_hotpatch_trampoline_halfwords >= 0)
{
if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl)))
{
if (do_warn)
warning (OPT_Wattributes, "function %qE with the %qs attribute"
" is not hotpatchable", DECL_NAME (decl), "always_inline");
return -1;
}
else
{
return (attr) ?
get_hotpatch_attribute (attr) : s390_hotpatch_trampoline_halfwords;
}
}
return -1;
}
/* Hook to determine if one function can safely inline another. */
static bool
s390_can_inline_p (tree caller, tree callee)
{
if (s390_function_num_hotpatch_trampoline_halfwords (callee, false) >= 0)
return false;
return default_target_can_inline_p (caller, callee);
}
/* Write the extra assembler code needed to declare a function properly. */
void
s390_asm_output_function_label (FILE *asm_out_file, const char *fname,
tree decl)
{
int hotpatch_trampoline_halfwords = -1;
if (decl)
{
hotpatch_trampoline_halfwords =
s390_function_num_hotpatch_trampoline_halfwords (decl, true);
if (hotpatch_trampoline_halfwords >= 0
&& decl_function_context (decl) != NULL_TREE)
{
warning_at (0, DECL_SOURCE_LOCATION (decl),
"hotpatch_prologue is not compatible with nested"
" function");
hotpatch_trampoline_halfwords = -1;
}
}
if (hotpatch_trampoline_halfwords > 0)
{
int i;
/* 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 < hotpatch_trampoline_halfwords; i++)
asm_fprintf (asm_out_file, "\tnopr\t%%r7\n");
/* 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. */
}
ASM_OUTPUT_LABEL (asm_out_file, fname);
/* Output a four-byte nop if hotpatching is enabled. This can be overwritten
atomically with a relative backwards jump to the trampoline area. */
if (hotpatch_trampoline_halfwords >= 0)
asm_fprintf (asm_out_file, "\tnop\t0\n");
}
/* Output machine-dependent UNSPECs occurring in address constant X /* Output machine-dependent UNSPECs occurring in address constant X
in assembler syntax to stdio stream FILE. Returns true if the in assembler syntax to stdio stream FILE. Returns true if the
constant X could be recognized, false otherwise. */ constant X could be recognized, false otherwise. */
@ -11920,6 +12115,12 @@ s390_loop_unroll_adjust (unsigned nunroll, struct loop *loop)
#undef TARGET_HARD_REGNO_SCRATCH_OK #undef TARGET_HARD_REGNO_SCRATCH_OK
#define TARGET_HARD_REGNO_SCRATCH_OK s390_hard_regno_scratch_ok #define TARGET_HARD_REGNO_SCRATCH_OK s390_hard_regno_scratch_ok
#undef TARGET_ATTRIBUTE_TABLE
#define TARGET_ATTRIBUTE_TABLE s390_attribute_table
#undef TARGET_CAN_INLINE_P
#define TARGET_CAN_INLINE_P s390_can_inline_p
struct gcc_target targetm = TARGET_INITIALIZER; struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-s390.h" #include "gt-s390.h"

View File

@ -217,7 +217,7 @@ enum processor_flags
#define STACK_BOUNDARY 64 #define STACK_BOUNDARY 64
/* Allocation boundary (in *bits*) for the code of a function. */ /* Allocation boundary (in *bits*) for the code of a function. */
#define FUNCTION_BOUNDARY 32 #define FUNCTION_BOUNDARY 64
/* There is no point aligning anything to a rounder boundary than this. */ /* There is no point aligning anything to a rounder boundary than this. */
#define BIGGEST_ALIGNMENT 64 #define BIGGEST_ALIGNMENT 64
@ -878,6 +878,9 @@ do { \
fputc ('\n', (FILE)); \ fputc ('\n', (FILE)); \
} while (0) } while (0)
#undef ASM_OUTPUT_FUNCTION_LABEL
#define ASM_OUTPUT_FUNCTION_LABEL(FILE, NAME, DECL) \
s390_asm_output_function_label (FILE, NAME, DECL)
/* Miscellaneous parameters. */ /* Miscellaneous parameters. */

View File

@ -96,6 +96,14 @@ mhard-float
Target Report RejectNegative Negative(msoft-float) InverseMask(SOFT_FLOAT, HARD_FLOAT) Target Report RejectNegative Negative(msoft-float) InverseMask(SOFT_FLOAT, HARD_FLOAT)
Enable hardware floating point Enable hardware floating point
mhotpatch
Target Report Var(s390_deferred_options) Defer
Prepend the function label with 12 two-byte Nop instructions, and add a four byte Nop instruction after the label for hotpatching.
mhotpatch=
Target RejectNegative Report Joined Var(s390_deferred_options) Defer
Prepend the function label with the given number of two-byte Nop instructions, and add a four byte Nop instruction after the label for hotpatching.
mlong-double-128 mlong-double-128
Target Report RejectNegative Negative(mlong-double-64) Mask(LONG_DOUBLE_128) Target Report RejectNegative Negative(mlong-double-64) Mask(LONG_DOUBLE_128)
Use 128-bit long double Use 128-bit long double

View File

@ -3266,6 +3266,17 @@ this function attribute to make GCC generate the ``hot-patching'' function
prologue used in Win32 API functions in Microsoft Windows XP Service Pack 2 prologue used in Win32 API functions in Microsoft Windows XP Service Pack 2
and newer. and newer.
@item hotpatch [(@var{prologue-halfwords})]
@cindex @code{hotpatch} attribute
On S/390 System z targets, you can use this function attribute to
make GCC generate a ``hot-patching'' function prologue. The
@code{hotpatch} has no effect on funtions that are explicitly
inline. If the @option{-mhotpatch} or @option{-mno-hotpatch}
command-line option is used at the same time, the @code{hotpatch}
attribute takes precedence. If an argument is given, the maximum
allowed value is 1000000.
@item naked @item naked
@cindex function without a prologue/epilogue code @cindex function without a prologue/epilogue code
Use this attribute on the ARM, AVR, MCORE, MSP430, NDS32, RL78, RX and SPU Use this attribute on the ARM, AVR, MCORE, MSP430, NDS32, RL78, RX and SPU

View File

@ -933,7 +933,8 @@ See RS/6000 and PowerPC Options.
-msmall-exec -mno-small-exec -mmvcle -mno-mvcle @gol -msmall-exec -mno-small-exec -mmvcle -mno-mvcle @gol
-m64 -m31 -mdebug -mno-debug -mesa -mzarch @gol -m64 -m31 -mdebug -mno-debug -mesa -mzarch @gol
-mtpf-trace -mno-tpf-trace -mfused-madd -mno-fused-madd @gol -mtpf-trace -mno-tpf-trace -mfused-madd -mno-fused-madd @gol
-mwarn-framesize -mwarn-dynamicstack -mstack-size -mstack-guard} -mwarn-framesize -mwarn-dynamicstack -mstack-size -mstack-guard @gol
-mhotpatch[=@var{halfwords}] -mno-hotpatch}
@emph{Score Options} @emph{Score Options}
@gccoptlist{-meb -mel @gol @gccoptlist{-meb -mel @gol
@ -19777,6 +19778,21 @@ values have to be exact powers of 2 and @var{stack-size} has to be greater than
In order to be efficient the extra code makes the assumption that the stack starts In order to be efficient the extra code makes the assumption that the stack starts
at an address aligned to the value given by @var{stack-size}. at an address aligned to the value given by @var{stack-size}.
The @var{stack-guard} option can only be used in conjunction with @var{stack-size}. The @var{stack-guard} option can only be used in conjunction with @var{stack-size}.
@item -mhotpatch[=@var{halfwords}]
@itemx -mno-hotpatch
@opindex mhotpatch
If the hotpatch option is enabled, a ``hot-patching'' function
prologue is generated for all functions in the compilation unit.
The funtion label is prepended with the given number of two-byte
Nop instructions (@var{halfwords}, maximum 1000000) or 12 Nop
instructions if no argument is present. Functions with a
hot-patching prologue are never inlined automatically, and a
hot-patching prologue is never generated for functions functions
that are explicitly inline.
This option can be overridden for individual functions with the
@code{hotpatch} attribute.
@end table @end table
@node Score Options @node Score Options

View File

@ -1,3 +1,26 @@
2013-12-19 Dominik Vogt <vogt@linux.vnet.ibm.com>
Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
* gcc/testsuite/gcc.target/s390/hotpatch-1.c: New test
* gcc/testsuite/gcc.target/s390/hotpatch-2.c: New test
* gcc/testsuite/gcc.target/s390/hotpatch-3.c: New test
* gcc/testsuite/gcc.target/s390/hotpatch-4.c: New test
* gcc/testsuite/gcc.target/s390/hotpatch-5.c: New test
* gcc/testsuite/gcc.target/s390/hotpatch-6.c: New test
* gcc/testsuite/gcc.target/s390/hotpatch-7.c: New test
* gcc/testsuite/gcc.target/s390/hotpatch-8.c: New test
* gcc/testsuite/gcc.target/s390/hotpatch-9.c: New test
* gcc/testsuite/gcc.target/s390/hotpatch-10.c: New test
* gcc/testsuite/gcc.target/s390/hotpatch-11.c: New test
* gcc/testsuite/gcc.target/s390/hotpatch-12.c: New test
* gcc/testsuite/gcc.target/s390/hotpatch-compile-1.c: New test
* gcc/testsuite/gcc.target/s390/hotpatch-compile-2.c: New test
* gcc/testsuite/gcc.target/s390/hotpatch-compile-3.c: New test
* gcc/testsuite/gcc.target/s390/hotpatch-compile-4.c: New test
* gcc/testsuite/gcc.target/s390/hotpatch-compile-5.c: New test
* gcc/testsuite/gcc.target/s390/hotpatch-compile-6.c: New test
* gcc/testsuite/gcc.target/s390/hotpatch-compile-7.c: New test
2013-12-19 Kyrylo Tkachov <kyrylo.tkachov@arm.com> 2013-12-19 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* c-c++-common/cilk-plus/SE/ef_error.c: Add fopenmp effective * c-c++-common/cilk-plus/SE/ef_error.c: Add fopenmp effective

View File

@ -0,0 +1,20 @@
/* Functional tests for the function hotpatching feature. */
/* { dg-do run } */
/* { dg-options "-O3 -mzarch -mhotpatch --save-temps" } */
#include <stdio.h>
void hp1(void)
{
printf("hello, world!\n");
}
int main (void)
{
return 0;
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-times "nopr\t%r7" 12 } } */
/* { dg-final { scan-assembler-times "nop\t0" 1 } } */

View File

@ -0,0 +1,21 @@
/* Functional tests for the function hotpatching feature. */
/* { dg-do run } */
/* { dg-options "-O3 -mzarch -mno-hotpatch --save-temps" } */
#include <stdio.h>
__attribute__ ((hotpatch(2)))
void hp1(void)
{
printf("hello, world!\n");
}
int main (void)
{
return 0;
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-times "nopr\t%r7" 2 } } */
/* { dg-final { scan-assembler-times "nop\t0" 1 } } */

View File

@ -0,0 +1,20 @@
/* Functional tests for the function hotpatching feature. */
/* { dg-do run } */
/* { dg-options "-O3 -mzarch -mhotpatch -mno-hotpatch --save-temps" } */
#include <stdio.h>
void hp1(void)
{
printf("hello, world!\n");
}
int main (void)
{
return 0;
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-not "nopr\t%r7" } } */
/* { dg-final { scan-assembler-not "nop\t0" } } */

View File

@ -0,0 +1,20 @@
/* Functional tests for the function hotpatching feature. */
/* { dg-do run } */
/* { dg-options "-O3 -mzarch -mno-hotpatch -mhotpatch=1 --save-temps" } */
#include <stdio.h>
void hp1(void)
{
printf("hello, world!\n");
}
int main (void)
{
return 0;
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-times "nopr\t%r7" 1 } } */
/* { dg-final { scan-assembler-times "nop\t0" 1 } } */

View File

@ -0,0 +1,20 @@
/* Functional tests for the function hotpatching feature. */
/* { dg-do run } */
/* { dg-options "-O3 -mzarch -mhotpatch=1 --save-temps" } */
#include <stdio.h>
void hp1(void)
{
printf("hello, world!\n");
}
int main (void)
{
return 0;
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-times "nopr\t%r7" 1 } } */
/* { dg-final { scan-assembler-times "nop\t0" 1 } } */

View File

@ -0,0 +1,20 @@
/* Functional tests for the function hotpatching feature. */
/* { dg-do run } */
/* { dg-options "-O3 -mzarch -mhotpatch=0 --save-temps" } */
#include <stdio.h>
void hp1(void)
{
printf("hello, world!\n");
}
int main (void)
{
return 0;
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-not "nopr\t%r7" } } */
/* { dg-final { scan-assembler-times "nop\t0" 1 } } */

View File

@ -0,0 +1,26 @@
/* Functional tests for the function hotpatching feature. */
/* { dg-do run } */
/* { dg-options "-O3 -mzarch -mhotpatch --save-temps" } */
#include <stdio.h>
inline void hp1(void)
{
printf("hello, world!\n");
}
__attribute__ ((always_inline))
void hp2(void) /* { dg-warning "always_inline function might not be inlinable" } */
{
printf("hello, world!\n");
} /* { dg-warning "function 'hp2' with the 'always_inline' attribute is not hotpatchable" } */
int main (void)
{
return 0;
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-not "nopr\t%r7" } } */
/* { dg-final { scan-assembler-not "nop\t0" } } */

View File

@ -0,0 +1,21 @@
/* Functional tests for the function hotpatching feature. */
/* { dg-do run } */
/* { dg-options "-O3 -mzarch -mhotpatch --save-temps" } */
#include <stdio.h>
__attribute__ ((hotpatch))
void hp1(void)
{
printf("hello, world!\n");
}
int main (void)
{
return 0;
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-times "nopr\t%r7" 12 } } */
/* { dg-final { scan-assembler-times "nop\t0" 1 } } */

View File

@ -0,0 +1,21 @@
/* Functional tests for the function hotpatching feature. */
/* { dg-do run } */
/* { dg-options "-O3 -mzarch -mhotpatch --save-temps" } */
#include <stdio.h>
__attribute__ ((hotpatch(1)))
void hp1(void)
{
printf("hello, world!\n");
}
int main (void)
{
return 0;
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-times "nopr\t%r7" 1 } } */
/* { dg-final { scan-assembler-times "nop\t0" 1 } } */

View File

@ -0,0 +1,21 @@
/* Functional tests for the function hotpatching feature. */
/* { dg-do run } */
/* { dg-options "-O3 -mzarch -mhotpatch --save-temps" } */
#include <stdio.h>
__attribute__ ((hotpatch(0)))
void hp1(void)
{
printf("hello, world!\n");
}
int main (void)
{
return 0;
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-not "nopr\t%r7" } } */
/* { dg-final { scan-assembler-times "nop\t0" 1 } } */

View File

@ -0,0 +1,28 @@
/* Functional tests for the function hotpatching feature. */
/* { dg-do run } */
/* { dg-options "-O3 -mzarch -mhotpatch --save-temps" } */
#include <stdio.h>
__attribute__ ((hotpatch))
inline void hp1(void)
{
printf("hello, world!\n");
}
__attribute__ ((hotpatch))
__attribute__ ((always_inline))
void hp2(void) /* { dg-warning "always_inline function might not be inlinable" } */
{
printf("hello, world!\n");
} /* { dg-warning "function 'hp2' with the 'always_inline' attribute is not hotpatchable" } */
int main (void)
{
return 0;
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-not "nopr\t%r7" } } */
/* { dg-final { scan-assembler-not "nop\t0" } } */

View File

@ -0,0 +1,21 @@
/* Functional tests for the function hotpatching feature. */
/* { dg-do run } */
/* { dg-options "-O3 -mzarch -mhotpatch=1 --save-temps" } */
#include <stdio.h>
__attribute__ ((hotpatch(2)))
void hp1(void)
{
printf("hello, world!\n");
}
int main (void)
{
return 0;
}
/* Check number of occurences of certain instructions. */
/* { dg-final { scan-assembler-times "nopr\t%r7" 2 } } */
/* { dg-final { scan-assembler-times "nop\t0" 1 } } */

View File

@ -0,0 +1,27 @@
/* Functional tests for the function hotpatching feature. */
/* { dg-do run } */
/* { dg-options "-O3 -mzarch -mhotpatch" } */
#include <stdio.h>
void hp1(void)
{
printf("hello, world!\n");
}
inline void hp2(void)
{
printf("hello, world!\n");
}
__attribute__ ((always_inline))
void hp3(void) /* { dg-warning "always_inline function might not be inlinable" } */
{
printf("hello, world!\n");
} /* { dg-warning "function 'hp3' with the 'always_inline' attribute is not hotpatchable" } */
int main (void)
{
return 0;
}

View File

@ -0,0 +1,27 @@
/* Functional tests for the function hotpatching feature. */
/* { dg-do run } */
/* { dg-options "-O3 -mzarch -mhotpatch=0" } */
#include <stdio.h>
void hp1(void)
{
printf("hello, world!\n");
}
inline void hp2(void)
{
printf("hello, world!\n");
}
__attribute__ ((always_inline))
void hp3(void) /* { dg-warning "always_inline function might not be inlinable" } */
{
printf("hello, world!\n");
} /* { dg-warning "function 'hp3' with the 'always_inline' attribute is not hotpatchable" } */
int main (void)
{
return 0;
}

View File

@ -0,0 +1,27 @@
/* Functional tests for the function hotpatching feature. */
/* { dg-do run } */
/* { dg-options "-O3 -mzarch -mhotpatch=1" } */
#include <stdio.h>
void hp1(void)
{
printf("hello, world!\n");
}
inline void hp2(void)
{
printf("hello, world!\n");
}
__attribute__ ((always_inline))
void hp3(void) /* { dg-warning "always_inline function might not be inlinable" } */
{
printf("hello, world!\n");
} /* { dg-warning "function 'hp3' with the 'always_inline' attribute is not hotpatchable" } */
int main (void)
{
return 0;
}

View File

@ -0,0 +1,11 @@
/* Functional tests for the function hotpatching feature. */
/* { dg-do compile } */
/* { dg-options "-O3 -mzarch -mhotpatch=-1" } */
int main (void)
{
return 0;
}
/* { dg-excess-errors "argument to '-mhotpatch=' should be a non-negative integer" } */

View File

@ -0,0 +1,28 @@
/* Functional tests for the function hotpatching feature. */
/* { dg-do compile } */
/* { dg-options "-O3 -mzarch -mhotpatch=1000000" } */
#include <stdio.h>
void hp1(void)
{
printf("hello, world!\n");
}
__attribute__ ((hotpatch(1000000)))
void hp2(void)
{
printf("hello, world!\n");
}
__attribute__ ((hotpatch(1000001)))
void hp3(void)
{ /* { dg-error "requested 'hotpatch' attribute is not a non-negative integer constant or too large .max. 1000000." } */
printf("hello, world!\n");
}
int main (void)
{
return 0;
}

View File

@ -0,0 +1,11 @@
/* Functional tests for the function hotpatching feature. */
/* { dg-do compile } */
/* { dg-options "-O3 -mzarch -mhotpatch=1000001" } */
int main (void)
{
return 0;
}
/* { dg-excess-errors "argument to '-mhotpatch=' is too large .max. 1000000." } */

View File

@ -0,0 +1,68 @@
/* Functional tests for the function hotpatching feature. */
/* { dg-do run } */
/* { dg-options "-O3 -mzarch -mno-hotpatch" } */
#include <stdio.h>
__attribute__ ((hotpatch))
void hp1(void)
{
printf("hello, world!\n");
}
__attribute__ ((hotpatch))
inline void hp2(void)
{
printf("hello, world!\n");
}
__attribute__ ((hotpatch))
__attribute__ ((always_inline))
void hp3(void) /* { dg-warning "always_inline function might not be inlinable" } */
{
printf("hello, world!\n");
} /* { dg-warning "function 'hp3' with the 'always_inline' attribute is not hotpatchable" } */
__attribute__ ((hotpatch(0)))
void hp4(void)
{
printf("hello, world!\n");
}
__attribute__ ((hotpatch(0)))
inline void hp5(void)
{
printf("hello, world!\n");
}
__attribute__ ((hotpatch(0)))
__attribute__ ((always_inline))
void hp6(void) /* { dg-warning "always_inline function might not be inlinable" } */
{
printf("hello, world!\n");
} /* { dg-warning "function 'hp6' with the 'always_inline' attribute is not hotpatchable" } */
__attribute__ ((hotpatch(1)))
void hp7(void)
{
printf("hello, world!\n");
}
__attribute__ ((hotpatch(1)))
inline void hp8(void)
{
printf("hello, world!\n");
}
__attribute__ ((hotpatch(1)))
__attribute__ ((always_inline))
void hp9(void) /* { dg-warning "always_inline function might not be inlinable" } */
{
printf("hello, world!\n");
} /* { dg-warning "function 'hp9' with the 'always_inline' attribute is not hotpatchable" } */
int main (void)
{
return 0;
}