Skip to content

Commit c0628ae

Browse files
maksfbmemfrob
authored andcommitted
[BOLT][Refactoring] Change landing pads handling
Summary: Change the way we store and handle landing pads and throwers. (cherry picked from FBD6169992)
1 parent 6260ea8 commit c0628ae

File tree

5 files changed

+62
-130
lines changed

5 files changed

+62
-130
lines changed

bolt/BinaryBasicBlock.cpp

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -293,22 +293,6 @@ void BinaryBasicBlock::removeDuplicateConditionalSuccessor(MCInst *CondBranch) {
293293
BranchInfo.push_back({Count, 0});
294294
}
295295

296-
void BinaryBasicBlock::addLandingPad(BinaryBasicBlock *LPBlock) {
297-
if (std::find(LandingPads.begin(), LandingPads.end(), LPBlock) == LandingPads.end()) {
298-
LandingPads.push_back(LPBlock);
299-
}
300-
LPBlock->Throwers.insert(this);
301-
}
302-
303-
void BinaryBasicBlock::clearLandingPads() {
304-
for (auto *LPBlock : LandingPads) {
305-
auto Count = LPBlock->Throwers.erase(this);
306-
(void)Count;
307-
assert(Count == 1 && "Possible duplicate entry in LandingPads");
308-
}
309-
LandingPads.clear();
310-
}
311-
312296
bool BinaryBasicBlock::analyzeBranch(const MCSymbol *&TBB,
313297
const MCSymbol *&FBB,
314298
MCInst *&CondBranch,

bolt/BinaryBasicBlock.h

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class BinaryBasicBlock {
6060
/// CFG information.
6161
std::vector<BinaryBasicBlock *> Predecessors;
6262
std::vector<BinaryBasicBlock *> Successors;
63-
std::set<BinaryBasicBlock *> Throwers;
63+
std::vector<BinaryBasicBlock *> Throwers;
6464
std::vector<BinaryBasicBlock *> LandingPads;
6565

6666
/// Each successor has a corresponding BranchInfo entry in the list.
@@ -222,7 +222,7 @@ class BinaryBasicBlock {
222222
return (unsigned)Throwers.size();
223223
}
224224
bool throw_empty() const { return Throwers.empty(); }
225-
bool isLandingPad() const { return !Throwers.empty(); }
225+
bool isLandingPad() const { return !Throwers.empty(); }
226226

227227
lp_iterator lp_begin() { return LandingPads.begin(); }
228228
const_lp_iterator lp_begin() const { return LandingPads.begin(); }
@@ -524,9 +524,6 @@ class BinaryBasicBlock {
524524
uint64_t Count = 0,
525525
uint64_t MispredictedCount = 0);
526526

527-
/// Adds block to landing pad list.
528-
void addLandingPad(BinaryBasicBlock *LPBlock);
529-
530527
/// Remove /p Succ basic block from the list of successors. Update the
531528
/// list of predecessors of /p Succ and update branch info.
532529
void removeSuccessor(BinaryBasicBlock *Succ);
@@ -781,9 +778,6 @@ class BinaryBasicBlock {
781778
/// use removeSuccessor() function.
782779
void removePredecessor(BinaryBasicBlock *Pred);
783780

784-
/// Remove landing pads of this basic block.
785-
void clearLandingPads();
786-
787781
/// Return offset of the basic block from the function start.
788782
uint32_t getOffset() const {
789783
return InputRange.first;

bolt/BinaryFunction.cpp

Lines changed: 58 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -330,10 +330,8 @@ std::pair<unsigned, uint64_t> BinaryFunction::eraseInvalidBBs() {
330330
assert(BasicBlocks.size() == BasicBlocksLayout.size());
331331

332332
// Update CFG state if needed
333-
if (Count > 0) {
334-
updateBBIndices(0);
335-
recomputeLandingPads(0, BasicBlocks.size());
336-
}
333+
if (Count > 0)
334+
recomputeLandingPads();
337335

338336
return std::make_pair(Count, Bytes);
339337
}
@@ -1457,54 +1455,39 @@ bool BinaryFunction::postProcessIndirectBranches() {
14571455
return true;
14581456
}
14591457

1460-
void BinaryFunction::clearLandingPads(const unsigned StartIndex,
1461-
const unsigned NumBlocks) {
1462-
// remove all landing pads/throws for the given collection of blocks
1463-
for (auto I = StartIndex; I < StartIndex + NumBlocks; ++I) {
1464-
BasicBlocks[I]->clearLandingPads();
1465-
}
1466-
}
1458+
void BinaryFunction::recomputeLandingPads() {
1459+
updateBBIndices(0);
14671460

1468-
void BinaryFunction::addLandingPads(const unsigned StartIndex,
1469-
const unsigned NumBlocks) {
14701461
for (auto *BB : BasicBlocks) {
1471-
if (LandingPads.find(BB->getLabel()) != LandingPads.end()) {
1472-
const MCSymbol *LP = BB->getLabel();
1473-
for (unsigned I : LPToBBIndex[LP]) {
1474-
assert(I < BasicBlocks.size());
1475-
BinaryBasicBlock *ThrowBB = BasicBlocks[I];
1476-
const unsigned ThrowBBIndex = getIndex(ThrowBB);
1477-
if (ThrowBBIndex >= StartIndex && ThrowBBIndex < StartIndex + NumBlocks)
1478-
ThrowBB->addLandingPad(BB);
1479-
}
1480-
}
1462+
BB->LandingPads.clear();
1463+
BB->Throwers.clear();
14811464
}
14821465

1483-
clearList(LPToBBIndex);
1484-
}
1466+
for (auto *BB : BasicBlocks) {
1467+
for (auto &Instr : *BB) {
1468+
if (!BC.MIA->isInvoke(Instr))
1469+
continue;
14851470

1486-
void BinaryFunction::recomputeLandingPads(const unsigned StartIndex,
1487-
const unsigned NumBlocks) {
1488-
assert(LPToBBIndex.empty());
1489-
1490-
clearLandingPads(StartIndex, NumBlocks);
1491-
1492-
for (auto I = StartIndex; I < StartIndex + NumBlocks; ++I) {
1493-
auto *BB = BasicBlocks[I];
1494-
for (auto &Instr : BB->instructions()) {
1495-
// Store info about associated landing pad.
1496-
if (BC.MIA->isInvoke(Instr)) {
1497-
const MCSymbol *LP;
1498-
uint64_t Action;
1499-
std::tie(LP, Action) = BC.MIA->getEHInfo(Instr);
1500-
if (LP) {
1501-
LPToBBIndex[LP].push_back(getIndex(BB));
1502-
}
1503-
}
1471+
const MCSymbol *LPLabel;
1472+
uint64_t Action;
1473+
std::tie(LPLabel, Action) = BC.MIA->getEHInfo(Instr);
1474+
if (!LPLabel)
1475+
continue;
1476+
1477+
auto *LPBlock = getBasicBlockForLabel(LPLabel);
1478+
BB->LandingPads.emplace_back(LPBlock);
1479+
LPBlock->Throwers.emplace_back(BB);
15041480
}
1481+
std::sort(BB->lp_begin(), BB->lp_end());
1482+
auto NewEnd = std::unique(BB->lp_begin(), BB->lp_end());
1483+
BB->LandingPads.erase(NewEnd, BB->lp_end());
15051484
}
15061485

1507-
addLandingPads(StartIndex, NumBlocks);
1486+
for (auto *BB : BasicBlocks) {
1487+
std::sort(BB->throw_begin(), BB->throw_end());
1488+
auto NewEnd = std::unique(BB->throw_begin(), BB->throw_end());
1489+
BB->Throwers.erase(NewEnd, BB->throw_end());
1490+
}
15081491
}
15091492

15101493
bool BinaryFunction::buildCFG() {
@@ -1608,16 +1591,6 @@ bool BinaryFunction::buildCFG() {
16081591
CFIOffset = getSize();
16091592
addCFIPlaceholders(CFIOffset, InsertBB);
16101593

1611-
// Store info about associated landing pad.
1612-
if (MIA->isInvoke(Instr)) {
1613-
const MCSymbol *LP;
1614-
uint64_t Action;
1615-
std::tie(LP, Action) = MIA->getEHInfo(Instr);
1616-
if (LP) {
1617-
LPToBBIndex[LP].push_back(getIndex(InsertBB));
1618-
}
1619-
}
1620-
16211594
if (MIA->isTerminator(Instr)) {
16221595
PrevBB = InsertBB;
16231596
InsertBB = nullptr;
@@ -1810,8 +1783,7 @@ bool BinaryFunction::buildCFG() {
18101783
DEBUG(dbgs() << "last block was marked as a fall-through\n");
18111784
}
18121785

1813-
// Add associated landing pad blocks to each basic block.
1814-
addLandingPads(0, BasicBlocks.size());
1786+
recomputeLandingPads();
18151787

18161788
// Infer frequency for non-taken branches
18171789
if (hasValidProfile() && opts::DoMCF != MCF_DISABLE) {
@@ -1873,7 +1845,6 @@ bool BinaryFunction::buildCFG() {
18731845
clearList(TakenBranches);
18741846
clearList(FTBranches);
18751847
clearList(IgnoredBranches);
1876-
clearList(LPToBBIndex);
18771848
clearList(EntryOffsets);
18781849

18791850
// Update the state.
@@ -3033,23 +3004,35 @@ bool BinaryFunction::validateCFG() const {
30333004
return Valid;
30343005

30353006
for (auto *BB : BasicBlocks) {
3036-
std::set<BinaryBasicBlock *> Seen;
3007+
if (!std::is_sorted(BB->lp_begin(), BB->lp_end())) {
3008+
errs() << "BOLT-ERROR: unsorted list of landing pads in "
3009+
<< BB->getName() << " in function " << *this << '\n';
3010+
return false;
3011+
}
3012+
if (std::unique(BB->lp_begin(), BB->lp_end()) != BB->lp_end()) {
3013+
errs() << "BOLT-ERROR: duplicate landing pad detected in"
3014+
<< BB->getName() << " in function " << *this << '\n';
3015+
return false;
3016+
}
3017+
if (!std::is_sorted(BB->throw_begin(), BB->throw_end())) {
3018+
errs() << "BOLT-ERROR: unsorted list of throwers in "
3019+
<< BB->getName() << " in function " << *this << '\n';
3020+
return false;
3021+
}
3022+
if (std::unique(BB->throw_begin(), BB->throw_end()) != BB->throw_end()) {
3023+
errs() << "BOLT-ERROR: duplicate thrower detected in"
3024+
<< BB->getName() << " in function " << *this << '\n';
3025+
return false;
3026+
}
30373027
for (auto *LPBlock : BB->LandingPads) {
3038-
Valid &= Seen.count(LPBlock) == 0;
3039-
if (!Valid) {
3040-
errs() << "BOLT-WARNING: Duplicate LP seen " << LPBlock->getName()
3041-
<< "in " << *this << "\n";
3042-
break;
3043-
}
3044-
Seen.insert(LPBlock);
3045-
auto count = LPBlock->Throwers.count(BB);
3046-
Valid &= (count == 1);
3047-
if (!Valid) {
3048-
errs() << "BOLT-WARNING: Inconsistent landing pad detected in "
3049-
<< *this << ": " << LPBlock->getName()
3050-
<< " is in LandingPads but not in " << BB->getName()
3051-
<< "->Throwers\n";
3052-
break;
3028+
if (!std::binary_search(LPBlock->throw_begin(),
3029+
LPBlock->throw_end(),
3030+
BB)) {
3031+
errs() << "BOLT-ERROR: inconsistent landing pad detected in "
3032+
<< *this << ": " << BB->getName()
3033+
<< " is in LandingPads but not in " << LPBlock->getName()
3034+
<< " Throwers\n";
3035+
return false;
30533036
}
30543037
}
30553038
}
@@ -3590,12 +3573,7 @@ void BinaryFunction::insertBasicBlocks(
35903573
BasicBlocks[I++] = BB.release();
35913574
}
35923575

3593-
updateBBIndices(StartIndex);
3594-
3595-
recomputeLandingPads(StartIndex, NumNewBlocks + 1);
3596-
3597-
// Make sure the basic blocks are sorted properly.
3598-
assert(std::is_sorted(begin(), end()));
3576+
recomputeLandingPads();
35993577

36003578
if (UpdateLayout) {
36013579
updateLayout(Start, NumNewBlocks);
@@ -3624,12 +3602,7 @@ BinaryFunction::iterator BinaryFunction::insertBasicBlocks(
36243602
BasicBlocks[I++] = BB.release();
36253603
}
36263604

3627-
updateBBIndices(StartIndex);
3628-
3629-
recomputeLandingPads(StartIndex, NumNewBlocks + 1);
3630-
3631-
// Make sure the basic blocks are sorted properly.
3632-
assert(std::is_sorted(begin(), end()));
3605+
recomputeLandingPads();
36333606

36343607
if (UpdateLayout) {
36353608
updateLayout(*std::prev(RetIter), NumNewBlocks);

bolt/BinaryFunction.h

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -325,9 +325,6 @@ class BinaryFunction {
325325
/// Original LSDA address for the function.
326326
uint64_t LSDAAddress{0};
327327

328-
/// Landing pads for the function.
329-
std::set<const MCSymbol *> LandingPads;
330-
331328
/// Associated DIEs in the .debug_info section with their respective CUs.
332329
/// There can be multiple because of identical code folding.
333330
std::vector<std::pair<const DWARFDebugInfoEntryMinimal *,
@@ -441,19 +438,8 @@ class BinaryFunction {
441438
return InstA.equals(InstB, Comp);
442439
}
443440

444-
/// Clear the landing pads for all blocks contained in the range of
445-
/// [StartIndex, StartIndex + NumBlocks). This also has the effect of
446-
/// removing throws that point to any of these blocks.
447-
void clearLandingPads(const unsigned StartIndex, const unsigned NumBlocks);
448-
449-
/// Add landing pads for all blocks in the range
450-
/// [StartIndex, StartIndex + NumBlocks) using LPToBBIndex.
451-
void addLandingPads(const unsigned StartIndex, const unsigned NumBlocks);
452-
453-
/// Recompute the landing pad information for all the basic blocks in the
454-
/// range of [StartIndex to StartIndex + NumBlocks).
455-
void recomputeLandingPads(const unsigned StartIndex,
456-
const unsigned NumBlocks);
441+
/// Recompute landing pad information for the function and all its blocks.
442+
void recomputeLandingPads();
457443

458444
/// Temporary holder of offsets that are potentially entry points.
459445
std::unordered_set<uint64_t> EntryOffsets;
@@ -466,10 +452,6 @@ class BinaryFunction {
466452
BranchListType FTBranches; /// All fall-through branches.
467453
BranchListType IgnoredBranches; /// Branches ignored by CFG purposes.
468454

469-
/// Storage for all landing pads and their corresponding invokes.
470-
using LandingPadsMapType = std::map<const MCSymbol *, std::vector<unsigned> >;
471-
LandingPadsMapType LPToBBIndex;
472-
473455
/// Map offset in the function to a label.
474456
/// Labels are used for building CFG for simple functions. For non-simple
475457
/// function in relocation mode we need to emit them for relocations

bolt/Exceptions.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,6 @@ void BinaryFunction::parseLSDA(ArrayRef<uint8_t> LSDASectionData,
233233
LPSymbol = BC.Ctx->createTempSymbol("LP", true);
234234
Labels[LandingPad] = LPSymbol;
235235
}
236-
LandingPads.insert(LPSymbol);
237236
}
238237
}
239238

0 commit comments

Comments
 (0)