Add patch_area_size and patch_area_entry to crtl
authorH.J. Lu <hjl.tools@gmail.com>
Sat, 2 May 2020 04:03:10 +0000 (21:03 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Sat, 2 May 2020 04:04:01 +0000 (21:04 -0700)
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.

12 files changed:
gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-attribs.c
gcc/cfgexpand.c
gcc/doc/invoke.texi
gcc/emit-rtl.h
gcc/opts.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/patchable_function_entry-error-1.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/patchable_function_entry-error-2.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/patchable_function_entry-error-3.c [new file with mode: 0644]
gcc/varasm.c

index e85a8e8813e1621a3ece8ad2d9c8e021535b862e..fb776ba5a0e09351084de2197d054fc4a297faa4 100644 (file)
@@ -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.
index c429b49e68c70178a74d0fa9409610b758b229c4..69ea1fdc4f35e4f262342aa1ad875c29dc146b30 100644 (file)
@@ -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 %}.
index ac936d5bbbb45ec38a9572acb0ef4d4ae8870751..a101312c5817cb918d64961372580801cd84622c 100644 (file)
@@ -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;
 }
index a7ec77d5c85e9b11f545f3d13bb23ad32b734e14..86efa22bf60b6b9315e86eb934239cd3dd467849 100644 (file)
@@ -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)
index 527d362533ab503cee9568b27808177977a52ac8..767d1f07801cdf9219a5a02493fcc1af861f4887 100644 (file)
@@ -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
 
 
index a878efe3cf7e86e9e5068904a3094eb0ba704b38..3d6565c8a30d8da0bae32a09584ef5c7f2671074 100644 (file)
@@ -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
index c212a1a57dcfbdfb9cb419bfeaeb17aa9f23fdb0..3dccef3970131902e93cf45df8de7d11d4251c98 100644 (file)
@@ -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;
index 176aa117904b3e27cc73454630d73b2cf1cd2798..185f9ea725e711e465d484286f380e311f62d50e 100644 (file)
@@ -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 (file)
index 0000000..f60bf46
--- /dev/null
@@ -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 (file)
index 0000000..90f88c7
--- /dev/null
@@ -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 (file)
index 0000000..4490e5c
--- /dev/null
@@ -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" } */
+}
index 271a67abf56200ffb5e996356ef0b537ec41e0c4..f062e48071fefb82e0603a2f74b7fc89cbe96350 100644 (file)
@@ -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)