diff mbox series

[3/3] x86: Simplify UNSPECV_PATCHABLE_AREA generation

Message ID 20200205143300.144541-4-hjl.tools@gmail.com
State New
Headers show
Series Update -fpatchable-function-entry implementation | expand

Commit Message

H.J. Lu Feb. 5, 2020, 2:33 p.m. UTC
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 mbox series

Patch

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")