ellis created this revision. Herald added subscribers: Enna1, wenlei, jdoerfert, hiraditya. Herald added a project: All. ellis edited the summary of this revision. ellis added reviewers: phosek, davidxl. ellis published this revision for review. Herald added projects: clang, LLVM. Herald added subscribers: llvm-commits, cfe-commits.
As discussed in [0], this diff adds the `omitprofile` attribute to prevent the function from being profiled while allowing profiled functions to be inlined into it. The `noprofile` attribute remains unchanged. The `noprofile` attribute is used for functions where it is dangerous to add instrumentation to while the `omitprofile` attribute is used to reduce code size or performance overhead. [0] https://discourse.llvm.org/t/why-does-the-noprofile-attribute-restrict-inlining/64108 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D130807 Files: clang/lib/CodeGen/CodeGenFunction.h clang/lib/CodeGen/CodeGenPGO.cpp clang/test/CodeGen/profile-function-groups.c llvm/docs/LangRef.rst llvm/include/llvm/Bitcode/LLVMBitCodes.h llvm/include/llvm/IR/Attributes.td llvm/lib/Bitcode/Reader/BitcodeReader.cpp llvm/lib/Bitcode/Writer/BitcodeWriter.cpp llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp llvm/lib/Transforms/Utils/CodeExtractor.cpp llvm/test/Bitcode/attributes.ll llvm/test/Transforms/GCOVProfiling/noprofile.ll llvm/test/Transforms/PGOProfile/noprofile.ll
Index: llvm/test/Transforms/PGOProfile/noprofile.ll =================================================================== --- llvm/test/Transforms/PGOProfile/noprofile.ll +++ llvm/test/Transforms/PGOProfile/noprofile.ll @@ -21,4 +21,10 @@ ret i32 %sub } +define i32 @test3() omitprofile { +entry: +; CHECK-NOT: call void @llvm.instrprof.increment + ret i32 101 +} + attributes #0 = { noprofile } Index: llvm/test/Transforms/GCOVProfiling/noprofile.ll =================================================================== --- llvm/test/Transforms/GCOVProfiling/noprofile.ll +++ llvm/test/Transforms/GCOVProfiling/noprofile.ll @@ -10,6 +10,14 @@ ret i32 42, !dbg !27 } +; Test that the omitprofile attribute disables profiling. +define dso_local i32 @omit_instr(i32 %a) omitprofile { +; CHECK-LABEL: @omit_instr( +; CHECK-NEXT: ret i32 52 +; + ret i32 52 +} + define dso_local i32 @instr(i32 %a) !dbg !28 { ; CHECK-LABEL: @instr( ; CHECK-NEXT: [[GCOV_CTR:%.*]] = load i64, ptr @__llvm_gcov_ctr, align 4, !dbg [[DBG8:![0-9]+]] Index: llvm/test/Bitcode/attributes.ll =================================================================== --- llvm/test/Bitcode/attributes.ll +++ llvm/test/Bitcode/attributes.ll @@ -535,6 +535,9 @@ ; CHECK: define void @f87() [[FNRETTHUNKEXTERN:#[0-9]+]] define void @f87() fn_ret_thunk_extern { ret void } +; CHECK: define void @f88() [[OMITPROFILE:#[0-9]+]] +define void @f88() omitprofile { ret void } + ; CHECK: attributes #0 = { noreturn } ; CHECK: attributes #1 = { nounwind } ; CHECK: attributes #2 = { readnone } @@ -589,4 +592,5 @@ ; CHECK: attributes #51 = { uwtable(sync) } ; CHECK: attributes #52 = { nosanitize_bounds } ; CHECK: attributes [[FNRETTHUNKEXTERN]] = { fn_ret_thunk_extern } +; CHECK: attributes [[OMITPROFILE]] = { omitprofile } ; CHECK: attributes #[[NOBUILTIN]] = { nobuiltin } Index: llvm/lib/Transforms/Utils/CodeExtractor.cpp =================================================================== --- llvm/lib/Transforms/Utils/CodeExtractor.cpp +++ llvm/lib/Transforms/Utils/CodeExtractor.cpp @@ -963,6 +963,7 @@ case Attribute::NoCfCheck: case Attribute::MustProgress: case Attribute::NoProfile: + case Attribute::OmitProfile: break; // These attributes cannot be applied to functions. case Attribute::Alignment: Index: llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp =================================================================== --- llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp +++ llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp @@ -1573,6 +1573,8 @@ continue; if (F.hasFnAttribute(llvm::Attribute::NoProfile)) continue; + if (F.hasFnAttribute(llvm::Attribute::OmitProfile)) + continue; auto &TLI = LookupTLI(F); auto *BPI = LookupBPI(F); auto *BFI = LookupBFI(F); Index: llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp =================================================================== --- llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp +++ llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp @@ -797,6 +797,8 @@ if (isUsingScopeBasedEH(F)) continue; if (F.hasFnAttribute(llvm::Attribute::NoProfile)) continue; + if (F.hasFnAttribute(llvm::Attribute::OmitProfile)) + continue; // Add the function line number to the lines of the entry block // to have a counter for the function definition. Index: llvm/lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -698,6 +698,8 @@ return bitc::ATTR_KIND_NOCF_CHECK; case Attribute::NoProfile: return bitc::ATTR_KIND_NO_PROFILE; + case Attribute::OmitProfile: + return bitc::ATTR_KIND_OMIT_PROFILE; case Attribute::NoUnwind: return bitc::ATTR_KIND_NO_UNWIND; case Attribute::NoSanitizeBounds: Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1919,6 +1919,8 @@ return Attribute::NoCfCheck; case bitc::ATTR_KIND_NO_PROFILE: return Attribute::NoProfile; + case bitc::ATTR_KIND_OMIT_PROFILE: + return Attribute::OmitProfile; case bitc::ATTR_KIND_NO_UNWIND: return Attribute::NoUnwind; case bitc::ATTR_KIND_NO_SANITIZE_BOUNDS: Index: llvm/include/llvm/IR/Attributes.td =================================================================== --- llvm/include/llvm/IR/Attributes.td +++ llvm/include/llvm/IR/Attributes.td @@ -187,6 +187,10 @@ /// inlined into it. def NoProfile : EnumAttr<"noprofile", [FnAttr]>; +/// This function should not be instrumented but it is ok to inline profiled +// functions into it. +def OmitProfile : EnumAttr<"omitprofile", [FnAttr]>; + /// Function doesn't unwind stack. def NoUnwind : EnumAttr<"nounwind", [FnAttr]>; Index: llvm/include/llvm/Bitcode/LLVMBitCodes.h =================================================================== --- llvm/include/llvm/Bitcode/LLVMBitCodes.h +++ llvm/include/llvm/Bitcode/LLVMBitCodes.h @@ -689,6 +689,7 @@ ATTR_KIND_ALLOC_KIND = 82, ATTR_KIND_PRESPLIT_COROUTINE = 83, ATTR_KIND_FNRETTHUNK_EXTERN = 84, + ATTR_KIND_OMIT_PROFILE = 85, }; enum ComdatSelectionKindCodes { Index: llvm/docs/LangRef.rst =================================================================== --- llvm/docs/LangRef.rst +++ llvm/docs/LangRef.rst @@ -1805,6 +1805,11 @@ This function attribute prevents instrumentation based profiling, used for coverage or profile based optimization, from being added to a function. It also prevents instrumented functions from being inlined into this function. +``omitprofile`` + This function attribute prevents instrumentation based profiling, used for + coverage or profile based optimization, from being added to a function. This + attribute does not restrict inlining, so instrumented instruction could end + up in this function. ``noredzone`` This attribute indicates that the code generator should not use a red zone, even if the target-specific ABI normally permits it. Index: clang/test/CodeGen/profile-function-groups.c =================================================================== --- clang/test/CodeGen/profile-function-groups.c +++ clang/test/CodeGen/profile-function-groups.c @@ -1,24 +1,24 @@ -// RUN: %clang -fprofile-generate -fprofile-function-groups=3 -fprofile-selected-function-group=0 -emit-llvm -S %s -o - | FileCheck %s --check-prefixes=CHECK,SELECT0 -// RUN: %clang -fprofile-generate -fprofile-function-groups=3 -fprofile-selected-function-group=1 -emit-llvm -S %s -o - | FileCheck %s --check-prefixes=CHECK,SELECT1 -// RUN: %clang -fprofile-generate -fprofile-function-groups=3 -fprofile-selected-function-group=2 -emit-llvm -S %s -o - | FileCheck %s --check-prefixes=CHECK,SELECT2 +// RUN: %clang -fprofile-generate -fprofile-function-groups=3 -fprofile-selected-function-group=0 -emit-llvm -S %s -o - | FileCheck %s --implicit-check-not="; {{.* (noprofile|omitprofile)}}" --check-prefixes=CHECK,SELECT0 +// RUN: %clang -fprofile-generate -fprofile-function-groups=3 -fprofile-selected-function-group=1 -emit-llvm -S %s -o - | FileCheck %s --implicit-check-not="; {{.* (noprofile|omitprofile)}}" --check-prefixes=CHECK,SELECT1 +// RUN: %clang -fprofile-generate -fprofile-function-groups=3 -fprofile-selected-function-group=2 -emit-llvm -S %s -o - | FileCheck %s --implicit-check-not="; {{.* (noprofile|omitprofile)}}" --check-prefixes=CHECK,SELECT2 // Group 0 -// SELECT0-NOT: noprofile -// SELECT1: noprofile -// SELECT2: noprofile + +// SELECT1: omitprofile +// SELECT2: omitprofile // CHECK: define {{.*}} @hoo() void hoo() {} // Group 1 -// SELECT0: noprofile -// SELECT1-NOT: noprofile -// SELECT2: noprofile +// SELECT0: omitprofile + +// SELECT2: omitprofile // CHECK: define {{.*}} @goo() void goo() {} // Group 2 -// SELECT0: noprofile -// SELECT1: noprofile -// SELECT2-NOT: noprofile +// SELECT0: omitprofile +// SELECT1: omitprofile + // CHECK: define {{.*}} @boo() void boo() {} Index: clang/lib/CodeGen/CodeGenPGO.cpp =================================================================== --- clang/lib/CodeGen/CodeGenPGO.cpp +++ clang/lib/CodeGen/CodeGenPGO.cpp @@ -822,6 +822,8 @@ CGM.ClearUnusedCoverageMapping(D); if (Fn->hasFnAttribute(llvm::Attribute::NoProfile)) return; + if (Fn->hasFnAttribute(llvm::Attribute::OmitProfile)) + return; setFuncName(Fn); Index: clang/lib/CodeGen/CodeGenFunction.h =================================================================== --- clang/lib/CodeGen/CodeGenFunction.h +++ clang/lib/CodeGen/CodeGenFunction.h @@ -1522,7 +1522,8 @@ /// If \p StepV is null, the default increment is 1. void incrementProfileCounter(const Stmt *S, llvm::Value *StepV = nullptr) { if (CGM.getCodeGenOpts().hasProfileClangInstr() && - !CurFn->hasFnAttribute(llvm::Attribute::NoProfile)) + !CurFn->hasFnAttribute(llvm::Attribute::NoProfile) && + !CurFn->hasFnAttribute(llvm::Attribute::OmitProfile)) PGO.emitCounterIncrement(Builder, S, StepV); PGO.setCurrentStmt(S); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits