Support changing fentry name per function
authorAndi Kleen <ak@linux.intel.com>
Thu, 29 Nov 2018 23:11:53 +0000 (23:11 +0000)
committerAndi Kleen <ak@gcc.gnu.org>
Thu, 29 Nov 2018 23:11:53 +0000 (23:11 +0000)
It can be useful to have some classes of functions that use a different
__fentry__ instrumentation than others.  Currently it is only
possible to disable instrumentation on the command line or with
no_instrument_function, but not to change the instrumentation function
on a case by case base.

Add some flexibility to allow to change the instrumentation function
name per file with an option or per function with a new attribute.
This also allows switching to nops for individual functions.

gcc/:

2018-11-29  Andi Kleen  <ak@linux.intel.com>

* config/i386/i386.c (x86_print_call_or_nop): Handle nop name.
(current_fentry_name): Add.
(x86_function_profiler): Handle fentry_name attribute.
(ix86_handle_fentry_name): Add.
(ix86_attribute_table): Add fentry_name.
* config/i386/i386.opt: Add -mfentry-name
* doc/extend.texi: Document fentry_name.
* doc/invoke.texi: Document minstrument-return.

gcc/testsuite/:

2018-11-29  Andi Kleen  <ak@linux.intel.com>

* gcc.target/i386/fentryname1.c: New test.

From-SVN: r266653

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/i386/i386.opt
gcc/doc/extend.texi
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/fentryname1.c [new file with mode: 0644]

index 9f19bc685ed8d0bbc02acd567e6fec20a0b9fabc..73a98523b968eb6faa082bae9b4dd49f7d478ecc 100644 (file)
@@ -1,3 +1,14 @@
+2018-11-29  Andi Kleen  <ak@linux.intel.com>
+
+       * config/i386/i386.c (x86_print_call_or_nop): Handle nop name.
+       (current_fentry_name): Add.
+       (x86_function_profiler): Handle fentry_name attribute.
+       (ix86_handle_fentry_name): Add.
+       (ix86_attribute_table): Add fentry_name.
+       * config/i386/i386.opt: Add -mfentry-name
+       * doc/extend.texi: Document fentry_name.
+       * doc/invoke.texi: Document minstrument-return.
+
 2018-11-29  Andi Kleen  <ak@linux.intel.com>
 
        * config/i386/i386-opts.h (enum instrument_return): Add.
index 98928d99265d0f7cd2519a2988eb36bc2a2208c8..ae6aa8d422c83561c8bc06c64c2d7df8596a2401 100644 (file)
@@ -41273,24 +41273,41 @@ x86_field_alignment (tree type, int computed)
 static void
 x86_print_call_or_nop (FILE *file, const char *target)
 {
-  if (flag_nop_mcount)
+  if (flag_nop_mcount || !strcmp (target, "nop"))
     /* 5 byte nop: nopl 0(%[re]ax,%[re]ax,1) */
     fprintf (file, "1:" ASM_BYTE "0x0f, 0x1f, 0x44, 0x00, 0x00\n");
   else
     fprintf (file, "1:\tcall\t%s\n", target);
 }
 
+static bool
+current_fentry_name (const char **name)
+{
+  tree attr = lookup_attribute ("fentry_name",
+                               DECL_ATTRIBUTES (current_function_decl));
+  if (!attr)
+    return false;
+  *name = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)));
+  return true;
+}
+
 /* Output assembler code to FILE to increment profiler label # LABELNO
    for profiling a function entry.  */
 void
 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");
 
+  const char *mcount_name = MCOUNT_NAME;
+
+  if (current_fentry_name (&mcount_name))
+    ;
+  else if (fentry_name)
+    mcount_name = fentry_name;
+  else if (flag_fentry)
+    mcount_name = MCOUNT_NAME_BEFORE_PROLOGUE;
+
   if (TARGET_64BIT)
     {
 #ifndef NO_PROFILE_COUNTERS
@@ -45111,6 +45128,26 @@ ix86_expand_round_sse4 (rtx op0, rtx op1)
 
   emit_move_insn (op0, res);
 }
+
+/* Handle fentry_name attribute.  */
+
+static tree
+ix86_handle_fentry_name (tree *node, tree name, tree args,
+                        int, bool *no_add_attrs)
+{
+  if (TREE_CODE (*node) == FUNCTION_DECL
+      && TREE_CODE (TREE_VALUE (args)) == STRING_CST)
+    /* Do nothing else, just set the attribute.  We'll get at
+       it later with lookup_attribute.  */
+    ;
+  else
+    {
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
+      *no_add_attrs = true;
+    }
+
+  return NULL_TREE;
+}
 \f
 
 /* Table of valid machine attributes.  */
@@ -45187,7 +45224,8 @@ static const struct attribute_spec ix86_attribute_table[] =
     ix86_handle_fndecl_attribute, NULL },
   { "indirect_return", 0, 0, false, true, true, false,
     NULL, NULL },
-
+  { "fentry_name", 1, 1, true, false, false, false,
+    ix86_handle_fentry_name, NULL },
   /* End element.  */
   { NULL, 0, 0, false, false, false, false, NULL, NULL }
 };
index bacfabe378edcd0710dd2b3958b534fe486cc84f..20798644451c8ef498ce45c3ae62010128194f8d 100644 (file)
@@ -934,6 +934,10 @@ Target Report Var(flag_nop_mcount)
 Generate mcount/__fentry__ calls as nops. To activate they need to be
 patched in.
 
+mfentry-name=
+Target RejectNegative Joined Var(fentry_name)
+Set name of __fentry__ symbol called at function entry.
+
 mskip-rax-setup
 Target Report Var(flag_skip_rax_setup)
 Skip setting up RAX register when passing variable arguments.
index 8c7b178519a29b1ba4278b0e14e362dcd9febbe9..937e8fcc4ff9da40d27fe3dc8d364dbe480b5a4e 100644 (file)
@@ -6026,6 +6026,13 @@ The @code{indirect_return} attribute can be applied to a function,
 as well as variable or type of function pointer to inform the
 compiler that the function may return via indirect branch.
 
+@item fentry_name("@var{name}")
+@cindex @code{fentry_name} function attribute, x86
+On x86 targets, the @code{fentry_name} attribute sets the function to
+call on function entry when function instrumentation is enabled
+with @option{-pg -mfentry}. When @var{name} is nop then a 5 byte
+nop sequence is generated.
+
 @end table
 
 On the x86, the inliner does not inline a
index d457980dbf74378364eb2f2736cb8435176b95ab..7ff5597a12530840f05d5dab9aae089c4e263d66 100644 (file)
@@ -1316,7 +1316,7 @@ See RS/6000 and PowerPC Options.
 -mcmodel=@var{code-model}  -mabi=@var{name}  -maddress-mode=@var{mode} @gol
 -m32  -m64  -mx32  -m16  -miamcu  -mlarge-data-threshold=@var{num} @gol
 -msse2avx  -mfentry  -mrecord-mcount  -mnop-mcount  -m8bit-idiv @gol
--minstrument-return=@var{type} @gol
+-minstrument-return=@var{type} -mfentry-name=@var{name} @gol
 -mavx256-split-unaligned-load  -mavx256-split-unaligned-store @gol
 -malign-data=@var{type}  -mstack-protector-guard=@var{guard} @gol
 -mstack-protector-guard-reg=@var{reg} @gol
@@ -29091,6 +29091,10 @@ or @var{nop5} to generate a 5 byte nop.
 @opindex mrecord-return
 Generate a __return_loc section pointing to all return instrumentation code.
 
+@item -mfentry-name=@var{name}
+@opindex mfentry-name
+Set name of __fentry__ symbol called at function entry for -pg -mfentry functions.
+
 @item -mskip-rax-setup
 @itemx -mno-skip-rax-setup
 @opindex mskip-rax-setup
index ebe2813c93fb45faa00959b4b392d6a56f9334d7..f45128ebe0e14a6e51af93d4768402a51d25f676 100644 (file)
@@ -1,3 +1,7 @@
+2018-11-29  Andi Kleen  <ak@linux.intel.com>
+
+       * gcc.target/i386/fentryname1.c: New test.
+
 2018-11-29  Andi Kleen  <ak@linux.intel.com>
 
        * gcc.target/i386/returninst1.c: New test.
diff --git a/gcc/testsuite/gcc.target/i386/fentryname1.c b/gcc/testsuite/gcc.target/i386/fentryname1.c
new file mode 100644 (file)
index 0000000..6d2e76d
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-pg -mfentry -mfentry-name=foo" } */
+/* { dg-final { scan-assembler "call.*foo" } } */
+/* { dg-final { scan-assembler "call.*bar" } } */
+
+int func(int a)
+{
+  return a+1;
+}
+
+__attribute__((fentry_name("bar")))
+int func2(int a)
+{
+  return a+1;
+}