Skip to content

Commit 3e303bf

Browse files
committed
[ctxprof][nfc] Prepare CtxProfAnalysis for flat profiles
1 parent 5b223e7 commit 3e303bf

File tree

11 files changed

+58
-49
lines changed

11 files changed

+58
-49
lines changed

llvm/include/llvm/Analysis/CtxProfAnalysis.h

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,6 @@ namespace llvm {
2121

2222
class CtxProfAnalysis;
2323

24-
// Setting initial capacity to 1 because all contexts must have at least 1
25-
// counter, and then, because all contexts belonging to a function have the same
26-
// size, there'll be at most one other heap allocation.
27-
using CtxProfFlatProfile =
28-
std::map<GlobalValue::GUID, SmallVector<uint64_t, 1>>;
29-
3024
/// The instrumented contextual profile, produced by the CtxProfAnalysis.
3125
class PGOContextualProfile {
3226
friend class CtxProfAnalysis;
@@ -38,7 +32,7 @@ class PGOContextualProfile {
3832
PGOCtxProfContext Index;
3933
FunctionInfo(StringRef Name) : Name(Name) {}
4034
};
41-
std::optional<PGOCtxProfContext::CallTargetMapTy> Profiles;
35+
PGOCtxProfile Profiles;
4236
// For the GUIDs in this module, associate metadata about each function which
4337
// we'll need when we maintain the profiles during IPO transformations.
4438
std::map<GlobalValue::GUID, FunctionInfo> FuncInfo;
@@ -56,10 +50,8 @@ class PGOContextualProfile {
5650
PGOContextualProfile(const PGOContextualProfile &) = delete;
5751
PGOContextualProfile(PGOContextualProfile &&) = default;
5852

59-
operator bool() const { return Profiles.has_value(); }
60-
61-
const PGOCtxProfContext::CallTargetMapTy &profiles() const {
62-
return *Profiles;
53+
const CtxProfContextualProfiles &contexts() const {
54+
return Profiles.Contexts;
6355
}
6456

6557
bool isFunctionKnown(const Function &F) const {

llvm/include/llvm/ProfileData/PGOCtxProfReader.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,23 @@ class PGOCtxProfContext final : public internal::IndexNode {
164164
}
165165
};
166166

167+
// Setting initial capacity to 1 because all contexts must have at least 1
168+
// counter, and then, because all contexts belonging to a function have the same
169+
// size, there'll be at most one other heap allocation.
170+
using CtxProfFlatProfile =
171+
std::map<GlobalValue::GUID, SmallVector<uint64_t, 1>>;
172+
173+
using CtxProfContextualProfiles =
174+
std::map<GlobalValue::GUID, PGOCtxProfContext>;
175+
struct PGOCtxProfile {
176+
CtxProfContextualProfiles Contexts;
177+
178+
PGOCtxProfile() = default;
179+
PGOCtxProfile(const PGOCtxProfile &) = delete;
180+
PGOCtxProfile(PGOCtxProfile &&) = default;
181+
PGOCtxProfile &operator=(PGOCtxProfile &&) = default;
182+
};
183+
167184
class PGOCtxProfileReader final {
168185
StringRef Magic;
169186
BitstreamCursor Cursor;
@@ -181,7 +198,7 @@ class PGOCtxProfileReader final {
181198
: Magic(Buffer.substr(0, PGOCtxProfileWriter::ContainerMagic.size())),
182199
Cursor(Buffer.substr(PGOCtxProfileWriter::ContainerMagic.size())) {}
183200

184-
Expected<std::map<GlobalValue::GUID, PGOCtxProfContext>> loadContexts();
201+
Expected<PGOCtxProfile> loadProfiles();
185202
};
186203

187204
void convertCtxProfToYaml(raw_ostream &OS,

llvm/lib/Analysis/CtxProfAnalysis.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -88,27 +88,28 @@ PGOContextualProfile CtxProfAnalysis::run(Module &M,
8888
return {};
8989
}
9090
PGOCtxProfileReader Reader(MB.get()->getBuffer());
91-
auto MaybeCtx = Reader.loadContexts();
92-
if (!MaybeCtx) {
91+
auto MaybeProfiles = Reader.loadProfiles();
92+
if (!MaybeProfiles) {
9393
M.getContext().emitError("contextual profile file is invalid: " +
94-
toString(MaybeCtx.takeError()));
94+
toString(MaybeProfiles.takeError()));
9595
return {};
9696
}
9797

9898
DenseSet<GlobalValue::GUID> ProfileRootsInModule;
9999
for (const auto &F : M)
100100
if (!F.isDeclaration())
101101
if (auto GUID = AssignGUIDPass::getGUID(F);
102-
MaybeCtx->find(GUID) != MaybeCtx->end())
102+
MaybeProfiles->Contexts.find(GUID) != MaybeProfiles->Contexts.end())
103103
ProfileRootsInModule.insert(GUID);
104104

105105
// Trim first the roots that aren't in this module.
106-
for (auto &[RootGuid, _] : llvm::make_early_inc_range(*MaybeCtx))
106+
for (auto &[RootGuid, _] :
107+
llvm::make_early_inc_range(MaybeProfiles->Contexts))
107108
if (!ProfileRootsInModule.contains(RootGuid))
108-
MaybeCtx->erase(RootGuid);
109+
MaybeProfiles->Contexts.erase(RootGuid);
109110
// If none of the roots are in the module, we have no profile (for this
110111
// module)
111-
if (MaybeCtx->empty())
112+
if (MaybeProfiles->Contexts.empty())
112113
return {};
113114

114115
// OK, so we have a valid profile and it's applicable to roots in this module.
@@ -146,7 +147,7 @@ PGOContextualProfile CtxProfAnalysis::run(Module &M,
146147
}
147148
// If we made it this far, the Result is valid - which we mark by setting
148149
// .Profiles.
149-
Result.Profiles = std::move(*MaybeCtx);
150+
Result.Profiles = std::move(*MaybeProfiles);
150151
Result.initIndex();
151152
return Result;
152153
}
@@ -164,7 +165,7 @@ CtxProfAnalysisPrinterPass::CtxProfAnalysisPrinterPass(raw_ostream &OS)
164165
PreservedAnalyses CtxProfAnalysisPrinterPass::run(Module &M,
165166
ModuleAnalysisManager &MAM) {
166167
CtxProfAnalysis::Result &C = MAM.getResult<CtxProfAnalysis>(M);
167-
if (!C) {
168+
if (C.contexts().empty()) {
168169
OS << "No contextual profile was provided.\n";
169170
return PreservedAnalyses::all();
170171
}
@@ -179,7 +180,7 @@ PreservedAnalyses CtxProfAnalysisPrinterPass::run(Module &M,
179180

180181
if (Mode == PrintMode::Everything)
181182
OS << "\nCurrent Profile:\n";
182-
convertCtxProfToYaml(OS, C.profiles());
183+
convertCtxProfToYaml(OS, C.contexts());
183184
OS << "\n";
184185
if (Mode == PrintMode::YAML)
185186
return PreservedAnalyses::all();
@@ -245,7 +246,7 @@ void PGOContextualProfile::initIndex() {
245246
for (auto &[Guid, FI] : FuncInfo)
246247
InsertionPoints[Guid] = &FI.Index;
247248
preorderVisit<PGOCtxProfContext::CallTargetMapTy, PGOCtxProfContext>(
248-
*Profiles, [&](PGOCtxProfContext &Ctx) {
249+
Profiles.Contexts, [&](PGOCtxProfContext &Ctx) {
249250
auto InsertIt = InsertionPoints.find(Ctx.guid());
250251
if (InsertIt == InsertionPoints.end())
251252
return;
@@ -270,7 +271,7 @@ void PGOContextualProfile::update(Visitor V, const Function &F) {
270271
void PGOContextualProfile::visit(ConstVisitor V, const Function *F) const {
271272
if (!F)
272273
return preorderVisit<const PGOCtxProfContext::CallTargetMapTy,
273-
const PGOCtxProfContext>(*Profiles, V);
274+
const PGOCtxProfContext>(Profiles.Contexts, V);
274275
assert(isFunctionKnown(*F));
275276
GlobalValue::GUID G = getDefinedFunctionGUID(*F);
276277
for (const auto *Node = FuncInfo.find(G)->second.Index.Next; Node;
@@ -279,11 +280,10 @@ void PGOContextualProfile::visit(ConstVisitor V, const Function *F) const {
279280
}
280281

281282
const CtxProfFlatProfile PGOContextualProfile::flatten() const {
282-
assert(Profiles.has_value());
283283
CtxProfFlatProfile Flat;
284284
preorderVisit<const PGOCtxProfContext::CallTargetMapTy,
285285
const PGOCtxProfContext>(
286-
*Profiles, [&](const PGOCtxProfContext &Ctx) {
286+
Profiles.Contexts, [&](const PGOCtxProfContext &Ctx) {
287287
auto [It, Ins] = Flat.insert({Ctx.guid(), {}});
288288
if (Ins) {
289289
llvm::append_range(It->second, Ctx.counters());

llvm/lib/ProfileData/PGOCtxProfReader.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -168,14 +168,13 @@ Error PGOCtxProfileReader::readMetadata() {
168168
return Error::success();
169169
}
170170

171-
Expected<std::map<GlobalValue::GUID, PGOCtxProfContext>>
172-
PGOCtxProfileReader::loadContexts() {
173-
std::map<GlobalValue::GUID, PGOCtxProfContext> Ret;
171+
Expected<PGOCtxProfile> PGOCtxProfileReader::loadProfiles() {
172+
PGOCtxProfile Ret;
174173
RET_ON_ERR(readMetadata());
175174
while (canReadContext()) {
176175
EXPECT_OR_RET(E, readContext(false));
177176
auto Key = E->second.guid();
178-
if (!Ret.insert({Key, std::move(E->second)}).second)
177+
if (!Ret.Contexts.insert({Key, std::move(E->second)}).second)
179178
return wrongValue("Duplicate roots");
180179
}
181180
return std::move(Ret);

llvm/lib/Transforms/IPO/ElimAvailExtern.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,8 @@ EliminateAvailableExternallyPass::run(Module &M, ModuleAnalysisManager &MAM) {
133133
// that's imported, its optimizations will, thus, differ, and be specialized
134134
// for this contextual information. Eliding it in favor of the original would
135135
// undo these optimizations.
136-
if (!eliminateAvailableExternally(M, /*Convert=*/(CtxProf && !!(*CtxProf))))
136+
if (!eliminateAvailableExternally(
137+
M, /*Convert=*/(CtxProf && !CtxProf->contexts().empty())))
137138
return PreservedAnalyses::all();
138139
return PreservedAnalyses::none();
139140
}

llvm/lib/Transforms/IPO/FunctionImport.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -724,12 +724,12 @@ class WorkloadImportsManager : public ModuleImportsManager {
724724
auto Buffer = std::move(BufferOrErr.get());
725725

726726
PGOCtxProfileReader Reader(Buffer->getBuffer());
727-
auto Ctx = Reader.loadContexts();
727+
auto Ctx = Reader.loadProfiles();
728728
if (!Ctx) {
729729
report_fatal_error("Failed to parse contextual profiles");
730730
return;
731731
}
732-
const auto &CtxMap = *Ctx;
732+
const auto &CtxMap = Ctx->Contexts;
733733
SetVector<GlobalValue::GUID> ContainedGUIDs;
734734
for (const auto &[RootGuid, Root] : CtxMap) {
735735
// Avoid ContainedGUIDs to get in/out of scope. Reuse its memory for

llvm/lib/Transforms/IPO/ModuleInliner.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ PreservedAnalyses ModuleInlinerPass::run(Module &M,
171171
<< setIsVerbose();
172172
});
173173
}
174-
} else if (CtxProfPromoteAlwaysInline && CtxProf &&
174+
} else if (CtxProfPromoteAlwaysInline && !CtxProf.contexts().empty() &&
175175
CB->isIndirectCall()) {
176176
CtxProfAnalysis::collectIndirectCallPromotionList(*CB, CtxProf,
177177
ICPCandidates);
@@ -260,7 +260,7 @@ PreservedAnalyses ModuleInlinerPass::run(Module &M,
260260
// iteration because the next iteration may not happen and we may
261261
// miss inlining it.
262262
// FIXME: enable for ctxprof.
263-
if (!CtxProf)
263+
if (CtxProf.contexts().empty())
264264
if (tryPromoteCall(*ICB))
265265
NewCallee = ICB->getCalledFunction();
266266
}

llvm/lib/Transforms/Instrumentation/PGOCtxProfFlattening.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ PreservedAnalyses PGOCtxProfFlatteningPass::run(Module &M,
435435
removeInstrumentation(F);
436436
});
437437
auto &CtxProf = MAM.getResult<CtxProfAnalysis>(M);
438-
if (!CtxProf)
438+
if (CtxProf.contexts().empty())
439439
return PreservedAnalyses::none();
440440

441441
const auto FlattenedProfile = CtxProf.flatten();

llvm/lib/Transforms/Utils/InlineFunction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2357,7 +2357,7 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
23572357
AAResults *CalleeAAR,
23582358
bool InsertLifetime,
23592359
Function *ForwardVarArgsTo) {
2360-
if (!CtxProf)
2360+
if (CtxProf.contexts().empty())
23612361
return InlineFunction(CB, IFI, MergeAttributes, CalleeAAR, InsertLifetime,
23622362
ForwardVarArgsTo);
23632363

llvm/tools/llvm-ctxprof-util/llvm-ctxprof-util.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,10 @@ Error convertToYaml() {
7474
if (EC)
7575
return createStringError(EC, "failed to open output");
7676
PGOCtxProfileReader Reader(BufOrError.get()->getBuffer());
77-
auto Prof = Reader.loadContexts();
77+
auto Prof = Reader.loadProfiles();
7878
if (!Prof)
7979
return Prof.takeError();
80-
llvm::convertCtxProfToYaml(Out, *Prof);
80+
llvm::convertCtxProfToYaml(Out, Prof->Contexts);
8181
Out << "\n";
8282
return Error::success();
8383
}

llvm/unittests/ProfileData/PGOCtxProfReaderWriterTest.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,9 @@ TEST_F(PGOCtxProfRWTest, RoundTrip) {
121121
EXPECT_TRUE(AnalyzerDump.find("<CalleeIndex codeid") != std::string::npos);
122122

123123
PGOCtxProfileReader Reader((*MB)->getBuffer());
124-
auto Expected = Reader.loadContexts();
124+
auto Expected = Reader.loadProfiles();
125125
ASSERT_TRUE(!!Expected);
126-
auto &Ctxes = *Expected;
126+
auto &Ctxes = Expected->Contexts;
127127
EXPECT_EQ(Ctxes.size(), roots().size());
128128
EXPECT_EQ(Ctxes.size(), 2U);
129129
for (auto &[G, R] : roots())
@@ -157,22 +157,22 @@ TEST_F(PGOCtxProfRWTest, InvalidCounters) {
157157
ASSERT_TRUE(!!MB);
158158
ASSERT_NE(*MB, nullptr);
159159
PGOCtxProfileReader Reader((*MB)->getBuffer());
160-
auto Expected = Reader.loadContexts();
160+
auto Expected = Reader.loadProfiles();
161161
EXPECT_FALSE(Expected);
162162
consumeError(Expected.takeError());
163163
}
164164
}
165165

166166
TEST_F(PGOCtxProfRWTest, Empty) {
167167
PGOCtxProfileReader Reader("");
168-
auto Expected = Reader.loadContexts();
168+
auto Expected = Reader.loadProfiles();
169169
EXPECT_FALSE(Expected);
170170
consumeError(Expected.takeError());
171171
}
172172

173173
TEST_F(PGOCtxProfRWTest, Invalid) {
174174
PGOCtxProfileReader Reader("Surely this is not valid");
175-
auto Expected = Reader.loadContexts();
175+
auto Expected = Reader.loadProfiles();
176176
EXPECT_FALSE(Expected);
177177
consumeError(Expected.takeError());
178178
}
@@ -194,9 +194,9 @@ TEST_F(PGOCtxProfRWTest, ValidButEmpty) {
194194
ASSERT_NE(*MB, nullptr);
195195

196196
PGOCtxProfileReader Reader((*MB)->getBuffer());
197-
auto Expected = Reader.loadContexts();
197+
auto Expected = Reader.loadProfiles();
198198
EXPECT_TRUE(!!Expected);
199-
EXPECT_TRUE(Expected->empty());
199+
EXPECT_TRUE(Expected->Contexts.empty());
200200
}
201201
}
202202

@@ -216,7 +216,7 @@ TEST_F(PGOCtxProfRWTest, WrongVersion) {
216216
ASSERT_NE(*MB, nullptr);
217217

218218
PGOCtxProfileReader Reader((*MB)->getBuffer());
219-
auto Expected = Reader.loadContexts();
219+
auto Expected = Reader.loadProfiles();
220220
EXPECT_FALSE(Expected);
221221
consumeError(Expected.takeError());
222222
}
@@ -239,7 +239,7 @@ TEST_F(PGOCtxProfRWTest, DuplicateRoots) {
239239
ASSERT_TRUE(!!MB);
240240
ASSERT_NE(*MB, nullptr);
241241
PGOCtxProfileReader Reader((*MB)->getBuffer());
242-
auto Expected = Reader.loadContexts();
242+
auto Expected = Reader.loadProfiles();
243243
EXPECT_FALSE(Expected);
244244
consumeError(Expected.takeError());
245245
}
@@ -265,7 +265,7 @@ TEST_F(PGOCtxProfRWTest, DuplicateTargets) {
265265
ASSERT_TRUE(!!MB);
266266
ASSERT_NE(*MB, nullptr);
267267
PGOCtxProfileReader Reader((*MB)->getBuffer());
268-
auto Expected = Reader.loadContexts();
268+
auto Expected = Reader.loadProfiles();
269269
EXPECT_FALSE(Expected);
270270
consumeError(Expected.takeError());
271271
}

0 commit comments

Comments
 (0)