@@ -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.
229230void 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.
15381532void 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