mirror of git://gcc.gnu.org/git/gcc.git
Allow changing the fentry section per file and per function
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
This commit is contained in:
parent
d7bf0bd696
commit
1c31f6c896
|
|
@ -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>
|
2018-11-29 Andi Kleen <ak@linux.intel.com>
|
||||||
|
|
||||||
* config/i386/i386.c (x86_print_call_or_nop): Handle nop name.
|
* config/i386/i386.c (x86_print_call_or_nop): Handle nop name.
|
||||||
|
|
|
||||||
|
|
@ -41291,6 +41291,17 @@ current_fentry_name (const char **name)
|
||||||
return true;
|
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
|
/* Output assembler code to FILE to increment profiler label # LABELNO
|
||||||
for profiling a function entry. */
|
for profiling a function entry. */
|
||||||
void
|
void
|
||||||
|
|
@ -41336,9 +41347,18 @@ x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
|
||||||
x86_print_call_or_nop (file, mcount_name);
|
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.%s 1b\n", TARGET_64BIT ? "quad" : "long");
|
||||||
fprintf (file, "\t.previous\n");
|
fprintf (file, "\t.previous\n");
|
||||||
}
|
}
|
||||||
|
|
@ -45129,7 +45149,7 @@ ix86_expand_round_sse4 (rtx op0, rtx op1)
|
||||||
emit_move_insn (op0, res);
|
emit_move_insn (op0, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle fentry_name attribute. */
|
/* Handle fentry_name / fentry_section attribute. */
|
||||||
|
|
||||||
static tree
|
static tree
|
||||||
ix86_handle_fentry_name (tree *node, tree name, tree args,
|
ix86_handle_fentry_name (tree *node, tree name, tree args,
|
||||||
|
|
@ -45226,6 +45246,8 @@ static const struct attribute_spec ix86_attribute_table[] =
|
||||||
NULL, NULL },
|
NULL, NULL },
|
||||||
{ "fentry_name", 1, 1, true, false, false, false,
|
{ "fentry_name", 1, 1, true, false, false, false,
|
||||||
ix86_handle_fentry_name, NULL },
|
ix86_handle_fentry_name, NULL },
|
||||||
|
{ "fentry_section", 1, 1, true, false, false, false,
|
||||||
|
ix86_handle_fentry_name, NULL },
|
||||||
/* End element. */
|
/* End element. */
|
||||||
{ NULL, 0, 0, false, false, false, false, NULL, NULL }
|
{ NULL, 0, 0, false, false, false, false, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -938,6 +938,10 @@ mfentry-name=
|
||||||
Target RejectNegative Joined Var(fentry_name)
|
Target RejectNegative Joined Var(fentry_name)
|
||||||
Set name of __fentry__ symbol called at function entry.
|
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
|
mskip-rax-setup
|
||||||
Target Report Var(flag_skip_rax_setup)
|
Target Report Var(flag_skip_rax_setup)
|
||||||
Skip setting up RAX register when passing variable arguments.
|
Skip setting up RAX register when passing variable arguments.
|
||||||
|
|
|
||||||
|
|
@ -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
|
with @option{-pg -mfentry}. When @var{name} is nop then a 5 byte
|
||||||
nop sequence is generated.
|
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
|
@end table
|
||||||
|
|
||||||
On the x86, the inliner does not inline a
|
On the x86, the inliner does not inline a
|
||||||
|
|
|
||||||
|
|
@ -1316,7 +1316,7 @@ See RS/6000 and PowerPC Options.
|
||||||
-mcmodel=@var{code-model} -mabi=@var{name} -maddress-mode=@var{mode} @gol
|
-mcmodel=@var{code-model} -mabi=@var{name} -maddress-mode=@var{mode} @gol
|
||||||
-m32 -m64 -mx32 -m16 -miamcu -mlarge-data-threshold=@var{num} @gol
|
-m32 -m64 -mx32 -m16 -miamcu -mlarge-data-threshold=@var{num} @gol
|
||||||
-msse2avx -mfentry -mrecord-mcount -mnop-mcount -m8bit-idiv @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
|
-mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol
|
||||||
-malign-data=@var{type} -mstack-protector-guard=@var{guard} @gol
|
-malign-data=@var{type} -mstack-protector-guard=@var{guard} @gol
|
||||||
-mstack-protector-guard-reg=@var{reg} @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
|
@opindex mfentry-name
|
||||||
Set name of __fentry__ symbol called at function entry for -pg -mfentry functions.
|
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
|
@item -mskip-rax-setup
|
||||||
@itemx -mno-skip-rax-setup
|
@itemx -mno-skip-rax-setup
|
||||||
@opindex mskip-rax-setup
|
@opindex mskip-rax-setup
|
||||||
|
|
|
||||||
|
|
@ -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>
|
2018-11-29 Andi Kleen <ak@linux.intel.com>
|
||||||
|
|
||||||
* gcc.target/i386/fentryname1.c: New test.
|
* gcc.target/i386/fentryname1.c: New test.
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -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)
|
||||||
|
{
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue