[Clang][Codegen] Add GNU function attribute 'no_profile' and lower it to noprofile

noprofile IR attribute already exists to prevent profiling with PGO;
emit that when a function uses the newly added no_profile function
attribute.

The Linux kernel would like to avoid compiler generated code in
functions annotated with such attribute. We already respect this for
libcalls to fentry() and mcount().

Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80223
Link: https://lore.kernel.org/lkml/CAKwvOdmPTi93n2L0_yQkrzLdmpxzrOR7zggSzonyaw2PGshApw@mail.gmail.com/

Reviewed By: MaskRay, void, phosek, aaron.ballman

Differential Revision: https://reviews.llvm.org/D104475
This commit is contained in:
Nick Desaulniers 2021-06-18 13:33:44 -07:00
parent f7999e73ca
commit 193e41c987
6 changed files with 56 additions and 0 deletions

View File

@ -1970,6 +1970,13 @@ def NoInstrumentFunction : InheritableAttr {
let SimpleHandler = 1;
}
def NoProfileFunction : InheritableAttr {
let Spellings = [Clang<"no_profile">];
let Subjects = SubjectList<[Function]>;
let Documentation = [NoProfileDocs];
let SimpleHandler = 1;
}
def NotTailCalled : InheritableAttr {
let Spellings = [Clang<"not_tail_called">];
let Subjects = SubjectList<[Function]>;

View File

@ -2559,6 +2559,17 @@ This attribute accepts a single parameter that must be one of the following:
}];
}
def NoProfileDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
Use the ``no_profile`` attribute on a function declaration to denote that the
compiler should not instrument the function with profile-related
instrumentation, such as via the
``-fprofile-generate`` / ``-fprofile-instr-generate`` /
``-fcs-profile-generate`` / ``-fprofile-arcs`` flags.
}];
}
def NoSanitizeDocs : Documentation {
let Category = DocCatFunction;
let Content = [{

View File

@ -893,6 +893,9 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
if (D && D->hasAttr<CFICanonicalJumpTableAttr>())
Fn->addFnAttr("cfi-canonical-jump-table");
if (D && D->hasAttr<NoProfileFunctionAttr>())
Fn->addFnAttr(llvm::Attribute::NoProfile);
if (getLangOpts().OpenCL) {
// Add metadata for a kernel function.
if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))

View File

@ -0,0 +1,21 @@
// RUN: %clang_cc1 -fprofile-instrument=llvm -disable-llvm-passes \
// RUN: -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -fprofile-instrument=csllvm -disable-llvm-passes \
// RUN: -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -fprofile-instrument=clang -disable-llvm-passes \
// RUN: -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -fprofile-arcs -disable-llvm-passes \
// RUN: -emit-llvm -o - %s | FileCheck %s
int g(int);
void __attribute__((no_profile)) no_instr() {
// CHECK: define {{.*}} void @no_instr() [[ATTR:#[0-9]+]]
}
void instr(void) {
// CHECK: define {{.*}} void @instr() [[ATTR2:#[0-9]+]]
}
// CHECK: attributes [[ATTR]] = {{.*}} noprofile
// CHECK: attributes [[ATTR2]] = {
// CHECK-NOT: noprofile
// CHECK: }

View File

@ -99,6 +99,7 @@
// CHECK-NEXT: NoMerge (SubjectMatchRule_function)
// CHECK-NEXT: NoMicroMips (SubjectMatchRule_function)
// CHECK-NEXT: NoMips16 (SubjectMatchRule_function)
// CHECK-NEXT: NoProfileFunction (SubjectMatchRule_function)
// CHECK-NEXT: NoSanitize (SubjectMatchRule_function, SubjectMatchRule_objc_method, SubjectMatchRule_variable_is_global)
// CHECK-NEXT: NoSanitizeSpecific (SubjectMatchRule_function, SubjectMatchRule_variable_is_global)
// CHECK-NEXT: NoSpeculativeLoadHardening (SubjectMatchRule_function, SubjectMatchRule_objc_method)

View File

@ -0,0 +1,13 @@
// RUN: %clang_cc1 %s -fsyntax-only -verify
__attribute__((no_profile))
void no_profile0(void);
#if !__has_attribute(no_profile)
#error "Where did the no_profile function attribute go?"
#endif
void no_profile1(__attribute__((no_profile)) int param); // expected-warning {{'no_profile' attribute only applies to functions}}
__attribute__((no_profile(""))) // expected-error {{'no_profile' attribute takes no arguments}}
void no_profile2(void);
void no_profile3(void) {
__attribute__((no_profile)); // expected-error {{'no_profile' attribute cannot be applied to a statement}}
}