Commit d0de9e13 by Dominik Vogt Committed by Andreas Krebbel

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
parent 2f62165d
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>
* config/i386/i386.c: Include cfgloop.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 */
......@@ -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<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. */
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"
......@@ -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. */
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
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>
* c-c++-common/cilk-plus/SE/ef_error.c: Add fopenmp effective
......
/* 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 } } */
/* 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 } } */
/* 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" } } */
/* 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 } } */
/* 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 } } */
/* 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 } } */
/* 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" } } */
/* 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 } } */
/* 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 } } */
/* 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 } } */
/* 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" } } */
/* 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 } } */
/* 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;
}
/* 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;
}
/* 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;
}
/* 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" } */
/* 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;
}
/* 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." } */
/* 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;
}
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