[llvm] [ctx_prof] Extend `WorkloadImportsManager` to use the contextual profile (PR #98682)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 12 12:15:34 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Mircea Trofin (mtrofin)
<details>
<summary>Changes</summary>
Keeping the json-based input as it's useful for diagnostics or for driving the import by other means than contextual composition.
The support for the contextual profile is just another modality for constructing the import list (`WorkloadImportsManager::Workloads`). Everything else - i.e. the actual importing logic - is already independent from how that list was obtained.
---
Full diff: https://github.com/llvm/llvm-project/pull/98682.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/IPO/FunctionImport.cpp (+68-8)
- (modified) llvm/unittests/ProfileData/PGOCtxProfReaderWriterTest.cpp (+9)
``````````diff
diff --git a/llvm/lib/Transforms/IPO/FunctionImport.cpp b/llvm/lib/Transforms/IPO/FunctionImport.cpp
index 038785114a0cf..985e419c2bb5e 100644
--- a/llvm/lib/Transforms/IPO/FunctionImport.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionImport.cpp
@@ -18,6 +18,7 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Bitcode/BitcodeReader.h"
+#include "llvm/Bitstream/BitstreamWriter.h"
#include "llvm/IR/AutoUpgrade.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
@@ -30,6 +31,7 @@
#include "llvm/IR/ModuleSummaryIndex.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/Linker/IRMover.h"
+#include "llvm/ProfileData/PGOCtxProfReader.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
@@ -174,6 +176,10 @@ static cl::opt<std::string> WorkloadDefinitions(
"}"),
cl::Hidden);
+static cl::opt<std::string>
+ ContextualProfile("thinlto-pgo-ctx-prof",
+ cl::desc("Path to a contextual profile."), cl::Hidden);
+
namespace llvm {
extern cl::opt<bool> EnableMemProfContextDisambiguation;
}
@@ -586,13 +592,7 @@ class WorkloadImportsManager : public ModuleImportsManager {
LLVM_DEBUG(dbgs() << "[Workload] Done\n");
}
-public:
- WorkloadImportsManager(
- function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>
- IsPrevailing,
- const ModuleSummaryIndex &Index,
- DenseMap<StringRef, FunctionImporter::ExportSetTy> *ExportLists)
- : ModuleImportsManager(IsPrevailing, Index, ExportLists) {
+ void loadFromJson() {
// Since the workload def uses names, we need a quick lookup
// name->ValueInfo.
StringMap<ValueInfo> NameToValueInfo;
@@ -672,6 +672,66 @@ class WorkloadImportsManager : public ModuleImportsManager {
});
}
}
+
+ void loadFromCtxProf() {
+ std::error_code EC;
+ auto BufferOrErr = MemoryBuffer::getFileOrSTDIN(ContextualProfile);
+ if (std::error_code EC = BufferOrErr.getError()) {
+ report_fatal_error("Failed to open contextual profile file");
+ return;
+ }
+ auto Buffer = std::move(BufferOrErr.get());
+
+ BitstreamCursor Cursor(*Buffer);
+ PGOCtxProfileReader Reader(Cursor);
+ auto Ctx = Reader.loadContexts();
+ if (!Ctx) {
+ report_fatal_error("Failed to parse contextual profiles");
+ return;
+ }
+ const auto &CtxMap = *Ctx;
+ for (const auto &[RootGuid, Root] : CtxMap) {
+ auto RootVI = Index.getValueInfo(RootGuid);
+ if (!RootVI) {
+ LLVM_DEBUG(dbgs() << "[Workload] Root " << RootGuid
+ << " not found in this linkage unit.\n");
+ continue;
+ }
+ if (RootVI.getSummaryList().size() != 1) {
+ LLVM_DEBUG(dbgs() << "[Workload] Root " << RootGuid
+ << " should have exactly one summary, but has "
+ << RootVI.getSummaryList().size() << ". Skipping.\n");
+ continue;
+ }
+ StringRef RootDefiningModule =
+ RootVI.getSummaryList().front()->modulePath();
+ LLVM_DEBUG(dbgs() << "[Workload] Root defining module for " << RootGuid
+ << " is : " << RootDefiningModule << "\n");
+ DenseSet<GlobalValue::GUID> ContainedGUIDs;
+ auto &Set = Workloads[RootDefiningModule];
+ Root.getContainedGuids(ContainedGUIDs);
+ for (auto Guid : ContainedGUIDs)
+ if (auto VI = Index.getValueInfo(Guid))
+ Set.insert(VI);
+ }
+ }
+
+public:
+ WorkloadImportsManager(
+ function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>
+ IsPrevailing,
+ const ModuleSummaryIndex &Index,
+ DenseMap<StringRef, FunctionImporter::ExportSetTy> *ExportLists)
+ : ModuleImportsManager(IsPrevailing, Index, ExportLists) {
+ if (ContextualProfile.empty() == WorkloadDefinitions.empty()) {
+ report_fatal_error(
+ "Pass only one of: -thinlto-pgo-ctx-prof or -thinlto-workload-def");
+ return;
+ }
+ if (!ContextualProfile.empty())
+ loadFromCtxProf();
+ loadFromJson();
+ }
};
std::unique_ptr<ModuleImportsManager> ModuleImportsManager::create(
@@ -679,7 +739,7 @@ std::unique_ptr<ModuleImportsManager> ModuleImportsManager::create(
IsPrevailing,
const ModuleSummaryIndex &Index,
DenseMap<StringRef, FunctionImporter::ExportSetTy> *ExportLists) {
- if (WorkloadDefinitions.empty()) {
+ if (WorkloadDefinitions.empty() && ContextualProfile.empty()) {
LLVM_DEBUG(dbgs() << "[Workload] Using the regular imports manager.\n");
return std::unique_ptr<ModuleImportsManager>(
new ModuleImportsManager(IsPrevailing, Index, ExportLists));
diff --git a/llvm/unittests/ProfileData/PGOCtxProfReaderWriterTest.cpp b/llvm/unittests/ProfileData/PGOCtxProfReaderWriterTest.cpp
index d2cdbb28e2fce..6c6798ded00b5 100644
--- a/llvm/unittests/ProfileData/PGOCtxProfReaderWriterTest.cpp
+++ b/llvm/unittests/ProfileData/PGOCtxProfReaderWriterTest.cpp
@@ -115,6 +115,15 @@ TEST_F(PGOCtxProfRWTest, RoundTrip) {
EXPECT_EQ(Ctxes.size(), 2U);
for (auto &[G, R] : roots())
checkSame(*R, Ctxes.find(G)->second);
+
+ DenseSet<GlobalValue::GUID> Guids;
+ Ctxes.at(1U).getContainedGuids(Guids);
+ EXPECT_THAT(Guids,
+ testing::WhenSorted(testing::ElementsAre(1U, 2U, 4U, 5U)));
+
+ Guids.clear();
+ Ctxes.at(3U).getContainedGuids(Guids);
+ EXPECT_THAT(Guids, testing::ElementsAre(3U));
}
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/98682
More information about the llvm-commits
mailing list