From a8839c989de50b1d83363fbc2431a9d5c6c9d679 Mon Sep 17 00:00:00 2001 From: Petr Hosek Date: Fri, 15 Jan 2021 01:14:37 -0800 Subject: [PATCH] Support for instrumenting only selected files or functions This change implements support for applying profile instrumentation only to selected files or functions. The implementation uses the sanitizer special case list format to select which files and functions to instrument, and relies on the new noprofile IR attribute to exclude functions from instrumentation. Differential Revision: https://reviews.llvm.org/D94820 --- include/llvm/Bitcode/LLVMBitCodes.h | 1 + include/llvm/IR/Attributes.td | 3 +++ lib/AsmParser/LLLexer.cpp | 1 + lib/AsmParser/LLParser.cpp | 3 +++ lib/AsmParser/LLToken.h | 1 + lib/Bitcode/Writer/BitcodeWriter.cpp | 2 ++ lib/IR/Attributes.cpp | 2 ++ lib/IR/Verifier.cpp | 1 + .../Instrumentation/PGOInstrumentation.cpp | 2 ++ lib/Transforms/Utils/CodeExtractor.cpp | 1 + test/Transforms/PGOProfile/noprofile.ll | 25 +++++++++++++++++++ 11 files changed, 42 insertions(+) create mode 100644 test/Transforms/PGOProfile/noprofile.ll diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index 03dac9ebede..5b4854d6c95 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -656,6 +656,7 @@ enum AttributeKindCodes { ATTR_KIND_MUSTPROGRESS = 70, ATTR_KIND_NO_CALLBACK = 71, ATTR_KIND_HOT = 72, + ATTR_KIND_NO_PROFILE = 73, }; enum ComdatSelectionKindCodes { diff --git a/include/llvm/IR/Attributes.td b/include/llvm/IR/Attributes.td index 45460742bf3..f7ffc888c65 100644 --- a/include/llvm/IR/Attributes.td +++ b/include/llvm/IR/Attributes.td @@ -148,6 +148,9 @@ def NoSync : EnumAttr<"nosync">; /// Disable Indirect Branch Tracking. def NoCfCheck : EnumAttr<"nocf_check">; +/// Function should be instrumented. +def NoProfile : EnumAttr<"noprofile">; + /// Function doesn't unwind stack. def NoUnwind : EnumAttr<"nounwind">; diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index 3c35c9b1a5d..427de74f91a 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -663,6 +663,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(nonlazybind); KEYWORD(nomerge); KEYWORD(nonnull); + KEYWORD(noprofile); KEYWORD(noredzone); KEYWORD(noreturn); KEYWORD(nosync); diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index eff81e36fed..2a3fb8fb665 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -1368,6 +1368,7 @@ bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B, case lltok::kw_noreturn: B.addAttribute(Attribute::NoReturn); break; case lltok::kw_nosync: B.addAttribute(Attribute::NoSync); break; case lltok::kw_nocf_check: B.addAttribute(Attribute::NoCfCheck); break; + case lltok::kw_noprofile: B.addAttribute(Attribute::NoProfile); break; case lltok::kw_norecurse: B.addAttribute(Attribute::NoRecurse); break; case lltok::kw_nounwind: B.addAttribute(Attribute::NoUnwind); break; case lltok::kw_null_pointer_is_valid: @@ -1778,6 +1779,7 @@ bool LLParser::parseOptionalParamAttrs(AttrBuilder &B) { case lltok::kw_noinline: case lltok::kw_nonlazybind: case lltok::kw_nomerge: + case lltok::kw_noprofile: case lltok::kw_noredzone: case lltok::kw_noreturn: case lltok::kw_nocf_check: @@ -1886,6 +1888,7 @@ bool LLParser::parseOptionalReturnAttrs(AttrBuilder &B) { case lltok::kw_noinline: case lltok::kw_nonlazybind: case lltok::kw_nomerge: + case lltok::kw_noprofile: case lltok::kw_noredzone: case lltok::kw_noreturn: case lltok::kw_nocf_check: diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h index 32e1165c774..5149f861837 100644 --- a/lib/AsmParser/LLToken.h +++ b/lib/AsmParser/LLToken.h @@ -210,6 +210,7 @@ enum Kind { kw_nonlazybind, kw_nomerge, kw_nonnull, + kw_noprofile, kw_noredzone, kw_noreturn, kw_nosync, diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 4d886f708cd..37ecb9992e4 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -680,6 +680,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) { return bitc::ATTR_KIND_NOSYNC; case Attribute::NoCfCheck: return bitc::ATTR_KIND_NOCF_CHECK; + case Attribute::NoProfile: + return bitc::ATTR_KIND_NO_PROFILE; case Attribute::NoUnwind: return bitc::ATTR_KIND_NO_UNWIND; case Attribute::NullPointerIsValid: diff --git a/lib/IR/Attributes.cpp b/lib/IR/Attributes.cpp index b17673f14c9..c4629decc6d 100644 --- a/lib/IR/Attributes.cpp +++ b/lib/IR/Attributes.cpp @@ -403,6 +403,8 @@ std::string Attribute::getAsString(bool InAttrGrp) const { return "nocf_check"; if (hasAttribute(Attribute::NoRecurse)) return "norecurse"; + if (hasAttribute(Attribute::NoProfile)) + return "noprofile"; if (hasAttribute(Attribute::NoUnwind)) return "nounwind"; if (hasAttribute(Attribute::OptForFuzzing)) diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index 2b12e656c45..100e881c8fa 100644 --- a/lib/IR/Verifier.cpp +++ b/lib/IR/Verifier.cpp @@ -1655,6 +1655,7 @@ static bool isFuncOnlyAttr(Attribute::AttrKind Kind) { case Attribute::StrictFP: case Attribute::NullPointerIsValid: case Attribute::MustProgress: + case Attribute::NoProfile: return true; default: break; diff --git a/lib/Transforms/Instrumentation/PGOInstrumentation.cpp b/lib/Transforms/Instrumentation/PGOInstrumentation.cpp index 17ccf3ab989..be6c8c63100 100644 --- a/lib/Transforms/Instrumentation/PGOInstrumentation.cpp +++ b/lib/Transforms/Instrumentation/PGOInstrumentation.cpp @@ -1591,6 +1591,8 @@ static bool InstrumentAllFunctions( for (auto &F : M) { if (F.isDeclaration()) continue; + if (F.hasFnAttribute(llvm::Attribute::NoProfile)) + continue; auto &TLI = LookupTLI(F); auto *BPI = LookupBPI(F); auto *BFI = LookupBFI(F); diff --git a/lib/Transforms/Utils/CodeExtractor.cpp b/lib/Transforms/Utils/CodeExtractor.cpp index 2a7c62b235f..390925a03b7 100644 --- a/lib/Transforms/Utils/CodeExtractor.cpp +++ b/lib/Transforms/Utils/CodeExtractor.cpp @@ -973,6 +973,7 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs, case Attribute::UWTable: case Attribute::NoCfCheck: case Attribute::MustProgress: + case Attribute::NoProfile: break; } diff --git a/test/Transforms/PGOProfile/noprofile.ll b/test/Transforms/PGOProfile/noprofile.ll new file mode 100644 index 00000000000..d7df07b4043 --- /dev/null +++ b/test/Transforms/PGOProfile/noprofile.ll @@ -0,0 +1,25 @@ +; RUN: opt < %s -pgo-instr-gen -S | FileCheck %s +; RUN: opt < %s -passes=pgo-instr-gen -S | FileCheck %s + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@i = dso_local global i32 0, align 4 + +define i32 @test1() { +entry: +; CHECK: call void @llvm.instrprof.increment + %0 = load i32, i32* @i, align 4 + %add = add i32 %0, 1 + ret i32 %add +} + +define i32 @test2() #0 { +entry: +; CHECK-NOT: call void @llvm.instrprof.increment + %0 = load i32, i32* @i, align 4 + %sub = sub i32 %0, 1 + ret i32 %sub +} + +attributes #0 = { noprofile }