diff mbox series

i386: Insert ENDBR before the profiling counter call

Message ID 20171024160405.GA13209@gmail.com
State New
Headers show
Series i386: Insert ENDBR before the profiling counter call | expand

Commit Message

H.J. Lu Oct. 24, 2017, 4:04 p.m. UTC
ENDBR must be the first instruction of a function.  This patch queues
ENDBR if we need to put the profiling counter call before the prologue
and generate ENDBR before the profiling counter call.

OK for trunk if there is no regressions?

H.J.
---
gcc/

	PR target/82699
	* config/i386/i386.c (ix86_profile_before_prologue): Add a
	prototype.
	(rest_of_insert_endbranch): Set endbr_queued_at_entrance to
	true and don't insert ENDBR if ix86_profile_before_prologue ()
	returns true.
	(x86_function_profiler): Insert ENDBR if endbr_queued_at_entrance
	is true.

gcc/testsuite/

	PR target/82699
	* gcc.target/i386/pr82699-1.c: New file.
	* gcc.target/i386/pr82699-2.c: Likewise.
	* gcc.target/i386/pr82699-3.c: Likewise.
	* gcc.target/i386/pr82699-4.c: Likewise.
---
 gcc/config/i386/i386.c                    | 18 ++++++++++++++----
 gcc/config/i386/i386.h                    |  3 +++
 gcc/testsuite/gcc.target/i386/pr82699-1.c | 11 +++++++++++
 gcc/testsuite/gcc.target/i386/pr82699-2.c | 11 +++++++++++
 gcc/testsuite/gcc.target/i386/pr82699-3.c | 11 +++++++++++
 gcc/testsuite/gcc.target/i386/pr82699-4.c | 11 +++++++++++
 6 files changed, 61 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr82699-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr82699-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr82699-3.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr82699-4.c

Comments

H.J. Lu Oct. 24, 2017, 5:12 p.m. UTC | #1
On Tue, Oct 24, 2017 at 09:04:05AM -0700, H.J. Lu wrote:
> ENDBR must be the first instruction of a function.  This patch queues
> ENDBR if we need to put the profiling counter call before the prologue
> and generate ENDBR before the profiling counter call.
> 
> OK for trunk if there is no regressions?
> 

Here is the updated patch to handle -mfentry without -pg.


H.J.
---
gcc/

	PR target/82699
	* config/i386/i386.c (rest_of_insert_endbranch): Set
	endbr_queued_at_entrance to true and don't insert ENDBR if
	x86_function_profiler will be called.
	(x86_function_profiler): Insert ENDBR if endbr_queued_at_entrance
	is true.
	* config/i386/i386.h (machine_function): Add
	endbr_queued_at_entrance.

gcc/testsuite/

	PR target/82699
	* gcc.target/i386/pr82699-1.c: New file.
	* gcc.target/i386/pr82699-2.c: Likewise.
	* gcc.target/i386/pr82699-3.c: Likewise.
	* gcc.target/i386/pr82699-4.c: Likewise.
	* gcc.target/i386/pr82699-5.c: Likewise.
---
 gcc/config/i386/i386.c                    | 18 ++++++++++++++----
 gcc/config/i386/i386.h                    |  3 +++
 gcc/testsuite/gcc.target/i386/pr82699-1.c | 11 +++++++++++
 gcc/testsuite/gcc.target/i386/pr82699-2.c | 11 +++++++++++
 gcc/testsuite/gcc.target/i386/pr82699-3.c | 11 +++++++++++
 gcc/testsuite/gcc.target/i386/pr82699-4.c | 11 +++++++++++
 gcc/testsuite/gcc.target/i386/pr82699-5.c | 11 +++++++++++
 7 files changed, 72 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr82699-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr82699-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr82699-3.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr82699-4.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr82699-5.c

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index d2188ad6086..7974a915b38 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -2590,11 +2590,17 @@ rest_of_insert_endbranch (void)
 			 TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl)))
       && !cgraph_node::get (cfun->decl)->only_called_directly_p ())
     {
-      cet_eb = gen_nop_endbr ();
+      /* Queue ENDBR insertion to x86_function_profiler.  */
+      if (crtl->profile && flag_fentry)
+	cfun->machine->endbr_queued_at_entrance = true;
+      else
+	{
+	  cet_eb = gen_nop_endbr ();
 
-      bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
-      insn = BB_HEAD (bb);
-      emit_insn_before (cet_eb, insn);
+	  bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
+	  insn = BB_HEAD (bb);
+	  emit_insn_before (cet_eb, insn);
+	}
     }
 
   bb = 0;
@@ -40427,6 +40433,10 @@ x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
 {
   const char *mcount_name = (flag_fentry ? MCOUNT_NAME_BEFORE_PROLOGUE
 					 : MCOUNT_NAME);
+
+  if (cfun->machine->endbr_queued_at_entrance)
+    fprintf (file, "\t%s\n", TARGET_64BIT ? "endbr64" : "endbr32");
+
   if (TARGET_64BIT)
     {
 #ifndef NO_PROFILE_COUNTERS
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 27fc9f08cc7..925557d32cb 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -2581,6 +2581,9 @@ struct GTY(()) machine_function {
   /* Nonzero if the function places outgoing arguments on stack.  */
   BOOL_BITFIELD outgoing_args_on_stack : 1;
 
+  /* If true, ENDBR is queued at function entrance.  */
+  BOOL_BITFIELD endbr_queued_at_entrance : 1;
+
   /* During prologue/epilogue generation, the current frame state.
      Otherwise, the frame state at the end of the prologue.  */
   struct machine_frame_state fs;
diff --git a/gcc/testsuite/gcc.target/i386/pr82699-1.c b/gcc/testsuite/gcc.target/i386/pr82699-1.c
new file mode 100644
index 00000000000..4fc404753e8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr82699-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -fcf-protection -mcet -pg -fasynchronous-unwind-tables" } */
+/* { dg-final { scan-assembler-times {\t\.cfi_startproc\n\tendbr} 1 } } */
+
+extern int bar (int);
+
+int
+foo (int i)
+{
+  return bar (i);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr82699-2.c b/gcc/testsuite/gcc.target/i386/pr82699-2.c
new file mode 100644
index 00000000000..4fb9cb9e68b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr82699-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -fcf-protection -mcet -pg -mfentry -fasynchronous-unwind-tables" } */
+/* { dg-final { scan-assembler-times {\t\.cfi_startproc\n\tendbr} 1 } } */
+
+extern int bar (int);
+
+int
+foo (int i)
+{
+  return bar (i);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr82699-3.c b/gcc/testsuite/gcc.target/i386/pr82699-3.c
new file mode 100644
index 00000000000..92d84ee4ab5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr82699-3.c
@@ -0,0 +1,11 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic -fcf-protection -mcet -pg -fasynchronous-unwind-tables" } */
+/* { dg-final { scan-assembler-times {\t\.cfi_startproc\n\tendbr} 1 } } */
+
+extern int bar (int);
+
+int
+foo (int i)
+{
+  return bar (i);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr82699-4.c b/gcc/testsuite/gcc.target/i386/pr82699-4.c
new file mode 100644
index 00000000000..415ce3b913a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr82699-4.c
@@ -0,0 +1,11 @@
+/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
+/* { dg-options "-O2 -fpic -fcf-protection -mcet -pg -mfentry -fasynchronous-unwind-tables" } */
+/* { dg-final { scan-assembler-times {\t\.cfi_startproc\n\tendbr} 1 } } */
+
+extern int bar (int);
+
+int
+foo (int i)
+{
+  return bar (i);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr82699-5.c b/gcc/testsuite/gcc.target/i386/pr82699-5.c
new file mode 100644
index 00000000000..c0820352ac2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr82699-5.c
@@ -0,0 +1,11 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fcf-protection -mcet -mfentry -fasynchronous-unwind-tables" } */
+/* { dg-final { scan-assembler-times {\t\.cfi_startproc\n\tendbr} 1 } } */
+
+extern int bar (int);
+
+int
+foo (int i)
+{
+  return bar (i);
+}
Andi Kleen Oct. 24, 2017, 5:40 p.m. UTC | #2
"H.J. Lu" <hongjiu.lu@intel.com> writes:
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr82699-4.c
> @@ -0,0 +1,11 @@
> +/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
> +/* { dg-options "-O2 -fpic -fcf-protection -mcet -pg -mfentry -fasynchronous-unwind-tables" } */
> +/* { dg-final { scan-assembler-times {\t\.cfi_startproc\n\tendbr} 1 }
> } */

Would add test cases for -mnop-mcount and -mrecord-mcount too

-Andi
H.J. Lu Oct. 24, 2017, 5:58 p.m. UTC | #3
On Tue, Oct 24, 2017 at 10:40 AM, Andi Kleen <ak@linux.intel.com> wrote:
> "H.J. Lu" <hongjiu.lu@intel.com> writes:
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.target/i386/pr82699-4.c
>> @@ -0,0 +1,11 @@
>> +/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
>> +/* { dg-options "-O2 -fpic -fcf-protection -mcet -pg -mfentry -fasynchronous-unwind-tables" } */
>> +/* { dg-final { scan-assembler-times {\t\.cfi_startproc\n\tendbr} 1 }
>> } */
>
> Would add test cases for -mnop-mcount and -mrecord-mcount too
>

Here is the updated patch to add a testcase for -mnop-mcount -mrecord-mcount.
No other changes otherwise.
diff mbox series

Patch

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index d2188ad6086..4e6936cd987 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -101,6 +101,7 @@  static void ix86_print_operand_address_as (FILE *, rtx, addr_space_t, bool);
 static bool ix86_save_reg (unsigned int, bool, bool);
 static bool ix86_function_naked (const_tree);
 static bool ix86_notrack_prefixed_insn_p (rtx);
+static bool ix86_profile_before_prologue (void);
 
 #ifndef CHECK_STACK_LIMIT
 #define CHECK_STACK_LIMIT (-1)
@@ -2590,11 +2591,16 @@  rest_of_insert_endbranch (void)
 			 TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl)))
       && !cgraph_node::get (cfun->decl)->only_called_directly_p ())
     {
-      cet_eb = gen_nop_endbr ();
+      if (ix86_profile_before_prologue ())
+	cfun->machine->endbr_queued_at_entrance = true;
+      else
+	{
+	  cet_eb = gen_nop_endbr ();
 
-      bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
-      insn = BB_HEAD (bb);
-      emit_insn_before (cet_eb, insn);
+	  bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
+	  insn = BB_HEAD (bb);
+	  emit_insn_before (cet_eb, insn);
+	}
     }
 
   bb = 0;
@@ -40427,6 +40433,10 @@  x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
 {
   const char *mcount_name = (flag_fentry ? MCOUNT_NAME_BEFORE_PROLOGUE
 					 : MCOUNT_NAME);
+
+  if (cfun->machine->endbr_queued_at_entrance)
+    fprintf (file, "\t%s\n", TARGET_64BIT ? "endbr64" : "endbr32");
+
   if (TARGET_64BIT)
     {
 #ifndef NO_PROFILE_COUNTERS
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 27fc9f08cc7..925557d32cb 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -2581,6 +2581,9 @@  struct GTY(()) machine_function {
   /* Nonzero if the function places outgoing arguments on stack.  */
   BOOL_BITFIELD outgoing_args_on_stack : 1;
 
+  /* If true, ENDBR is queued at function entrance.  */
+  BOOL_BITFIELD endbr_queued_at_entrance : 1;
+
   /* During prologue/epilogue generation, the current frame state.
      Otherwise, the frame state at the end of the prologue.  */
   struct machine_frame_state fs;
diff --git a/gcc/testsuite/gcc.target/i386/pr82699-1.c b/gcc/testsuite/gcc.target/i386/pr82699-1.c
new file mode 100644
index 00000000000..4fc404753e8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr82699-1.c
@@ -0,0 +1,11 @@ 
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -fcf-protection -mcet -pg -fasynchronous-unwind-tables" } */
+/* { dg-final { scan-assembler-times {\t\.cfi_startproc\n\tendbr} 1 } } */
+
+extern int bar (int);
+
+int
+foo (int i)
+{
+  return bar (i);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr82699-2.c b/gcc/testsuite/gcc.target/i386/pr82699-2.c
new file mode 100644
index 00000000000..4fb9cb9e68b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr82699-2.c
@@ -0,0 +1,11 @@ 
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fno-pic -fcf-protection -mcet -pg -mfentry -fasynchronous-unwind-tables" } */
+/* { dg-final { scan-assembler-times {\t\.cfi_startproc\n\tendbr} 1 } } */
+
+extern int bar (int);
+
+int
+foo (int i)
+{
+  return bar (i);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr82699-3.c b/gcc/testsuite/gcc.target/i386/pr82699-3.c
new file mode 100644
index 00000000000..92d84ee4ab5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr82699-3.c
@@ -0,0 +1,11 @@ 
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-O2 -fpic -fcf-protection -mcet -pg -fasynchronous-unwind-tables" } */
+/* { dg-final { scan-assembler-times {\t\.cfi_startproc\n\tendbr} 1 } } */
+
+extern int bar (int);
+
+int
+foo (int i)
+{
+  return bar (i);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr82699-4.c b/gcc/testsuite/gcc.target/i386/pr82699-4.c
new file mode 100644
index 00000000000..415ce3b913a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr82699-4.c
@@ -0,0 +1,11 @@ 
+/* { dg-do compile { target { *-*-linux* && { ! ia32 } } } } */
+/* { dg-options "-O2 -fpic -fcf-protection -mcet -pg -mfentry -fasynchronous-unwind-tables" } */
+/* { dg-final { scan-assembler-times {\t\.cfi_startproc\n\tendbr} 1 } } */
+
+extern int bar (int);
+
+int
+foo (int i)
+{
+  return bar (i);
+}