Since patch_area_size and patch_area_entry have been added to cfun,
we can use them to directly insert the pseudo UNSPECV_PATCHABLE_AREA
instruction.

        PR target/93492
        * config/i386/i386-features.c
        (rest_of_insert_endbr_and_patchable_area): Change
        need_patchable_area argument to patchable_area_size.  Generate
        UNSPECV_PATCHABLE_AREA instruction with proper arguments.
        (pass_insert_endbr_and_patchable_area::gate): Set and check
        patchable_area_size instead of need_patchable_area.
        (pass_insert_endbr_and_patchable_area::execute): Pass
        patchable_area_size to rest_of_insert_endbr_and_patchable_area.
        (pass_insert_endbr_and_patchable_area): Replace
        need_patchable_area with patchable_area_size.
        * config/i386/i386.c (ix86_print_patchable_function_entry):
        Just return if function table has been emitted.
        (x86_function_profiler): Use cfun->patch_area_size and
        cfun->patch_area_entry.
        * config/i386/i386.h (machine_function): Remove patch_area_size
        and record_patch_area.
        * config/i386/i386.md (patchable_area): Set length attribute.
---
 gcc/config/i386/i386-features.c | 22 +++++-------
 gcc/config/i386/i386.c          | 60 ++++++---------------------------
 gcc/config/i386/i386.h          |  6 ----
 gcc/config/i386/i386.md         | 10 +++---
 4 files changed, 25 insertions(+), 73 deletions(-)

diff --git a/gcc/config/i386/i386-features.c b/gcc/config/i386/i386-features.c
index be46f036126..d358abe7064 100644
--- a/gcc/config/i386/i386-features.c
+++ b/gcc/config/i386/i386-features.c
@@ -1941,7 +1941,7 @@ make_pass_stv (gcc::context *ctxt)
 
 static void
 rest_of_insert_endbr_and_patchable_area (bool need_endbr,
-                                        bool need_patchable_area)
+                                        unsigned int patchable_area_size)
 {
   rtx endbr;
   rtx_insn *insn;
@@ -1980,7 +1980,7 @@ rest_of_insert_endbr_and_patchable_area (bool need_endbr,
        }
     }
 
-  if (need_patchable_area)
+  if (patchable_area_size)
     {
       if (crtl->profile && flag_fentry)
        {
@@ -1992,10 +1992,9 @@ rest_of_insert_endbr_and_patchable_area (bool need_endbr,
        }
       else
        {
-         /* ix86_print_patchable_function_entry will provide actual
-            size.  */
-         rtx patchable_area = gen_patchable_area (GEN_INT (0),
-                                                  GEN_INT (0));
+         rtx patchable_area
+           = gen_patchable_area (GEN_INT (patchable_area_size),
+                                 GEN_INT (cfun->patch_area_entry == 0));
          if (endbr_insn)
            emit_insn_after (patchable_area, endbr_insn);
          else
@@ -2123,25 +2122,22 @@ public:
   virtual bool gate (function *fun)
     {
       need_endbr = (flag_cf_protection & CF_BRANCH) != 0;
-      need_patchable_area
-       = (function_entry_patch_area_size
-          || lookup_attribute ("patchable_function_entry",
-                               DECL_ATTRIBUTES (fun->decl)));
-      return need_endbr || need_patchable_area;
+      patchable_area_size = fun->patch_area_size - fun->patch_area_entry;
+      return need_endbr || patchable_area_size;
     }
 
   virtual unsigned int execute (function *)
     {
       timevar_push (TV_MACH_DEP);
       rest_of_insert_endbr_and_patchable_area (need_endbr,
-                                              need_patchable_area);
+                                              patchable_area_size);
       timevar_pop (TV_MACH_DEP);
       return 0;
     }
 
 private:
   bool need_endbr;
-  bool need_patchable_area;
+  unsigned int patchable_area_size;
 }; // class pass_insert_endbr_and_patchable_area
 
 } // anon namespace
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 051a1fcbdc2..79a8823f61e 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -9130,53 +9130,11 @@ ix86_print_patchable_function_entry (FILE *file,
 {
   if (cfun->machine->function_label_emitted)
     {
-      /* The insert_endbr_and_patchable_area pass inserted a dummy
-        UNSPECV_PATCHABLE_AREA with 0 patchable area size.  If the
-        patchable area is placed after the function label, we replace
-        0 patchable area size with the real one.  Otherwise, the
-        dummy UNSPECV_PATCHABLE_AREA will be ignored.  */
-      if (cfun->machine->insn_queued_at_entrance)
-       {
-         /* Record the patchable area.  Both ENDBR and patchable area
-            will be inserted by x86_function_profiler later.  */
-         cfun->machine->patch_area_size = patch_area_size;
-         cfun->machine->record_patch_area = record_p;
-         return;
-       }
-
-      /* We can have
-
-        UNSPECV_NOP_ENDBR
-        UNSPECV_PATCHABLE_AREA
-
-        or just
-
-        UNSPECV_PATCHABLE_AREA
-       */
-      rtx_insn *patchable_insn;
-      rtx_insn *insn = next_real_nondebug_insn (get_insns ());
-      if (insn
-         && INSN_P (insn)
-         && GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
-         && XINT (PATTERN (insn), 1) == UNSPECV_NOP_ENDBR)
-       patchable_insn = next_real_nondebug_insn (insn);
-      else
-       patchable_insn = insn;
-
-      if (patchable_insn && INSN_P (patchable_insn))
-       {
-         /* Replace the dummy patchable area size with the real one.  */
-         rtx pattern = PATTERN (patchable_insn);
-         if (GET_CODE (pattern) == UNSPEC_VOLATILE
-             && XINT (pattern, 1) == UNSPECV_PATCHABLE_AREA)
-           {
-             XVECEXP (pattern, 0, 0) = GEN_INT (patch_area_size);
-             XVECEXP (pattern, 0, 1) = GEN_INT (record_p);
-           }
-         return;
-       }
-
-      gcc_unreachable ();
+      /* NB: When ix86_print_patchable_function_entry is called after
+        function table has been emitted, we have inserted or queued
+        a pseudo UNSPECV_PATCHABLE_AREA instruction at the proper
+        place.  There is nothing to do here.  */
+      return;
     }
 
   default_print_patchable_function_entry (file, patch_area_size,
@@ -20232,9 +20190,11 @@ x86_function_profiler (FILE *file, int labelno 
ATTRIBUTE_UNUSED)
     {
       if (cfun->machine->insn_queued_at_entrance == TYPE_ENDBR)
        fprintf (file, "\t%s\n", TARGET_64BIT ? "endbr64" : "endbr32");
-      if (cfun->machine->patch_area_size)
-       ix86_output_patchable_area (cfun->machine->patch_area_size,
-                                   cfun->machine->record_patch_area);
+      unsigned int patch_area_size
+       = cfun->patch_area_size - cfun->patch_area_entry;
+      if (patch_area_size)
+       ix86_output_patchable_area (patch_area_size,
+                                   cfun->patch_area_entry == 0);
     }
 
   const char *mcount_name = MCOUNT_NAME;
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 7c8f0cd4c70..e63edf16bcc 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -2774,12 +2774,6 @@ struct GTY(()) machine_function {
      structure.  */
   rtx split_stack_varargs_pointer;
 
-  /* The size of the patchable area at function entry.  */
-  unsigned int patch_area_size;
-
-  /* If true, record patchable area at function entry.  */
-  BOOL_BITFIELD record_patch_area : 1;
-
   /* This value is used for amd64 targets and specifies the current abi
      to be used. MS_ABI means ms abi. Otherwise SYSV_ABI means sysv abi.  */
   ENUM_BITFIELD(calling_abi) call_abi : 8;
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 78c38d5704a..3b243048d81 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -21289,11 +21289,13 @@ (define_insn "patchable_area"
                    UNSPECV_PATCHABLE_AREA)]
   ""
 {
-  if (INTVAL (operands[0]))
-    ix86_output_patchable_area (INTVAL (operands[0]),
-                               INTVAL (operands[1]) != 0);
+  ix86_output_patchable_area (INTVAL (operands[0]),
+                             INTVAL (operands[1]) != 0);
   return "";
-})
+}
+  [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
+   (set_attr "length_immediate" "0")
+   (set_attr "modrm" "0")])
 
 (include "mmx.md")
 (include "sse.md")
-- 
2.24.1

Reply via email to