Remove backported tests: - g++.dg/pr93195a.C - gcc.dg/tree-ssa/pr84859.c Fix assembly match on i586: - gcc.target/i386/pr93492-3.c - gcc.target/i386/pr93492-5.c OBS-URL: https://build.opensuse.org/request/show/927326 OBS-URL: https://build.opensuse.org/package/show/devel:gcc/gcc7?expand=0&rev=219
556 lines
21 KiB
Diff
556 lines
21 KiB
Diff
From 1258c4f8a08681cce523c40352a37584f9ba63bd Mon Sep 17 00:00:00 2001
|
|
From: Torsten Duwe <duwe@suse.de>
|
|
Date: Tue, 25 Jul 2017 14:16:10 +0000
|
|
Subject: [PATCH 01/22] Backport "Add entry for "patchable_function_entry".
|
|
|
|
2021-10-07 Giuliano Belinassi <gbelinassi@suse.de>
|
|
Backport from mainline
|
|
|
|
2017-07-07 Torsten Duwe <duwe@suse.de>
|
|
|
|
c-family/
|
|
* c-attribs.c (c_common_attribute_table): Add entry for
|
|
"patchable_function_entry".
|
|
|
|
lto/
|
|
* lto-lang.c (lto_attribute_table): Add entry for
|
|
"patchable_function_entry".
|
|
|
|
* common.opt: Introduce -fpatchable-function-entry
|
|
command line option, and its variables function_entry_patch_area_size
|
|
and function_entry_patch_area_start.
|
|
* opts.c (common_handle_option): Add -fpatchable_function_entry_ case,
|
|
including a two-value parser.
|
|
* target.def (print_patchable_function_entry): New target hook.
|
|
* targhooks.h (default_print_patchable_function_entry): New function.
|
|
* targhooks.c (default_print_patchable_function_entry): Likewise.
|
|
* toplev.c (process_options): Switch off IPA-RA if
|
|
patchable function entries are being generated.
|
|
* varasm.c (assemble_start_function): Look at the
|
|
patchable-function-entry command line switch and current
|
|
function attributes and maybe generate NOP instructions by
|
|
calling the print_patchable_function_entry hook.
|
|
* doc/extend.texi: Document patchable_function_entry attribute.
|
|
* doc/invoke.texi: Document -fpatchable_function_entry
|
|
command line option.
|
|
* doc/tm.texi.in (TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY):
|
|
New target hook.
|
|
* doc/tm.texi: Re-generate.
|
|
|
|
* c-c++-common/patchable_function_entry-default.c: New test.
|
|
* c-c++-common/patchable_function_entry-decl.c: Likewise.
|
|
* c-c++-common/patchable_function_entry-definition.c: Likewise.
|
|
---
|
|
gcc/c-family/c-attribs.c | 12 +++++
|
|
gcc/common.opt | 11 +++++
|
|
gcc/doc/extend.texi | 21 +++++++++
|
|
gcc/doc/invoke.texi | 28 +++++++++++
|
|
gcc/doc/tm.texi | 9 ++++
|
|
gcc/doc/tm.texi.in | 2 +
|
|
gcc/lto/lto-lang.c | 12 +++++
|
|
gcc/opts.c | 27 +++++++++++
|
|
gcc/target.def | 11 +++++
|
|
gcc/targhooks.c | 46 +++++++++++++++++++
|
|
gcc/targhooks.h | 3 ++
|
|
.../patchable_function_entry-decl.c | 16 +++++++
|
|
.../patchable_function_entry-default.c | 16 +++++++
|
|
.../patchable_function_entry-definition.c | 16 +++++++
|
|
gcc/toplev.c | 4 +-
|
|
gcc/varasm.c | 46 +++++++++++++++++++
|
|
16 files changed, 279 insertions(+), 1 deletion(-)
|
|
create mode 100644 gcc/testsuite/c-c++-common/patchable_function_entry-decl.c
|
|
create mode 100644 gcc/testsuite/c-c++-common/patchable_function_entry-default.c
|
|
create mode 100644 gcc/testsuite/c-c++-common/patchable_function_entry-definition.c
|
|
|
|
diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
|
|
index 90b17bc00d2..b2820dd1586 100644
|
|
--- a/gcc/c-family/c-attribs.c
|
|
+++ b/gcc/c-family/c-attribs.c
|
|
@@ -139,6 +139,8 @@ static tree handle_bnd_variable_size_attribute (tree *, tree, tree, int, bool *)
|
|
static tree handle_bnd_legacy (tree *, tree, tree, int, bool *);
|
|
static tree handle_bnd_instrument (tree *, tree, tree, int, bool *);
|
|
static tree handle_fallthrough_attribute (tree *, tree, tree, int, bool *);
|
|
+static tree handle_patchable_function_entry_attribute (tree *, tree, tree,
|
|
+ int, bool *);
|
|
|
|
/* Table of machine-independent attributes common to all C-like languages.
|
|
|
|
@@ -345,6 +347,9 @@ const struct attribute_spec c_common_attribute_table[] =
|
|
handle_bnd_instrument, false },
|
|
{ "fallthrough", 0, 0, false, false, false,
|
|
handle_fallthrough_attribute, false },
|
|
+ { "patchable_function_entry", 1, 2, true, false, false,
|
|
+ handle_patchable_function_entry_attribute,
|
|
+ false },
|
|
{ NULL, 0, 0, false, false, false, NULL, false }
|
|
};
|
|
|
|
@@ -3178,3 +3183,10 @@ handle_fallthrough_attribute (tree *, tree name, tree, int,
|
|
*no_add_attrs = true;
|
|
return NULL_TREE;
|
|
}
|
|
+
|
|
+static tree
|
|
+handle_patchable_function_entry_attribute (tree *, tree, tree, int, bool *)
|
|
+{
|
|
+ /* Nothing to be done here. */
|
|
+ return NULL_TREE;
|
|
+}
|
|
diff --git a/gcc/common.opt b/gcc/common.opt
|
|
index 437db8e8615..ca1613b6808 100644
|
|
--- a/gcc/common.opt
|
|
+++ b/gcc/common.opt
|
|
@@ -163,6 +163,13 @@ bool flag_stack_usage_info = false
|
|
Variable
|
|
int flag_debug_asm
|
|
|
|
+; How many NOP insns to place at each function entry by default
|
|
+Variable
|
|
+HOST_WIDE_INT function_entry_patch_area_size
|
|
+
|
|
+; And how far the real asm entry point is into this area
|
|
+Variable
|
|
+HOST_WIDE_INT function_entry_patch_area_start
|
|
|
|
; Balance between GNAT encodings and standard DWARF to emit.
|
|
Variable
|
|
@@ -2022,6 +2029,10 @@ fprofile-reorder-functions
|
|
Common Report Var(flag_profile_reorder_functions)
|
|
Enable function reordering that improves code placement.
|
|
|
|
+fpatchable-function-entry=
|
|
+Common Joined Optimization
|
|
+Insert NOP instructions at each function entry.
|
|
+
|
|
frandom-seed
|
|
Common Var(common_deferred_options) Defer
|
|
|
|
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
|
|
index 1ef46799907..6860a391f62 100644
|
|
--- a/gcc/doc/extend.texi
|
|
+++ b/gcc/doc/extend.texi
|
|
@@ -3083,6 +3083,27 @@ that affect more than one function.
|
|
This attribute should be used for debugging purposes only. It is not
|
|
suitable in production code.
|
|
|
|
+@item patchable_function_entry
|
|
+@cindex @code{patchable_function_entry} function attribute
|
|
+@cindex extra NOP instructions at the function entry point
|
|
+In case the target's text segment can be made writable at run time by
|
|
+any means, padding the function entry with a number of NOPs can be
|
|
+used to provide a universal tool for instrumentation.
|
|
+
|
|
+The @code{patchable_function_entry} function attribute can be used to
|
|
+change the number of NOPs to any desired value. The two-value syntax
|
|
+is the same as for the command-line switch
|
|
+@option{-fpatchable-function-entry=N,M}, generating @var{N} NOPs, with
|
|
+the function entry point before the @var{M}th NOP instruction.
|
|
+@var{M} defaults to 0 if omitted e.g. function entry point is before
|
|
+the first NOP.
|
|
+
|
|
+If patchable function entries are enabled globally using the command-line
|
|
+option @option{-fpatchable-function-entry=N,M}, then you must disable
|
|
+instrumentation on all functions that are part of the instrumentation
|
|
+framework with the attribute @code{patchable_function_entry (0)}
|
|
+to prevent recursion.
|
|
+
|
|
@item pure
|
|
@cindex @code{pure} function attribute
|
|
@cindex functions that have no side effects
|
|
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
|
|
index 8f279e454b0..ad71be54e07 100644
|
|
--- a/gcc/doc/invoke.texi
|
|
+++ b/gcc/doc/invoke.texi
|
|
@@ -11417,6 +11417,34 @@ of the function name, it is considered to be a match. For C99 and C++
|
|
extended identifiers, the function name must be given in UTF-8, not
|
|
using universal character names.
|
|
|
|
+@item -fpatchable-function-entry=@var{N}[,@var{M}]
|
|
+@opindex fpatchable-function-entry
|
|
+Generate @var{N} NOPs right at the beginning
|
|
+of each function, with the function entry point before the @var{M}th NOP.
|
|
+If @var{M} is omitted, it defaults to @code{0} so the
|
|
+function entry points to the address just at the first NOP.
|
|
+The NOP instructions reserve extra space which can be used to patch in
|
|
+any desired instrumentation at run time, provided that the code segment
|
|
+is writable. The amount of space is controllable indirectly via
|
|
+the number of NOPs; the NOP instruction used corresponds to the instruction
|
|
+emitted by the internal GCC back-end interface @code{gen_nop}. This behavior
|
|
+is target-specific and may also depend on the architecture variant and/or
|
|
+other compilation options.
|
|
+
|
|
+For run-time identification, the starting addresses of these areas,
|
|
+which correspond to their respective function entries minus @var{M},
|
|
+are additionally collected in the @code{__patchable_function_entries}
|
|
+section of the resulting binary.
|
|
+
|
|
+Note that the value of @code{__attribute__ ((patchable_function_entry
|
|
+(N,M)))} takes precedence over command-line option
|
|
+@option{-fpatchable-function-entry=N,M}. This can be used to increase
|
|
+the area size or to remove it completely on a single function.
|
|
+If @code{N=0}, no pad location is recorded.
|
|
+
|
|
+The NOP instructions are inserted at---and maybe before, depending on
|
|
+@var{M}---the function entry address, even before the prologue.
|
|
+
|
|
@end table
|
|
|
|
|
|
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
|
|
index 1bb5a9d9579..b4456f7cd40 100644
|
|
--- a/gcc/doc/tm.texi
|
|
+++ b/gcc/doc/tm.texi
|
|
@@ -4566,6 +4566,15 @@ will select the smallest suitable mode.
|
|
This section describes the macros that output function entry
|
|
(@dfn{prologue}) and exit (@dfn{epilogue}) code.
|
|
|
|
+@deftypefn {Target Hook} void TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY (FILE *@var{file}, unsigned HOST_WIDE_INT @var{patch_area_size}, bool @var{record_p})
|
|
+Generate a patchable area at the function start, consisting of
|
|
+@var{patch_area_size} NOP instructions. If the target supports named
|
|
+sections and if @var{record_p} is true, insert a pointer to the current
|
|
+location in the table of patchable functions. The default implementation
|
|
+of the hook places the table of pointers in the special section named
|
|
+@code{__patchable_function_entries}.
|
|
+@end deftypefn
|
|
+
|
|
@deftypefn {Target Hook} void TARGET_ASM_FUNCTION_PROLOGUE (FILE *@var{file}, HOST_WIDE_INT @var{size})
|
|
If defined, a function that outputs the assembler code for entry to a
|
|
function. The prologue is responsible for setting up the stack frame,
|
|
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
|
|
index d4047142027..b188c94ae5e 100644
|
|
--- a/gcc/doc/tm.texi.in
|
|
+++ b/gcc/doc/tm.texi.in
|
|
@@ -3650,6 +3650,8 @@ will select the smallest suitable mode.
|
|
This section describes the macros that output function entry
|
|
(@dfn{prologue}) and exit (@dfn{epilogue}) code.
|
|
|
|
+@hook TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY
|
|
+
|
|
@hook TARGET_ASM_FUNCTION_PROLOGUE
|
|
|
|
@hook TARGET_ASM_FUNCTION_END_PROLOGUE
|
|
diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c
|
|
index fdd6ae08a1c..530d9dc31d0 100644
|
|
--- a/gcc/lto/lto-lang.c
|
|
+++ b/gcc/lto/lto-lang.c
|
|
@@ -48,6 +48,8 @@ static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *);
|
|
static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);
|
|
static tree handle_transaction_pure_attribute (tree *, tree, tree, int, bool *);
|
|
static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *);
|
|
+static tree handle_patchable_function_entry_attribute (tree *, tree, tree,
|
|
+ int, bool *);
|
|
static tree ignore_attribute (tree *, tree, tree, int, bool *);
|
|
|
|
static tree handle_format_attribute (tree *, tree, tree, int, bool *);
|
|
@@ -76,6 +78,9 @@ const struct attribute_spec lto_attribute_table[] =
|
|
handle_nonnull_attribute, false },
|
|
{ "nothrow", 0, 0, true, false, false,
|
|
handle_nothrow_attribute, false },
|
|
+ { "patchable_function_entry", 1, 2, true, false, false,
|
|
+ handle_patchable_function_entry_attribute,
|
|
+ false },
|
|
{ "returns_twice", 0, 0, true, false, false,
|
|
handle_returns_twice_attribute, false },
|
|
{ "sentinel", 0, 1, false, true, true,
|
|
@@ -473,6 +478,13 @@ handle_returns_twice_attribute (tree *node, tree ARG_UNUSED (name),
|
|
return NULL_TREE;
|
|
}
|
|
|
|
+static tree
|
|
+handle_patchable_function_entry_attribute (tree *, tree, tree, int, bool *)
|
|
+{
|
|
+ /* Nothing to be done here. */
|
|
+ return NULL_TREE;
|
|
+}
|
|
+
|
|
/* Ignore the given attribute. Used when this attribute may be usefully
|
|
overridden by the target, but is not used generically. */
|
|
|
|
diff --git a/gcc/opts.c b/gcc/opts.c
|
|
index b98a0ca73a8..d0430e777ee 100644
|
|
--- a/gcc/opts.c
|
|
+++ b/gcc/opts.c
|
|
@@ -2201,6 +2201,33 @@ common_handle_option (struct gcc_options *opts,
|
|
opts->x_flag_ipa_reference = false;
|
|
break;
|
|
|
|
+ case OPT_fpatchable_function_entry_:
|
|
+ {
|
|
+ char *patch_area_arg = xstrdup (arg);
|
|
+ char *comma = strchr (patch_area_arg, ',');
|
|
+ if (comma)
|
|
+ {
|
|
+ *comma = '\0';
|
|
+ function_entry_patch_area_size =
|
|
+ integral_argument (patch_area_arg);
|
|
+ function_entry_patch_area_start =
|
|
+ integral_argument (comma + 1);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ function_entry_patch_area_size =
|
|
+ integral_argument (patch_area_arg);
|
|
+ function_entry_patch_area_start = 0;
|
|
+ }
|
|
+ if (function_entry_patch_area_size < 0
|
|
+ || function_entry_patch_area_start < 0
|
|
+ || function_entry_patch_area_size
|
|
+ < function_entry_patch_area_start)
|
|
+ error ("invalid arguments for %<-fpatchable_function_entry%>");
|
|
+ free (patch_area_arg);
|
|
+ }
|
|
+ break;
|
|
+
|
|
case OPT_ftree_vectorize:
|
|
if (!opts_set->x_flag_tree_loop_vectorize)
|
|
opts->x_flag_tree_loop_vectorize = value;
|
|
diff --git a/gcc/target.def b/gcc/target.def
|
|
index 6bebfd5b9d6..bea79404836 100644
|
|
--- a/gcc/target.def
|
|
+++ b/gcc/target.def
|
|
@@ -288,6 +288,17 @@ hidden, protected or internal visibility as specified by @var{visibility}.",
|
|
void, (tree decl, int visibility),
|
|
default_assemble_visibility)
|
|
|
|
+DEFHOOK
|
|
+(print_patchable_function_entry,
|
|
+ "Generate a patchable area at the function start, consisting of\n\
|
|
+@var{patch_area_size} NOP instructions. If the target supports named\n\
|
|
+sections and if @var{record_p} is true, insert a pointer to the current\n\
|
|
+location in the table of patchable functions. The default implementation\n\
|
|
+of the hook places the table of pointers in the special section named\n\
|
|
+@code{__patchable_function_entries}.",
|
|
+ void, (FILE *file, unsigned HOST_WIDE_INT patch_area_size, bool record_p),
|
|
+ default_print_patchable_function_entry)
|
|
+
|
|
/* Output the assembler code for entry to a function. */
|
|
DEFHOOK
|
|
(function_prologue,
|
|
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
|
|
index 1cdec068ed8..77ca69105d0 100644
|
|
--- a/gcc/targhooks.c
|
|
+++ b/gcc/targhooks.c
|
|
@@ -72,6 +72,7 @@ along with GCC; see the file COPYING3. If not see
|
|
#include "calls.h"
|
|
#include "expr.h"
|
|
#include "output.h"
|
|
+#include "common/common-target.h"
|
|
#include "reload.h"
|
|
#include "intl.h"
|
|
#include "opts.h"
|
|
@@ -1609,6 +1610,51 @@ default_compare_by_pieces_branch_ratio (machine_mode)
|
|
return 1;
|
|
}
|
|
|
|
+/* Write PATCH_AREA_SIZE NOPs into the asm outfile FILE around a function
|
|
+ entry. If RECORD_P is true and the target supports named sections,
|
|
+ the location of the NOPs will be recorded in a special object section
|
|
+ called "__patchable_function_entries". This routine may be called
|
|
+ twice per function to put NOPs before and after the function
|
|
+ entry. */
|
|
+
|
|
+void
|
|
+default_print_patchable_function_entry (FILE *file,
|
|
+ unsigned HOST_WIDE_INT patch_area_size,
|
|
+ bool record_p)
|
|
+{
|
|
+ const char *nop_templ = 0;
|
|
+ int code_num;
|
|
+ rtx_insn *my_nop = make_insn_raw (gen_nop ());
|
|
+
|
|
+ /* We use the template alone, relying on the (currently sane) assumption
|
|
+ that the NOP template does not have variable operands. */
|
|
+ code_num = recog_memoized (my_nop);
|
|
+ nop_templ = get_insn_template (code_num, my_nop);
|
|
+
|
|
+ if (record_p && targetm_common.have_named_sections)
|
|
+ {
|
|
+ char buf[256];
|
|
+ static int patch_area_number;
|
|
+ section *previous_section = in_section;
|
|
+
|
|
+ patch_area_number++;
|
|
+ ASM_GENERATE_INTERNAL_LABEL (buf, "LPFE", patch_area_number);
|
|
+
|
|
+ switch_to_section (get_section ("__patchable_function_entries",
|
|
+ 0, NULL));
|
|
+ fputs (integer_asm_op (POINTER_SIZE_UNITS, false), file);
|
|
+ assemble_name_raw (file, buf);
|
|
+ fputc ('\n', file);
|
|
+
|
|
+ switch_to_section (previous_section);
|
|
+ ASM_OUTPUT_LABEL (file, buf);
|
|
+ }
|
|
+
|
|
+ unsigned i;
|
|
+ for (i = 0; i < patch_area_size; ++i)
|
|
+ fprintf (file, "\t%s\n", nop_templ);
|
|
+}
|
|
+
|
|
bool
|
|
default_profile_before_prologue (void)
|
|
{
|
|
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
|
|
index 18070df7839..6206fe20823 100644
|
|
--- a/gcc/targhooks.h
|
|
+++ b/gcc/targhooks.h
|
|
@@ -203,6 +203,9 @@ extern bool default_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT,
|
|
bool);
|
|
extern int default_compare_by_pieces_branch_ratio (machine_mode);
|
|
|
|
+extern void default_print_patchable_function_entry (FILE *,
|
|
+ unsigned HOST_WIDE_INT,
|
|
+ bool);
|
|
extern bool default_profile_before_prologue (void);
|
|
extern reg_class_t default_preferred_reload_class (rtx, reg_class_t);
|
|
extern reg_class_t default_preferred_output_reload_class (rtx, reg_class_t);
|
|
diff --git a/gcc/testsuite/c-c++-common/patchable_function_entry-decl.c b/gcc/testsuite/c-c++-common/patchable_function_entry-decl.c
|
|
new file mode 100644
|
|
index 00000000000..8514b10e820
|
|
--- /dev/null
|
|
+++ b/gcc/testsuite/c-c++-common/patchable_function_entry-decl.c
|
|
@@ -0,0 +1,16 @@
|
|
+/* { dg-do compile } */
|
|
+/* { dg-options "-O2 -fpatchable-function-entry=3,1" } */
|
|
+/* { dg-final { scan-assembler-times "nop" 2 } } */
|
|
+
|
|
+extern int a;
|
|
+
|
|
+/* Respect overriding attributes in the declaration. */
|
|
+int f3 (void) __attribute__((patchable_function_entry(2)));
|
|
+
|
|
+/* F3 should now get 2 NOPs. */
|
|
+int
|
|
+__attribute__((noinline))
|
|
+f3 (void)
|
|
+{
|
|
+ return 5*a;
|
|
+}
|
|
diff --git a/gcc/testsuite/c-c++-common/patchable_function_entry-default.c b/gcc/testsuite/c-c++-common/patchable_function_entry-default.c
|
|
new file mode 100644
|
|
index 00000000000..0dcf1181dde
|
|
--- /dev/null
|
|
+++ b/gcc/testsuite/c-c++-common/patchable_function_entry-default.c
|
|
@@ -0,0 +1,16 @@
|
|
+/* { dg-do compile } */
|
|
+/* { dg-options "-O2 -fpatchable-function-entry=3,1" } */
|
|
+/* { dg-final { scan-assembler-times "nop" 3 } } */
|
|
+
|
|
+extern int a;
|
|
+
|
|
+/* Nothing declared must not mean anything. */
|
|
+int f3 (void);
|
|
+
|
|
+/* F3 should get a default-sized NOP area. */
|
|
+int
|
|
+__attribute__((noinline))
|
|
+f3 (void)
|
|
+{
|
|
+ return 5*a;
|
|
+}
|
|
diff --git a/gcc/testsuite/c-c++-common/patchable_function_entry-definition.c b/gcc/testsuite/c-c++-common/patchable_function_entry-definition.c
|
|
new file mode 100644
|
|
index 00000000000..a007867dcb0
|
|
--- /dev/null
|
|
+++ b/gcc/testsuite/c-c++-common/patchable_function_entry-definition.c
|
|
@@ -0,0 +1,16 @@
|
|
+/* { dg-do compile } */
|
|
+/* { dg-options "-O2 -fpatchable-function-entry=3,1" } */
|
|
+/* { dg-final { scan-assembler-times "nop" 1 } } */
|
|
+
|
|
+extern int a;
|
|
+
|
|
+int f3 (void);
|
|
+
|
|
+/* F3 should now get 1 NOP. */
|
|
+int
|
|
+__attribute__((noinline))
|
|
+__attribute__((patchable_function_entry(1)))
|
|
+f3 (void)
|
|
+{
|
|
+ return 5*a;
|
|
+}
|
|
diff --git a/gcc/toplev.c b/gcc/toplev.c
|
|
index 6f0bc9fe736..7d3aa280f15 100644
|
|
--- a/gcc/toplev.c
|
|
+++ b/gcc/toplev.c
|
|
@@ -1612,8 +1612,10 @@ process_options (void)
|
|
}
|
|
|
|
/* Do not use IPA optimizations for register allocation if profiler is active
|
|
+ or patchable function entries are inserted for run-time instrumentation
|
|
or port does not emit prologue and epilogue as RTL. */
|
|
- if (profile_flag || !targetm.have_prologue () || !targetm.have_epilogue ())
|
|
+ if (profile_flag || function_entry_patch_area_size
|
|
+ || !targetm.have_prologue () || !targetm.have_epilogue ())
|
|
flag_ipa_ra = 0;
|
|
|
|
/* Enable -Werror=coverage-mismatch when -Werror and -Wno-error
|
|
diff --git a/gcc/varasm.c b/gcc/varasm.c
|
|
index 1b9030029ac..6e9a8c3133e 100644
|
|
--- a/gcc/varasm.c
|
|
+++ b/gcc/varasm.c
|
|
@@ -1829,6 +1829,46 @@ assemble_start_function (tree decl, const char *fnname)
|
|
if (DECL_PRESERVE_P (decl))
|
|
targetm.asm_out.mark_decl_preserved (fnname);
|
|
|
|
+ unsigned HOST_WIDE_INT patch_area_size = function_entry_patch_area_size;
|
|
+ unsigned HOST_WIDE_INT patch_area_entry = function_entry_patch_area_start;
|
|
+
|
|
+ tree patchable_function_entry_attr
|
|
+ = lookup_attribute ("patchable_function_entry", DECL_ATTRIBUTES (decl));
|
|
+ if (patchable_function_entry_attr)
|
|
+ {
|
|
+ tree pp_val = TREE_VALUE (patchable_function_entry_attr);
|
|
+ tree patchable_function_entry_value1 = TREE_VALUE (pp_val);
|
|
+
|
|
+ if (tree_fits_uhwi_p (patchable_function_entry_value1))
|
|
+ patch_area_size = tree_to_uhwi (patchable_function_entry_value1);
|
|
+ else
|
|
+ gcc_unreachable ();
|
|
+
|
|
+ patch_area_entry = 0;
|
|
+ if (list_length (pp_val) > 1)
|
|
+ {
|
|
+ tree patchable_function_entry_value2 =
|
|
+ TREE_VALUE (TREE_CHAIN (pp_val));
|
|
+
|
|
+ if (tree_fits_uhwi_p (patchable_function_entry_value2))
|
|
+ patch_area_entry = tree_to_uhwi (patchable_function_entry_value2);
|
|
+ else
|
|
+ gcc_unreachable ();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (patch_area_entry > patch_area_size)
|
|
+ {
|
|
+ if (patch_area_size > 0)
|
|
+ warning (OPT_Wattributes, "Patchable function entry > size");
|
|
+ patch_area_entry = 0;
|
|
+ }
|
|
+
|
|
+ /* Emit the patching area before the entry label, if any. */
|
|
+ if (patch_area_entry > 0)
|
|
+ targetm.asm_out.print_patchable_function_entry (asm_out_file,
|
|
+ patch_area_entry, true);
|
|
+
|
|
/* Do any machine/system dependent processing of the function name. */
|
|
#ifdef ASM_DECLARE_FUNCTION_NAME
|
|
ASM_DECLARE_FUNCTION_NAME (asm_out_file, fnname, current_function_decl);
|
|
@@ -1837,6 +1877,12 @@ assemble_start_function (tree decl, const char *fnname)
|
|
ASM_OUTPUT_FUNCTION_LABEL (asm_out_file, fnname, current_function_decl);
|
|
#endif /* ASM_DECLARE_FUNCTION_NAME */
|
|
|
|
+ /* And the area after the label. Record it if we haven't done so yet. */
|
|
+ if (patch_area_size > patch_area_entry)
|
|
+ targetm.asm_out.print_patchable_function_entry (asm_out_file,
|
|
+ patch_area_size-patch_area_entry,
|
|
+ patch_area_entry == 0);
|
|
+
|
|
if (lookup_attribute ("no_split_stack", DECL_ATTRIBUTES (decl)))
|
|
saw_no_split_stack = true;
|
|
}
|
|
--
|
|
2.33.1
|
|
|