aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2020-05-01 21:03:10 -0700
committerH.J. Lu <hjl.tools@gmail.com>2020-05-01 21:04:01 -0700
commit6607bdd99994c834f92fce924abdaea3405f62dc (patch)
tree9263654efb733aa5e0fdd7c218ab784c96ae69e0
parent23c42a01bce298d1578bd0421db1d463739cdf2b (diff)
downloadgcc-6607bdd99994c834f92fce924abdaea3405f62dc.zip
gcc-6607bdd99994c834f92fce924abdaea3405f62dc.tar.gz
gcc-6607bdd99994c834f92fce924abdaea3405f62dc.tar.bz2
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.
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/c-family/ChangeLog6
-rw-r--r--gcc/c-family/c-attribs.c9
-rw-r--r--gcc/cfgexpand.c33
-rw-r--r--gcc/doc/invoke.texi1
-rw-r--r--gcc/emit-rtl.h6
-rw-r--r--gcc/opts.c4
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/c-c++-common/patchable_function_entry-error-1.c9
-rw-r--r--gcc/testsuite/c-c++-common/patchable_function_entry-error-2.c9
-rw-r--r--gcc/testsuite/c-c++-common/patchable_function_entry-error-3.c17
-rw-r--r--gcc/varasm.c30
12 files changed, 116 insertions, 29 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e85a8e8..fb776ba 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2020-05-01 H.J. Lu <hongjiu.lu@intel.com>
+
+ 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.
+
2020-05-01 Iain Sandoe <iain@sandoe.co.uk>
* config/i386/darwin.h: Repair SUBTARGET_INIT_BUILTINS.
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index c429b49..69ea1fd 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,9 @@
+2020-05-01 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/93492
+ * c-attribs.c (handle_patchable_function_entry_attribute): Limit
+ value to USHRT_MAX (65535).
+
2020-04-29 Jakub Jelinek <jakub@redhat.com>
* c-format.c (PP_FORMAT_CHAR_TABLE): Add %{ and %}.
diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
index ac936d5..a101312 100644
--- a/gcc/c-family/c-attribs.c
+++ b/gcc/c-family/c-attribs.c
@@ -4553,6 +4553,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 a7ec77d..86efa22 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -6656,6 +6656,39 @@ 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;
+
/* BB subdivision may have created basic blocks that are only reachable
from unlikely bbs but not marked as such in the profile. */
if (optimize)
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 527d362..767d1f0 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -14112,6 +14112,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 a878efe..3d6565c 100644
--- a/gcc/emit-rtl.h
+++ b/gcc/emit-rtl.h
@@ -173,6 +173,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 c212a1a..3dccef3 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -2615,10 +2615,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/ChangeLog b/gcc/testsuite/ChangeLog
index 176aa11..185f9ea 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2020-05-01 H.J. Lu <hongjiu.lu@intel.com>
+
+ 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.
+
2020-05-01 Patrick Palka <ppalka@redhat.com>
PR c++/90880
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 0000000..f60bf46
--- /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 0000000..90f88c78
--- /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 0000000..4490e5c
--- /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 271a67a..f062e48 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -1857,34 +1857,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;
-
- 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);
-
- 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;
- }
+ unsigned short patch_area_size = crtl->patch_area_size;
+ unsigned short patch_area_entry = crtl->patch_area_entry;
/* Emit the patching area before the entry label, if any. */
if (patch_area_entry > 0)