Skip to content

Commit 23c64be

Browse files
authored
[PGO] Preserve analysis results when nothing was instrumented (#93421)
The `PGOInstrumentationGen` pass should preserve all analysis results when nothing was actually instrumented. Currently, only modules that contain at least a single function definition are instrumented. When a module contains only function declarations and, optionally, global variable definitions (a module for the regular-LTO phase for thin-LTO when LTOUnit splitting is enabled, for example), such module is not instrumented (yet?) and there is no reason to invalidate any analysis results. NFC.
1 parent 9bf2e20 commit 23c64be

File tree

2 files changed

+53
-19
lines changed

2 files changed

+53
-19
lines changed

llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1916,6 +1916,7 @@ static bool InstrumentAllFunctions(
19161916
std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
19171917
collectComdatMembers(M, ComdatMembers);
19181918

1919+
bool AnythingInstrumented = false;
19191920
for (auto &F : M) {
19201921
if (skipPGOGen(F))
19211922
continue;
@@ -1925,8 +1926,9 @@ static bool InstrumentAllFunctions(
19251926
FunctionInstrumenter FI(M, F, TLI, ComdatMembers, BPI, BFI,
19261927
InstrumentationType);
19271928
FI.instrument();
1929+
AnythingInstrumented = true;
19281930
}
1929-
return true;
1931+
return AnythingInstrumented;
19301932
}
19311933

19321934
PreservedAnalyses

llvm/unittests/Transforms/Instrumentation/PGOInstrumentationTest.cpp

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,13 @@ class MockModuleAnalysisHandle
103103
ModuleAnalysisManager::Invalidator &));
104104
};
105105

106-
struct PGOInstrumentationGenTest
107-
: public Test,
108-
WithParamInterface<std::tuple<StringRef, StringRef>> {
106+
template <typename ParamType> struct PGOTestName {
107+
std::string operator()(const TestParamInfo<ParamType> &Info) const {
108+
return std::get<1>(Info.param).str();
109+
}
110+
};
111+
112+
struct PGOInstrumentationGenTest : public Test {
109113
ModulePassManager MPM;
110114
PassBuilder PB;
111115
MockModuleAnalysisHandle MMAHandle;
@@ -141,12 +145,47 @@ struct PGOInstrumentationGenTest
141145
}
142146
};
143147

148+
struct PGOInstrumentationGenInstrumentTest
149+
: PGOInstrumentationGenTest,
150+
WithParamInterface<std::tuple<StringRef, StringRef>> {};
151+
144152
static constexpr StringRef CodeWithFuncDefs = R"(
145153
define i32 @f(i32 %n) {
146154
entry:
147155
ret i32 0
148156
})";
149157

158+
INSTANTIATE_TEST_SUITE_P(
159+
PGOInstrumetationGenTestSuite, PGOInstrumentationGenInstrumentTest,
160+
Values(std::make_tuple(CodeWithFuncDefs, "instrument_function_defs")),
161+
PGOTestName<PGOInstrumentationGenInstrumentTest::ParamType>());
162+
163+
TEST_P(PGOInstrumentationGenInstrumentTest, Instrumented) {
164+
const StringRef Code = std::get<0>(GetParam());
165+
parseAssembly(Code);
166+
167+
ASSERT_THAT(M, NotNull());
168+
169+
Sequence PassSequence;
170+
EXPECT_CALL(MMAHandle, run(Ref(*M), _))
171+
.InSequence(PassSequence)
172+
.WillOnce(DoDefault());
173+
EXPECT_CALL(MMAHandle, invalidate(Ref(*M), _, _))
174+
.InSequence(PassSequence)
175+
.WillOnce(DoDefault());
176+
177+
MPM.run(*M, MAM);
178+
179+
const auto *IRInstrVar =
180+
M->getNamedGlobal(INSTR_PROF_QUOTE(INSTR_PROF_RAW_VERSION_VAR));
181+
ASSERT_THAT(IRInstrVar, NotNull());
182+
EXPECT_FALSE(IRInstrVar->isDeclaration());
183+
}
184+
185+
struct PGOInstrumentationGenIgnoreTest
186+
: PGOInstrumentationGenTest,
187+
WithParamInterface<std::tuple<StringRef, StringRef>> {};
188+
150189
static constexpr StringRef CodeWithFuncDecls = R"(
151190
declare i32 @f(i32);
152191
)";
@@ -157,33 +196,26 @@ static constexpr StringRef CodeWithGlobals = R"(
157196
)";
158197

159198
INSTANTIATE_TEST_SUITE_P(
160-
PGOInstrumetationGenTestSuite, PGOInstrumentationGenTest,
161-
Values(std::make_tuple(CodeWithFuncDefs, "instrument_function_defs"),
162-
std::make_tuple(CodeWithFuncDecls, "instrument_function_decls"),
199+
PGOInstrumetationGenIgnoreTestSuite, PGOInstrumentationGenIgnoreTest,
200+
Values(std::make_tuple(CodeWithFuncDecls, "instrument_function_decls"),
163201
std::make_tuple(CodeWithGlobals, "instrument_globals")),
164-
[](const TestParamInfo<PGOInstrumentationGenTest::ParamType> &Info) {
165-
return std::get<1>(Info.param).str();
166-
});
202+
PGOTestName<PGOInstrumentationGenIgnoreTest::ParamType>());
167203

168-
TEST_P(PGOInstrumentationGenTest, Instrumented) {
204+
TEST_P(PGOInstrumentationGenIgnoreTest, NotInstrumented) {
169205
const StringRef Code = std::get<0>(GetParam());
206+
170207
parseAssembly(Code);
171208

172209
ASSERT_THAT(M, NotNull());
173210

174-
Sequence PassSequence;
175-
EXPECT_CALL(MMAHandle, run(Ref(*M), _))
176-
.InSequence(PassSequence)
177-
.WillOnce(DoDefault());
178-
EXPECT_CALL(MMAHandle, invalidate(Ref(*M), _, _))
179-
.InSequence(PassSequence)
180-
.WillOnce(DoDefault());
211+
EXPECT_CALL(MMAHandle, run(Ref(*M), _)).WillOnce(DoDefault());
212+
EXPECT_CALL(MMAHandle, invalidate(Ref(*M), _, _)).Times(0);
181213

182214
MPM.run(*M, MAM);
183215

184216
const auto *IRInstrVar =
185217
M->getNamedGlobal(INSTR_PROF_QUOTE(INSTR_PROF_RAW_VERSION_VAR));
186-
EXPECT_THAT(IRInstrVar, NotNull());
218+
ASSERT_THAT(IRInstrVar, NotNull());
187219
EXPECT_FALSE(IRInstrVar->isDeclaration());
188220
}
189221

0 commit comments

Comments
 (0)