From 77bc991286f1e7e90335648dc049948259dc64b6 Mon Sep 17 00:00:00 2001 From: krebbel Date: Thu, 19 Dec 2013 12:00:43 +0000 Subject: [PATCH] 2013-12-19 Dominik Vogt Andreas Krebbel * 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 Andreas Krebbel * 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 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@206111 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 27 +++ gcc/config/s390/s390-protos.h | 1 + gcc/config/s390/s390.c | 201 +++++++++++++++++++++ gcc/config/s390/s390.h | 5 +- gcc/config/s390/s390.opt | 8 + gcc/doc/extend.texi | 11 ++ gcc/doc/invoke.texi | 18 +- gcc/testsuite/ChangeLog | 23 +++ gcc/testsuite/gcc.target/s390/hotpatch-1.c | 20 ++ gcc/testsuite/gcc.target/s390/hotpatch-10.c | 21 +++ gcc/testsuite/gcc.target/s390/hotpatch-11.c | 20 ++ gcc/testsuite/gcc.target/s390/hotpatch-12.c | 20 ++ gcc/testsuite/gcc.target/s390/hotpatch-2.c | 20 ++ gcc/testsuite/gcc.target/s390/hotpatch-3.c | 20 ++ gcc/testsuite/gcc.target/s390/hotpatch-4.c | 26 +++ gcc/testsuite/gcc.target/s390/hotpatch-5.c | 21 +++ gcc/testsuite/gcc.target/s390/hotpatch-6.c | 21 +++ gcc/testsuite/gcc.target/s390/hotpatch-7.c | 21 +++ gcc/testsuite/gcc.target/s390/hotpatch-8.c | 28 +++ gcc/testsuite/gcc.target/s390/hotpatch-9.c | 21 +++ gcc/testsuite/gcc.target/s390/hotpatch-compile-1.c | 27 +++ gcc/testsuite/gcc.target/s390/hotpatch-compile-2.c | 27 +++ gcc/testsuite/gcc.target/s390/hotpatch-compile-3.c | 27 +++ gcc/testsuite/gcc.target/s390/hotpatch-compile-4.c | 11 ++ gcc/testsuite/gcc.target/s390/hotpatch-compile-5.c | 28 +++ gcc/testsuite/gcc.target/s390/hotpatch-compile-6.c | 11 ++ gcc/testsuite/gcc.target/s390/hotpatch-compile-7.c | 68 +++++++ 27 files changed, 750 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/s390/hotpatch-1.c create mode 100644 gcc/testsuite/gcc.target/s390/hotpatch-10.c create mode 100644 gcc/testsuite/gcc.target/s390/hotpatch-11.c create mode 100644 gcc/testsuite/gcc.target/s390/hotpatch-12.c create mode 100644 gcc/testsuite/gcc.target/s390/hotpatch-2.c create mode 100644 gcc/testsuite/gcc.target/s390/hotpatch-3.c create mode 100644 gcc/testsuite/gcc.target/s390/hotpatch-4.c create mode 100644 gcc/testsuite/gcc.target/s390/hotpatch-5.c create mode 100644 gcc/testsuite/gcc.target/s390/hotpatch-6.c create mode 100644 gcc/testsuite/gcc.target/s390/hotpatch-7.c create mode 100644 gcc/testsuite/gcc.target/s390/hotpatch-8.c create mode 100644 gcc/testsuite/gcc.target/s390/hotpatch-9.c create mode 100644 gcc/testsuite/gcc.target/s390/hotpatch-compile-1.c create mode 100644 gcc/testsuite/gcc.target/s390/hotpatch-compile-2.c create mode 100644 gcc/testsuite/gcc.target/s390/hotpatch-compile-3.c create mode 100644 gcc/testsuite/gcc.target/s390/hotpatch-compile-4.c create mode 100644 gcc/testsuite/gcc.target/s390/hotpatch-compile-5.c create mode 100644 gcc/testsuite/gcc.target/s390/hotpatch-compile-6.c create mode 100644 gcc/testsuite/gcc.target/s390/hotpatch-compile-7.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6f69334..9417065 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,30 @@ +2013-12-19 Dominik Vogt + Andreas Krebbel + + * 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 * config/i386/i386.c: Include cfgloop.h. diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h index 67283df..7b43ed0 100644 --- a/gcc/config/s390/s390-protos.h +++ b/gcc/config/s390/s390-protos.h @@ -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_compare_and_branch_condition_mask (rtx); 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 */ diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index f9b7cd0..5319a69 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -434,6 +434,65 @@ struct GTY(()) machine_function bytes on a z10 (or higher) CPU. */ #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 value except for the literal pool base label. */ int @@ -1622,6 +1681,46 @@ s390_init_machine_status (void) static void s390_option_override (void) { + unsigned int i; + cl_deferred_option *opt; + vec *v = + (vec *) 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. */ init_machine_status = s390_init_machine_status; @@ -5347,6 +5446,102 @@ get_some_local_dynamic_name (void) 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 in assembler syntax to stdio stream FILE. Returns true if the 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 #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; #include "gt-s390.h" diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h index bca18fe..75b642b 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -217,7 +217,7 @@ enum processor_flags #define STACK_BOUNDARY 64 /* 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. */ #define BIGGEST_ALIGNMENT 64 @@ -878,6 +878,9 @@ do { \ fputc ('\n', (FILE)); \ } 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. */ diff --git a/gcc/config/s390/s390.opt b/gcc/config/s390/s390.opt index 7dedb83..ef92f46 100644 --- a/gcc/config/s390/s390.opt +++ b/gcc/config/s390/s390.opt @@ -96,6 +96,14 @@ mhard-float Target Report RejectNegative Negative(msoft-float) InverseMask(SOFT_FLOAT, HARD_FLOAT) 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 Target Report RejectNegative Negative(mlong-double-64) Mask(LONG_DOUBLE_128) Use 128-bit long double diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index af258d7..2ce0098 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -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 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 @cindex function without a prologue/epilogue code Use this attribute on the ARM, AVR, MCORE, MSP430, NDS32, RL78, RX and SPU diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 1a6d815..6e888bd 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -933,7 +933,8 @@ See RS/6000 and PowerPC Options. -msmall-exec -mno-small-exec -mmvcle -mno-mvcle @gol -m64 -m31 -mdebug -mno-debug -mesa -mzarch @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} @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 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}. + +@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 @node Score Options diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b5100b7..3f9884f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,26 @@ +2013-12-19 Dominik Vogt + Andreas Krebbel + + * 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 * c-c++-common/cilk-plus/SE/ef_error.c: Add fopenmp effective diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-1.c b/gcc/testsuite/gcc.target/s390/hotpatch-1.c new file mode 100644 index 0000000..b9d6139 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-1.c @@ -0,0 +1,20 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mhotpatch --save-temps" } */ + +#include + +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 } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-10.c b/gcc/testsuite/gcc.target/s390/hotpatch-10.c new file mode 100644 index 0000000..b91b347 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-10.c @@ -0,0 +1,21 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mno-hotpatch --save-temps" } */ + +#include + +__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 } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-11.c b/gcc/testsuite/gcc.target/s390/hotpatch-11.c new file mode 100644 index 0000000..4916773 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-11.c @@ -0,0 +1,20 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mhotpatch -mno-hotpatch --save-temps" } */ + +#include + +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" } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-12.c b/gcc/testsuite/gcc.target/s390/hotpatch-12.c new file mode 100644 index 0000000..b3e9427 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-12.c @@ -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 + +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 } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-2.c b/gcc/testsuite/gcc.target/s390/hotpatch-2.c new file mode 100644 index 0000000..6cc2944 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-2.c @@ -0,0 +1,20 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mhotpatch=1 --save-temps" } */ + +#include + +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 } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-3.c b/gcc/testsuite/gcc.target/s390/hotpatch-3.c new file mode 100644 index 0000000..9f0b2b7 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-3.c @@ -0,0 +1,20 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mhotpatch=0 --save-temps" } */ + +#include + +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 } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-4.c b/gcc/testsuite/gcc.target/s390/hotpatch-4.c new file mode 100644 index 0000000..c1dba20 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-4.c @@ -0,0 +1,26 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mhotpatch --save-temps" } */ + +#include + +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" } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-5.c b/gcc/testsuite/gcc.target/s390/hotpatch-5.c new file mode 100644 index 0000000..ec267d6 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-5.c @@ -0,0 +1,21 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mhotpatch --save-temps" } */ + +#include + +__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 } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-6.c b/gcc/testsuite/gcc.target/s390/hotpatch-6.c new file mode 100644 index 0000000..5af090d --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-6.c @@ -0,0 +1,21 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mhotpatch --save-temps" } */ + +#include + +__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 } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-7.c b/gcc/testsuite/gcc.target/s390/hotpatch-7.c new file mode 100644 index 0000000..e73a510 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-7.c @@ -0,0 +1,21 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mhotpatch --save-temps" } */ + +#include + +__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 } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-8.c b/gcc/testsuite/gcc.target/s390/hotpatch-8.c new file mode 100644 index 0000000..399aa72 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-8.c @@ -0,0 +1,28 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mhotpatch --save-temps" } */ + +#include + +__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" } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-9.c b/gcc/testsuite/gcc.target/s390/hotpatch-9.c new file mode 100644 index 0000000..5da6758 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-9.c @@ -0,0 +1,21 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mhotpatch=1 --save-temps" } */ + +#include + +__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 } } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-compile-1.c b/gcc/testsuite/gcc.target/s390/hotpatch-compile-1.c new file mode 100644 index 0000000..45a2cc5 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-compile-1.c @@ -0,0 +1,27 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mhotpatch" } */ + +#include + +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; +} diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-compile-2.c b/gcc/testsuite/gcc.target/s390/hotpatch-compile-2.c new file mode 100644 index 0000000..5947f56 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-compile-2.c @@ -0,0 +1,27 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mhotpatch=0" } */ + +#include + +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; +} diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-compile-3.c b/gcc/testsuite/gcc.target/s390/hotpatch-compile-3.c new file mode 100644 index 0000000..e0c7f6f --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-compile-3.c @@ -0,0 +1,27 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mhotpatch=1" } */ + +#include + +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; +} diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-compile-4.c b/gcc/testsuite/gcc.target/s390/hotpatch-compile-4.c new file mode 100644 index 0000000..d9f1342 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-compile-4.c @@ -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" } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-compile-5.c b/gcc/testsuite/gcc.target/s390/hotpatch-compile-5.c new file mode 100644 index 0000000..53f7eac --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-compile-5.c @@ -0,0 +1,28 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -mhotpatch=1000000" } */ + +#include + +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; +} diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-compile-6.c b/gcc/testsuite/gcc.target/s390/hotpatch-compile-6.c new file mode 100644 index 0000000..cb10b66 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-compile-6.c @@ -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." } */ diff --git a/gcc/testsuite/gcc.target/s390/hotpatch-compile-7.c b/gcc/testsuite/gcc.target/s390/hotpatch-compile-7.c new file mode 100644 index 0000000..98ccb42 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/hotpatch-compile-7.c @@ -0,0 +1,68 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mno-hotpatch" } */ + +#include + +__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; +} -- 2.7.4