Skip to content

Commit 8228c70

Browse files
committed
[BOLT][NFCI] Refactor interface for adding basic blocks
Reviewed By: Amir Differential Revision: https://reviews.llvm.org/D127935
1 parent 2d43de1 commit 8228c70

14 files changed

+71
-68
lines changed

bolt/include/bolt/Core/BinaryBasicBlock.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,11 +150,9 @@ class BinaryBasicBlock {
150150
BinaryBasicBlock &operator=(const BinaryBasicBlock &) = delete;
151151
BinaryBasicBlock &operator=(const BinaryBasicBlock &&) = delete;
152152

153-
explicit BinaryBasicBlock(BinaryFunction *Function, MCSymbol *Label,
154-
uint32_t Offset = INVALID_OFFSET)
153+
explicit BinaryBasicBlock(BinaryFunction *Function, MCSymbol *Label)
155154
: Function(Function), Label(Label) {
156155
assert(Function && "Function must be non-null");
157-
InputRange.first = Offset;
158156
}
159157

160158
// Exclusively managed by BinaryFunction.
@@ -561,6 +559,12 @@ class BinaryBasicBlock {
561559
/// Set minimum alignment for the basic block.
562560
void setAlignment(uint32_t Align) { Alignment = Align; }
563561

562+
/// Set alignment of the block based on the alignment of its offset.
563+
void setDerivedAlignment() {
564+
const uint64_t DerivedAlignment = getOffset() & (1 + ~getOffset());
565+
Alignment = std::min(DerivedAlignment, uint64_t(32));
566+
}
567+
564568
/// Return required alignment for the block.
565569
uint32_t getAlignment() const { return Alignment; }
566570

@@ -787,6 +791,9 @@ class BinaryBasicBlock {
787791
/// at the split point.
788792
BinaryBasicBlock *splitAt(iterator II);
789793

794+
/// Set start offset of this basic block in the input binary.
795+
void setOffset(uint32_t Offset) { InputRange.first = Offset; };
796+
790797
/// Sets address of the basic block in the output.
791798
void setOutputStartAddress(uint64_t Address) {
792799
OutputAddressRange.first = Address;

bolt/include/bolt/Core/BinaryFunction.h

Lines changed: 36 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,28 @@ class BinaryFunction {
701701
IsInjected = true;
702702
}
703703

704+
/// Create a basic block at a given \p Offset in the function and append it
705+
/// to the end of list of blocks. Used during CFG construction only.
706+
BinaryBasicBlock *addBasicBlockAt(uint64_t Offset, MCSymbol *Label) {
707+
assert(CurrentState == State::Disassembled &&
708+
"Cannot add block with an offset in non-disassembled state.");
709+
assert(!getBasicBlockAtOffset(Offset) &&
710+
"Basic block already exists at the offset.");
711+
712+
BasicBlocks.emplace_back(createBasicBlock(Label).release());
713+
BinaryBasicBlock *BB = BasicBlocks.back();
714+
715+
BB->setIndex(BasicBlocks.size() - 1);
716+
BB->setOffset(Offset);
717+
718+
BasicBlockOffsets.emplace_back(Offset, BB);
719+
assert(std::is_sorted(BasicBlockOffsets.begin(), BasicBlockOffsets.end(),
720+
CompareBasicBlockOffsets()) &&
721+
std::is_sorted(begin(), end()));
722+
723+
return BB;
724+
}
725+
704726
/// Clear state of the function that could not be disassembled or if its
705727
/// disassembled state was later invalidated.
706728
void clearDisasmState();
@@ -1531,62 +1553,34 @@ class BinaryFunction {
15311553
return Address <= PC && PC < Address + Size;
15321554
}
15331555

1534-
/// Create a basic block at a given \p Offset in the
1535-
/// function.
1536-
/// If \p DeriveAlignment is true, set the alignment of the block based
1537-
/// on the alignment of the existing offset.
1538-
/// The new block is not inserted into the CFG. The client must
1539-
/// use insertBasicBlocks to add any new blocks to the CFG.
1556+
/// Create a basic block in the function. The new block is *NOT* inserted
1557+
/// into the CFG. The caller must use insertBasicBlocks() to add any new
1558+
/// blocks to the CFG.
15401559
std::unique_ptr<BinaryBasicBlock>
1541-
createBasicBlock(uint64_t Offset, MCSymbol *Label = nullptr,
1542-
bool DeriveAlignment = false) {
1543-
assert(BC.Ctx && "cannot be called with empty context");
1560+
createBasicBlock(MCSymbol *Label = nullptr) {
15441561
if (!Label) {
15451562
std::unique_lock<std::shared_timed_mutex> Lock(BC.CtxMutex);
15461563
Label = BC.Ctx->createNamedTempSymbol("BB");
15471564
}
1548-
auto BB = std::unique_ptr<BinaryBasicBlock>(
1549-
new BinaryBasicBlock(this, Label, Offset));
1550-
1551-
if (DeriveAlignment) {
1552-
uint64_t DerivedAlignment = Offset & (1 + ~Offset);
1553-
BB->setAlignment(std::min(DerivedAlignment, uint64_t(32)));
1554-
}
1565+
auto BB =
1566+
std::unique_ptr<BinaryBasicBlock>(new BinaryBasicBlock(this, Label));
15551567

15561568
LabelToBB[Label] = BB.get();
15571569

15581570
return BB;
15591571
}
15601572

1561-
/// Create a basic block at a given \p Offset in the
1562-
/// function and append it to the end of list of blocks.
1563-
/// If \p DeriveAlignment is true, set the alignment of the block based
1564-
/// on the alignment of the existing offset.
1565-
///
1566-
/// Returns NULL if basic block already exists at the \p Offset.
1567-
BinaryBasicBlock *addBasicBlock(uint64_t Offset, MCSymbol *Label = nullptr,
1568-
bool DeriveAlignment = false) {
1569-
assert((CurrentState == State::CFG || !getBasicBlockAtOffset(Offset)) &&
1570-
"basic block already exists in pre-CFG state");
1571-
1572-
std::unique_ptr<BinaryBasicBlock> BBPtr =
1573-
createBasicBlock(Offset, Label, DeriveAlignment);
1574-
BasicBlocks.emplace_back(BBPtr.release());
1573+
/// Create a new basic block with an optional \p Label and add it to the list
1574+
/// of basic blocks of this function.
1575+
BinaryBasicBlock *addBasicBlock(MCSymbol *Label = nullptr) {
1576+
assert(CurrentState == State::CFG && "Can only add blocks in CFG state");
15751577

1578+
BasicBlocks.emplace_back(createBasicBlock(Label).release());
15761579
BinaryBasicBlock *BB = BasicBlocks.back();
1577-
BB->setIndex(BasicBlocks.size() - 1);
1578-
1579-
if (CurrentState == State::Disassembled) {
1580-
BasicBlockOffsets.emplace_back(Offset, BB);
1581-
} else if (CurrentState == State::CFG) {
1582-
BB->setLayoutIndex(layout_size());
1583-
BasicBlocksLayout.emplace_back(BB);
1584-
}
15851580

1586-
assert(CurrentState == State::CFG ||
1587-
(std::is_sorted(BasicBlockOffsets.begin(), BasicBlockOffsets.end(),
1588-
CompareBasicBlockOffsets()) &&
1589-
std::is_sorted(begin(), end())));
1581+
BB->setIndex(BasicBlocks.size() - 1);
1582+
BB->setLayoutIndex(layout_size());
1583+
BasicBlocksLayout.emplace_back(BB);
15901584

15911585
return BB;
15921586
}

bolt/lib/Core/BinaryBasicBlock.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,7 @@ BinaryBasicBlock::getBranchInfo(const MCSymbol *Label) {
608608
BinaryBasicBlock *BinaryBasicBlock::splitAt(iterator II) {
609609
assert(II != end() && "expected iterator pointing to instruction");
610610

611-
BinaryBasicBlock *NewBlock = getFunction()->addBasicBlock(0);
611+
BinaryBasicBlock *NewBlock = getFunction()->addBasicBlock();
612612

613613
// Adjust successors/predecessors and propagate the execution count.
614614
moveAllSuccessorsTo(NewBlock);

bolt/lib/Core/BinaryFunction.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1957,8 +1957,10 @@ bool BinaryFunction::buildCFG(MCPlusBuilder::AllocatorIdTy AllocatorId) {
19571957
if (LI != Labels.end()) {
19581958
// Always create new BB at branch destination.
19591959
PrevBB = InsertBB ? InsertBB : PrevBB;
1960-
InsertBB = addBasicBlock(LI->first, LI->second,
1961-
opts::PreserveBlocksAlignment && IsLastInstrNop);
1960+
InsertBB = addBasicBlockAt(LI->first, LI->second);
1961+
if (opts::PreserveBlocksAlignment && IsLastInstrNop)
1962+
InsertBB->setDerivedAlignment();
1963+
19621964
if (PrevBB)
19631965
updateOffset(LastInstrOffset);
19641966
}
@@ -1997,8 +1999,9 @@ bool BinaryFunction::buildCFG(MCPlusBuilder::AllocatorIdTy AllocatorId) {
19971999
auto L = BC.scopeLock();
19982000
Label = BC.Ctx->createNamedTempSymbol("FT");
19992001
}
2000-
InsertBB = addBasicBlock(
2001-
Offset, Label, opts::PreserveBlocksAlignment && IsLastInstrNop);
2002+
InsertBB = addBasicBlockAt(Offset, Label);
2003+
if (opts::PreserveBlocksAlignment && IsLastInstrNop)
2004+
InsertBB->setDerivedAlignment();
20022005
updateOffset(LastInstrOffset);
20032006
}
20042007
}
@@ -2255,8 +2258,9 @@ void BinaryFunction::removeConditionalTailCalls() {
22552258
// Link new BBs to the original input offset of the BB where the CTC
22562259
// is, so we can map samples recorded in new BBs back to the original BB
22572260
// seem in the input binary (if using BAT)
2258-
std::unique_ptr<BinaryBasicBlock> TailCallBB = createBasicBlock(
2259-
BB.getInputOffset(), BC.Ctx->createNamedTempSymbol("TC"));
2261+
std::unique_ptr<BinaryBasicBlock> TailCallBB =
2262+
createBasicBlock(BC.Ctx->createNamedTempSymbol("TC"));
2263+
TailCallBB->setOffset(BB.getInputOffset());
22602264
TailCallBB->addInstruction(TailCallInstr);
22612265
TailCallBB->setCFIState(CFIStateBeforeCTC);
22622266

@@ -3833,8 +3837,8 @@ BinaryBasicBlock *BinaryFunction::splitEdge(BinaryBasicBlock *From,
38333837
// Link new BBs to the original input offset of the From BB, so we can map
38343838
// samples recorded in new BBs back to the original BB seem in the input
38353839
// binary (if using BAT)
3836-
std::unique_ptr<BinaryBasicBlock> NewBB =
3837-
createBasicBlock(From->getInputOffset(), Tmp);
3840+
std::unique_ptr<BinaryBasicBlock> NewBB = createBasicBlock(Tmp);
3841+
NewBB->setOffset(From->getInputOffset());
38383842
BinaryBasicBlock *NewBBPtr = NewBB.get();
38393843

38403844
// Update "From" BB

bolt/lib/Passes/BinaryPasses.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1760,8 +1760,8 @@ void SpecializeMemcpy1::runOnFunctions(BinaryContext &BC) {
17601760
assert(NextBB && "unexpected call to memcpy() with no return");
17611761
}
17621762

1763-
BinaryBasicBlock *MemcpyBB =
1764-
Function.addBasicBlock(CurBB->getInputOffset());
1763+
BinaryBasicBlock *MemcpyBB = Function.addBasicBlock();
1764+
MemcpyBB->setOffset(CurBB->getInputOffset());
17651765
InstructionListType CmpJCC =
17661766
BC.MIB->createCmpJE(BC.MIB->getIntArgRegister(2), 1,
17671767
OneByteMemcpyBB->getLabel(), BC.Ctx.get());

bolt/lib/Passes/IndirectCallPromotion.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -764,8 +764,8 @@ IndirectCallPromotion::rewriteCall(
764764
MCSymbol *&Sym = Itr->first;
765765
InstructionListType &Insts = Itr->second;
766766
assert(Sym);
767-
std::unique_ptr<BinaryBasicBlock> TBB =
768-
Function.createBasicBlock(OrigOffset, Sym);
767+
std::unique_ptr<BinaryBasicBlock> TBB = Function.createBasicBlock(Sym);
768+
TBB->setOffset(OrigOffset);
769769
for (MCInst &Inst : Insts) // sanitize new instructions.
770770
if (MIB->isCall(Inst))
771771
MIB->removeAnnotation(Inst, "CallProfile");

bolt/lib/Passes/Inliner.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ Inliner::inlineCall(BinaryBasicBlock &CallerBB,
289289
std::unordered_map<const BinaryBasicBlock *, BinaryBasicBlock *> InlinedBBMap;
290290
InlinedBBMap[&Callee.front()] = FirstInlinedBB;
291291
for (auto BBI = std::next(Callee.begin()); BBI != Callee.end(); ++BBI) {
292-
BinaryBasicBlock *InlinedBB = CallerFunction.addBasicBlock(0);
292+
BinaryBasicBlock *InlinedBB = CallerFunction.addBasicBlock();
293293
InlinedBBMap[&*BBI] = InlinedBB;
294294
InlinedBB->setCFIState(FirstInlinedBB->getCFIState());
295295
if (Callee.hasValidProfile())

bolt/lib/Passes/Instrumentation.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -597,8 +597,7 @@ void Instrumentation::createAuxiliaryFunctions(BinaryContext &BC) {
597597
BinaryFunction *Func = BC.createInjectedBinaryFunction(std::string(Title));
598598

599599
std::vector<std::unique_ptr<BinaryBasicBlock>> BBs;
600-
BBs.emplace_back(
601-
Func->createBasicBlock(BinaryBasicBlock::INVALID_OFFSET, nullptr));
600+
BBs.emplace_back(Func->createBasicBlock());
602601
BBs.back()->addInstructions(Instrs.begin(), Instrs.end());
603602
BBs.back()->setCFIState(0);
604603
Func->insertBasicBlocks(nullptr, std::move(BBs),

bolt/lib/Passes/LongJmp.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ LongJmpPass::createNewStub(BinaryBasicBlock &SourceBB, const MCSymbol *TgtSym,
7777
const BinaryContext &BC = Func.getBinaryContext();
7878
const bool IsCold = SourceBB.isCold();
7979
MCSymbol *StubSym = BC.Ctx->createNamedTempSymbol("Stub");
80-
std::unique_ptr<BinaryBasicBlock> StubBB = Func.createBasicBlock(0, StubSym);
80+
std::unique_ptr<BinaryBasicBlock> StubBB = Func.createBasicBlock(StubSym);
8181
MCInst Inst;
8282
BC.MIB->createUncondBranch(Inst, TgtSym, BC.Ctx.get());
8383
if (TgtIsFunc)

bolt/lib/Passes/PatchEntries.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ void PatchEntries::runOnFunctions(BinaryContext &BC) {
118118

119119
InstructionListType Seq;
120120
BC.MIB->createLongTailCall(Seq, Patch.Symbol, BC.Ctx.get());
121-
PatchFunction->addBasicBlock(0)->addInstructions(Seq);
121+
PatchFunction->addBasicBlock()->addInstructions(Seq);
122122

123123
// Verify the size requirements.
124124
uint64_t HotSize, ColdSize;

bolt/lib/Passes/RetpolineInsertion.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,7 @@ BinaryFunction *createNewRetpoline(BinaryContext &BC,
9191
for (int I = 0; I < 3; I++) {
9292
MCSymbol *Symbol =
9393
Ctx.createNamedTempSymbol(Twine(RetpolineTag + "_BB" + to_string(I)));
94-
NewBlocks[I] = NewRetpoline->createBasicBlock(
95-
BinaryBasicBlock::INVALID_OFFSET, Symbol);
94+
NewBlocks[I] = NewRetpoline->createBasicBlock(Symbol);
9695
NewBlocks[I].get()->setCFIState(0);
9796
}
9897

bolt/lib/Passes/TailDuplication.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@ std::vector<BinaryBasicBlock *> TailDuplication::duplicateBlocks(
532532

533533
for (BinaryBasicBlock *CurBB : BlocksToDuplicate) {
534534
DuplicatedBlocks.emplace_back(
535-
BF->createBasicBlock(0, (BC.Ctx)->createNamedTempSymbol("tail-dup")));
535+
BF->createBasicBlock((BC.Ctx)->createNamedTempSymbol("tail-dup")));
536536
BinaryBasicBlock *NewBB = DuplicatedBlocks.back().get();
537537

538538
NewBB->addInstructions(CurBB->begin(), CurBB->end());

bolt/lib/Passes/ValidateInternalCalls.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ bool ValidateInternalCalls::fixCFGForPIC(BinaryFunction &Function) const {
105105
// Split this block at the call instruction. Create an unreachable
106106
// block.
107107
std::vector<std::unique_ptr<BinaryBasicBlock>> NewBBs;
108-
NewBBs.emplace_back(Function.createBasicBlock(0));
108+
NewBBs.emplace_back(Function.createBasicBlock());
109109
NewBBs.back()->addInstructions(MovedInsts.begin(), MovedInsts.end());
110110
BB.moveAllSuccessorsTo(NewBBs.back().get());
111111
Function.insertBasicBlocks(&BB, std::move(NewBBs));

bolt/unittests/Core/MCPlusBuilder.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ TEST_P(MCPlusBuilderTester, ReplaceRegWithImm) {
115115
if (GetParam() != Triple::x86_64)
116116
GTEST_SKIP();
117117
BinaryFunction *BF = BC->createInjectedBinaryFunction("BF", true);
118-
std::unique_ptr<BinaryBasicBlock> BB = BF->createBasicBlock(0);
118+
std::unique_ptr<BinaryBasicBlock> BB = BF->createBasicBlock();
119119
MCInst Inst; // cmpl %eax, %ebx
120120
Inst.setOpcode(X86::CMP32rr);
121121
Inst.addOperand(MCOperand::createReg(X86::EAX));

0 commit comments

Comments
 (0)