Skip to content

Commit 4d47f05

Browse files
committed
[BOLT] Refactor SplitFunctions for function reuse. NFC.
This commit updates SplitFunctions.h and SplitFunctions.cpp to enable the reuse of createEHTrampolines, mergeEHTrampolines, hasFullProfile, and allBlocksCold by a distinct function splitting pass (CDSplit).
1 parent d333c0e commit 4d47f05

File tree

3 files changed

+33
-31
lines changed

3 files changed

+33
-31
lines changed

bolt/include/bolt/Core/BinaryFunction.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,6 +1272,20 @@ class BinaryFunction {
12721272
/// otherwise processed.
12731273
bool isPseudo() const { return IsPseudo; }
12741274

1275+
/// Return true if every block in the function has a valid execution count.
1276+
bool hasFullProfile() const {
1277+
return llvm::all_of(blocks(), [](const BinaryBasicBlock &BB) {
1278+
return BB.getExecutionCount() != BinaryBasicBlock::COUNT_NO_PROFILE;
1279+
});
1280+
}
1281+
1282+
/// Return true if every block in the function has a zero execution count.
1283+
bool allBlocksCold() const {
1284+
return llvm::all_of(blocks(), [](const BinaryBasicBlock &BB) {
1285+
return BB.getExecutionCount() == 0;
1286+
});
1287+
}
1288+
12751289
/// Return true if the function contains explicit or implicit indirect branch
12761290
/// to its split fragments, e.g., split jump table, landing pad in split
12771291
/// fragment.

bolt/include/bolt/Passes/SplitFunctions.h

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,19 @@ class SplitFunctions : public BinaryFunctionPass {
5050
/// Split function body into fragments.
5151
void splitFunction(BinaryFunction &Function, SplitStrategy &Strategy);
5252

53+
std::atomic<uint64_t> SplitBytesHot{0ull};
54+
std::atomic<uint64_t> SplitBytesCold{0ull};
55+
56+
public:
57+
explicit SplitFunctions(const cl::opt<bool> &PrintPass)
58+
: BinaryFunctionPass(PrintPass) {}
59+
60+
bool shouldOptimize(const BinaryFunction &BF) const override;
61+
62+
const char *getName() const override { return "split-functions"; }
63+
64+
void runOnFunctions(BinaryContext &BC) override;
65+
5366
struct TrampolineKey {
5467
FragmentNum SourceFN = FragmentNum::main();
5568
const MCSymbol *Target = nullptr;
@@ -81,27 +94,14 @@ class SplitFunctions : public BinaryFunctionPass {
8194
/// corresponding thrower block. The trampoline landing pad, when created,
8295
/// will redirect the execution to the real landing pad in a different
8396
/// fragment.
84-
TrampolineSetType createEHTrampolines(BinaryFunction &Function) const;
97+
static TrampolineSetType createEHTrampolines(BinaryFunction &Function);
8598

8699
/// Merge trampolines into \p Layout without trampolines. The merge will place
87100
/// a trampoline immediately before its destination. Used to revert the effect
88101
/// of trampolines after createEHTrampolines().
89-
BasicBlockOrderType
102+
static BasicBlockOrderType
90103
mergeEHTrampolines(BinaryFunction &BF, BasicBlockOrderType &Layout,
91-
const TrampolineSetType &Trampolines) const;
92-
93-
std::atomic<uint64_t> SplitBytesHot{0ull};
94-
std::atomic<uint64_t> SplitBytesCold{0ull};
95-
96-
public:
97-
explicit SplitFunctions(const cl::opt<bool> &PrintPass)
98-
: BinaryFunctionPass(PrintPass) {}
99-
100-
bool shouldOptimize(const BinaryFunction &BF) const override;
101-
102-
const char *getName() const override { return "split-functions"; }
103-
104-
void runOnFunctions(BinaryContext &BC) override;
104+
const TrampolineSetType &Trampolines);
105105
};
106106

107107
} // namespace bolt

bolt/lib/Passes/SplitFunctions.cpp

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -109,21 +109,9 @@ static cl::opt<SplitFunctionsStrategy> SplitStrategy(
109109
} // namespace opts
110110

111111
namespace {
112-
bool hasFullProfile(const BinaryFunction &BF) {
113-
return llvm::all_of(BF.blocks(), [](const BinaryBasicBlock &BB) {
114-
return BB.getExecutionCount() != BinaryBasicBlock::COUNT_NO_PROFILE;
115-
});
116-
}
117-
118-
bool allBlocksCold(const BinaryFunction &BF) {
119-
return llvm::all_of(BF.blocks(), [](const BinaryBasicBlock &BB) {
120-
return BB.getExecutionCount() == 0;
121-
});
122-
}
123-
124112
struct SplitProfile2 final : public SplitStrategy {
125113
bool canSplit(const BinaryFunction &BF) override {
126-
return BF.hasValidProfile() && hasFullProfile(BF) && !allBlocksCold(BF);
114+
return BF.hasValidProfile() && BF.hasFullProfile() && !BF.allBlocksCold();
127115
}
128116

129117
bool keepEmpty() override { return false; }
@@ -434,7 +422,7 @@ void SplitFunctions::splitFunction(BinaryFunction &BF, SplitStrategy &S) {
434422
}
435423

436424
SplitFunctions::TrampolineSetType
437-
SplitFunctions::createEHTrampolines(BinaryFunction &BF) const {
425+
SplitFunctions::createEHTrampolines(BinaryFunction &BF) {
438426
const auto &MIB = BF.getBinaryContext().MIB;
439427

440428
// Map real landing pads to the corresponding trampolines.
@@ -501,7 +489,7 @@ SplitFunctions::createEHTrampolines(BinaryFunction &BF) const {
501489

502490
SplitFunctions::BasicBlockOrderType SplitFunctions::mergeEHTrampolines(
503491
BinaryFunction &BF, SplitFunctions::BasicBlockOrderType &Layout,
504-
const SplitFunctions::TrampolineSetType &Trampolines) const {
492+
const SplitFunctions::TrampolineSetType &Trampolines) {
505493
DenseMap<const MCSymbol *, SmallVector<const MCSymbol *, 0>>
506494
IncomingTrampolines;
507495
for (const auto &Entry : Trampolines) {

0 commit comments

Comments
 (0)