2021-10-26 06:17:33 +00:00
|
|
|
From 961670bae0c7b37073dbc0bb58d730d1ed603d5d Mon Sep 17 00:00:00 2001
|
2021-10-22 07:20:27 +00:00
|
|
|
From: "H.J. Lu" <hjl.tools@gmail.com>
|
|
|
|
Date: Fri, 1 May 2020 21:03:10 -0700
|
|
|
|
Subject: [PATCH 17/22] Backport Add patch_area_size and patch_area_entry to
|
|
|
|
crtl
|
|
|
|
|
|
|
|
Currently patchable area is at the wrong place. It is placed immediately
|
|
|
|
after function label and before .cfi_startproc. A backend should be able
|
|
|
|
to add a pseudo patchable area instruction durectly into RTL. This patch
|
|
|
|
adds patch_area_size and patch_area_entry to crtl so that the patchable
|
|
|
|
area info is available in RTL passes.
|
|
|
|
|
|
|
|
It also limits patch_area_size and patch_area_entry to 65535, which is
|
|
|
|
a reasonable maximum size for patchable area.
|
|
|
|
|
|
|
|
gcc/
|
|
|
|
|
|
|
|
PR target/93492
|
|
|
|
* cfgexpand.c (pass_expand::execute): Set crtl->patch_area_size
|
|
|
|
and crtl->patch_area_entry.
|
|
|
|
* emit-rtl.h (rtl_data): Add patch_area_size and patch_area_entry.
|
|
|
|
* opts.c (common_handle_option): Limit
|
|
|
|
function_entry_patch_area_size and function_entry_patch_area_start
|
|
|
|
to USHRT_MAX. Fix a typo in error message.
|
|
|
|
* varasm.c (assemble_start_function): Use crtl->patch_area_size
|
|
|
|
and crtl->patch_area_entry.
|
|
|
|
* doc/invoke.texi: Document the maximum value for
|
|
|
|
-fpatchable-function-entry.
|
|
|
|
|
|
|
|
gcc/c-family/
|
|
|
|
|
|
|
|
PR target/93492
|
|
|
|
* c-attribs.c (handle_patchable_function_entry_attribute): Limit
|
|
|
|
value to USHRT_MAX (65535).
|
|
|
|
|
|
|
|
gcc/testsuite/
|
|
|
|
|
|
|
|
PR target/93492
|
|
|
|
* c-c++-common/patchable_function_entry-error-1.c: New test.
|
|
|
|
* c-c++-common/patchable_function_entry-error-2.c: Likewise.
|
|
|
|
* c-c++-common/patchable_function_entry-error-3.c: Likewise.
|
|
|
|
---
|
|
|
|
gcc/c-family/c-attribs.c | 9 ++++
|
|
|
|
gcc/cfgexpand.c | 44 +++++++++++++++++++
|
|
|
|
gcc/doc/invoke.texi | 1 +
|
|
|
|
gcc/emit-rtl.h | 6 +++
|
|
|
|
gcc/opts.c | 4 +-
|
|
|
|
.../patchable_function_entry-error-1.c | 9 ++++
|
|
|
|
.../patchable_function_entry-error-2.c | 9 ++++
|
|
|
|
.../patchable_function_entry-error-3.c | 17 +++++++
|
|
|
|
gcc/varasm.c | 4 +-
|
|
|
|
9 files changed, 100 insertions(+), 3 deletions(-)
|
|
|
|
create mode 100644 gcc/testsuite/c-c++-common/patchable_function_entry-error-1.c
|
|
|
|
create mode 100644 gcc/testsuite/c-c++-common/patchable_function_entry-error-2.c
|
|
|
|
create mode 100644 gcc/testsuite/c-c++-common/patchable_function_entry-error-3.c
|
|
|
|
|
|
|
|
diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
|
|
|
|
index f0d2b1ed500..c01baffbc57 100644
|
|
|
|
--- a/gcc/c-family/c-attribs.c
|
|
|
|
+++ b/gcc/c-family/c-attribs.c
|
|
|
|
@@ -3206,6 +3206,15 @@ handle_patchable_function_entry_attribute (tree *, tree name, tree args,
|
|
|
|
*no_add_attrs = true;
|
|
|
|
return NULL_TREE;
|
|
|
|
}
|
|
|
|
+
|
|
|
|
+ if (tree_to_uhwi (val) > USHRT_MAX)
|
|
|
|
+ {
|
|
|
|
+ warning (OPT_Wattributes,
|
|
|
|
+ "%qE attribute argument %qE is out of range (> 65535)",
|
|
|
|
+ name, val);
|
|
|
|
+ *no_add_attrs = true;
|
|
|
|
+ return NULL_TREE;
|
|
|
|
+ }
|
|
|
|
}
|
|
|
|
return NULL_TREE;
|
|
|
|
}
|
|
|
|
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
|
|
|
|
index 7fd3916a3c7..2a603823a71 100644
|
|
|
|
--- a/gcc/cfgexpand.c
|
|
|
|
+++ b/gcc/cfgexpand.c
|
|
|
|
@@ -6481,6 +6481,50 @@ pass_expand::execute (function *fun)
|
|
|
|
if (crtl->tail_call_emit)
|
|
|
|
fixup_tail_calls ();
|
|
|
|
|
|
|
|
+ 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 (cfun->decl));
|
|
|
|
+ if (patchable_function_entry_attr)
|
|
|
|
+ {
|
|
|
|
+ tree pp_val = TREE_VALUE (patchable_function_entry_attr);
|
|
|
|
+ tree patchable_function_entry_value1 = TREE_VALUE (pp_val);
|
|
|
|
+
|
|
|
|
+ patch_area_size = tree_to_uhwi (patchable_function_entry_value1);
|
|
|
|
+ patch_area_entry = 0;
|
|
|
|
+ if (TREE_CHAIN (pp_val) != NULL_TREE)
|
|
|
|
+ {
|
|
|
|
+ tree patchable_function_entry_value2
|
|
|
|
+ = TREE_VALUE (TREE_CHAIN (pp_val));
|
|
|
|
+ patch_area_entry = tree_to_uhwi (patchable_function_entry_value2);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (patch_area_entry > patch_area_size)
|
|
|
|
+ {
|
|
|
|
+ if (patch_area_size > 0)
|
|
|
|
+ warning (OPT_Wattributes,
|
|
|
|
+ "patchable function entry %wu exceeds size %wu",
|
|
|
|
+ patch_area_entry, patch_area_size);
|
|
|
|
+ patch_area_entry = 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ crtl->patch_area_size = patch_area_size;
|
|
|
|
+ crtl->patch_area_entry = patch_area_entry;
|
|
|
|
+
|
|
|
|
+ /* This function is not present in gcc 7, nor the profile_count datastructures,
|
|
|
|
+ so it may be safe to assume that there is not enough engine implemented so
|
|
|
|
+ far to support that. */
|
|
|
|
+#if 0
|
|
|
|
+ /* BB subdivision may have created basic blocks that are only reachable
|
|
|
|
+ from unlikely bbs but not marked as such in the profile. */
|
|
|
|
+
|
|
|
|
+ if (optimize)
|
|
|
|
+ propagate_unlikely_bbs_forward ();
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
/* Remove unreachable blocks, otherwise we cannot compute dominators
|
|
|
|
which are needed for loop state verification. As a side-effect
|
|
|
|
this also compacts blocks.
|
|
|
|
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
|
|
|
|
index ad71be54e07..9fd3b013ff7 100644
|
|
|
|
--- a/gcc/doc/invoke.texi
|
|
|
|
+++ b/gcc/doc/invoke.texi
|
|
|
|
@@ -11445,6 +11445,7 @@ 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.
|
|
|
|
|
|
|
|
+The maximum value of @var{N} and @var{M} is 65535.
|
|
|
|
@end table
|
|
|
|
|
|
|
|
|
|
|
|
diff --git a/gcc/emit-rtl.h b/gcc/emit-rtl.h
|
|
|
|
index da60a2d808c..66bc1bef391 100644
|
|
|
|
--- a/gcc/emit-rtl.h
|
|
|
|
+++ b/gcc/emit-rtl.h
|
|
|
|
@@ -163,6 +163,12 @@ struct GTY(()) rtl_data {
|
|
|
|
local stack. */
|
|
|
|
unsigned int stack_alignment_estimated;
|
|
|
|
|
|
|
|
+ /* How many NOP insns to place at each function entry by default. */
|
|
|
|
+ unsigned short patch_area_size;
|
|
|
|
+
|
|
|
|
+ /* How far the real asm entry point is into this area. */
|
|
|
|
+ unsigned short patch_area_entry;
|
|
|
|
+
|
|
|
|
/* For reorg. */
|
|
|
|
|
|
|
|
/* Nonzero if function being compiled called builtin_return_addr or
|
|
|
|
diff --git a/gcc/opts.c b/gcc/opts.c
|
|
|
|
index d0430e777ee..3de12b3662f 100644
|
|
|
|
--- a/gcc/opts.c
|
|
|
|
+++ b/gcc/opts.c
|
|
|
|
@@ -2220,10 +2220,12 @@ common_handle_option (struct gcc_options *opts,
|
|
|
|
function_entry_patch_area_start = 0;
|
|
|
|
}
|
|
|
|
if (function_entry_patch_area_size < 0
|
|
|
|
+ || function_entry_patch_area_size > USHRT_MAX
|
|
|
|
|| function_entry_patch_area_start < 0
|
|
|
|
+ || function_entry_patch_area_start > USHRT_MAX
|
|
|
|
|| function_entry_patch_area_size
|
|
|
|
< function_entry_patch_area_start)
|
|
|
|
- error ("invalid arguments for %<-fpatchable_function_entry%>");
|
|
|
|
+ error ("invalid arguments for %<-fpatchable-function-entry%>");
|
|
|
|
free (patch_area_arg);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
diff --git a/gcc/testsuite/c-c++-common/patchable_function_entry-error-1.c b/gcc/testsuite/c-c++-common/patchable_function_entry-error-1.c
|
|
|
|
new file mode 100644
|
|
|
|
index 00000000000..f60bf46cfe3
|
|
|
|
--- /dev/null
|
|
|
|
+++ b/gcc/testsuite/c-c++-common/patchable_function_entry-error-1.c
|
|
|
|
@@ -0,0 +1,9 @@
|
|
|
|
+/* { dg-do compile { target { ! { nvptx*-*-* visium-*-* } } } } */
|
|
|
|
+/* { dg-options "-O2 -fpatchable-function-entry=65536,1" } */
|
|
|
|
+/* { dg-additional-options "-fno-pie" { target sparc*-*-* } } */
|
|
|
|
+/* { dg-error "invalid arguments for '-fpatchable-function-entry'" "" { target *-*-* } 0 } */
|
|
|
|
+
|
|
|
|
+void
|
|
|
|
+foo (void)
|
|
|
|
+{
|
|
|
|
+}
|
|
|
|
diff --git a/gcc/testsuite/c-c++-common/patchable_function_entry-error-2.c b/gcc/testsuite/c-c++-common/patchable_function_entry-error-2.c
|
|
|
|
new file mode 100644
|
|
|
|
index 00000000000..90f88c78be7
|
|
|
|
--- /dev/null
|
|
|
|
+++ b/gcc/testsuite/c-c++-common/patchable_function_entry-error-2.c
|
|
|
|
@@ -0,0 +1,9 @@
|
|
|
|
+/* { dg-do compile { target { ! { nvptx*-*-* visium-*-* } } } } */
|
|
|
|
+/* { dg-options "-O2 -fpatchable-function-entry=1,65536" } */
|
|
|
|
+/* { dg-additional-options "-fno-pie" { target sparc*-*-* } } */
|
|
|
|
+/* { dg-error "invalid arguments for '-fpatchable-function-entry'" "" { target *-*-* } 0 } */
|
|
|
|
+
|
|
|
|
+void
|
|
|
|
+foo (void)
|
|
|
|
+{
|
|
|
|
+}
|
|
|
|
diff --git a/gcc/testsuite/c-c++-common/patchable_function_entry-error-3.c b/gcc/testsuite/c-c++-common/patchable_function_entry-error-3.c
|
|
|
|
new file mode 100644
|
|
|
|
index 00000000000..4490e5c15ca
|
|
|
|
--- /dev/null
|
|
|
|
+++ b/gcc/testsuite/c-c++-common/patchable_function_entry-error-3.c
|
|
|
|
@@ -0,0 +1,17 @@
|
|
|
|
+/* { dg-do compile { target { ! { nvptx*-*-* visium-*-* } } } } */
|
|
|
|
+/* { dg-additional-options "-fno-pie" { target sparc*-*-* } } */
|
|
|
|
+
|
|
|
|
+void
|
|
|
|
+ __attribute__((patchable_function_entry(65536)))
|
|
|
|
+foo1 (void) { /* { dg-warning "'patchable_function_entry' attribute argument '65536' is out of range" } */
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void
|
|
|
|
+ __attribute__((patchable_function_entry(65536,1)))
|
|
|
|
+foo2 (void) { /* { dg-warning "'patchable_function_entry' attribute argument '65536' is out of range" } */
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void
|
|
|
|
+ __attribute__((patchable_function_entry(65536,65536)))
|
|
|
|
+foo3 (void) { /* { dg-warning "'patchable_function_entry' attribute argument '65536' is out of range" } */
|
|
|
|
+}
|
|
|
|
diff --git a/gcc/varasm.c b/gcc/varasm.c
|
|
|
|
index 0e6f20db361..8d4c0386fe3 100644
|
|
|
|
--- a/gcc/varasm.c
|
|
|
|
+++ b/gcc/varasm.c
|
|
|
|
@@ -1829,8 +1829,8 @@ 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;
|
|
|
|
+ unsigned short patch_area_size = crtl->patch_area_size;
|
|
|
|
+ unsigned short patch_area_entry = crtl->patch_area_entry;
|
|
|
|
|
|
|
|
tree patchable_function_entry_attr
|
|
|
|
= lookup_attribute ("patchable_function_entry", DECL_ATTRIBUTES (decl));
|
|
|
|
--
|
|
|
|
2.33.1
|
|
|
|
|