[clang] 193e41c - [Clang][Codegen] Add GNU function attribute 'no_profile' and lower it to noprofile

Nick Desaulniers via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 18 13:42:45 PDT 2021


Author: Nick Desaulniers
Date: 2021-06-18T13:42:32-07:00
New Revision: 193e41c987127aad86d0380df83e67a85266f1f1

URL: https://github.com/llvm/llvm-project/commit/193e41c987127aad86d0380df83e67a85266f1f1
DIFF: https://github.com/llvm/llvm-project/commit/193e41c987127aad86d0380df83e67a85266f1f1.diff

LOG: [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

Added: 
    clang/test/CodeGen/no_profile.c
    clang/test/Sema/no_profile-attribute.c

Modified: 
    clang/include/clang/Basic/Attr.td
    clang/include/clang/Basic/AttrDocs.td
    clang/lib/CodeGen/CodeGenFunction.cpp
    clang/test/Misc/pragma-attribute-supported-attributes-list.test

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 714621087cb77..8829b4b6d560b 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -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]>;

diff  --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 6594e77d0beef..6173c8cd90af0 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -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 = [{

diff  --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 518305e1113cd..97288d01686e1 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -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))

diff  --git a/clang/test/CodeGen/no_profile.c b/clang/test/CodeGen/no_profile.c
new file mode 100644
index 0000000000000..5ac116b19c7a0
--- /dev/null
+++ b/clang/test/CodeGen/no_profile.c
@@ -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: }

diff  --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index 8256f12a07684..290306bfb6a23 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -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)

diff  --git a/clang/test/Sema/no_profile-attribute.c b/clang/test/Sema/no_profile-attribute.c
new file mode 100644
index 0000000000000..b3c073f130ac3
--- /dev/null
+++ b/clang/test/Sema/no_profile-attribute.c
@@ -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}}
+}


        


More information about the cfe-commits mailing list