@@ -63,8 +63,9 @@ class WebAssemblyCFGStackify final : public MachineFunctionPass {
63
63
// over scoped regions when walking blocks.
64
64
SmallVector<MachineBasicBlock *, 8 > ScopeTops;
65
65
void updateScopeTops (MachineBasicBlock *Begin, MachineBasicBlock *End) {
66
+ int BeginNo = Begin->getNumber ();
66
67
int EndNo = End->getNumber ();
67
- if (!ScopeTops[EndNo] || ScopeTops[EndNo]->getNumber () > Begin-> getNumber () )
68
+ if (!ScopeTops[EndNo] || ScopeTops[EndNo]->getNumber () > BeginNo )
68
69
ScopeTops[EndNo] = Begin;
69
70
}
70
71
@@ -77,8 +78,8 @@ class WebAssemblyCFGStackify final : public MachineFunctionPass {
77
78
// Exception handling related functions
78
79
bool fixCallUnwindMismatches (MachineFunction &MF);
79
80
bool fixCatchUnwindMismatches (MachineFunction &MF);
80
- void addTryDelegate (MachineInstr *RangeBegin, MachineInstr *RangeEnd,
81
- MachineBasicBlock *DelegateDest );
81
+ void addNestedTryDelegate (MachineInstr *RangeBegin, MachineInstr *RangeEnd,
82
+ MachineBasicBlock *UnwindDest );
82
83
void recalculateScopeTops (MachineFunction &MF);
83
84
void removeUnnecessaryInstrs (MachineFunction &MF);
84
85
@@ -225,7 +226,7 @@ void WebAssemblyCFGStackify::registerScope(MachineInstr *Begin,
225
226
EndToBegin[End] = Begin;
226
227
}
227
228
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.
229
230
void WebAssemblyCFGStackify::registerTryScope (MachineInstr *Begin,
230
231
MachineInstr *End,
231
232
MachineBasicBlock *EHPad) {
@@ -293,7 +294,7 @@ void WebAssemblyCFGStackify::placeBlockMarker(MachineBasicBlock &MBB) {
293
294
}
294
295
}
295
296
296
- // Decide where in Header to put the BLOCK.
297
+ // Decide where in MBB to put the BLOCK.
297
298
298
299
// Instructions that should go before the BLOCK.
299
300
SmallPtrSet<const MachineInstr *, 4 > BeforeSet;
@@ -359,21 +360,20 @@ void WebAssemblyCFGStackify::placeBlockMarker(MachineBasicBlock &MBB) {
359
360
TII.get (WebAssembly::BLOCK))
360
361
.addImm (int64_t (ReturnType));
361
362
362
- // Decide where in Header to put the END_BLOCK.
363
+ // Decide where in MBB to put the END_BLOCK.
363
364
BeforeSet.clear ();
364
365
AfterSet.clear ();
365
366
for (auto &MI : MBB) {
366
367
#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)
370
370
AfterSet.insert (&MI);
371
371
#endif
372
372
373
373
// If there is a previously placed END_LOOP marker and the header of the
374
374
// 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.
377
377
if (MI.getOpcode () == WebAssembly::END_LOOP ||
378
378
MI.getOpcode () == WebAssembly::END_TRY) {
379
379
if (EndToBegin[&MI]->getParent ()->getNumber () >= Header->getNumber ())
@@ -437,7 +437,7 @@ void WebAssemblyCFGStackify::placeLoopMarker(MachineBasicBlock &MBB) {
437
437
TII.get (WebAssembly::LOOP))
438
438
.addImm (int64_t (WebAssembly::BlockType::Void));
439
439
440
- // Decide where in Header to put the END_LOOP.
440
+ // Decide where in MBB to put the END_LOOP.
441
441
BeforeSet.clear ();
442
442
AfterSet.clear ();
443
443
#ifndef NDEBUG
@@ -491,20 +491,16 @@ void WebAssemblyCFGStackify::placeTryMarker(MachineBasicBlock &MBB) {
491
491
WebAssemblyException *WE = WEI.getExceptionFor (&MBB);
492
492
assert (WE);
493
493
MachineBasicBlock *Bottom = SRI.getBottom (WE);
494
-
495
494
auto Iter = std::next (Bottom->getIterator ());
496
495
if (Iter == MF.end ()) {
497
496
getAppendixBlock (MF);
498
497
Iter = std::next (Bottom->getIterator ());
499
498
}
500
499
MachineBasicBlock *Cont = &*Iter;
501
500
502
- assert (Cont != &MF.front ());
503
- MachineBasicBlock *LayoutPred = Cont->getPrevNode ();
504
-
505
501
// If the nearest common dominator is inside a more deeply nested context,
506
502
// 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) {
508
504
if (MachineBasicBlock *ScopeTop = ScopeTops[I->getNumber ()]) {
509
505
if (ScopeTop->getNumber () > Header->getNumber ()) {
510
506
// Skip over an intervening scope.
@@ -538,7 +534,7 @@ void WebAssemblyCFGStackify::placeTryMarker(MachineBasicBlock &MBB) {
538
534
}
539
535
540
536
// 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.
542
538
if (MI.getOpcode () == WebAssembly::BLOCK ||
543
539
MI.getOpcode () == WebAssembly::TRY)
544
540
AfterSet.insert (&MI);
@@ -607,14 +603,13 @@ void WebAssemblyCFGStackify::placeTryMarker(MachineBasicBlock &MBB) {
607
603
TII.get (WebAssembly::TRY))
608
604
.addImm (int64_t (WebAssembly::BlockType::Void));
609
605
610
- // Decide where in Header to put the END_TRY.
606
+ // Decide where in Cont to put the END_TRY.
611
607
BeforeSet.clear ();
612
608
AfterSet.clear ();
613
609
for (const auto &MI : *Cont) {
614
610
#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)
618
613
AfterSet.insert (&MI);
619
614
620
615
// All END_TRY markers placed earlier belong to exceptions that contains
@@ -643,9 +638,8 @@ void WebAssemblyCFGStackify::placeTryMarker(MachineBasicBlock &MBB) {
643
638
644
639
// Mark the end of the TRY.
645
640
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));
649
643
registerTryScope (Begin, End, &MBB);
650
644
651
645
// Track the farthest-spanning scope that ends at this point. We create two
@@ -845,9 +839,9 @@ static void unstackifyVRegsUsedInSplitBB(MachineBasicBlock &MBB,
845
839
846
840
// Wrap the given range of instruction with try-delegate. RangeBegin and
847
841
// 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 ) {
851
845
auto *BeginBB = RangeBegin->getParent ();
852
846
auto *EndBB = RangeEnd->getParent ();
853
847
MachineFunction &MF = *BeginBB->getParent ();
@@ -879,8 +873,8 @@ void WebAssemblyCFGStackify::addTryDelegate(MachineInstr *RangeBegin,
879
873
MachineBasicBlock *DelegateBB = MF.CreateMachineBasicBlock ();
880
874
// If the destination of 'delegate' is not the caller, adds the destination to
881
875
// the BB's successors.
882
- if (DelegateDest != FakeCallerBB)
883
- DelegateBB->addSuccessor (DelegateDest );
876
+ if (UnwindDest != FakeCallerBB)
877
+ DelegateBB->addSuccessor (UnwindDest );
884
878
885
879
auto SplitPos = std::next (RangeEnd->getIterator ());
886
880
if (SplitPos == EndBB->end ()) {
@@ -962,7 +956,7 @@ void WebAssemblyCFGStackify::addTryDelegate(MachineInstr *RangeBegin,
962
956
// Add 'delegate' instruction in the delegate BB created above.
963
957
MachineInstr *Delegate = BuildMI (DelegateBB, RangeEnd->getDebugLoc (),
964
958
TII.get (WebAssembly::DELEGATE))
965
- .addMBB (DelegateDest );
959
+ .addMBB (UnwindDest );
966
960
registerTryScope (Try, Delegate, nullptr );
967
961
}
968
962
@@ -1130,7 +1124,7 @@ bool WebAssemblyCFGStackify::fixCallUnwindMismatches(MachineFunction &MF) {
1130
1124
if (EHPadStack.back () == UnwindDest)
1131
1125
continue ;
1132
1126
1133
- // Include EH_LABELs in the range before and afer the invoke
1127
+ // Include EH_LABELs in the range before and after the invoke
1134
1128
MachineInstr *RangeBegin = &MI, *RangeEnd = &MI;
1135
1129
if (RangeBegin->getIterator () != MBB.begin () &&
1136
1130
std::prev (RangeBegin->getIterator ())->isEHLabel ())
@@ -1231,22 +1225,24 @@ bool WebAssemblyCFGStackify::fixCallUnwindMismatches(MachineFunction &MF) {
1231
1225
std::tie (RangeBegin, RangeEnd) = Range;
1232
1226
auto *MBB = RangeBegin->getParent ();
1233
1227
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
+ }
1244
1240
}
1241
+ if (EHPad)
1242
+ MBB->removeSuccessor (EHPad);
1245
1243
}
1246
- if (EHPad)
1247
- MBB->removeSuccessor (EHPad);
1248
1244
1249
- addTryDelegate (RangeBegin, RangeEnd, UnwindDest);
1245
+ addNestedTryDelegate (RangeBegin, RangeEnd, UnwindDest);
1250
1246
}
1251
1247
}
1252
1248
@@ -1354,12 +1350,10 @@ bool WebAssemblyCFGStackify::fixCatchUnwindMismatches(MachineFunction &MF) {
1354
1350
NumCatchUnwindMismatches += EHPadToUnwindDest.size ();
1355
1351
SmallPtrSet<MachineBasicBlock *, 4 > NewEndTryBBs;
1356
1352
1357
- for (auto &P : EHPadToUnwindDest) {
1358
- MachineBasicBlock *EHPad = P.first ;
1359
- MachineBasicBlock *UnwindDest = P.second ;
1353
+ for (auto &[EHPad, UnwindDest] : EHPadToUnwindDest) {
1360
1354
MachineInstr *Try = EHPadToTry[EHPad];
1361
1355
MachineInstr *EndTry = BeginToEnd[Try];
1362
- addTryDelegate (Try, EndTry, UnwindDest);
1356
+ addNestedTryDelegate (Try, EndTry, UnwindDest);
1363
1357
NewEndTryBBs.insert (EndTry->getParent ());
1364
1358
}
1365
1359
@@ -1534,7 +1528,7 @@ static void appendEndToFunction(MachineFunction &MF,
1534
1528
TII.get (WebAssembly::END_FUNCTION));
1535
1529
}
1536
1530
1537
- // / Insert LOOP/TRY/BLOCK markers at appropriate places.
1531
+ // / Insert BLOCK/ LOOP/TRY markers at appropriate places.
1538
1532
void WebAssemblyCFGStackify::placeMarkers (MachineFunction &MF) {
1539
1533
// We allocate one more than the number of blocks in the function to
1540
1534
// accommodate for the possible fake block we may insert at the end.
@@ -1558,9 +1552,9 @@ void WebAssemblyCFGStackify::placeMarkers(MachineFunction &MF) {
1558
1552
// Fix mismatches in unwind destinations induced by linearizing the code.
1559
1553
if (MCAI->getExceptionHandlingType () == ExceptionHandling::Wasm &&
1560
1554
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 )
1564
1558
recalculateScopeTops (MF);
1565
1559
}
1566
1560
}
@@ -1654,6 +1648,23 @@ void WebAssemblyCFGStackify::rewriteDepthImmediates(MachineFunction &MF) {
1654
1648
// Now rewrite references to basic blocks to be depth immediates.
1655
1649
SmallVector<EndMarkerInfo, 8 > Stack;
1656
1650
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
+
1657
1668
for (auto &MBB : reverse (MF)) {
1658
1669
for (MachineInstr &MI : llvm::reverse (MBB)) {
1659
1670
switch (MI.getOpcode ()) {
@@ -1697,23 +1708,8 @@ void WebAssemblyCFGStackify::rewriteDepthImmediates(MachineFunction &MF) {
1697
1708
break ;
1698
1709
1699
1710
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);
1717
1713
1718
1714
if (MI.getOpcode () == WebAssembly::DELEGATE)
1719
1715
Stack.push_back (std::make_pair (&MBB, &MI));
@@ -1767,10 +1763,7 @@ bool WebAssemblyCFGStackify::runOnMachineFunction(MachineFunction &MF) {
1767
1763
1768
1764
// Add an end instruction at the end of the function body.
1769
1765
const auto &TII = *MF.getSubtarget <WebAssemblySubtarget>().getInstrInfo ();
1770
- if (!MF.getSubtarget <WebAssemblySubtarget>()
1771
- .getTargetTriple ()
1772
- .isOSBinFormatELF ())
1773
- appendEndToFunction (MF, TII);
1766
+ appendEndToFunction (MF, TII);
1774
1767
1775
1768
cleanupFunctionData (MF);
1776
1769
0 commit comments