[llvm] [BOLT] Run EliminateUnreachableBlocks in parallel (PR #71299)
Vladislav Khmelevsky via llvm-commits
llvm-commits at lists.llvm.org
Sat Nov 4 14:59:14 PDT 2023
https://github.com/yota9 created https://github.com/llvm/llvm-project/pull/71299
The wall time for this pass decreased on my laptop from ~80 sec to 5
sec.
>From 3c3d5e3c1b6fe1bdeca5352bbb88adb296b6f996 Mon Sep 17 00:00:00 2001
From: Vladislav Khmelevsky <och95 at yandex.ru>
Date: Sun, 5 Nov 2023 01:57:13 +0400
Subject: [PATCH] [BOLT] Run EliminateUnreachableBlocks in parallel
The wall time for this pass decreased on my laptop from ~80 sec to 5
sec.
---
bolt/include/bolt/Core/BinaryFunction.h | 2 +-
bolt/lib/Core/BinaryFunction.cpp | 2 +-
bolt/lib/Passes/BinaryPasses.cpp | 48 ++++++++++++++-----------
3 files changed, 30 insertions(+), 22 deletions(-)
diff --git a/bolt/include/bolt/Core/BinaryFunction.h b/bolt/include/bolt/Core/BinaryFunction.h
index c67ddccbf4892a7..2abaff663624874 100644
--- a/bolt/include/bolt/Core/BinaryFunction.h
+++ b/bolt/include/bolt/Core/BinaryFunction.h
@@ -1445,7 +1445,7 @@ class BinaryFunction {
/// Rebuilds BBs layout, ignoring dead BBs. Returns the number of removed
/// BBs and the removed number of bytes of code.
- std::pair<unsigned, uint64_t> eraseInvalidBBs();
+ std::pair<unsigned, uint64_t> eraseInvalidBBs(const MCCodeEmitter *Emitter = nullptr);
/// Get the relative order between two basic blocks in the original
/// layout. The result is > 0 if B occurs before A and < 0 if B
diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp
index 2e1fa739e53f20b..11aa9b364220a87 100644
--- a/bolt/lib/Core/BinaryFunction.cpp
+++ b/bolt/lib/Core/BinaryFunction.cpp
@@ -322,7 +322,7 @@ void BinaryFunction::markUnreachableBlocks() {
// Any unnecessary fallthrough jumps revealed after calling eraseInvalidBBs
// will be cleaned up by fixBranches().
-std::pair<unsigned, uint64_t> BinaryFunction::eraseInvalidBBs() {
+std::pair<unsigned, uint64_t> BinaryFunction::eraseInvalidBBs(const MCCodeEmitter *Emitter) {
DenseSet<const BinaryBasicBlock *> InvalidBBs;
unsigned Count = 0;
uint64_t Bytes = 0;
diff --git a/bolt/lib/Passes/BinaryPasses.cpp b/bolt/lib/Passes/BinaryPasses.cpp
index e50fa9dea602bc7..870ea6497b63aca 100644
--- a/bolt/lib/Passes/BinaryPasses.cpp
+++ b/bolt/lib/Passes/BinaryPasses.cpp
@@ -317,11 +317,11 @@ void NormalizeCFG::runOnFunctions(BinaryContext &BC) {
}
void EliminateUnreachableBlocks::runOnFunction(BinaryFunction &Function) {
- if (!Function.getLayout().block_empty()) {
- unsigned Count;
- uint64_t Bytes;
- Function.markUnreachableBlocks();
- LLVM_DEBUG({
+ BinaryContext &BC = Function.getBinaryContext();
+ unsigned Count;
+ uint64_t Bytes;
+ Function.markUnreachableBlocks();
+ LLVM_DEBUG({
for (BinaryBasicBlock &BB : Function) {
if (!BB.isValid()) {
dbgs() << "BOLT-INFO: UCE found unreachable block " << BB.getName()
@@ -330,25 +330,33 @@ void EliminateUnreachableBlocks::runOnFunction(BinaryFunction &Function) {
}
}
});
- std::tie(Count, Bytes) = Function.eraseInvalidBBs();
- DeletedBlocks += Count;
- DeletedBytes += Bytes;
- if (Count) {
- Modified.insert(&Function);
- if (opts::Verbosity > 0)
- outs() << "BOLT-INFO: removed " << Count
- << " dead basic block(s) accounting for " << Bytes
- << " bytes in function " << Function << '\n';
- }
+ BinaryContext::IndependentCodeEmitter Emitter =
+ BC.createIndependentMCCodeEmitter();
+ std::tie(Count, Bytes) = Function.eraseInvalidBBs(Emitter.MCE.get());
+ DeletedBlocks += Count;
+ DeletedBytes += Bytes;
+ if (Count) {
+ auto L = BC.scopeLock();
+ Modified.insert(&Function);
+ if (opts::Verbosity > 0)
+ outs() << "BOLT-INFO: removed " << Count
+ << " dead basic block(s) accounting for " << Bytes
+ << " bytes in function " << Function << '\n';
}
}
void EliminateUnreachableBlocks::runOnFunctions(BinaryContext &BC) {
- for (auto &It : BC.getBinaryFunctions()) {
- BinaryFunction &Function = It.second;
- if (shouldOptimize(Function))
- runOnFunction(Function);
- }
+ ParallelUtilities::WorkFuncTy WorkFun = [&](BinaryFunction &BF) {
+ runOnFunction(BF);
+ };
+
+ ParallelUtilities::PredicateTy SkipPredicate = [&](const BinaryFunction &BF) {
+ return !shouldOptimize(BF) || BF.getLayout().block_empty();
+ };
+
+ ParallelUtilities::runOnEachFunction(
+ BC, ParallelUtilities::SchedulingPolicy::SP_CONSTANT, WorkFun,
+ SkipPredicate, "elimininate-unreachable");
if (DeletedBlocks)
outs() << "BOLT-INFO: UCE removed " << DeletedBlocks << " blocks and "
More information about the llvm-commits
mailing list