Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PGO] Generate __llvm_profile_raw_version only when instrumented #93917

Open
wants to merge 2 commits into
base: users/psamolysov/pgo-instrument-when-at-least-one-definition
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 deletions llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,9 +405,14 @@ static GlobalVariable *createIRLevelProfileFlagVar(Module &M, bool IsCS) {
ProfileVersion |= VARIANT_MASK_BYTE_COVERAGE;
if (PGOTemporalInstrumentation)
ProfileVersion |= VARIANT_MASK_TEMPORAL_PROF;
auto IRLevelVersionVariable = new GlobalVariable(
assert(!M.global_empty() &&
"If a module was instrumented, there must be defined global variables "
"at least for the counters.");
auto *InsertionPoint = &*M.global_begin();
auto *IRLevelVersionVariable = new GlobalVariable(
M, IntTy64, true, GlobalValue::WeakAnyLinkage,
Constant::getIntegerValue(IntTy64, APInt(64, ProfileVersion)), VarName);
Constant::getIntegerValue(IntTy64, APInt(64, ProfileVersion)), VarName,
InsertionPoint);
IRLevelVersionVariable->setVisibility(GlobalValue::HiddenVisibility);
Triple TT(M.getTargetTriple());
if (TT.supportsCOMDAT()) {
Expand Down Expand Up @@ -1829,11 +1834,6 @@ static bool InstrumentAllFunctions(
Module &M, function_ref<TargetLibraryInfo &(Function &)> LookupTLI,
function_ref<BranchProbabilityInfo *(Function &)> LookupBPI,
function_ref<BlockFrequencyInfo *(Function &)> LookupBFI, bool IsCS) {
// For the context-sensitve instrumentation, we should have a separated pass
// (before LTO/ThinLTO linking) to create these variables.
if (!IsCS && !PGOCtxProfLoweringPass::isContextualIRPGOEnabled())
createIRLevelProfileFlagVar(M, /*IsCS=*/false);

Triple TT(M.getTargetTriple());
LLVMContext &Ctx = M.getContext();
if (!TT.isOSBinFormatELF() && EnableVTableValueProfiling)
Expand All @@ -1845,14 +1845,25 @@ static bool InstrumentAllFunctions(
std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
collectComdatMembers(M, ComdatMembers);

bool AnythingInstrumented = false;
for (auto &F : M) {
if (skipPGOGen(F))
continue;
auto &TLI = LookupTLI(F);
auto *BPI = LookupBPI(F);
auto *BFI = LookupBFI(F);
instrumentOneFunc(F, &M, TLI, BPI, BFI, ComdatMembers, IsCS);
AnythingInstrumented = true;
}

if (!AnythingInstrumented)
return false;

// For the context-sensitve instrumentation, we should have a separated pass
// (before LTO/ThinLTO linking) to create these variables.
if (!IsCS && !PGOCtxProfLoweringPass::isContextualIRPGOEnabled())
createIRLevelProfileFlagVar(M, /*IsCS=*/false);

return true;
}

Expand Down
7 changes: 1 addition & 6 deletions llvm/test/Transforms/PGOProfile/declarations_only.ll
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
; RUN: opt < %s -passes=pgo-instr-gen -S | FileCheck %s --check-prefix=GEN --check-prefix=GEN-COMDAT
; RUN: opt < %s -passes=pgo-instr-gen -S | FileCheck %s --implicit-check-not='__llvm_profile_raw_version'

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"

; GEN-COMDAT: $__llvm_profile_raw_version = comdat any
; GEN-COMDAT: @__llvm_profile_raw_version = hidden constant i64 {{[0-9]+}}, comdat
; GEN-NOT: @__profn_test_1 = private constant [6 x i8] c"test_1"
; GEN-NOT: @__profn_test_2 = private constant [6 x i8] c"test_2"

declare i32 @test_1(i32 %i)

declare i32 @test_2(i32 %i)
5 changes: 1 addition & 4 deletions llvm/test/Transforms/PGOProfile/global_variables_only.ll
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
; RUN: opt < %s -passes=pgo-instr-gen -S | FileCheck %s --check-prefix=GEN-COMDAT
; RUN: opt < %s -passes=pgo-instr-gen -S | FileCheck %s --implicit-check-not='__llvm_profile_raw_version'

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"

; GEN-COMDAT: $__llvm_profile_raw_version = comdat any
; GEN-COMDAT: @__llvm_profile_raw_version = hidden constant i64 {{[0-9]+}}, comdat

@var = internal unnamed_addr global [35 x ptr] zeroinitializer, align 16
15 changes: 15 additions & 0 deletions llvm/test/Transforms/PGOProfile/no_global_variables.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
; RUN: opt < %s -passes=pgo-instr-gen -S | FileCheck %s --check-prefix=GEN-COMDAT
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"
; GEN-COMDAT: $__llvm_profile_raw_version = comdat any
; GEN-COMDAT: @__llvm_profile_raw_version = hidden constant i64 {{[0-9]+}}, comdat

define i32 @test_1(i32 %i) {
entry:
ret i32 0
}

define i32 @test_2(i32 %i) {
entry:
ret i32 1
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,13 @@ class MockModuleAnalysisHandle
ModuleAnalysisManager::Invalidator &));
};

struct PGOInstrumentationGenTest
: public Test,
WithParamInterface<std::tuple<StringRef, StringRef>> {
template <typename ParamType> struct PGOTestName {
std::string operator()(const TestParamInfo<ParamType> &Info) const {
return std::get<1>(Info.param).str();
}
};

struct PGOInstrumentationGenTest : public Test {
LLVMContext Ctx;
ModulePassManager MPM;
PassBuilder PB;
Expand Down Expand Up @@ -143,12 +147,47 @@ struct PGOInstrumentationGenTest
}
};

struct PGOInstrumentationGenInstrumentTest
: PGOInstrumentationGenTest,
WithParamInterface<std::tuple<StringRef, StringRef>> {};

static constexpr StringRef CodeWithFuncDefs = R"(
define i32 @f(i32 %n) {
entry:
ret i32 0
})";

INSTANTIATE_TEST_SUITE_P(
PGOInstrumetationGenTestSuite, PGOInstrumentationGenInstrumentTest,
Values(std::make_tuple(CodeWithFuncDefs, "instrument_function_defs")),
PGOTestName<PGOInstrumentationGenInstrumentTest::ParamType>());

TEST_P(PGOInstrumentationGenInstrumentTest, Instrumented) {
const StringRef Code = std::get<0>(GetParam());
parseAssembly(Code);

ASSERT_THAT(M, NotNull());

Sequence PassSequence;
EXPECT_CALL(MMAHandle, run(Ref(*M), _))
.InSequence(PassSequence)
.WillOnce(DoDefault());
EXPECT_CALL(MMAHandle, invalidate(Ref(*M), _, _))
.InSequence(PassSequence)
.WillOnce(DoDefault());

MPM.run(*M, MAM);

const auto *IRInstrVar =
M->getNamedGlobal(INSTR_PROF_QUOTE(INSTR_PROF_RAW_VERSION_VAR));
EXPECT_THAT(IRInstrVar, NotNull());
EXPECT_FALSE(IRInstrVar->isDeclaration());
}

struct PGOInstrumentationGenIgnoreTest
: PGOInstrumentationGenTest,
WithParamInterface<std::tuple<StringRef, StringRef>> {};

static constexpr StringRef CodeWithFuncDecls = R"(
declare i32 @f(i32);
)";
Expand All @@ -159,34 +198,26 @@ static constexpr StringRef CodeWithGlobals = R"(
)";

INSTANTIATE_TEST_SUITE_P(
PGOInstrumetationGenTestSuite, PGOInstrumentationGenTest,
Values(std::make_tuple(CodeWithFuncDefs, "instrument_function_defs"),
std::make_tuple(CodeWithFuncDecls, "instrument_function_decls"),
PGOInstrumetationGenIgnoreTestSuite, PGOInstrumentationGenIgnoreTest,
Values(std::make_tuple(CodeWithFuncDecls, "instrument_function_decls"),
std::make_tuple(CodeWithGlobals, "instrument_globals")),
[](const TestParamInfo<PGOInstrumentationGenTest::ParamType> &Info) {
return std::get<1>(Info.param).str();
});
PGOTestName<PGOInstrumentationGenIgnoreTest::ParamType>());

TEST_P(PGOInstrumentationGenTest, Instrumented) {
TEST_P(PGOInstrumentationGenIgnoreTest, NotInstrumented) {
const StringRef Code = std::get<0>(GetParam());

parseAssembly(Code);

ASSERT_THAT(M, NotNull());

Sequence PassSequence;
EXPECT_CALL(MMAHandle, run(Ref(*M), _))
.InSequence(PassSequence)
.WillOnce(DoDefault());
EXPECT_CALL(MMAHandle, invalidate(Ref(*M), _, _))
.InSequence(PassSequence)
.WillOnce(DoDefault());
EXPECT_CALL(MMAHandle, run(Ref(*M), _)).WillOnce(DoDefault());
EXPECT_CALL(MMAHandle, invalidate(Ref(*M), _, _)).Times(0);

MPM.run(*M, MAM);

const auto *IRInstrVar =
M->getNamedGlobal(INSTR_PROF_QUOTE(INSTR_PROF_RAW_VERSION_VAR));
EXPECT_THAT(IRInstrVar, NotNull());
EXPECT_FALSE(IRInstrVar->isDeclaration());
EXPECT_THAT(IRInstrVar, IsNull());
}

} // end anonymous namespace
Loading