Skip to content

Commit 32bc670

Browse files
authored
[WebAssembly] Misc. fixes in CFGStackify (NFC) (#107182)
This contains misc. small fixes in CFGStackify. Most of them are comment fixes and variable name changes. Two code changes are removing the cases that can never occur. Another is extracting a routine as a lambda function. I will add explanations inline in the code as Github comments.
1 parent b2223b4 commit 32bc670

File tree

1 file changed

+67
-74
lines changed

1 file changed

+67
-74
lines changed

llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp

Lines changed: 67 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,9 @@ class WebAssemblyCFGStackify final : public MachineFunctionPass {
6363
// over scoped regions when walking blocks.
6464
SmallVector<MachineBasicBlock *, 8> ScopeTops;
6565
void updateScopeTops(MachineBasicBlock *Begin, MachineBasicBlock *End) {
66+
int BeginNo = Begin->getNumber();
6667
int EndNo = End->getNumber();
67-
if (!ScopeTops[EndNo] || ScopeTops[EndNo]->getNumber() > Begin->getNumber())
68+
if (!ScopeTops[EndNo] || ScopeTops[EndNo]->getNumber() > BeginNo)
6869
ScopeTops[EndNo] = Begin;
6970
}
7071

@@ -77,8 +78,8 @@ class WebAssemblyCFGStackify final : public MachineFunctionPass {
7778
// Exception handling related functions
7879
bool fixCallUnwindMismatches(MachineFunction &MF);
7980
bool fixCatchUnwindMismatches(MachineFunction &MF);
80-
void addTryDelegate(MachineInstr *RangeBegin, MachineInstr *RangeEnd,
81-
MachineBasicBlock *DelegateDest);
81+
void addNestedTryDelegate(MachineInstr *RangeBegin, MachineInstr *RangeEnd,
82+
MachineBasicBlock *UnwindDest);
8283
void recalculateScopeTops(MachineFunction &MF);
8384
void removeUnnecessaryInstrs(MachineFunction &MF);
8485

@@ -225,7 +226,7 @@ void WebAssemblyCFGStackify::registerScope(MachineInstr *Begin,
225226
EndToBegin[End] = Begin;
226227
}
227228

228-
// When 'End' is not an 'end_try' but 'delegate, EHPad is nullptr.
229+
// When 'End' is not an 'end_try' but a 'delegate', EHPad is nullptr.
229230
void WebAssemblyCFGStackify::registerTryScope(MachineInstr *Begin,
230231
MachineInstr *End,
231232
MachineBasicBlock *EHPad) {
@@ -293,7 +294,7 @@ void WebAssemblyCFGStackify::placeBlockMarker(MachineBasicBlock &MBB) {
293294
}
294295
}
295296

296-
// Decide where in Header to put the BLOCK.
297+
// Decide where in MBB to put the BLOCK.
297298

298299
// Instructions that should go before the BLOCK.
299300
SmallPtrSet<const MachineInstr *, 4> BeforeSet;
@@ -359,21 +360,20 @@ void WebAssemblyCFGStackify::placeBlockMarker(MachineBasicBlock &MBB) {
359360
TII.get(WebAssembly::BLOCK))
360361
.addImm(int64_t(ReturnType));
361362

362-
// Decide where in Header to put the END_BLOCK.
363+
// Decide where in MBB to put the END_BLOCK.
363364
BeforeSet.clear();
364365
AfterSet.clear();
365366
for (auto &MI : MBB) {
366367
#ifndef NDEBUG
367-
// END_BLOCK should precede existing LOOP and TRY markers.
368-
if (MI.getOpcode() == WebAssembly::LOOP ||
369-
MI.getOpcode() == WebAssembly::TRY)
368+
// END_BLOCK should precede existing LOOP markers.
369+
if (MI.getOpcode() == WebAssembly::LOOP)
370370
AfterSet.insert(&MI);
371371
#endif
372372

373373
// If there is a previously placed END_LOOP marker and the header of the
374374
// loop is above this block's header, the END_LOOP should be placed after
375-
// the BLOCK, because the loop contains this block. Otherwise the END_LOOP
376-
// should be placed before the BLOCK. The same for END_TRY.
375+
// the END_BLOCK, because the loop contains this block. Otherwise the
376+
// END_LOOP should be placed before the END_BLOCK. The same for END_TRY.
377377
if (MI.getOpcode() == WebAssembly::END_LOOP ||
378378
MI.getOpcode() == WebAssembly::END_TRY) {
379379
if (EndToBegin[&MI]->getParent()->getNumber() >= Header->getNumber())
@@ -437,7 +437,7 @@ void WebAssemblyCFGStackify::placeLoopMarker(MachineBasicBlock &MBB) {
437437
TII.get(WebAssembly::LOOP))
438438
.addImm(int64_t(WebAssembly::BlockType::Void));
439439

440-
// Decide where in Header to put the END_LOOP.
440+
// Decide where in MBB to put the END_LOOP.
441441
BeforeSet.clear();
442442
AfterSet.clear();
443443
#ifndef NDEBUG
@@ -491,20 +491,16 @@ void WebAssemblyCFGStackify::placeTryMarker(MachineBasicBlock &MBB) {
491491
WebAssemblyException *WE = WEI.getExceptionFor(&MBB);
492492
assert(WE);
493493
MachineBasicBlock *Bottom = SRI.getBottom(WE);
494-
495494
auto Iter = std::next(Bottom->getIterator());
496495
if (Iter == MF.end()) {
497496
getAppendixBlock(MF);
498497
Iter = std::next(Bottom->getIterator());
499498
}
500499
MachineBasicBlock *Cont = &*Iter;
501500

502-
assert(Cont != &MF.front());
503-
MachineBasicBlock *LayoutPred = Cont->getPrevNode();
504-
505501
// If the nearest common dominator is inside a more deeply nested context,
506502
// walk out to the nearest scope which isn't more deeply nested.
507-
for (MachineFunction::iterator I(LayoutPred), E(Header); I != E; --I) {
503+
for (MachineFunction::iterator I(Bottom), E(Header); I != E; --I) {
508504
if (MachineBasicBlock *ScopeTop = ScopeTops[I->getNumber()]) {
509505
if (ScopeTop->getNumber() > Header->getNumber()) {
510506
// Skip over an intervening scope.
@@ -538,7 +534,7 @@ void WebAssemblyCFGStackify::placeTryMarker(MachineBasicBlock &MBB) {
538534
}
539535

540536
// All previously inserted BLOCK/TRY markers should be after the TRY because
541-
// they are all nested trys.
537+
// they are all nested blocks/trys.
542538
if (MI.getOpcode() == WebAssembly::BLOCK ||
543539
MI.getOpcode() == WebAssembly::TRY)
544540
AfterSet.insert(&MI);
@@ -607,14 +603,13 @@ void WebAssemblyCFGStackify::placeTryMarker(MachineBasicBlock &MBB) {
607603
TII.get(WebAssembly::TRY))
608604
.addImm(int64_t(WebAssembly::BlockType::Void));
609605

610-
// Decide where in Header to put the END_TRY.
606+
// Decide where in Cont to put the END_TRY.
611607
BeforeSet.clear();
612608
AfterSet.clear();
613609
for (const auto &MI : *Cont) {
614610
#ifndef NDEBUG
615-
// END_TRY should precede existing LOOP and BLOCK markers.
616-
if (MI.getOpcode() == WebAssembly::LOOP ||
617-
MI.getOpcode() == WebAssembly::BLOCK)
611+
// END_TRY should precede existing LOOP markers.
612+
if (MI.getOpcode() == WebAssembly::LOOP)
618613
AfterSet.insert(&MI);
619614

620615
// All END_TRY markers placed earlier belong to exceptions that contains
@@ -643,9 +638,8 @@ void WebAssemblyCFGStackify::placeTryMarker(MachineBasicBlock &MBB) {
643638

644639
// Mark the end of the TRY.
645640
InsertPos = getEarliestInsertPos(Cont, BeforeSet, AfterSet);
646-
MachineInstr *End =
647-
BuildMI(*Cont, InsertPos, Bottom->findBranchDebugLoc(),
648-
TII.get(WebAssembly::END_TRY));
641+
MachineInstr *End = BuildMI(*Cont, InsertPos, Bottom->findBranchDebugLoc(),
642+
TII.get(WebAssembly::END_TRY));
649643
registerTryScope(Begin, End, &MBB);
650644

651645
// Track the farthest-spanning scope that ends at this point. We create two
@@ -845,9 +839,9 @@ static void unstackifyVRegsUsedInSplitBB(MachineBasicBlock &MBB,
845839

846840
// Wrap the given range of instruction with try-delegate. RangeBegin and
847841
// RangeEnd are inclusive.
848-
void WebAssemblyCFGStackify::addTryDelegate(MachineInstr *RangeBegin,
849-
MachineInstr *RangeEnd,
850-
MachineBasicBlock *DelegateDest) {
842+
void WebAssemblyCFGStackify::addNestedTryDelegate(
843+
MachineInstr *RangeBegin, MachineInstr *RangeEnd,
844+
MachineBasicBlock *UnwindDest) {
851845
auto *BeginBB = RangeBegin->getParent();
852846
auto *EndBB = RangeEnd->getParent();
853847
MachineFunction &MF = *BeginBB->getParent();
@@ -879,8 +873,8 @@ void WebAssemblyCFGStackify::addTryDelegate(MachineInstr *RangeBegin,
879873
MachineBasicBlock *DelegateBB = MF.CreateMachineBasicBlock();
880874
// If the destination of 'delegate' is not the caller, adds the destination to
881875
// the BB's successors.
882-
if (DelegateDest != FakeCallerBB)
883-
DelegateBB->addSuccessor(DelegateDest);
876+
if (UnwindDest != FakeCallerBB)
877+
DelegateBB->addSuccessor(UnwindDest);
884878

885879
auto SplitPos = std::next(RangeEnd->getIterator());
886880
if (SplitPos == EndBB->end()) {
@@ -962,7 +956,7 @@ void WebAssemblyCFGStackify::addTryDelegate(MachineInstr *RangeBegin,
962956
// Add 'delegate' instruction in the delegate BB created above.
963957
MachineInstr *Delegate = BuildMI(DelegateBB, RangeEnd->getDebugLoc(),
964958
TII.get(WebAssembly::DELEGATE))
965-
.addMBB(DelegateDest);
959+
.addMBB(UnwindDest);
966960
registerTryScope(Try, Delegate, nullptr);
967961
}
968962

@@ -1130,7 +1124,7 @@ bool WebAssemblyCFGStackify::fixCallUnwindMismatches(MachineFunction &MF) {
11301124
if (EHPadStack.back() == UnwindDest)
11311125
continue;
11321126

1133-
// Include EH_LABELs in the range before and afer the invoke
1127+
// Include EH_LABELs in the range before and after the invoke
11341128
MachineInstr *RangeBegin = &MI, *RangeEnd = &MI;
11351129
if (RangeBegin->getIterator() != MBB.begin() &&
11361130
std::prev(RangeBegin->getIterator())->isEHLabel())
@@ -1231,22 +1225,24 @@ bool WebAssemblyCFGStackify::fixCallUnwindMismatches(MachineFunction &MF) {
12311225
std::tie(RangeBegin, RangeEnd) = Range;
12321226
auto *MBB = RangeBegin->getParent();
12331227

1234-
// If this BB has an EH pad successor, i.e., ends with an 'invoke', now we
1235-
// are going to wrap the invoke with try-delegate, making the 'delegate'
1236-
// BB the new successor instead, so remove the EH pad succesor here. The
1237-
// BB may not have an EH pad successor if calls in this BB throw to the
1238-
// caller.
1239-
MachineBasicBlock *EHPad = nullptr;
1240-
for (auto *Succ : MBB->successors()) {
1241-
if (Succ->isEHPad()) {
1242-
EHPad = Succ;
1243-
break;
1228+
// If this BB has an EH pad successor, i.e., ends with an 'invoke', and if
1229+
// the current range contains the invoke, now we are going to wrap the
1230+
// invoke with try-delegate, making the 'delegate' BB the new successor
1231+
// instead, so remove the EH pad succesor here. The BB may not have an EH
1232+
// pad successor if calls in this BB throw to the caller.
1233+
if (UnwindDest != getFakeCallerBlock(MF)) {
1234+
MachineBasicBlock *EHPad = nullptr;
1235+
for (auto *Succ : MBB->successors()) {
1236+
if (Succ->isEHPad()) {
1237+
EHPad = Succ;
1238+
break;
1239+
}
12441240
}
1241+
if (EHPad)
1242+
MBB->removeSuccessor(EHPad);
12451243
}
1246-
if (EHPad)
1247-
MBB->removeSuccessor(EHPad);
12481244

1249-
addTryDelegate(RangeBegin, RangeEnd, UnwindDest);
1245+
addNestedTryDelegate(RangeBegin, RangeEnd, UnwindDest);
12501246
}
12511247
}
12521248

@@ -1354,12 +1350,10 @@ bool WebAssemblyCFGStackify::fixCatchUnwindMismatches(MachineFunction &MF) {
13541350
NumCatchUnwindMismatches += EHPadToUnwindDest.size();
13551351
SmallPtrSet<MachineBasicBlock *, 4> NewEndTryBBs;
13561352

1357-
for (auto &P : EHPadToUnwindDest) {
1358-
MachineBasicBlock *EHPad = P.first;
1359-
MachineBasicBlock *UnwindDest = P.second;
1353+
for (auto &[EHPad, UnwindDest] : EHPadToUnwindDest) {
13601354
MachineInstr *Try = EHPadToTry[EHPad];
13611355
MachineInstr *EndTry = BeginToEnd[Try];
1362-
addTryDelegate(Try, EndTry, UnwindDest);
1356+
addNestedTryDelegate(Try, EndTry, UnwindDest);
13631357
NewEndTryBBs.insert(EndTry->getParent());
13641358
}
13651359

@@ -1534,7 +1528,7 @@ static void appendEndToFunction(MachineFunction &MF,
15341528
TII.get(WebAssembly::END_FUNCTION));
15351529
}
15361530

1537-
/// Insert LOOP/TRY/BLOCK markers at appropriate places.
1531+
/// Insert BLOCK/LOOP/TRY markers at appropriate places.
15381532
void WebAssemblyCFGStackify::placeMarkers(MachineFunction &MF) {
15391533
// We allocate one more than the number of blocks in the function to
15401534
// accommodate for the possible fake block we may insert at the end.
@@ -1558,9 +1552,9 @@ void WebAssemblyCFGStackify::placeMarkers(MachineFunction &MF) {
15581552
// Fix mismatches in unwind destinations induced by linearizing the code.
15591553
if (MCAI->getExceptionHandlingType() == ExceptionHandling::Wasm &&
15601554
MF.getFunction().hasPersonalityFn()) {
1561-
bool Changed = fixCallUnwindMismatches(MF);
1562-
Changed |= fixCatchUnwindMismatches(MF);
1563-
if (Changed)
1555+
bool MismatchFixed = fixCallUnwindMismatches(MF);
1556+
MismatchFixed |= fixCatchUnwindMismatches(MF);
1557+
if (MismatchFixed)
15641558
recalculateScopeTops(MF);
15651559
}
15661560
}
@@ -1654,6 +1648,23 @@ void WebAssemblyCFGStackify::rewriteDepthImmediates(MachineFunction &MF) {
16541648
// Now rewrite references to basic blocks to be depth immediates.
16551649
SmallVector<EndMarkerInfo, 8> Stack;
16561650
SmallVector<const MachineBasicBlock *, 8> EHPadStack;
1651+
1652+
auto RewriteOperands = [&](MachineInstr &MI) {
1653+
// Rewrite MBB operands to be depth immediates.
1654+
SmallVector<MachineOperand, 4> Ops(MI.operands());
1655+
while (MI.getNumOperands() > 0)
1656+
MI.removeOperand(MI.getNumOperands() - 1);
1657+
for (auto MO : Ops) {
1658+
if (MO.isMBB()) {
1659+
if (MI.getOpcode() == WebAssembly::DELEGATE)
1660+
MO = MachineOperand::CreateImm(getDelegateDepth(Stack, MO.getMBB()));
1661+
else
1662+
MO = MachineOperand::CreateImm(getBranchDepth(Stack, MO.getMBB()));
1663+
}
1664+
MI.addOperand(MF, MO);
1665+
}
1666+
};
1667+
16571668
for (auto &MBB : reverse(MF)) {
16581669
for (MachineInstr &MI : llvm::reverse(MBB)) {
16591670
switch (MI.getOpcode()) {
@@ -1697,23 +1708,8 @@ void WebAssemblyCFGStackify::rewriteDepthImmediates(MachineFunction &MF) {
16971708
break;
16981709

16991710
default:
1700-
if (MI.isTerminator()) {
1701-
// Rewrite MBB operands to be depth immediates.
1702-
SmallVector<MachineOperand, 4> Ops(MI.operands());
1703-
while (MI.getNumOperands() > 0)
1704-
MI.removeOperand(MI.getNumOperands() - 1);
1705-
for (auto MO : Ops) {
1706-
if (MO.isMBB()) {
1707-
if (MI.getOpcode() == WebAssembly::DELEGATE)
1708-
MO = MachineOperand::CreateImm(
1709-
getDelegateDepth(Stack, MO.getMBB()));
1710-
else
1711-
MO = MachineOperand::CreateImm(
1712-
getBranchDepth(Stack, MO.getMBB()));
1713-
}
1714-
MI.addOperand(MF, MO);
1715-
}
1716-
}
1711+
if (MI.isTerminator())
1712+
RewriteOperands(MI);
17171713

17181714
if (MI.getOpcode() == WebAssembly::DELEGATE)
17191715
Stack.push_back(std::make_pair(&MBB, &MI));
@@ -1767,10 +1763,7 @@ bool WebAssemblyCFGStackify::runOnMachineFunction(MachineFunction &MF) {
17671763

17681764
// Add an end instruction at the end of the function body.
17691765
const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
1770-
if (!MF.getSubtarget<WebAssemblySubtarget>()
1771-
.getTargetTriple()
1772-
.isOSBinFormatELF())
1773-
appendEndToFunction(MF, TII);
1766+
appendEndToFunction(MF, TII);
17741767

17751768
cleanupFunctionData(MF);
17761769

0 commit comments

Comments
 (0)