Allow changing the fentry section per file and per function
authorAndi Kleen <ak@linux.intel.com>
Thu, 29 Nov 2018 23:11:59 +0000 (23:11 +0000)
committerAndi Kleen <ak@gcc.gnu.org>
Thu, 29 Nov 2018 23:11:59 +0000 (23:11 +0000)
When dynamically patching in/out instrumentation it can be useful
to handle different classes of functions differently. Add support
for changing the fentry section name on the command line
or as a function attributes. This allows to mark functions differently,
and handle them differently in dynamic patching.

gcc/:

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

* config/i386/i386.c (current_fentry_section): Add.
(x86_function_profiler): Handle fentry section.
(ix86_attribute_table): Add fentry section.
* config/i386/i386.opt: Add -mfentry-section.
* doc/extend.texi: Document fentry_section attribute.
* doc/invoke.texi: Document -mfentry-section.

gcc/testsuite/:

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

* gcc.target/i386/fentryname2.c: New test.
* gcc.target/i386/fentryname3.c: New test.

From-SVN: r266654

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/fentryname2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/fentryname3.c [new file with mode: 0644]

index 73a98523b968eb6faa082bae9b4dd49f7d478ecc..76db5d562192d18b8b67378bc3d252b00a81fd2e 100644 (file)
@@ -1,3 +1,12 @@
+2018-11-29  Andi Kleen  <ak@linux.intel.com>
+
+       * config/i386/i386.c (current_fentry_section): Add.
+       (x86_function_profiler): Handle fentry section.
+       (ix86_attribute_table): Add fentry section.
+       * config/i386/i386.opt: Add -mfentry-section.
+       * doc/extend.texi: Document fentry_section attribute.
+       * doc/invoke.texi: Document -mfentry-section.
+
 2018-11-29  Andi Kleen  <ak@linux.intel.com>
 
        * config/i386/i386.c (x86_print_call_or_nop): Handle nop name.
index ae6aa8d422c83561c8bc06c64c2d7df8596a2401..653d7204d5a6b8c6e0dd0e9333c71eef3888dbd6 100644 (file)
@@ -41291,6 +41291,17 @@ current_fentry_name (const char **name)
   return true;
 }
 
+static bool
+current_fentry_section (const char **name)
+{
+  tree attr = lookup_attribute ("fentry_section",
+                               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
@@ -41336,9 +41347,18 @@ x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
       x86_print_call_or_nop (file, mcount_name);
     }
 
-  if (flag_record_mcount)
+  if (flag_record_mcount
+       || lookup_attribute ("fentry_section",
+                                DECL_ATTRIBUTES (current_function_decl)))
     {
-      fprintf (file, "\t.section __mcount_loc, \"a\",@progbits\n");
+      const char *sname = "__mcount_loc";
+
+      if (current_fentry_section (&sname))
+       ;
+      else if (fentry_section)
+       sname = fentry_section;
+
+      fprintf (file, "\t.section %s, \"a\",@progbits\n", sname);
       fprintf (file, "\t.%s 1b\n", TARGET_64BIT ? "quad" : "long");
       fprintf (file, "\t.previous\n");
     }
@@ -45129,7 +45149,7 @@ ix86_expand_round_sse4 (rtx op0, rtx op1)
   emit_move_insn (op0, res);
 }
 
-/* Handle fentry_name attribute.  */
+/* Handle fentry_name / fentry_section attribute.  */
 
 static tree
 ix86_handle_fentry_name (tree *node, tree name, tree args,
@@ -45226,6 +45246,8 @@ static const struct attribute_spec ix86_attribute_table[] =
     NULL, NULL },
   { "fentry_name", 1, 1, true, false, false, false,
     ix86_handle_fentry_name, NULL },
+  { "fentry_section", 1, 1, true, false, false, false,
+    ix86_handle_fentry_name, NULL },
   /* End element.  */
   { NULL, 0, 0, false, false, false, false, NULL, NULL }
 };
index 20798644451c8ef498ce45c3ae62010128194f8d..b30b55b782630115d678930fa8347b9a3f17cc88 100644 (file)
@@ -938,6 +938,10 @@ mfentry-name=
 Target RejectNegative Joined Var(fentry_name)
 Set name of __fentry__ symbol called at function entry.
 
+mfentry-section=
+Target RejectNegative Joined Var(fentry_section)
+Set name of section to record mrecord-mcount calls.
+
 mskip-rax-setup
 Target Report Var(flag_skip_rax_setup)
 Skip setting up RAX register when passing variable arguments.
index 937e8fcc4ff9da40d27fe3dc8d364dbe480b5a4e..8c9e0fa544b2e6b10b6827ec2904559ff764cce6 100644 (file)
@@ -6033,6 +6033,12 @@ 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.
 
+@item fentry_section("@var{name}")
+@cindex @code{fentry_section} function attribute, x86
+On x86 targets, the @code{fentry_section} attribute sets the name
+of the section to record function entry instrumentation calls in when
+enabled with @option{-pg -mrecord-mcount}
+
 @end table
 
 On the x86, the inliner does not inline a
index 7ff5597a12530840f05d5dab9aae089c4e263d66..3b6912ea1cca52a981376a5a256d02cb00aabef7 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} -mfentry-name=@var{name} @gol
+-minstrument-return=@var{type} -mfentry-name=@var{name} -mfentry-section=@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
@@ -29095,6 +29095,10 @@ Generate a __return_loc section pointing to all return instrumentation code.
 @opindex mfentry-name
 Set name of __fentry__ symbol called at function entry for -pg -mfentry functions.
 
+@item -mfentry-section=@var{name}
+@opindex mfentry-section
+Set name of section to record -mrecord-mcount calls (default __mcount_loc).
+
 @item -mskip-rax-setup
 @itemx -mno-skip-rax-setup
 @opindex mskip-rax-setup
index f45128ebe0e14a6e51af93d4768402a51d25f676..1855153f4ecc9525d72b3b768857a5f84d80668a 100644 (file)
@@ -1,3 +1,8 @@
+2018-11-29  Andi Kleen  <ak@linux.intel.com>
+
+       * gcc.target/i386/fentryname2.c: New test.
+       * gcc.target/i386/fentryname3.c: New test.
+
 2018-11-29  Andi Kleen  <ak@linux.intel.com>
 
        * gcc.target/i386/fentryname1.c: New test.
diff --git a/gcc/testsuite/gcc.target/i386/fentryname2.c b/gcc/testsuite/gcc.target/i386/fentryname2.c
new file mode 100644 (file)
index 0000000..7d102bf
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-pg -mfentry -mrecord-mcount -mfentry-section=foo" } */
+/* { dg-final { scan-assembler "section.*foo" } } */
+/* { dg-final { scan-assembler "section.*bar" } } */
+
+int func(int a)
+{
+  return a+1;
+}
+
+__attribute__((fentry_section("bar")))
+int func2(int a)
+{
+  return a+1;
+}
diff --git a/gcc/testsuite/gcc.target/i386/fentryname3.c b/gcc/testsuite/gcc.target/i386/fentryname3.c
new file mode 100644 (file)
index 0000000..777f4e4
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-pg -mfentry"  } */
+/* { dg-final { scan-assembler "section.*__entry_loc" } } */
+/* { dg-final { scan-assembler "0x0f, 0x1f, 0x44, 0x00, 0x00" } } */
+/* { dg-final { scan-assembler-not "__fentry__" } } */
+
+__attribute__((fentry_name("nop"), fentry_section("__entry_loc")))
+void foo(void)
+{
+}