xref: /llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp (revision 380fd09d982eb199e3c79834fc0f6dc92eb90239)
1 //===-- WebAssemblyCFGStackify.cpp - CFG Stackification -------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// This file implements a CFG stacking pass.
11 ///
12 /// This pass inserts BLOCK, LOOP, TRY, and TRY_TABLE markers to mark the start
13 /// of scopes, since scope boundaries serve as the labels for WebAssembly's
14 /// control transfers.
15 ///
16 /// This is sufficient to convert arbitrary CFGs into a form that works on
17 /// WebAssembly, provided that all loops are single-entry.
18 ///
19 /// In case we use exceptions, this pass also fixes mismatches in unwind
20 /// destinations created during transforming CFG into wasm structured format.
21 ///
22 //===----------------------------------------------------------------------===//
23 
24 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
25 #include "Utils/WebAssemblyTypeUtilities.h"
26 #include "WebAssembly.h"
27 #include "WebAssemblyExceptionInfo.h"
28 #include "WebAssemblyMachineFunctionInfo.h"
29 #include "WebAssemblySortRegion.h"
30 #include "WebAssemblySubtarget.h"
31 #include "WebAssemblyUtilities.h"
32 #include "llvm/ADT/Statistic.h"
33 #include "llvm/BinaryFormat/Wasm.h"
34 #include "llvm/CodeGen/MachineDominators.h"
35 #include "llvm/CodeGen/MachineInstrBuilder.h"
36 #include "llvm/CodeGen/MachineLoopInfo.h"
37 #include "llvm/CodeGen/WasmEHFuncInfo.h"
38 #include "llvm/MC/MCAsmInfo.h"
39 #include "llvm/Target/TargetMachine.h"
40 using namespace llvm;
41 using WebAssembly::SortRegionInfo;
42 
43 #define DEBUG_TYPE "wasm-cfg-stackify"
44 
45 STATISTIC(NumCallUnwindMismatches, "Number of call unwind mismatches found");
46 STATISTIC(NumCatchUnwindMismatches, "Number of catch unwind mismatches found");
47 
48 namespace {
49 class WebAssemblyCFGStackify final : public MachineFunctionPass {
50   MachineDominatorTree *MDT;
51 
52   StringRef getPassName() const override { return "WebAssembly CFG Stackify"; }
53 
54   void getAnalysisUsage(AnalysisUsage &AU) const override {
55     AU.addRequired<MachineDominatorTreeWrapperPass>();
56     AU.addRequired<MachineLoopInfoWrapperPass>();
57     AU.addRequired<WebAssemblyExceptionInfo>();
58     MachineFunctionPass::getAnalysisUsage(AU);
59   }
60 
61   bool runOnMachineFunction(MachineFunction &MF) override;
62 
63   // For each block whose label represents the end of a scope, record the block
64   // which holds the beginning of the scope. This will allow us to quickly skip
65   // over scoped regions when walking blocks.
66   SmallVector<MachineBasicBlock *, 8> ScopeTops;
67   void updateScopeTops(MachineBasicBlock *Begin, MachineBasicBlock *End) {
68     int BeginNo = Begin->getNumber();
69     int EndNo = End->getNumber();
70     if (!ScopeTops[EndNo] || ScopeTops[EndNo]->getNumber() > BeginNo)
71       ScopeTops[EndNo] = Begin;
72   }
73 
74   // Placing markers.
75   void placeMarkers(MachineFunction &MF);
76   void placeBlockMarker(MachineBasicBlock &MBB);
77   void placeLoopMarker(MachineBasicBlock &MBB);
78   void placeTryMarker(MachineBasicBlock &MBB);
79   void placeTryTableMarker(MachineBasicBlock &MBB);
80 
81   // Unwind mismatch fixing for exception handling
82   // - Common functions
83   bool fixCallUnwindMismatches(MachineFunction &MF);
84   bool fixCatchUnwindMismatches(MachineFunction &MF);
85   void recalculateScopeTops(MachineFunction &MF);
86   // - Legacy EH
87   void addNestedTryDelegate(MachineInstr *RangeBegin, MachineInstr *RangeEnd,
88                             MachineBasicBlock *UnwindDest);
89   void removeUnnecessaryInstrs(MachineFunction &MF);
90   // - Standard EH (exnref)
91   void addNestedTryTable(MachineInstr *RangeBegin, MachineInstr *RangeEnd,
92                          MachineBasicBlock *UnwindDest);
93   MachineBasicBlock *getTrampolineBlock(MachineBasicBlock *UnwindDest);
94 
95   // Wrap-up
96   using EndMarkerInfo =
97       std::pair<const MachineBasicBlock *, const MachineInstr *>;
98   unsigned getBranchDepth(const SmallVectorImpl<EndMarkerInfo> &Stack,
99                           const MachineBasicBlock *MBB);
100   unsigned getDelegateDepth(const SmallVectorImpl<EndMarkerInfo> &Stack,
101                             const MachineBasicBlock *MBB);
102   unsigned
103   getRethrowDepth(const SmallVectorImpl<EndMarkerInfo> &Stack,
104                   const SmallVectorImpl<const MachineBasicBlock *> &EHPadStack);
105   void rewriteDepthImmediates(MachineFunction &MF);
106   void fixEndsAtEndOfFunction(MachineFunction &MF);
107   void cleanupFunctionData(MachineFunction &MF);
108 
109   // For each BLOCK|LOOP|TRY|TRY_TABLE, the corresponding
110   // END_(BLOCK|LOOP|TRY|TRY_TABLE) or DELEGATE (in case of TRY).
111   DenseMap<const MachineInstr *, MachineInstr *> BeginToEnd;
112   // For each END_(BLOCK|LOOP|TRY|TRY_TABLE) or DELEGATE, the corresponding
113   // BLOCK|LOOP|TRY|TRY_TABLE.
114   DenseMap<const MachineInstr *, MachineInstr *> EndToBegin;
115   // <TRY marker, EH pad> map
116   DenseMap<const MachineInstr *, MachineBasicBlock *> TryToEHPad;
117   // <EH pad, TRY marker> map
118   DenseMap<const MachineBasicBlock *, MachineInstr *> EHPadToTry;
119 
120   DenseMap<const MachineBasicBlock *, MachineBasicBlock *>
121       UnwindDestToTrampoline;
122 
123   // We need an appendix block to place 'end_loop' or 'end_try' marker when the
124   // loop / exception bottom block is the last block in a function
125   MachineBasicBlock *AppendixBB = nullptr;
126   MachineBasicBlock *getAppendixBlock(MachineFunction &MF) {
127     if (!AppendixBB) {
128       AppendixBB = MF.CreateMachineBasicBlock();
129       // Give it a fake predecessor so that AsmPrinter prints its label.
130       AppendixBB->addSuccessor(AppendixBB);
131       // If the caller trampoline BB exists, insert the appendix BB before it.
132       // Otherwise insert it at the end of the function.
133       if (CallerTrampolineBB)
134         MF.insert(CallerTrampolineBB->getIterator(), AppendixBB);
135       else
136         MF.push_back(AppendixBB);
137     }
138     return AppendixBB;
139   }
140 
141   // Create a caller-dedicated trampoline BB to be used for fixing unwind
142   // mismatches where the unwind destination is the caller.
143   MachineBasicBlock *CallerTrampolineBB = nullptr;
144   MachineBasicBlock *getCallerTrampolineBlock(MachineFunction &MF) {
145     if (!CallerTrampolineBB) {
146       CallerTrampolineBB = MF.CreateMachineBasicBlock();
147       MF.push_back(CallerTrampolineBB);
148     }
149     return CallerTrampolineBB;
150   }
151 
152   // Before running rewriteDepthImmediates function, 'delegate' has a BB as its
153   // destination operand. getFakeCallerBlock() returns a fake BB that will be
154   // used for the operand when 'delegate' needs to rethrow to the caller. This
155   // will be rewritten as an immediate value that is the number of block depths
156   // + 1 in rewriteDepthImmediates, and this fake BB will be removed at the end
157   // of the pass.
158   MachineBasicBlock *FakeCallerBB = nullptr;
159   MachineBasicBlock *getFakeCallerBlock(MachineFunction &MF) {
160     if (!FakeCallerBB)
161       FakeCallerBB = MF.CreateMachineBasicBlock();
162     return FakeCallerBB;
163   }
164 
165   // Helper functions to register / unregister scope information created by
166   // marker instructions.
167   void registerScope(MachineInstr *Begin, MachineInstr *End);
168   void registerTryScope(MachineInstr *Begin, MachineInstr *End,
169                         MachineBasicBlock *EHPad);
170   void unregisterScope(MachineInstr *Begin);
171 
172 public:
173   static char ID; // Pass identification, replacement for typeid
174   WebAssemblyCFGStackify() : MachineFunctionPass(ID) {}
175   ~WebAssemblyCFGStackify() override { releaseMemory(); }
176   void releaseMemory() override;
177 };
178 } // end anonymous namespace
179 
180 char WebAssemblyCFGStackify::ID = 0;
181 INITIALIZE_PASS(
182     WebAssemblyCFGStackify, DEBUG_TYPE,
183     "Insert BLOCK/LOOP/TRY/TRY_TABLE markers for WebAssembly scopes", false,
184     false)
185 
186 FunctionPass *llvm::createWebAssemblyCFGStackify() {
187   return new WebAssemblyCFGStackify();
188 }
189 
190 /// Test whether Pred has any terminators explicitly branching to MBB, as
191 /// opposed to falling through. Note that it's possible (eg. in unoptimized
192 /// code) for a branch instruction to both branch to a block and fallthrough
193 /// to it, so we check the actual branch operands to see if there are any
194 /// explicit mentions.
195 static bool explicitlyBranchesTo(MachineBasicBlock *Pred,
196                                  MachineBasicBlock *MBB) {
197   for (MachineInstr &MI : Pred->terminators())
198     for (MachineOperand &MO : MI.explicit_operands())
199       if (MO.isMBB() && MO.getMBB() == MBB)
200         return true;
201   return false;
202 }
203 
204 // Returns an iterator to the earliest position possible within the MBB,
205 // satisfying the restrictions given by BeforeSet and AfterSet. BeforeSet
206 // contains instructions that should go before the marker, and AfterSet contains
207 // ones that should go after the marker. In this function, AfterSet is only
208 // used for validation checking.
209 template <typename Container>
210 static MachineBasicBlock::iterator
211 getEarliestInsertPos(MachineBasicBlock *MBB, const Container &BeforeSet,
212                      const Container &AfterSet) {
213   auto InsertPos = MBB->end();
214   while (InsertPos != MBB->begin()) {
215     if (BeforeSet.count(&*std::prev(InsertPos))) {
216 #ifndef NDEBUG
217       // Validation check
218       for (auto Pos = InsertPos, E = MBB->begin(); Pos != E; --Pos)
219         assert(!AfterSet.count(&*std::prev(Pos)));
220 #endif
221       break;
222     }
223     --InsertPos;
224   }
225   return InsertPos;
226 }
227 
228 // Returns an iterator to the latest position possible within the MBB,
229 // satisfying the restrictions given by BeforeSet and AfterSet. BeforeSet
230 // contains instructions that should go before the marker, and AfterSet contains
231 // ones that should go after the marker. In this function, BeforeSet is only
232 // used for validation checking.
233 template <typename Container>
234 static MachineBasicBlock::iterator
235 getLatestInsertPos(MachineBasicBlock *MBB, const Container &BeforeSet,
236                    const Container &AfterSet) {
237   auto InsertPos = MBB->begin();
238   while (InsertPos != MBB->end()) {
239     if (AfterSet.count(&*InsertPos)) {
240 #ifndef NDEBUG
241       // Validation check
242       for (auto Pos = InsertPos, E = MBB->end(); Pos != E; ++Pos)
243         assert(!BeforeSet.count(&*Pos));
244 #endif
245       break;
246     }
247     ++InsertPos;
248   }
249   return InsertPos;
250 }
251 
252 void WebAssemblyCFGStackify::registerScope(MachineInstr *Begin,
253                                            MachineInstr *End) {
254   BeginToEnd[Begin] = End;
255   EndToBegin[End] = Begin;
256 }
257 
258 // When 'End' is not an 'end_try' but a 'delegate', EHPad is nullptr.
259 void WebAssemblyCFGStackify::registerTryScope(MachineInstr *Begin,
260                                               MachineInstr *End,
261                                               MachineBasicBlock *EHPad) {
262   registerScope(Begin, End);
263   TryToEHPad[Begin] = EHPad;
264   EHPadToTry[EHPad] = Begin;
265 }
266 
267 void WebAssemblyCFGStackify::unregisterScope(MachineInstr *Begin) {
268   assert(BeginToEnd.count(Begin));
269   MachineInstr *End = BeginToEnd[Begin];
270   assert(EndToBegin.count(End));
271   BeginToEnd.erase(Begin);
272   EndToBegin.erase(End);
273   MachineBasicBlock *EHPad = TryToEHPad.lookup(Begin);
274   if (EHPad) {
275     assert(EHPadToTry.count(EHPad));
276     TryToEHPad.erase(Begin);
277     EHPadToTry.erase(EHPad);
278   }
279 }
280 
281 /// Insert a BLOCK marker for branches to MBB (if needed).
282 // TODO Consider a more generalized way of handling block (and also loop and
283 // try) signatures when we implement the multi-value proposal later.
284 void WebAssemblyCFGStackify::placeBlockMarker(MachineBasicBlock &MBB) {
285   assert(!MBB.isEHPad());
286   MachineFunction &MF = *MBB.getParent();
287   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
288   const auto &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
289 
290   // First compute the nearest common dominator of all forward non-fallthrough
291   // predecessors so that we minimize the time that the BLOCK is on the stack,
292   // which reduces overall stack height.
293   MachineBasicBlock *Header = nullptr;
294   bool IsBranchedTo = false;
295   int MBBNumber = MBB.getNumber();
296   for (MachineBasicBlock *Pred : MBB.predecessors()) {
297     if (Pred->getNumber() < MBBNumber) {
298       Header = Header ? MDT->findNearestCommonDominator(Header, Pred) : Pred;
299       if (explicitlyBranchesTo(Pred, &MBB))
300         IsBranchedTo = true;
301     }
302   }
303   if (!Header)
304     return;
305   if (!IsBranchedTo)
306     return;
307 
308   assert(&MBB != &MF.front() && "Header blocks shouldn't have predecessors");
309   MachineBasicBlock *LayoutPred = MBB.getPrevNode();
310 
311   // If the nearest common dominator is inside a more deeply nested context,
312   // walk out to the nearest scope which isn't more deeply nested.
313   for (MachineFunction::iterator I(LayoutPred), E(Header); I != E; --I) {
314     if (MachineBasicBlock *ScopeTop = ScopeTops[I->getNumber()]) {
315       if (ScopeTop->getNumber() > Header->getNumber()) {
316         // Skip over an intervening scope.
317         I = std::next(ScopeTop->getIterator());
318       } else {
319         // We found a scope level at an appropriate depth.
320         Header = ScopeTop;
321         break;
322       }
323     }
324   }
325 
326   // Decide where in MBB to put the BLOCK.
327 
328   // Instructions that should go before the BLOCK.
329   SmallPtrSet<const MachineInstr *, 4> BeforeSet;
330   // Instructions that should go after the BLOCK.
331   SmallPtrSet<const MachineInstr *, 4> AfterSet;
332   for (const auto &MI : *Header) {
333     // If there is a previously placed LOOP marker and the bottom block of the
334     // loop is above MBB, it should be after the BLOCK, because the loop is
335     // nested in this BLOCK. Otherwise it should be before the BLOCK.
336     if (MI.getOpcode() == WebAssembly::LOOP) {
337       auto *LoopBottom = BeginToEnd[&MI]->getParent()->getPrevNode();
338       if (MBB.getNumber() > LoopBottom->getNumber())
339         AfterSet.insert(&MI);
340 #ifndef NDEBUG
341       else
342         BeforeSet.insert(&MI);
343 #endif
344     }
345 
346     // If there is a previously placed BLOCK/TRY/TRY_TABLE marker and its
347     // corresponding END marker is before the current BLOCK's END marker, that
348     // should be placed after this BLOCK. Otherwise it should be placed before
349     // this BLOCK marker.
350     if (MI.getOpcode() == WebAssembly::BLOCK ||
351         MI.getOpcode() == WebAssembly::TRY ||
352         MI.getOpcode() == WebAssembly::TRY_TABLE) {
353       if (BeginToEnd[&MI]->getParent()->getNumber() <= MBB.getNumber())
354         AfterSet.insert(&MI);
355 #ifndef NDEBUG
356       else
357         BeforeSet.insert(&MI);
358 #endif
359     }
360 
361 #ifndef NDEBUG
362     // All END_(BLOCK|LOOP|TRY|TRY_TABLE) markers should be before the BLOCK.
363     if (MI.getOpcode() == WebAssembly::END_BLOCK ||
364         MI.getOpcode() == WebAssembly::END_LOOP ||
365         MI.getOpcode() == WebAssembly::END_TRY ||
366         MI.getOpcode() == WebAssembly::END_TRY_TABLE)
367       BeforeSet.insert(&MI);
368 #endif
369 
370     // Terminators should go after the BLOCK.
371     if (MI.isTerminator())
372       AfterSet.insert(&MI);
373   }
374 
375   // Local expression tree should go after the BLOCK.
376   for (auto I = Header->getFirstTerminator(), E = Header->begin(); I != E;
377        --I) {
378     if (std::prev(I)->isDebugInstr() || std::prev(I)->isPosition())
379       continue;
380     if (WebAssembly::isChild(*std::prev(I), MFI))
381       AfterSet.insert(&*std::prev(I));
382     else
383       break;
384   }
385 
386   // Add the BLOCK.
387   WebAssembly::BlockType ReturnType = WebAssembly::BlockType::Void;
388   auto InsertPos = getLatestInsertPos(Header, BeforeSet, AfterSet);
389   MachineInstr *Begin =
390       BuildMI(*Header, InsertPos, Header->findDebugLoc(InsertPos),
391               TII.get(WebAssembly::BLOCK))
392           .addImm(int64_t(ReturnType));
393 
394   // Decide where in MBB to put the END_BLOCK.
395   BeforeSet.clear();
396   AfterSet.clear();
397   for (auto &MI : MBB) {
398 #ifndef NDEBUG
399     // END_BLOCK should precede existing LOOP markers.
400     if (MI.getOpcode() == WebAssembly::LOOP)
401       AfterSet.insert(&MI);
402 #endif
403 
404     // If there is a previously placed END_LOOP marker and the header of the
405     // loop is above this block's header, the END_LOOP should be placed after
406     // the END_BLOCK, because the loop contains this block. Otherwise the
407     // END_LOOP should be placed before the END_BLOCK. The same for END_TRY.
408     //
409     // Note that while there can be existing END_TRYs, there can't be
410     // END_TRY_TABLEs; END_TRYs are placed when its corresponding EH pad is
411     // processed, so they are placed below MBB (EH pad) in placeTryMarker. But
412     // END_TRY_TABLE is placed like a END_BLOCK, so they can't be here already.
413     if (MI.getOpcode() == WebAssembly::END_LOOP ||
414         MI.getOpcode() == WebAssembly::END_TRY) {
415       if (EndToBegin[&MI]->getParent()->getNumber() >= Header->getNumber())
416         BeforeSet.insert(&MI);
417 #ifndef NDEBUG
418       else
419         AfterSet.insert(&MI);
420 #endif
421     }
422   }
423 
424   // Mark the end of the block.
425   InsertPos = getEarliestInsertPos(&MBB, BeforeSet, AfterSet);
426   MachineInstr *End = BuildMI(MBB, InsertPos, MBB.findPrevDebugLoc(InsertPos),
427                               TII.get(WebAssembly::END_BLOCK));
428   registerScope(Begin, End);
429 
430   // Track the farthest-spanning scope that ends at this point.
431   updateScopeTops(Header, &MBB);
432 }
433 
434 /// Insert a LOOP marker for a loop starting at MBB (if it's a loop header).
435 void WebAssemblyCFGStackify::placeLoopMarker(MachineBasicBlock &MBB) {
436   MachineFunction &MF = *MBB.getParent();
437   const auto &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
438   const auto &WEI = getAnalysis<WebAssemblyExceptionInfo>();
439   SortRegionInfo SRI(MLI, WEI);
440   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
441 
442   MachineLoop *Loop = MLI.getLoopFor(&MBB);
443   if (!Loop || Loop->getHeader() != &MBB)
444     return;
445 
446   // The operand of a LOOP is the first block after the loop. If the loop is the
447   // bottom of the function, insert a dummy block at the end.
448   MachineBasicBlock *Bottom = SRI.getBottom(Loop);
449   auto Iter = std::next(Bottom->getIterator());
450   if (Iter == MF.end()) {
451     getAppendixBlock(MF);
452     Iter = std::next(Bottom->getIterator());
453   }
454   MachineBasicBlock *AfterLoop = &*Iter;
455 
456   // Decide where in Header to put the LOOP.
457   SmallPtrSet<const MachineInstr *, 4> BeforeSet;
458   SmallPtrSet<const MachineInstr *, 4> AfterSet;
459   for (const auto &MI : MBB) {
460     // LOOP marker should be after any existing loop that ends here. Otherwise
461     // we assume the instruction belongs to the loop.
462     if (MI.getOpcode() == WebAssembly::END_LOOP)
463       BeforeSet.insert(&MI);
464 #ifndef NDEBUG
465     else
466       AfterSet.insert(&MI);
467 #endif
468   }
469 
470   // Mark the beginning of the loop.
471   auto InsertPos = getEarliestInsertPos(&MBB, BeforeSet, AfterSet);
472   MachineInstr *Begin = BuildMI(MBB, InsertPos, MBB.findDebugLoc(InsertPos),
473                                 TII.get(WebAssembly::LOOP))
474                             .addImm(int64_t(WebAssembly::BlockType::Void));
475 
476   // Decide where in MBB to put the END_LOOP.
477   BeforeSet.clear();
478   AfterSet.clear();
479 #ifndef NDEBUG
480   for (const auto &MI : MBB)
481     // Existing END_LOOP markers belong to parent loops of this loop
482     if (MI.getOpcode() == WebAssembly::END_LOOP)
483       AfterSet.insert(&MI);
484 #endif
485 
486   // Mark the end of the loop (using arbitrary debug location that branched to
487   // the loop end as its location).
488   InsertPos = getEarliestInsertPos(AfterLoop, BeforeSet, AfterSet);
489   DebugLoc EndDL = AfterLoop->pred_empty()
490                        ? DebugLoc()
491                        : (*AfterLoop->pred_rbegin())->findBranchDebugLoc();
492   MachineInstr *End =
493       BuildMI(*AfterLoop, InsertPos, EndDL, TII.get(WebAssembly::END_LOOP));
494   registerScope(Begin, End);
495 
496   assert((!ScopeTops[AfterLoop->getNumber()] ||
497           ScopeTops[AfterLoop->getNumber()]->getNumber() < MBB.getNumber()) &&
498          "With block sorting the outermost loop for a block should be first.");
499   updateScopeTops(&MBB, AfterLoop);
500 }
501 
502 void WebAssemblyCFGStackify::placeTryMarker(MachineBasicBlock &MBB) {
503   assert(MBB.isEHPad());
504   MachineFunction &MF = *MBB.getParent();
505   auto &MDT = getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
506   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
507   const auto &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
508   const auto &WEI = getAnalysis<WebAssemblyExceptionInfo>();
509   SortRegionInfo SRI(MLI, WEI);
510   const auto &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
511 
512   // Compute the nearest common dominator of all unwind predecessors
513   MachineBasicBlock *Header = nullptr;
514   int MBBNumber = MBB.getNumber();
515   for (auto *Pred : MBB.predecessors()) {
516     if (Pred->getNumber() < MBBNumber) {
517       Header = Header ? MDT.findNearestCommonDominator(Header, Pred) : Pred;
518       assert(!explicitlyBranchesTo(Pred, &MBB) &&
519              "Explicit branch to an EH pad!");
520     }
521   }
522   if (!Header)
523     return;
524 
525   // If this try is at the bottom of the function, insert a dummy block at the
526   // end.
527   WebAssemblyException *WE = WEI.getExceptionFor(&MBB);
528   assert(WE);
529   MachineBasicBlock *Bottom = SRI.getBottom(WE);
530   auto Iter = std::next(Bottom->getIterator());
531   if (Iter == MF.end()) {
532     getAppendixBlock(MF);
533     Iter = std::next(Bottom->getIterator());
534   }
535   MachineBasicBlock *Cont = &*Iter;
536 
537   // If the nearest common dominator is inside a more deeply nested context,
538   // walk out to the nearest scope which isn't more deeply nested.
539   for (MachineFunction::iterator I(Bottom), E(Header); I != E; --I) {
540     if (MachineBasicBlock *ScopeTop = ScopeTops[I->getNumber()]) {
541       if (ScopeTop->getNumber() > Header->getNumber()) {
542         // Skip over an intervening scope.
543         I = std::next(ScopeTop->getIterator());
544       } else {
545         // We found a scope level at an appropriate depth.
546         Header = ScopeTop;
547         break;
548       }
549     }
550   }
551 
552   // Decide where in Header to put the TRY.
553 
554   // Instructions that should go before the TRY.
555   SmallPtrSet<const MachineInstr *, 4> BeforeSet;
556   // Instructions that should go after the TRY.
557   SmallPtrSet<const MachineInstr *, 4> AfterSet;
558   for (const auto &MI : *Header) {
559     // If there is a previously placed LOOP marker and the bottom block of the
560     // loop is above MBB, it should be after the TRY, because the loop is nested
561     // in this TRY. Otherwise it should be before the TRY.
562     if (MI.getOpcode() == WebAssembly::LOOP) {
563       auto *LoopBottom = BeginToEnd[&MI]->getParent()->getPrevNode();
564       if (MBB.getNumber() > LoopBottom->getNumber())
565         AfterSet.insert(&MI);
566 #ifndef NDEBUG
567       else
568         BeforeSet.insert(&MI);
569 #endif
570     }
571 
572     // All previously inserted BLOCK/TRY markers should be after the TRY because
573     // they are all nested blocks/trys.
574     if (MI.getOpcode() == WebAssembly::BLOCK ||
575         MI.getOpcode() == WebAssembly::TRY)
576       AfterSet.insert(&MI);
577 
578 #ifndef NDEBUG
579     // All END_(BLOCK/LOOP/TRY) markers should be before the TRY.
580     if (MI.getOpcode() == WebAssembly::END_BLOCK ||
581         MI.getOpcode() == WebAssembly::END_LOOP ||
582         MI.getOpcode() == WebAssembly::END_TRY)
583       BeforeSet.insert(&MI);
584 #endif
585 
586     // Terminators should go after the TRY.
587     if (MI.isTerminator())
588       AfterSet.insert(&MI);
589   }
590 
591   // If Header unwinds to MBB (= Header contains 'invoke'), the try block should
592   // contain the call within it. So the call should go after the TRY. The
593   // exception is when the header's terminator is a rethrow instruction, in
594   // which case that instruction, not a call instruction before it, is gonna
595   // throw.
596   MachineInstr *ThrowingCall = nullptr;
597   if (MBB.isPredecessor(Header)) {
598     auto TermPos = Header->getFirstTerminator();
599     if (TermPos == Header->end() ||
600         TermPos->getOpcode() != WebAssembly::RETHROW) {
601       for (auto &MI : reverse(*Header)) {
602         if (MI.isCall()) {
603           AfterSet.insert(&MI);
604           ThrowingCall = &MI;
605           // Possibly throwing calls are usually wrapped by EH_LABEL
606           // instructions. We don't want to split them and the call.
607           if (MI.getIterator() != Header->begin() &&
608               std::prev(MI.getIterator())->isEHLabel()) {
609             AfterSet.insert(&*std::prev(MI.getIterator()));
610             ThrowingCall = &*std::prev(MI.getIterator());
611           }
612           break;
613         }
614       }
615     }
616   }
617 
618   // Local expression tree should go after the TRY.
619   // For BLOCK placement, we start the search from the previous instruction of a
620   // BB's terminator, but in TRY's case, we should start from the previous
621   // instruction of a call that can throw, or a EH_LABEL that precedes the call,
622   // because the return values of the call's previous instructions can be
623   // stackified and consumed by the throwing call.
624   auto SearchStartPt = ThrowingCall ? MachineBasicBlock::iterator(ThrowingCall)
625                                     : Header->getFirstTerminator();
626   for (auto I = SearchStartPt, E = Header->begin(); I != E; --I) {
627     if (std::prev(I)->isDebugInstr() || std::prev(I)->isPosition())
628       continue;
629     if (WebAssembly::isChild(*std::prev(I), MFI))
630       AfterSet.insert(&*std::prev(I));
631     else
632       break;
633   }
634 
635   // Add the TRY.
636   auto InsertPos = getLatestInsertPos(Header, BeforeSet, AfterSet);
637   MachineInstr *Begin =
638       BuildMI(*Header, InsertPos, Header->findDebugLoc(InsertPos),
639               TII.get(WebAssembly::TRY))
640           .addImm(int64_t(WebAssembly::BlockType::Void));
641 
642   // Decide where in Cont to put the END_TRY.
643   BeforeSet.clear();
644   AfterSet.clear();
645   for (const auto &MI : *Cont) {
646 #ifndef NDEBUG
647     // END_TRY should precede existing LOOP markers.
648     if (MI.getOpcode() == WebAssembly::LOOP)
649       AfterSet.insert(&MI);
650 
651     // All END_TRY markers placed earlier belong to exceptions that contains
652     // this one.
653     if (MI.getOpcode() == WebAssembly::END_TRY)
654       AfterSet.insert(&MI);
655 #endif
656 
657     // If there is a previously placed END_LOOP marker and its header is after
658     // where TRY marker is, this loop is contained within the 'catch' part, so
659     // the END_TRY marker should go after that. Otherwise, the whole try-catch
660     // is contained within this loop, so the END_TRY should go before that.
661     if (MI.getOpcode() == WebAssembly::END_LOOP) {
662       // For a LOOP to be after TRY, LOOP's BB should be after TRY's BB; if they
663       // are in the same BB, LOOP is always before TRY.
664       if (EndToBegin[&MI]->getParent()->getNumber() > Header->getNumber())
665         BeforeSet.insert(&MI);
666 #ifndef NDEBUG
667       else
668         AfterSet.insert(&MI);
669 #endif
670     }
671 
672     // It is not possible for an END_BLOCK to be already in this block.
673   }
674 
675   // Mark the end of the TRY.
676   InsertPos = getEarliestInsertPos(Cont, BeforeSet, AfterSet);
677   MachineInstr *End = BuildMI(*Cont, InsertPos, Bottom->findBranchDebugLoc(),
678                               TII.get(WebAssembly::END_TRY));
679   registerTryScope(Begin, End, &MBB);
680 
681   // Track the farthest-spanning scope that ends at this point. We create two
682   // mappings: (BB with 'end_try' -> BB with 'try') and (BB with 'catch' -> BB
683   // with 'try'). We need to create 'catch' -> 'try' mapping here too because
684   // markers should not span across 'catch'. For example, this should not
685   // happen:
686   //
687   // try
688   //   block     --|  (X)
689   // catch         |
690   //   end_block --|
691   // end_try
692   for (auto *End : {&MBB, Cont})
693     updateScopeTops(Header, End);
694 }
695 
696 void WebAssemblyCFGStackify::placeTryTableMarker(MachineBasicBlock &MBB) {
697   assert(MBB.isEHPad());
698   MachineFunction &MF = *MBB.getParent();
699   auto &MDT = getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
700   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
701   const auto &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
702   const auto &WEI = getAnalysis<WebAssemblyExceptionInfo>();
703   SortRegionInfo SRI(MLI, WEI);
704   const auto &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
705 
706   // Compute the nearest common dominator of all unwind predecessors
707   MachineBasicBlock *Header = nullptr;
708   int MBBNumber = MBB.getNumber();
709   for (auto *Pred : MBB.predecessors()) {
710     if (Pred->getNumber() < MBBNumber) {
711       Header = Header ? MDT.findNearestCommonDominator(Header, Pred) : Pred;
712       assert(!explicitlyBranchesTo(Pred, &MBB) &&
713              "Explicit branch to an EH pad!");
714     }
715   }
716   if (!Header)
717     return;
718 
719   // Unlike the end_try marker, we don't place an end marker at the end of
720   // exception bottom, i.e., at the end of the old 'catch' block. But we still
721   // consider the try-catch part as a scope when computing ScopeTops.
722   WebAssemblyException *WE = WEI.getExceptionFor(&MBB);
723   assert(WE);
724   MachineBasicBlock *Bottom = SRI.getBottom(WE);
725   auto Iter = std::next(Bottom->getIterator());
726   if (Iter == MF.end())
727     Iter--;
728   MachineBasicBlock *Cont = &*Iter;
729 
730   // If the nearest common dominator is inside a more deeply nested context,
731   // walk out to the nearest scope which isn't more deeply nested.
732   for (MachineFunction::iterator I(Bottom), E(Header); I != E; --I) {
733     if (MachineBasicBlock *ScopeTop = ScopeTops[I->getNumber()]) {
734       if (ScopeTop->getNumber() > Header->getNumber()) {
735         // Skip over an intervening scope.
736         I = std::next(ScopeTop->getIterator());
737       } else {
738         // We found a scope level at an appropriate depth.
739         Header = ScopeTop;
740         break;
741       }
742     }
743   }
744 
745   // Decide where in Header to put the TRY_TABLE.
746 
747   // Instructions that should go before the TRY_TABLE.
748   SmallPtrSet<const MachineInstr *, 4> BeforeSet;
749   // Instructions that should go after the TRY_TABLE.
750   SmallPtrSet<const MachineInstr *, 4> AfterSet;
751   for (const auto &MI : *Header) {
752     // If there is a previously placed LOOP marker and the bottom block of the
753     // loop is above MBB, it should be after the TRY_TABLE, because the loop is
754     // nested in this TRY_TABLE. Otherwise it should be before the TRY_TABLE.
755     if (MI.getOpcode() == WebAssembly::LOOP) {
756       auto *LoopBottom = BeginToEnd[&MI]->getParent()->getPrevNode();
757       if (MBB.getNumber() > LoopBottom->getNumber())
758         AfterSet.insert(&MI);
759 #ifndef NDEBUG
760       else
761         BeforeSet.insert(&MI);
762 #endif
763     }
764 
765     // All previously inserted BLOCK/TRY_TABLE markers should be after the
766     // TRY_TABLE because they are all nested blocks/try_tables.
767     if (MI.getOpcode() == WebAssembly::BLOCK ||
768         MI.getOpcode() == WebAssembly::TRY_TABLE)
769       AfterSet.insert(&MI);
770 
771 #ifndef NDEBUG
772     // All END_(BLOCK/LOOP/TRY_TABLE) markers should be before the TRY_TABLE.
773     if (MI.getOpcode() == WebAssembly::END_BLOCK ||
774         MI.getOpcode() == WebAssembly::END_LOOP ||
775         MI.getOpcode() == WebAssembly::END_TRY_TABLE)
776       BeforeSet.insert(&MI);
777 #endif
778 
779     // Terminators should go after the TRY_TABLE.
780     if (MI.isTerminator())
781       AfterSet.insert(&MI);
782   }
783 
784   // If Header unwinds to MBB (= Header contains 'invoke'), the try_table block
785   // should contain the call within it. So the call should go after the
786   // TRY_TABLE. The exception is when the header's terminator is a rethrow
787   // instruction, in which case that instruction, not a call instruction before
788   // it, is gonna throw.
789   MachineInstr *ThrowingCall = nullptr;
790   if (MBB.isPredecessor(Header)) {
791     auto TermPos = Header->getFirstTerminator();
792     if (TermPos == Header->end() ||
793         TermPos->getOpcode() != WebAssembly::RETHROW) {
794       for (auto &MI : reverse(*Header)) {
795         if (MI.isCall()) {
796           AfterSet.insert(&MI);
797           ThrowingCall = &MI;
798           // Possibly throwing calls are usually wrapped by EH_LABEL
799           // instructions. We don't want to split them and the call.
800           if (MI.getIterator() != Header->begin() &&
801               std::prev(MI.getIterator())->isEHLabel()) {
802             AfterSet.insert(&*std::prev(MI.getIterator()));
803             ThrowingCall = &*std::prev(MI.getIterator());
804           }
805           break;
806         }
807       }
808     }
809   }
810 
811   // Local expression tree should go after the TRY_TABLE.
812   // For BLOCK placement, we start the search from the previous instruction of a
813   // BB's terminator, but in TRY_TABLE's case, we should start from the previous
814   // instruction of a call that can throw, or a EH_LABEL that precedes the call,
815   // because the return values of the call's previous instructions can be
816   // stackified and consumed by the throwing call.
817   auto SearchStartPt = ThrowingCall ? MachineBasicBlock::iterator(ThrowingCall)
818                                     : Header->getFirstTerminator();
819   for (auto I = SearchStartPt, E = Header->begin(); I != E; --I) {
820     if (std::prev(I)->isDebugInstr() || std::prev(I)->isPosition())
821       continue;
822     if (WebAssembly::isChild(*std::prev(I), MFI))
823       AfterSet.insert(&*std::prev(I));
824     else
825       break;
826   }
827 
828   // Add the TRY_TABLE and a BLOCK for the catch destination. We currently
829   // generate only one CATCH clause for a TRY_TABLE, so we need one BLOCK for
830   // its destination.
831   //
832   // Header:
833   //   block
834   //     try_table (catch ... $MBB)
835   //       ...
836   //
837   // MBB:
838   //     end_try_table
839   //   end_block                 ;; destination of (catch ...)
840   //   ... catch handler body ...
841   auto InsertPos = getLatestInsertPos(Header, BeforeSet, AfterSet);
842   MachineInstrBuilder BlockMIB =
843       BuildMI(*Header, InsertPos, Header->findDebugLoc(InsertPos),
844               TII.get(WebAssembly::BLOCK));
845   auto *Block = BlockMIB.getInstr();
846   MachineInstrBuilder TryTableMIB =
847       BuildMI(*Header, InsertPos, Header->findDebugLoc(InsertPos),
848               TII.get(WebAssembly::TRY_TABLE))
849           .addImm(int64_t(WebAssembly::BlockType::Void))
850           .addImm(1); // # of catch clauses
851   auto *TryTable = TryTableMIB.getInstr();
852 
853   // Add a CATCH_*** clause to the TRY_TABLE. These are pseudo instructions
854   // following the destination END_BLOCK to simulate block return values,
855   // because we currently don't support them.
856   auto *Catch = WebAssembly::findCatch(&MBB);
857   switch (Catch->getOpcode()) {
858   case WebAssembly::CATCH:
859     // CATCH's destination block's return type is the extracted value type,
860     // which is currently i32 for all supported tags.
861     BlockMIB.addImm(int64_t(WebAssembly::BlockType::I32));
862     TryTableMIB.addImm(wasm::WASM_OPCODE_CATCH);
863     for (const auto &Use : Catch->uses()) {
864       // The only use operand a CATCH can have is the tag symbol.
865       TryTableMIB.addExternalSymbol(Use.getSymbolName());
866       break;
867     }
868     TryTableMIB.addMBB(&MBB);
869     break;
870   case WebAssembly::CATCH_REF:
871     // CATCH_REF's destination block's return type is the extracted value type
872     // followed by an exnref, which is (i32, exnref) in our case. We assign the
873     // actual multiavlue signature in MCInstLower. MO_CATCH_BLOCK_SIG signals
874     // that this operand is used for catch_ref's multivalue destination.
875     BlockMIB.addImm(int64_t(WebAssembly::BlockType::Multivalue));
876     Block->getOperand(0).setTargetFlags(WebAssemblyII::MO_CATCH_BLOCK_SIG);
877     TryTableMIB.addImm(wasm::WASM_OPCODE_CATCH_REF);
878     for (const auto &Use : Catch->uses()) {
879       TryTableMIB.addExternalSymbol(Use.getSymbolName());
880       break;
881     }
882     TryTableMIB.addMBB(&MBB);
883     break;
884   case WebAssembly::CATCH_ALL:
885     // CATCH_ALL's destination block's return type is void.
886     BlockMIB.addImm(int64_t(WebAssembly::BlockType::Void));
887     TryTableMIB.addImm(wasm::WASM_OPCODE_CATCH_ALL);
888     TryTableMIB.addMBB(&MBB);
889     break;
890   case WebAssembly::CATCH_ALL_REF:
891     // CATCH_ALL_REF's destination block's return type is exnref.
892     BlockMIB.addImm(int64_t(WebAssembly::BlockType::Exnref));
893     TryTableMIB.addImm(wasm::WASM_OPCODE_CATCH_ALL_REF);
894     TryTableMIB.addMBB(&MBB);
895     break;
896   }
897 
898   // Decide where in MBB to put the END_TRY_TABLE, and the END_BLOCK for the
899   // CATCH destination.
900   BeforeSet.clear();
901   AfterSet.clear();
902   for (const auto &MI : MBB) {
903 #ifndef NDEBUG
904     // END_TRY_TABLE should precede existing LOOP markers.
905     if (MI.getOpcode() == WebAssembly::LOOP)
906       AfterSet.insert(&MI);
907 #endif
908 
909     // If there is a previously placed END_LOOP marker and the header of the
910     // loop is above this try_table's header, the END_LOOP should be placed
911     // after the END_TRY_TABLE, because the loop contains this block. Otherwise
912     // the END_LOOP should be placed before the END_TRY_TABLE.
913     if (MI.getOpcode() == WebAssembly::END_LOOP) {
914       if (EndToBegin[&MI]->getParent()->getNumber() >= Header->getNumber())
915         BeforeSet.insert(&MI);
916 #ifndef NDEBUG
917       else
918         AfterSet.insert(&MI);
919 #endif
920     }
921 
922 #ifndef NDEBUG
923     // CATCH, CATCH_REF, CATCH_ALL, and CATCH_ALL_REF are pseudo-instructions
924     // that simulate the block return value, so they should be placed after the
925     // END_TRY_TABLE.
926     if (WebAssembly::isCatch(MI.getOpcode()))
927       AfterSet.insert(&MI);
928 #endif
929   }
930 
931   // Mark the end of the TRY_TABLE and the BLOCK.
932   InsertPos = getEarliestInsertPos(&MBB, BeforeSet, AfterSet);
933   MachineInstr *EndTryTable =
934       BuildMI(MBB, InsertPos, MBB.findPrevDebugLoc(InsertPos),
935               TII.get(WebAssembly::END_TRY_TABLE));
936   registerTryScope(TryTable, EndTryTable, &MBB);
937   MachineInstr *EndBlock =
938       BuildMI(MBB, InsertPos, MBB.findPrevDebugLoc(InsertPos),
939               TII.get(WebAssembly::END_BLOCK));
940   registerScope(Block, EndBlock);
941 
942   // Track the farthest-spanning scope that ends at this point.
943   // Unlike the end_try, even if we don't put a end marker at the end of catch
944   // block, we still have to create two mappings: (BB with 'end_try_table' -> BB
945   // with 'try_table') and (BB after the (conceptual) catch block -> BB with
946   // 'try_table').
947   //
948   // This is what can happen if we don't create the latter mapping:
949   //
950   // Suppoe in the legacy EH we have this code:
951   // try
952   //   try
953   //     code1
954   //   catch (a)
955   //   end_try
956   //   code2
957   // catch (b)
958   // end_try
959   //
960   // If we don't create the latter mapping, try_table markers would be placed
961   // like this:
962   // try_table
963   //   code1
964   // end_try_table (a)
965   // try_table
966   //   code2
967   // end_try_table (b)
968   //
969   // This does not reflect the original structure, and more important problem
970   // is, in case 'code1' has an unwind mismatch and should unwind to
971   // 'end_try_table (b)' rather than 'end_try_table (a)', we don't have a way to
972   // make it jump after 'end_try_table (b)' without creating another block. So
973   // even if we don't place 'end_try' marker at the end of 'catch' block
974   // anymore, we create ScopeTops mapping the same way as the legacy exception,
975   // so the resulting code will look like:
976   // try_table
977   //   try_table
978   //     code1
979   //   end_try_table (a)
980   //   code2
981   // end_try_table (b)
982   for (auto *End : {&MBB, Cont})
983     updateScopeTops(Header, End);
984 }
985 
986 void WebAssemblyCFGStackify::removeUnnecessaryInstrs(MachineFunction &MF) {
987   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
988 
989   // When there is an unconditional branch right before a catch instruction and
990   // it branches to the end of end_try marker, we don't need the branch, because
991   // if there is no exception, the control flow transfers to that point anyway.
992   // bb0:
993   //   try
994   //     ...
995   //     br bb2      <- Not necessary
996   // bb1 (ehpad):
997   //   catch
998   //     ...
999   // bb2:            <- Continuation BB
1000   //   end
1001   //
1002   // A more involved case: When the BB where 'end' is located is an another EH
1003   // pad, the Cont (= continuation) BB is that EH pad's 'end' BB. For example,
1004   // bb0:
1005   //   try
1006   //     try
1007   //       ...
1008   //       br bb3      <- Not necessary
1009   // bb1 (ehpad):
1010   //     catch
1011   // bb2 (ehpad):
1012   //     end
1013   //   catch
1014   //     ...
1015   // bb3:            <- Continuation BB
1016   //   end
1017   //
1018   // When the EH pad at hand is bb1, its matching end_try is in bb2. But it is
1019   // another EH pad, so bb0's continuation BB becomes bb3. So 'br bb3' in the
1020   // code can be deleted. This is why we run 'while' until 'Cont' is not an EH
1021   // pad.
1022   for (auto &MBB : MF) {
1023     if (!MBB.isEHPad())
1024       continue;
1025 
1026     MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
1027     SmallVector<MachineOperand, 4> Cond;
1028     MachineBasicBlock *EHPadLayoutPred = MBB.getPrevNode();
1029 
1030     MachineBasicBlock *Cont = &MBB;
1031     while (Cont->isEHPad()) {
1032       MachineInstr *Try = EHPadToTry[Cont];
1033       MachineInstr *EndTry = BeginToEnd[Try];
1034       // We started from an EH pad, so the end marker cannot be a delegate
1035       assert(EndTry->getOpcode() != WebAssembly::DELEGATE);
1036       Cont = EndTry->getParent();
1037     }
1038 
1039     bool Analyzable = !TII.analyzeBranch(*EHPadLayoutPred, TBB, FBB, Cond);
1040     // This condition means either
1041     // 1. This BB ends with a single unconditional branch whose destinaion is
1042     //    Cont.
1043     // 2. This BB ends with a conditional branch followed by an unconditional
1044     //    branch, and the unconditional branch's destination is Cont.
1045     // In both cases, we want to remove the last (= unconditional) branch.
1046     if (Analyzable && ((Cond.empty() && TBB && TBB == Cont) ||
1047                        (!Cond.empty() && FBB && FBB == Cont))) {
1048       bool ErasedUncondBr = false;
1049       (void)ErasedUncondBr;
1050       for (auto I = EHPadLayoutPred->end(), E = EHPadLayoutPred->begin();
1051            I != E; --I) {
1052         auto PrevI = std::prev(I);
1053         if (PrevI->isTerminator()) {
1054           assert(PrevI->getOpcode() == WebAssembly::BR);
1055           PrevI->eraseFromParent();
1056           ErasedUncondBr = true;
1057           break;
1058         }
1059       }
1060       assert(ErasedUncondBr && "Unconditional branch not erased!");
1061     }
1062   }
1063 
1064   // When there are block / end_block markers that overlap with try / end_try
1065   // markers, and the block and try markers' return types are the same, the
1066   // block /end_block markers are not necessary, because try / end_try markers
1067   // also can serve as boundaries for branches.
1068   // block         <- Not necessary
1069   //   try
1070   //     ...
1071   //   catch
1072   //     ...
1073   //   end
1074   // end           <- Not necessary
1075   SmallVector<MachineInstr *, 32> ToDelete;
1076   for (auto &MBB : MF) {
1077     for (auto &MI : MBB) {
1078       if (MI.getOpcode() != WebAssembly::TRY)
1079         continue;
1080       MachineInstr *Try = &MI, *EndTry = BeginToEnd[Try];
1081       if (EndTry->getOpcode() == WebAssembly::DELEGATE)
1082         continue;
1083 
1084       MachineBasicBlock *TryBB = Try->getParent();
1085       MachineBasicBlock *Cont = EndTry->getParent();
1086       int64_t RetType = Try->getOperand(0).getImm();
1087       for (auto B = Try->getIterator(), E = std::next(EndTry->getIterator());
1088            B != TryBB->begin() && E != Cont->end() &&
1089            std::prev(B)->getOpcode() == WebAssembly::BLOCK &&
1090            E->getOpcode() == WebAssembly::END_BLOCK &&
1091            std::prev(B)->getOperand(0).getImm() == RetType;
1092            --B, ++E) {
1093         ToDelete.push_back(&*std::prev(B));
1094         ToDelete.push_back(&*E);
1095       }
1096     }
1097   }
1098   for (auto *MI : ToDelete) {
1099     if (MI->getOpcode() == WebAssembly::BLOCK)
1100       unregisterScope(MI);
1101     MI->eraseFromParent();
1102   }
1103 }
1104 
1105 // When MBB is split into MBB and Split, we should unstackify defs in MBB that
1106 // have their uses in Split.
1107 static void unstackifyVRegsUsedInSplitBB(MachineBasicBlock &MBB,
1108                                          MachineBasicBlock &Split) {
1109   MachineFunction &MF = *MBB.getParent();
1110   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
1111   auto &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
1112   auto &MRI = MF.getRegInfo();
1113 
1114   for (auto &MI : Split) {
1115     for (auto &MO : MI.explicit_uses()) {
1116       if (!MO.isReg() || MO.getReg().isPhysical())
1117         continue;
1118       if (MachineInstr *Def = MRI.getUniqueVRegDef(MO.getReg()))
1119         if (Def->getParent() == &MBB)
1120           MFI.unstackifyVReg(MO.getReg());
1121     }
1122   }
1123 
1124   // In RegStackify, when a register definition is used multiple times,
1125   //    Reg = INST ...
1126   //    INST ..., Reg, ...
1127   //    INST ..., Reg, ...
1128   //    INST ..., Reg, ...
1129   //
1130   // we introduce a TEE, which has the following form:
1131   //    DefReg = INST ...
1132   //    TeeReg, Reg = TEE_... DefReg
1133   //    INST ..., TeeReg, ...
1134   //    INST ..., Reg, ...
1135   //    INST ..., Reg, ...
1136   // with DefReg and TeeReg stackified but Reg not stackified.
1137   //
1138   // But the invariant that TeeReg should be stackified can be violated while we
1139   // unstackify registers in the split BB above. In this case, we convert TEEs
1140   // into two COPYs. This COPY will be eventually eliminated in ExplicitLocals.
1141   //    DefReg = INST ...
1142   //    TeeReg = COPY DefReg
1143   //    Reg = COPY DefReg
1144   //    INST ..., TeeReg, ...
1145   //    INST ..., Reg, ...
1146   //    INST ..., Reg, ...
1147   for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) {
1148     if (!WebAssembly::isTee(MI.getOpcode()))
1149       continue;
1150     Register TeeReg = MI.getOperand(0).getReg();
1151     Register Reg = MI.getOperand(1).getReg();
1152     Register DefReg = MI.getOperand(2).getReg();
1153     if (!MFI.isVRegStackified(TeeReg)) {
1154       // Now we are not using TEE anymore, so unstackify DefReg too
1155       MFI.unstackifyVReg(DefReg);
1156       unsigned CopyOpc =
1157           WebAssembly::getCopyOpcodeForRegClass(MRI.getRegClass(DefReg));
1158       BuildMI(MBB, &MI, MI.getDebugLoc(), TII.get(CopyOpc), TeeReg)
1159           .addReg(DefReg);
1160       BuildMI(MBB, &MI, MI.getDebugLoc(), TII.get(CopyOpc), Reg).addReg(DefReg);
1161       MI.eraseFromParent();
1162     }
1163   }
1164 }
1165 
1166 // Wrap the given range of instructions with a try-delegate that targets
1167 // 'UnwindDest'. RangeBegin and RangeEnd are inclusive.
1168 void WebAssemblyCFGStackify::addNestedTryDelegate(
1169     MachineInstr *RangeBegin, MachineInstr *RangeEnd,
1170     MachineBasicBlock *UnwindDest) {
1171   auto *BeginBB = RangeBegin->getParent();
1172   auto *EndBB = RangeEnd->getParent();
1173   MachineFunction &MF = *BeginBB->getParent();
1174   const auto &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
1175   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
1176 
1177   // Local expression tree before the first call of this range should go
1178   // after the nested TRY.
1179   SmallPtrSet<const MachineInstr *, 4> AfterSet;
1180   AfterSet.insert(RangeBegin);
1181   for (auto I = MachineBasicBlock::iterator(RangeBegin), E = BeginBB->begin();
1182        I != E; --I) {
1183     if (std::prev(I)->isDebugInstr() || std::prev(I)->isPosition())
1184       continue;
1185     if (WebAssembly::isChild(*std::prev(I), MFI))
1186       AfterSet.insert(&*std::prev(I));
1187     else
1188       break;
1189   }
1190 
1191   // Create the nested try instruction.
1192   auto TryPos = getLatestInsertPos(
1193       BeginBB, SmallPtrSet<const MachineInstr *, 4>(), AfterSet);
1194   MachineInstr *Try = BuildMI(*BeginBB, TryPos, RangeBegin->getDebugLoc(),
1195                               TII.get(WebAssembly::TRY))
1196                           .addImm(int64_t(WebAssembly::BlockType::Void));
1197 
1198   // Create a BB to insert the 'delegate' instruction.
1199   MachineBasicBlock *DelegateBB = MF.CreateMachineBasicBlock();
1200   // If the destination of 'delegate' is not the caller, adds the destination to
1201   // the BB's successors.
1202   if (UnwindDest != FakeCallerBB)
1203     DelegateBB->addSuccessor(UnwindDest);
1204 
1205   auto SplitPos = std::next(RangeEnd->getIterator());
1206   if (SplitPos == EndBB->end()) {
1207     // If the range's end instruction is at the end of the BB, insert the new
1208     // delegate BB after the current BB.
1209     MF.insert(std::next(EndBB->getIterator()), DelegateBB);
1210     EndBB->addSuccessor(DelegateBB);
1211 
1212   } else {
1213     // When the split pos is in the middle of a BB, we split the BB into two and
1214     // put the 'delegate' BB in between. We normally create a split BB and make
1215     // it a successor of the original BB (CatchAfterSplit == false), but in case
1216     // the BB is an EH pad and there is a 'catch' after the split pos
1217     // (CatchAfterSplit == true), we should preserve the BB's property,
1218     // including that it is an EH pad, in the later part of the BB, where the
1219     // 'catch' is.
1220     bool CatchAfterSplit = false;
1221     if (EndBB->isEHPad()) {
1222       for (auto I = MachineBasicBlock::iterator(SplitPos), E = EndBB->end();
1223            I != E; ++I) {
1224         if (WebAssembly::isCatch(I->getOpcode())) {
1225           CatchAfterSplit = true;
1226           break;
1227         }
1228       }
1229     }
1230 
1231     MachineBasicBlock *PreBB = nullptr, *PostBB = nullptr;
1232     if (!CatchAfterSplit) {
1233       // If the range's end instruction is in the middle of the BB, we split the
1234       // BB into two and insert the delegate BB in between.
1235       // - Before:
1236       // bb:
1237       //   range_end
1238       //   other_insts
1239       //
1240       // - After:
1241       // pre_bb: (previous 'bb')
1242       //   range_end
1243       // delegate_bb: (new)
1244       //   delegate
1245       // post_bb: (new)
1246       //   other_insts
1247       PreBB = EndBB;
1248       PostBB = MF.CreateMachineBasicBlock();
1249       MF.insert(std::next(PreBB->getIterator()), PostBB);
1250       MF.insert(std::next(PreBB->getIterator()), DelegateBB);
1251       PostBB->splice(PostBB->end(), PreBB, SplitPos, PreBB->end());
1252       PostBB->transferSuccessors(PreBB);
1253     } else {
1254       // - Before:
1255       // ehpad:
1256       //   range_end
1257       //   catch
1258       //   ...
1259       //
1260       // - After:
1261       // pre_bb: (new)
1262       //   range_end
1263       // delegate_bb: (new)
1264       //   delegate
1265       // post_bb: (previous 'ehpad')
1266       //   catch
1267       //   ...
1268       assert(EndBB->isEHPad());
1269       PreBB = MF.CreateMachineBasicBlock();
1270       PostBB = EndBB;
1271       MF.insert(PostBB->getIterator(), PreBB);
1272       MF.insert(PostBB->getIterator(), DelegateBB);
1273       PreBB->splice(PreBB->end(), PostBB, PostBB->begin(), SplitPos);
1274       // We don't need to transfer predecessors of the EH pad to 'PreBB',
1275       // because an EH pad's predecessors are all through unwind edges and they
1276       // should still unwind to the EH pad, not PreBB.
1277     }
1278     unstackifyVRegsUsedInSplitBB(*PreBB, *PostBB);
1279     PreBB->addSuccessor(DelegateBB);
1280     PreBB->addSuccessor(PostBB);
1281   }
1282 
1283   // Add a 'delegate' instruction in the delegate BB created above.
1284   MachineInstr *Delegate = BuildMI(DelegateBB, RangeEnd->getDebugLoc(),
1285                                    TII.get(WebAssembly::DELEGATE))
1286                                .addMBB(UnwindDest);
1287   registerTryScope(Try, Delegate, nullptr);
1288 }
1289 
1290 // Given an unwind destination, return a trampoline BB. A trampoline BB is a
1291 // destination of a nested try_table inserted to fix an unwind mismatch. It
1292 // contains an end_block, which is the target of the try_table, and a throw_ref,
1293 // to rethrow the exception to the right try_table.
1294 // try_table (catch ... )
1295 //   block exnref
1296 //     ...
1297 //     try_table (catch_all_ref N)
1298 //       some code
1299 //     end_try_table
1300 //     ...
1301 //   end_block                      ;; Trampoline BB
1302 //   throw_ref
1303 // end_try_table
1304 MachineBasicBlock *
1305 WebAssemblyCFGStackify::getTrampolineBlock(MachineBasicBlock *UnwindDest) {
1306   // We need one trampoline BB per unwind destination, even though there are
1307   // multiple try_tables target the same unwind destination. If we have already
1308   // created one for the given UnwindDest, return it.
1309   auto It = UnwindDestToTrampoline.find(UnwindDest);
1310   if (It != UnwindDestToTrampoline.end())
1311     return It->second;
1312 
1313   auto &MF = *UnwindDest->getParent();
1314   auto &MRI = MF.getRegInfo();
1315   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
1316 
1317   MachineInstr *Block = nullptr;
1318   MachineBasicBlock *TrampolineBB = nullptr;
1319   DebugLoc EndDebugLoc;
1320 
1321   if (UnwindDest == getFakeCallerBlock(MF)) {
1322     // If the unwind destination is the caller, create a caller-dedicated
1323     // trampoline BB at the end of the function and wrap the whole function with
1324     // a block.
1325     auto BeginPos = MF.begin()->begin();
1326     while (WebAssembly::isArgument(BeginPos->getOpcode()))
1327       BeginPos++;
1328     Block = BuildMI(*MF.begin(), BeginPos, MF.begin()->begin()->getDebugLoc(),
1329                     TII.get(WebAssembly::BLOCK))
1330                 .addImm(int64_t(WebAssembly::BlockType::Exnref));
1331     TrampolineBB = getCallerTrampolineBlock(MF);
1332     MachineBasicBlock *PrevBB = &*std::prev(CallerTrampolineBB->getIterator());
1333     EndDebugLoc = PrevBB->findPrevDebugLoc(PrevBB->end());
1334   } else {
1335     // If the unwind destination is another EH pad, create a trampoline BB for
1336     // the unwind dest and insert a block instruction right after the target
1337     // try_table.
1338     auto *TargetBeginTry = EHPadToTry[UnwindDest];
1339     auto *TargetEndTry = BeginToEnd[TargetBeginTry];
1340     auto *TargetBeginBB = TargetBeginTry->getParent();
1341     auto *TargetEndBB = TargetEndTry->getParent();
1342 
1343     Block = BuildMI(*TargetBeginBB, std::next(TargetBeginTry->getIterator()),
1344                     TargetBeginTry->getDebugLoc(), TII.get(WebAssembly::BLOCK))
1345                 .addImm(int64_t(WebAssembly::BlockType::Exnref));
1346     TrampolineBB = MF.CreateMachineBasicBlock();
1347     EndDebugLoc = TargetEndTry->getDebugLoc();
1348     MF.insert(TargetEndBB->getIterator(), TrampolineBB);
1349     TrampolineBB->addSuccessor(UnwindDest);
1350   }
1351 
1352   // Insert an end_block, catch_all_ref (pseudo instruction), and throw_ref
1353   // instructions in the trampoline BB.
1354   MachineInstr *EndBlock =
1355       BuildMI(TrampolineBB, EndDebugLoc, TII.get(WebAssembly::END_BLOCK));
1356   auto ExnReg = MRI.createVirtualRegister(&WebAssembly::EXNREFRegClass);
1357   BuildMI(TrampolineBB, EndDebugLoc, TII.get(WebAssembly::CATCH_ALL_REF))
1358       .addDef(ExnReg);
1359   BuildMI(TrampolineBB, EndDebugLoc, TII.get(WebAssembly::THROW_REF))
1360       .addReg(ExnReg);
1361 
1362   registerScope(Block, EndBlock);
1363   UnwindDestToTrampoline[UnwindDest] = TrampolineBB;
1364   return TrampolineBB;
1365 }
1366 
1367 // Wrap the given range of instructions with a try_table-end_try_table that
1368 // targets 'UnwindDest'. RangeBegin and RangeEnd are inclusive.
1369 void WebAssemblyCFGStackify::addNestedTryTable(MachineInstr *RangeBegin,
1370                                                MachineInstr *RangeEnd,
1371                                                MachineBasicBlock *UnwindDest) {
1372   auto *BeginBB = RangeBegin->getParent();
1373   auto *EndBB = RangeEnd->getParent();
1374 
1375   MachineFunction &MF = *BeginBB->getParent();
1376   const auto &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
1377   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
1378 
1379   // Get the trampoline BB that the new try_table will unwind to.
1380   auto *TrampolineBB = getTrampolineBlock(UnwindDest);
1381 
1382   // Local expression tree before the first call of this range should go
1383   // after the nested TRY_TABLE.
1384   SmallPtrSet<const MachineInstr *, 4> AfterSet;
1385   AfterSet.insert(RangeBegin);
1386   for (auto I = MachineBasicBlock::iterator(RangeBegin), E = BeginBB->begin();
1387        I != E; --I) {
1388     if (std::prev(I)->isDebugInstr() || std::prev(I)->isPosition())
1389       continue;
1390     if (WebAssembly::isChild(*std::prev(I), MFI))
1391       AfterSet.insert(&*std::prev(I));
1392     else
1393       break;
1394   }
1395 
1396   // Create the nested try_table instruction.
1397   auto TryTablePos = getLatestInsertPos(
1398       BeginBB, SmallPtrSet<const MachineInstr *, 4>(), AfterSet);
1399   MachineInstr *TryTable =
1400       BuildMI(*BeginBB, TryTablePos, RangeBegin->getDebugLoc(),
1401               TII.get(WebAssembly::TRY_TABLE))
1402           .addImm(int64_t(WebAssembly::BlockType::Void))
1403           .addImm(1) // # of catch clauses
1404           .addImm(wasm::WASM_OPCODE_CATCH_ALL_REF)
1405           .addMBB(TrampolineBB);
1406 
1407   // Create a BB to insert the 'end_try_table' instruction.
1408   MachineBasicBlock *EndTryTableBB = MF.CreateMachineBasicBlock();
1409   EndTryTableBB->addSuccessor(TrampolineBB);
1410 
1411   auto SplitPos = std::next(RangeEnd->getIterator());
1412   if (SplitPos == EndBB->end()) {
1413     // If the range's end instruction is at the end of the BB, insert the new
1414     // end_try_table BB after the current BB.
1415     MF.insert(std::next(EndBB->getIterator()), EndTryTableBB);
1416     EndBB->addSuccessor(EndTryTableBB);
1417 
1418   } else {
1419     // When the split pos is in the middle of a BB, we split the BB into two and
1420     // put the 'end_try_table' BB in between. We normally create a split BB and
1421     // make it a successor of the original BB (CatchAfterSplit == false), but in
1422     // case the BB is an EH pad and there is a 'catch' after split pos
1423     // (CatchAfterSplit == true), we should preserve the BB's property,
1424     // including that it is an EH pad, in the later part of the BB, where the
1425     // 'catch' is.
1426     bool CatchAfterSplit = false;
1427     if (EndBB->isEHPad()) {
1428       for (auto I = MachineBasicBlock::iterator(SplitPos), E = EndBB->end();
1429            I != E; ++I) {
1430         if (WebAssembly::isCatch(I->getOpcode())) {
1431           CatchAfterSplit = true;
1432           break;
1433         }
1434       }
1435     }
1436 
1437     MachineBasicBlock *PreBB = nullptr, *PostBB = nullptr;
1438     if (!CatchAfterSplit) {
1439       // If the range's end instruction is in the middle of the BB, we split the
1440       // BB into two and insert the end_try_table BB in between.
1441       // - Before:
1442       // bb:
1443       //   range_end
1444       //   other_insts
1445       //
1446       // - After:
1447       // pre_bb: (previous 'bb')
1448       //   range_end
1449       // end_try_table_bb: (new)
1450       //   end_try_table
1451       // post_bb: (new)
1452       //   other_insts
1453       PreBB = EndBB;
1454       PostBB = MF.CreateMachineBasicBlock();
1455       MF.insert(std::next(PreBB->getIterator()), PostBB);
1456       MF.insert(std::next(PreBB->getIterator()), EndTryTableBB);
1457       PostBB->splice(PostBB->end(), PreBB, SplitPos, PreBB->end());
1458       PostBB->transferSuccessors(PreBB);
1459     } else {
1460       // - Before:
1461       // ehpad:
1462       //   range_end
1463       //   catch
1464       //   ...
1465       //
1466       // - After:
1467       // pre_bb: (new)
1468       //   range_end
1469       // end_try_table: (new)
1470       //   end_try_table
1471       // post_bb: (previous 'ehpad')
1472       //   catch
1473       //   ...
1474       assert(EndBB->isEHPad());
1475       PreBB = MF.CreateMachineBasicBlock();
1476       PostBB = EndBB;
1477       MF.insert(PostBB->getIterator(), PreBB);
1478       MF.insert(PostBB->getIterator(), EndTryTableBB);
1479       PreBB->splice(PreBB->end(), PostBB, PostBB->begin(), SplitPos);
1480       // We don't need to transfer predecessors of the EH pad to 'PreBB',
1481       // because an EH pad's predecessors are all through unwind edges and they
1482       // should still unwind to the EH pad, not PreBB.
1483     }
1484     unstackifyVRegsUsedInSplitBB(*PreBB, *PostBB);
1485     PreBB->addSuccessor(EndTryTableBB);
1486     PreBB->addSuccessor(PostBB);
1487   }
1488 
1489   // Add a 'end_try_table' instruction in the EndTryTable BB created above.
1490   MachineInstr *EndTryTable = BuildMI(EndTryTableBB, RangeEnd->getDebugLoc(),
1491                                       TII.get(WebAssembly::END_TRY_TABLE));
1492   registerTryScope(TryTable, EndTryTable, nullptr);
1493 }
1494 
1495 // In the standard (exnref) EH, we fix unwind mismatches by adding a new
1496 // block~end_block inside of the unwind destination try_table~end_try_table:
1497 // try_table ...
1498 //   block exnref                   ;; (new)
1499 //     ...
1500 //     try_table (catch_all_ref N)  ;; (new) to trampoline BB
1501 //       code
1502 //     end_try_table                ;; (new)
1503 //     ...
1504 //   end_block                      ;; (new) trampoline BB
1505 //   throw_ref                      ;; (new)
1506 // end_try_table
1507 //
1508 // To do this, we will create a new BB that will contain the new 'end_block' and
1509 // 'throw_ref' and insert it before the 'end_try_table' BB.
1510 //
1511 // But there are cases when there are 'end_loop'(s) before the 'end_try_table'
1512 // in the same BB. (There can't be 'end_block' before 'end_try_table' in the
1513 // same BB because EH pads can't be directly branched to.) Then after fixing
1514 // unwind mismatches this will create the mismatching markers like below:
1515 // bb0:
1516 //   try_table
1517 //   block exnref
1518 //   ...
1519 //   loop
1520 //   ...
1521 // new_bb:
1522 //   end_block
1523 // end_try_table_bb:
1524 //   end_loop
1525 //   end_try_table
1526 //
1527 // So if the unwind dest BB has a end_loop before an end_try_table, we split the
1528 // BB with the end_loop as a separate BB before the end_try_table BB, so that
1529 // after we fix the unwind mismatch, the code will be like:
1530 // bb0:
1531 //   try_table
1532 //   block exnref
1533 //   ...
1534 //   loop
1535 //   ...
1536 // end_loop_bb:
1537 //   end_loop
1538 // new_bb:
1539 //   end_block
1540 // end_try_table_bb:
1541 //   end_try_table
1542 static void splitEndLoopBB(MachineBasicBlock *UnwindDest) {
1543   auto &MF = *UnwindDest->getParent();
1544   MachineInstr *EndTryTable = nullptr, *EndLoop = nullptr;
1545   for (auto &MI : reverse(*UnwindDest)) {
1546     if (MI.getOpcode() == WebAssembly::END_TRY_TABLE) {
1547       EndTryTable = &MI;
1548       continue;
1549     }
1550     if (EndTryTable && MI.getOpcode() == WebAssembly::END_LOOP) {
1551       EndLoop = &MI;
1552       break;
1553     }
1554   }
1555   if (!EndLoop)
1556     return;
1557 
1558   auto *EndLoopBB = MF.CreateMachineBasicBlock();
1559   MF.insert(UnwindDest->getIterator(), EndLoopBB);
1560   auto SplitPos = std::next(EndLoop->getIterator());
1561   EndLoopBB->splice(EndLoopBB->end(), UnwindDest, UnwindDest->begin(),
1562                     SplitPos);
1563   EndLoopBB->addSuccessor(UnwindDest);
1564 }
1565 
1566 bool WebAssemblyCFGStackify::fixCallUnwindMismatches(MachineFunction &MF) {
1567   // This function is used for both the legacy EH and the standard (exnref) EH,
1568   // and the reason we have unwind mismatches is the same for the both of them,
1569   // but the code examples in the comments are going to be different. To make
1570   // the description less confusing, we write the basically same comments twice,
1571   // once for the legacy EH and the standard EH.
1572   //
1573   // -- Legacy EH --------------------------------------------------------------
1574   //
1575   // Linearizing the control flow by placing TRY / END_TRY markers can create
1576   // mismatches in unwind destinations for throwing instructions, such as calls.
1577   //
1578   // We use the 'delegate' instruction to fix the unwind mismatches. 'delegate'
1579   // instruction delegates an exception to an outer 'catch'. It can target not
1580   // only 'catch' but all block-like structures including another 'delegate',
1581   // but with slightly different semantics than branches. When it targets a
1582   // 'catch', it will delegate the exception to that catch. It is being
1583   // discussed how to define the semantics when 'delegate''s target is a non-try
1584   // block: it will either be a validation failure or it will target the next
1585   // outer try-catch. But anyway our LLVM backend currently does not generate
1586   // such code. The example below illustrates where the 'delegate' instruction
1587   // in the middle will delegate the exception to, depending on the value of N.
1588   // try
1589   //   try
1590   //     block
1591   //       try
1592   //         try
1593   //           call @foo
1594   //         delegate N    ;; Where will this delegate to?
1595   //       catch           ;; N == 0
1596   //       end
1597   //     end               ;; N == 1 (invalid; will not be generated)
1598   //   delegate            ;; N == 2
1599   // catch                 ;; N == 3
1600   // end
1601   //                       ;; N == 4 (to caller)
1602   //
1603   // 1. When an instruction may throw, but the EH pad it will unwind to can be
1604   //    different from the original CFG.
1605   //
1606   // Example: we have the following CFG:
1607   // bb0:
1608   //   call @foo    ; if it throws, unwind to bb2
1609   // bb1:
1610   //   call @bar    ; if it throws, unwind to bb3
1611   // bb2 (ehpad):
1612   //   catch
1613   //   ...
1614   // bb3 (ehpad)
1615   //   catch
1616   //   ...
1617   //
1618   // And the CFG is sorted in this order. Then after placing TRY markers, it
1619   // will look like: (BB markers are omitted)
1620   // try
1621   //   try
1622   //     call @foo
1623   //     call @bar   ;; if it throws, unwind to bb3
1624   //   catch         ;; ehpad (bb2)
1625   //     ...
1626   //   end_try
1627   // catch           ;; ehpad (bb3)
1628   //   ...
1629   // end_try
1630   //
1631   // Now if bar() throws, it is going to end up in bb2, not bb3, where it is
1632   // supposed to end up. We solve this problem by wrapping the mismatching call
1633   // with an inner try-delegate that rethrows the exception to the right
1634   // 'catch'.
1635   //
1636   // try
1637   //   try
1638   //     call @foo
1639   //     try               ;; (new)
1640   //       call @bar
1641   //     delegate 1 (bb3)  ;; (new)
1642   //   catch               ;; ehpad (bb2)
1643   //     ...
1644   //   end_try
1645   // catch                 ;; ehpad (bb3)
1646   //   ...
1647   // end_try
1648   //
1649   // ---
1650   // 2. The same as 1, but in this case an instruction unwinds to a caller
1651   //    function and not another EH pad.
1652   //
1653   // Example: we have the following CFG:
1654   // bb0:
1655   //   call @foo       ; if it throws, unwind to bb2
1656   // bb1:
1657   //   call @bar       ; if it throws, unwind to caller
1658   // bb2 (ehpad):
1659   //   catch
1660   //   ...
1661   //
1662   // And the CFG is sorted in this order. Then after placing TRY markers, it
1663   // will look like:
1664   // try
1665   //   call @foo
1666   //   call @bar     ;; if it throws, unwind to caller
1667   // catch           ;; ehpad (bb2)
1668   //   ...
1669   // end_try
1670   //
1671   // Now if bar() throws, it is going to end up in bb2, when it is supposed
1672   // throw up to the caller. We solve this problem in the same way, but in this
1673   // case 'delegate's immediate argument is the number of block depths + 1,
1674   // which means it rethrows to the caller.
1675   // try
1676   //   call @foo
1677   //   try                  ;; (new)
1678   //     call @bar
1679   //   delegate 1 (caller)  ;; (new)
1680   // catch                  ;; ehpad (bb2)
1681   //   ...
1682   // end_try
1683   //
1684   // Before rewriteDepthImmediates, delegate's argument is a BB. In case of the
1685   // caller, it will take a fake BB generated by getFakeCallerBlock(), which
1686   // will be converted to a correct immediate argument later.
1687   //
1688   // In case there are multiple calls in a BB that may throw to the caller, they
1689   // can be wrapped together in one nested try-delegate scope. (In 1, this
1690   // couldn't happen, because may-throwing instruction there had an unwind
1691   // destination, i.e., it was an invoke before, and there could be only one
1692   // invoke within a BB.)
1693   //
1694   // -- Standard EH ------------------------------------------------------------
1695   //
1696   // Linearizing the control flow by placing TRY / END_TRY_TABLE markers can
1697   // create mismatches in unwind destinations for throwing instructions, such as
1698   // calls.
1699   //
1700   // We use the a nested 'try_table'~'end_try_table' instruction to fix the
1701   // unwind mismatches. try_table's catch clauses take an immediate argument
1702   // that specifics which block we should branch to.
1703   //
1704   // 1. When an instruction may throw, but the EH pad it will unwind to can be
1705   //    different from the original CFG.
1706   //
1707   // Example: we have the following CFG:
1708   // bb0:
1709   //   call @foo    ; if it throws, unwind to bb2
1710   // bb1:
1711   //   call @bar    ; if it throws, unwind to bb3
1712   // bb2 (ehpad):
1713   //   catch
1714   //   ...
1715   // bb3 (ehpad)
1716   //   catch
1717   //   ...
1718   //
1719   // And the CFG is sorted in this order. Then after placing TRY_TABLE markers
1720   // (and BLOCK markers for the TRY_TABLE's destinations), it will look like:
1721   // (BB markers are omitted)
1722   // block
1723   //   try_table (catch ... 0)
1724   //     block
1725   //       try_table (catch ... 0)
1726   //         call @foo
1727   //         call @bar              ;; if it throws, unwind to bb3
1728   //       end_try_table
1729   //     end_block                  ;; ehpad (bb2)
1730   //     ...
1731   //   end_try_table
1732   // end_block                      ;; ehpad (bb3)
1733   // ...
1734   //
1735   // Now if bar() throws, it is going to end up in bb2, not bb3, where it is
1736   // supposed to end up. We solve this problem by wrapping the mismatching call
1737   // with an inner try_table~end_try_table that sends the exception to the the
1738   // 'trampoline' block, which rethrows, or 'bounces' it to the right
1739   // end_try_table:
1740   // block
1741   //   try_table (catch ... 0)
1742   //     block exnref                       ;; (new)
1743   //       block
1744   //         try_table (catch ... 0)
1745   //           call @foo
1746   //           try_table (catch_all_ref 2)  ;; (new) to trampoline BB
1747   //             call @bar
1748   //           end_try_table                ;; (new)
1749   //         end_try_table
1750   //       end_block                        ;; ehpad (bb2)
1751   //       ...
1752   //     end_block                          ;; (new) trampoline BB
1753   //     throw_ref                          ;; (new)
1754   //   end_try_table
1755   // end_block                              ;; ehpad (bb3)
1756   //
1757   // ---
1758   // 2. The same as 1, but in this case an instruction unwinds to a caller
1759   //    function and not another EH pad.
1760   //
1761   // Example: we have the following CFG:
1762   // bb0:
1763   //   call @foo       ; if it throws, unwind to bb2
1764   // bb1:
1765   //   call @bar       ; if it throws, unwind to caller
1766   // bb2 (ehpad):
1767   //   catch
1768   //   ...
1769   //
1770   // And the CFG is sorted in this order. Then after placing TRY_TABLE markers
1771   // (and BLOCK markers for the TRY_TABLE's destinations), it will look like:
1772   // block
1773   //   try_table (catch ... 0)
1774   //     call @foo
1775   //     call @bar              ;; if it throws, unwind to caller
1776   //   end_try_table
1777   // end_block                  ;; ehpad (bb2)
1778   // ...
1779   //
1780   // Now if bar() throws, it is going to end up in bb2, when it is supposed
1781   // throw up to the caller. We solve this problem in the same way, but in this
1782   // case 'delegate's immediate argument is the number of block depths + 1,
1783   // which means it rethrows to the caller.
1784   // block exnref                       ;; (new)
1785   //   block
1786   //     try_table (catch ... 0)
1787   //       call @foo
1788   //       try_table (catch_all_ref 2)  ;; (new) to trampoline BB
1789   //         call @bar
1790   //       end_try_table                ;; (new)
1791   //     end_try_table
1792   //   end_block                        ;; ehpad (bb2)
1793   //   ...
1794   // end_block                          ;; (new) caller trampoline BB
1795   // throw_ref                          ;; (new) throw to the caller
1796   //
1797   // Before rewriteDepthImmediates, try_table's catch clauses' argument is a
1798   // trampoline BB from which we throw_ref the exception to the right
1799   // end_try_table. In case of the caller, it will take a new caller-dedicated
1800   // trampoline BB generated by getCallerTrampolineBlock(), which throws the
1801   // exception to the caller.
1802   //
1803   // In case there are multiple calls in a BB that may throw to the caller, they
1804   // can be wrapped together in one nested try_table-end_try_table scope. (In 1,
1805   // this couldn't happen, because may-throwing instruction there had an unwind
1806   // destination, i.e., it was an invoke before, and there could be only one
1807   // invoke within a BB.)
1808 
1809   SmallVector<const MachineBasicBlock *, 8> EHPadStack;
1810   // Range of intructions to be wrapped in a new nested try~delegate or
1811   // try_table~end_try_table. A range exists in a single BB and does not span
1812   // multiple BBs.
1813   using TryRange = std::pair<MachineInstr *, MachineInstr *>;
1814   // In original CFG, <unwind destination BB, a vector of try/try_table ranges>
1815   DenseMap<MachineBasicBlock *, SmallVector<TryRange, 4>> UnwindDestToTryRanges;
1816 
1817   // Gather possibly throwing calls (i.e., previously invokes) whose current
1818   // unwind destination is not the same as the original CFG. (Case 1)
1819 
1820   for (auto &MBB : reverse(MF)) {
1821     bool SeenThrowableInstInBB = false;
1822     for (auto &MI : reverse(MBB)) {
1823       if (WebAssembly::isTry(MI.getOpcode()))
1824         EHPadStack.pop_back();
1825       else if (WebAssembly::isCatch(MI.getOpcode()))
1826         EHPadStack.push_back(MI.getParent());
1827 
1828       // In this loop we only gather calls that have an EH pad to unwind. So
1829       // there will be at most 1 such call (= invoke) in a BB, so after we've
1830       // seen one, we can skip the rest of BB. Also if MBB has no EH pad
1831       // successor or MI does not throw, this is not an invoke.
1832       if (SeenThrowableInstInBB || !MBB.hasEHPadSuccessor() ||
1833           !WebAssembly::mayThrow(MI))
1834         continue;
1835       SeenThrowableInstInBB = true;
1836 
1837       // If the EH pad on the stack top is where this instruction should unwind
1838       // next, we're good.
1839       MachineBasicBlock *UnwindDest = getFakeCallerBlock(MF);
1840       for (auto *Succ : MBB.successors()) {
1841         // Even though semantically a BB can have multiple successors in case an
1842         // exception is not caught by a catchpad, in our backend implementation
1843         // it is guaranteed that a BB can have at most one EH pad successor. For
1844         // details, refer to comments in findWasmUnwindDestinations function in
1845         // SelectionDAGBuilder.cpp.
1846         if (Succ->isEHPad()) {
1847           UnwindDest = Succ;
1848           break;
1849         }
1850       }
1851       if (EHPadStack.back() == UnwindDest)
1852         continue;
1853 
1854       // Include EH_LABELs in the range before and after the invoke
1855       MachineInstr *RangeBegin = &MI, *RangeEnd = &MI;
1856       if (RangeBegin->getIterator() != MBB.begin() &&
1857           std::prev(RangeBegin->getIterator())->isEHLabel())
1858         RangeBegin = &*std::prev(RangeBegin->getIterator());
1859       if (std::next(RangeEnd->getIterator()) != MBB.end() &&
1860           std::next(RangeEnd->getIterator())->isEHLabel())
1861         RangeEnd = &*std::next(RangeEnd->getIterator());
1862 
1863       // If not, record the range.
1864       UnwindDestToTryRanges[UnwindDest].push_back(
1865           TryRange(RangeBegin, RangeEnd));
1866       LLVM_DEBUG(dbgs() << "- Call unwind mismatch: MBB = " << MBB.getName()
1867                         << "\nCall = " << MI
1868                         << "\nOriginal dest = " << UnwindDest->getName()
1869                         << "  Current dest = " << EHPadStack.back()->getName()
1870                         << "\n\n");
1871     }
1872   }
1873 
1874   assert(EHPadStack.empty());
1875 
1876   // Gather possibly throwing calls that are supposed to unwind up to the caller
1877   // if they throw, but currently unwind to an incorrect destination. Unlike the
1878   // loop above, there can be multiple calls within a BB that unwind to the
1879   // caller, which we should group together in a range. (Case 2)
1880 
1881   MachineInstr *RangeBegin = nullptr, *RangeEnd = nullptr; // inclusive
1882 
1883   // Record the range.
1884   auto RecordCallerMismatchRange = [&](const MachineBasicBlock *CurrentDest) {
1885     UnwindDestToTryRanges[getFakeCallerBlock(MF)].push_back(
1886         TryRange(RangeBegin, RangeEnd));
1887     LLVM_DEBUG(dbgs() << "- Call unwind mismatch: MBB = "
1888                       << RangeBegin->getParent()->getName()
1889                       << "\nRange begin = " << *RangeBegin
1890                       << "Range end = " << *RangeEnd
1891                       << "\nOriginal dest = caller  Current dest = "
1892                       << CurrentDest->getName() << "\n\n");
1893     RangeBegin = RangeEnd = nullptr; // Reset range pointers
1894   };
1895 
1896   for (auto &MBB : reverse(MF)) {
1897     bool SeenThrowableInstInBB = false;
1898     for (auto &MI : reverse(MBB)) {
1899       bool MayThrow = WebAssembly::mayThrow(MI);
1900 
1901       // If MBB has an EH pad successor and this is the last instruction that
1902       // may throw, this instruction unwinds to the EH pad and not to the
1903       // caller.
1904       if (MBB.hasEHPadSuccessor() && MayThrow && !SeenThrowableInstInBB)
1905         SeenThrowableInstInBB = true;
1906 
1907       // We wrap up the current range when we see a marker even if we haven't
1908       // finished a BB.
1909       else if (RangeEnd && WebAssembly::isMarker(MI.getOpcode()))
1910         RecordCallerMismatchRange(EHPadStack.back());
1911 
1912       // If EHPadStack is empty, that means it correctly unwinds to the caller
1913       // if it throws, so we're good. If MI does not throw, we're good too.
1914       else if (EHPadStack.empty() || !MayThrow) {
1915       }
1916 
1917       // We found an instruction that unwinds to the caller but currently has an
1918       // incorrect unwind destination. Create a new range or increment the
1919       // currently existing range.
1920       else {
1921         if (!RangeEnd)
1922           RangeBegin = RangeEnd = &MI;
1923         else
1924           RangeBegin = &MI;
1925       }
1926 
1927       // Update EHPadStack.
1928       if (WebAssembly::isTry(MI.getOpcode()))
1929         EHPadStack.pop_back();
1930       else if (WebAssembly::isCatch(MI.getOpcode()))
1931         EHPadStack.push_back(MI.getParent());
1932     }
1933 
1934     if (RangeEnd)
1935       RecordCallerMismatchRange(EHPadStack.back());
1936   }
1937 
1938   assert(EHPadStack.empty());
1939 
1940   // We don't have any unwind destination mismatches to resolve.
1941   if (UnwindDestToTryRanges.empty())
1942     return false;
1943 
1944   // When end_loop is before end_try_table within the same BB in unwind
1945   // destinations, we should split the end_loop into another BB.
1946   if (WebAssembly::WasmEnableExnref)
1947     for (auto &[UnwindDest, _] : UnwindDestToTryRanges)
1948       splitEndLoopBB(UnwindDest);
1949 
1950   // Now we fix the mismatches by wrapping calls with inner try-delegates.
1951   for (auto &P : UnwindDestToTryRanges) {
1952     NumCallUnwindMismatches += P.second.size();
1953     MachineBasicBlock *UnwindDest = P.first;
1954     auto &TryRanges = P.second;
1955 
1956     for (auto Range : TryRanges) {
1957       MachineInstr *RangeBegin = nullptr, *RangeEnd = nullptr;
1958       std::tie(RangeBegin, RangeEnd) = Range;
1959       auto *MBB = RangeBegin->getParent();
1960 
1961       // If this BB has an EH pad successor, i.e., ends with an 'invoke', and if
1962       // the current range contains the invoke, now we are going to wrap the
1963       // invoke with try-delegate or try_table-end_try_table, making the
1964       // 'delegate' or 'end_try_table' BB the new successor instead, so remove
1965       // the EH pad succesor here. The BB may not have an EH pad successor if
1966       // calls in this BB throw to the caller.
1967       if (UnwindDest != getFakeCallerBlock(MF)) {
1968         MachineBasicBlock *EHPad = nullptr;
1969         for (auto *Succ : MBB->successors()) {
1970           if (Succ->isEHPad()) {
1971             EHPad = Succ;
1972             break;
1973           }
1974         }
1975         if (EHPad)
1976           MBB->removeSuccessor(EHPad);
1977       }
1978 
1979       if (WebAssembly::WasmEnableExnref)
1980         addNestedTryTable(RangeBegin, RangeEnd, UnwindDest);
1981       else
1982         addNestedTryDelegate(RangeBegin, RangeEnd, UnwindDest);
1983     }
1984   }
1985 
1986   return true;
1987 }
1988 
1989 // Returns the single destination of try_table, if there is one. All try_table
1990 // we generate in this pass has a single destination, i.e., a single catch
1991 // clause.
1992 static MachineBasicBlock *getSingleUnwindDest(const MachineInstr *TryTable) {
1993   if (TryTable->getOperand(1).getImm() != 1)
1994     return nullptr;
1995   switch (TryTable->getOperand(2).getImm()) {
1996   case wasm::WASM_OPCODE_CATCH:
1997   case wasm::WASM_OPCODE_CATCH_REF:
1998     return TryTable->getOperand(4).getMBB();
1999   case wasm::WASM_OPCODE_CATCH_ALL:
2000   case wasm::WASM_OPCODE_CATCH_ALL_REF:
2001     return TryTable->getOperand(3).getMBB();
2002   default:
2003     llvm_unreachable("try_table: Invalid catch clause\n");
2004   }
2005 }
2006 
2007 bool WebAssemblyCFGStackify::fixCatchUnwindMismatches(MachineFunction &MF) {
2008   // This function is used for both the legacy EH and the standard (exnref) EH,
2009   // and the reason we have unwind mismatches is the same for the both of them,
2010   // but the code examples in the comments are going to be different. To make
2011   // the description less confusing, we write the basically same comments twice,
2012   // once for the legacy EH and the standard EH.
2013   //
2014   // -- Legacy EH --------------------------------------------------------------
2015   //
2016   // There is another kind of unwind destination mismatches besides call unwind
2017   // mismatches, which we will call "catch unwind mismatches". See this example
2018   // after the marker placement:
2019   // try
2020   //   try
2021   //     call @foo
2022   //   catch __cpp_exception  ;; ehpad A (next unwind dest: caller)
2023   //     ...
2024   //   end_try
2025   // catch_all                ;; ehpad B
2026   //   ...
2027   // end_try
2028   //
2029   // 'call @foo's unwind destination is the ehpad A. But suppose 'call @foo'
2030   // throws a foreign exception that is not caught by ehpad A, and its next
2031   // destination should be the caller. But after control flow linearization,
2032   // another EH pad can be placed in between (e.g. ehpad B here), making the
2033   // next unwind destination incorrect. In this case, the foreign exception will
2034   // instead go to ehpad B and will be caught there instead. In this example the
2035   // correct next unwind destination is the caller, but it can be another outer
2036   // catch in other cases.
2037   //
2038   // There is no specific 'call' or 'throw' instruction to wrap with a
2039   // try-delegate, so we wrap the whole try-catch-end with a try-delegate and
2040   // make it rethrow to the right destination, which is the caller in the
2041   // example below:
2042   // try
2043   //   try                     ;; (new)
2044   //     try
2045   //       call @foo
2046   //     catch __cpp_exception ;; ehpad A (next unwind dest: caller)
2047   //       ...
2048   //     end_try
2049   //   delegate 1 (caller)     ;; (new)
2050   // catch_all                 ;; ehpad B
2051   //   ...
2052   // end_try
2053   //
2054   // The right destination may be another EH pad or the caller. (The example
2055   // here shows the case it is the caller.)
2056   //
2057   // -- Standard EH ------------------------------------------------------------
2058   //
2059   // There is another kind of unwind destination mismatches besides call unwind
2060   // mismatches, which we will call "catch unwind mismatches". See this example
2061   // after the marker placement:
2062   // block
2063   //   try_table (catch_all_ref 0)
2064   //     block
2065   //       try_table (catch ... 0)
2066   //         call @foo
2067   //       end_try_table
2068   //     end_block                  ;; ehpad A (next unwind dest: caller)
2069   //     ...
2070   //   end_try_table
2071   // end_block                      ;; ehpad B
2072   // ...
2073   //
2074   // 'call @foo's unwind destination is the ehpad A. But suppose 'call @foo'
2075   // throws a foreign exception that is not caught by ehpad A, and its next
2076   // destination should be the caller. But after control flow linearization,
2077   // another EH pad can be placed in between (e.g. ehpad B here), making the
2078   // next unwind destination incorrect. In this case, the foreign exception will
2079   // instead go to ehpad B and will be caught there instead. In this example the
2080   // correct next unwind destination is the caller, but it can be another outer
2081   // catch in other cases.
2082   //
2083   // There is no specific 'call' or 'throw' instruction to wrap with an inner
2084   // try_table-end_try_table, so we wrap the whole try_table-end_try_table with
2085   // an inner try_table-end_try_table that sends the exception to a trampoline
2086   // BB. We rethrow the sent exception using a throw_ref to the right
2087   // destination, which is the caller in the example below:
2088   // block exnref
2089   //   block
2090   //     try_table (catch_all_ref 0)
2091   //       try_table (catch_all_ref 2)  ;; (new) to trampoline
2092   //         block
2093   //           try_table (catch ... 0)
2094   //             call @foo
2095   //           end_try_table
2096   //         end_block                  ;; ehpad A (next unwind dest: caller)
2097   //       end_try_table                ;; (new)
2098   //       ...
2099   //     end_try_table
2100   //   end_block                        ;; ehpad B
2101   //   ...
2102   // end_block                          ;; (new) caller trampoline BB
2103   // throw_ref                          ;; (new) throw to the caller
2104   //
2105   // The right destination may be another EH pad or the caller. (The example
2106   // here shows the case it is the caller.)
2107 
2108   const auto *EHInfo = MF.getWasmEHFuncInfo();
2109   assert(EHInfo);
2110   SmallVector<const MachineBasicBlock *, 8> EHPadStack;
2111   // For EH pads that have catch unwind mismatches, a map of <EH pad, its
2112   // correct unwind destination>.
2113   DenseMap<MachineBasicBlock *, MachineBasicBlock *> EHPadToUnwindDest;
2114 
2115   for (auto &MBB : reverse(MF)) {
2116     for (auto &MI : reverse(MBB)) {
2117       if (MI.getOpcode() == WebAssembly::TRY)
2118         EHPadStack.pop_back();
2119       else if (MI.getOpcode() == WebAssembly::TRY_TABLE) {
2120         // We want to exclude try_tables created in fixCallUnwindMismatches.
2121         // Check if the try_table's unwind destination matches the EH pad stack
2122         // top. If it is created in fixCallUnwindMismatches, it wouldn't.
2123         if (getSingleUnwindDest(&MI) == EHPadStack.back())
2124           EHPadStack.pop_back();
2125       } else if (MI.getOpcode() == WebAssembly::DELEGATE)
2126         EHPadStack.push_back(&MBB);
2127       else if (WebAssembly::isCatch(MI.getOpcode())) {
2128         auto *EHPad = &MBB;
2129 
2130         // If the BB has a catch pseudo instruction but is not marked as an EH
2131         // pad, it's a trampoline BB we created in fixCallUnwindMismatches. Skip
2132         // it.
2133         if (!EHPad->isEHPad())
2134           continue;
2135 
2136         // catch_all always catches an exception, so we don't need to do
2137         // anything
2138         if (WebAssembly::isCatchAll(MI.getOpcode())) {
2139         }
2140 
2141         // This can happen when the unwind dest was removed during the
2142         // optimization, e.g. because it was unreachable.
2143         else if (EHPadStack.empty() && EHInfo->hasUnwindDest(EHPad)) {
2144           LLVM_DEBUG(dbgs() << "EHPad (" << EHPad->getName()
2145                             << "'s unwind destination does not exist anymore"
2146                             << "\n\n");
2147         }
2148 
2149         // The EHPad's next unwind destination is the caller, but we incorrectly
2150         // unwind to another EH pad.
2151         else if (!EHPadStack.empty() && !EHInfo->hasUnwindDest(EHPad)) {
2152           EHPadToUnwindDest[EHPad] = getFakeCallerBlock(MF);
2153           LLVM_DEBUG(dbgs()
2154                      << "- Catch unwind mismatch:\nEHPad = " << EHPad->getName()
2155                      << "  Original dest = caller  Current dest = "
2156                      << EHPadStack.back()->getName() << "\n\n");
2157         }
2158 
2159         // The EHPad's next unwind destination is an EH pad, whereas we
2160         // incorrectly unwind to another EH pad.
2161         else if (!EHPadStack.empty() && EHInfo->hasUnwindDest(EHPad)) {
2162           auto *UnwindDest = EHInfo->getUnwindDest(EHPad);
2163           if (EHPadStack.back() != UnwindDest) {
2164             EHPadToUnwindDest[EHPad] = UnwindDest;
2165             LLVM_DEBUG(dbgs() << "- Catch unwind mismatch:\nEHPad = "
2166                               << EHPad->getName() << "  Original dest = "
2167                               << UnwindDest->getName() << "  Current dest = "
2168                               << EHPadStack.back()->getName() << "\n\n");
2169           }
2170         }
2171 
2172         EHPadStack.push_back(EHPad);
2173       }
2174     }
2175   }
2176 
2177   assert(EHPadStack.empty());
2178   if (EHPadToUnwindDest.empty())
2179     return false;
2180 
2181   // When end_loop is before end_try_table within the same BB in unwind
2182   // destinations, we should split the end_loop into another BB.
2183   for (auto &[_, UnwindDest] : EHPadToUnwindDest)
2184     splitEndLoopBB(UnwindDest);
2185 
2186   NumCatchUnwindMismatches += EHPadToUnwindDest.size();
2187   SmallPtrSet<MachineBasicBlock *, 4> NewEndTryBBs;
2188 
2189   for (auto &[EHPad, UnwindDest] : EHPadToUnwindDest) {
2190     MachineInstr *Try = EHPadToTry[EHPad];
2191     MachineInstr *EndTry = BeginToEnd[Try];
2192     if (WebAssembly::WasmEnableExnref) {
2193       addNestedTryTable(Try, EndTry, UnwindDest);
2194     } else {
2195       addNestedTryDelegate(Try, EndTry, UnwindDest);
2196       NewEndTryBBs.insert(EndTry->getParent());
2197     }
2198   }
2199 
2200   if (WebAssembly::WasmEnableExnref)
2201     return true;
2202 
2203   // Adding a try-delegate wrapping an existing try-catch-end can make existing
2204   // branch destination BBs invalid. For example,
2205   //
2206   // - Before:
2207   // bb0:
2208   //   block
2209   //     br bb3
2210   // bb1:
2211   //     try
2212   //       ...
2213   // bb2: (ehpad)
2214   //     catch
2215   // bb3:
2216   //     end_try
2217   //   end_block   ;; 'br bb3' targets here
2218   //
2219   // Suppose this try-catch-end has a catch unwind mismatch, so we need to wrap
2220   // this with a try-delegate. Then this becomes:
2221   //
2222   // - After:
2223   // bb0:
2224   //   block
2225   //     br bb3    ;; invalid destination!
2226   // bb1:
2227   //     try       ;; (new instruction)
2228   //       try
2229   //         ...
2230   // bb2: (ehpad)
2231   //       catch
2232   // bb3:
2233   //       end_try ;; 'br bb3' still incorrectly targets here!
2234   // delegate_bb:  ;; (new BB)
2235   //     delegate  ;; (new instruction)
2236   // split_bb:     ;; (new BB)
2237   //   end_block
2238   //
2239   // Now 'br bb3' incorrectly branches to an inner scope.
2240   //
2241   // As we can see in this case, when branches target a BB that has both
2242   // 'end_try' and 'end_block' and the BB is split to insert a 'delegate', we
2243   // have to remap existing branch destinations so that they target not the
2244   // 'end_try' BB but the new 'end_block' BB. There can be multiple 'delegate's
2245   // in between, so we try to find the next BB with 'end_block' instruction. In
2246   // this example, the 'br bb3' instruction should be remapped to 'br split_bb'.
2247   for (auto &MBB : MF) {
2248     for (auto &MI : MBB) {
2249       if (MI.isTerminator()) {
2250         for (auto &MO : MI.operands()) {
2251           if (MO.isMBB() && NewEndTryBBs.count(MO.getMBB())) {
2252             auto *BrDest = MO.getMBB();
2253             bool FoundEndBlock = false;
2254             for (; std::next(BrDest->getIterator()) != MF.end();
2255                  BrDest = BrDest->getNextNode()) {
2256               for (const auto &MI : *BrDest) {
2257                 if (MI.getOpcode() == WebAssembly::END_BLOCK) {
2258                   FoundEndBlock = true;
2259                   break;
2260                 }
2261               }
2262               if (FoundEndBlock)
2263                 break;
2264             }
2265             assert(FoundEndBlock);
2266             MO.setMBB(BrDest);
2267           }
2268         }
2269       }
2270     }
2271   }
2272 
2273   return true;
2274 }
2275 
2276 void WebAssemblyCFGStackify::recalculateScopeTops(MachineFunction &MF) {
2277   // Renumber BBs and recalculate ScopeTop info because new BBs might have been
2278   // created and inserted during fixing unwind mismatches.
2279   MF.RenumberBlocks();
2280   MDT->updateBlockNumbers();
2281   ScopeTops.clear();
2282   ScopeTops.resize(MF.getNumBlockIDs());
2283   for (auto &MBB : reverse(MF)) {
2284     for (auto &MI : reverse(MBB)) {
2285       if (ScopeTops[MBB.getNumber()])
2286         break;
2287       switch (MI.getOpcode()) {
2288       case WebAssembly::END_BLOCK:
2289       case WebAssembly::END_LOOP:
2290       case WebAssembly::END_TRY:
2291       case WebAssembly::END_TRY_TABLE:
2292       case WebAssembly::DELEGATE:
2293         updateScopeTops(EndToBegin[&MI]->getParent(), &MBB);
2294         break;
2295       case WebAssembly::CATCH_LEGACY:
2296       case WebAssembly::CATCH_ALL_LEGACY:
2297         updateScopeTops(EHPadToTry[&MBB]->getParent(), &MBB);
2298         break;
2299       }
2300     }
2301   }
2302 }
2303 
2304 /// In normal assembly languages, when the end of a function is unreachable,
2305 /// because the function ends in an infinite loop or a noreturn call or similar,
2306 /// it isn't necessary to worry about the function return type at the end of
2307 /// the function, because it's never reached. However, in WebAssembly, blocks
2308 /// that end at the function end need to have a return type signature that
2309 /// matches the function signature, even though it's unreachable. This function
2310 /// checks for such cases and fixes up the signatures.
2311 void WebAssemblyCFGStackify::fixEndsAtEndOfFunction(MachineFunction &MF) {
2312   const auto &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
2313 
2314   if (MFI.getResults().empty())
2315     return;
2316 
2317   // MCInstLower will add the proper types to multivalue signatures based on the
2318   // function return type
2319   WebAssembly::BlockType RetType =
2320       MFI.getResults().size() > 1
2321           ? WebAssembly::BlockType::Multivalue
2322           : WebAssembly::BlockType(
2323                 WebAssembly::toValType(MFI.getResults().front()));
2324 
2325   SmallVector<MachineBasicBlock::reverse_iterator, 4> Worklist;
2326   Worklist.push_back(MF.rbegin()->rbegin());
2327 
2328   auto Process = [&](MachineBasicBlock::reverse_iterator It) {
2329     auto *MBB = It->getParent();
2330     while (It != MBB->rend()) {
2331       MachineInstr &MI = *It++;
2332       if (MI.isPosition() || MI.isDebugInstr())
2333         continue;
2334       switch (MI.getOpcode()) {
2335       case WebAssembly::END_TRY: {
2336         // If a 'try''s return type is fixed, both its try body and catch body
2337         // should satisfy the return type, so we need to search 'end'
2338         // instructions before its corresponding 'catch' too.
2339         auto *EHPad = TryToEHPad.lookup(EndToBegin[&MI]);
2340         assert(EHPad);
2341         auto NextIt =
2342             std::next(WebAssembly::findCatch(EHPad)->getReverseIterator());
2343         if (NextIt != EHPad->rend())
2344           Worklist.push_back(NextIt);
2345         [[fallthrough]];
2346       }
2347       case WebAssembly::END_BLOCK:
2348       case WebAssembly::END_LOOP:
2349       case WebAssembly::END_TRY_TABLE:
2350       case WebAssembly::DELEGATE:
2351         EndToBegin[&MI]->getOperand(0).setImm(int32_t(RetType));
2352         continue;
2353       default:
2354         // Something other than an `end`. We're done for this BB.
2355         return;
2356       }
2357     }
2358     // We've reached the beginning of a BB. Continue the search in the previous
2359     // BB.
2360     Worklist.push_back(MBB->getPrevNode()->rbegin());
2361   };
2362 
2363   while (!Worklist.empty())
2364     Process(Worklist.pop_back_val());
2365 }
2366 
2367 // WebAssembly functions end with an end instruction, as if the function body
2368 // were a block.
2369 static void appendEndToFunction(MachineFunction &MF,
2370                                 const WebAssemblyInstrInfo &TII) {
2371   BuildMI(MF.back(), MF.back().end(),
2372           MF.back().findPrevDebugLoc(MF.back().end()),
2373           TII.get(WebAssembly::END_FUNCTION));
2374 }
2375 
2376 /// Insert BLOCK/LOOP/TRY/TRY_TABLE markers at appropriate places.
2377 void WebAssemblyCFGStackify::placeMarkers(MachineFunction &MF) {
2378   // We allocate one more than the number of blocks in the function to
2379   // accommodate for the possible fake block we may insert at the end.
2380   ScopeTops.resize(MF.getNumBlockIDs() + 1);
2381   // Place the LOOP for MBB if MBB is the header of a loop.
2382   for (auto &MBB : MF)
2383     placeLoopMarker(MBB);
2384 
2385   const MCAsmInfo *MCAI = MF.getTarget().getMCAsmInfo();
2386   for (auto &MBB : MF) {
2387     if (MBB.isEHPad()) {
2388       // Place the TRY/TRY_TABLE for MBB if MBB is the EH pad of an exception.
2389       if (MCAI->getExceptionHandlingType() == ExceptionHandling::Wasm &&
2390           MF.getFunction().hasPersonalityFn()) {
2391         if (WebAssembly::WasmEnableExnref)
2392           placeTryTableMarker(MBB);
2393         else
2394           placeTryMarker(MBB);
2395       }
2396     } else {
2397       // Place the BLOCK for MBB if MBB is branched to from above.
2398       placeBlockMarker(MBB);
2399     }
2400   }
2401 
2402   // Fix mismatches in unwind destinations induced by linearizing the code.
2403   if (MCAI->getExceptionHandlingType() == ExceptionHandling::Wasm &&
2404       MF.getFunction().hasPersonalityFn()) {
2405     bool MismatchFixed = fixCallUnwindMismatches(MF);
2406     MismatchFixed |= fixCatchUnwindMismatches(MF);
2407     if (MismatchFixed)
2408       recalculateScopeTops(MF);
2409   }
2410 }
2411 
2412 unsigned WebAssemblyCFGStackify::getBranchDepth(
2413     const SmallVectorImpl<EndMarkerInfo> &Stack, const MachineBasicBlock *MBB) {
2414   unsigned Depth = 0;
2415   for (auto X : reverse(Stack)) {
2416     if (X.first == MBB)
2417       break;
2418     ++Depth;
2419   }
2420   assert(Depth < Stack.size() && "Branch destination should be in scope");
2421   return Depth;
2422 }
2423 
2424 unsigned WebAssemblyCFGStackify::getDelegateDepth(
2425     const SmallVectorImpl<EndMarkerInfo> &Stack, const MachineBasicBlock *MBB) {
2426   if (MBB == FakeCallerBB)
2427     return Stack.size();
2428   // Delegate's destination is either a catch or a another delegate BB. When the
2429   // destination is another delegate, we can compute the argument in the same
2430   // way as branches, because the target delegate BB only contains the single
2431   // delegate instruction.
2432   if (!MBB->isEHPad()) // Target is a delegate BB
2433     return getBranchDepth(Stack, MBB);
2434 
2435   // When the delegate's destination is a catch BB, we need to use its
2436   // corresponding try's end_try BB because Stack contains each marker's end BB.
2437   // Also we need to check if the end marker instruction matches, because a
2438   // single BB can contain multiple end markers, like this:
2439   // bb:
2440   //   END_BLOCK
2441   //   END_TRY
2442   //   END_BLOCK
2443   //   END_TRY
2444   //   ...
2445   //
2446   // In case of branches getting the immediate that targets any of these is
2447   // fine, but delegate has to exactly target the correct try.
2448   unsigned Depth = 0;
2449   const MachineInstr *EndTry = BeginToEnd[EHPadToTry[MBB]];
2450   for (auto X : reverse(Stack)) {
2451     if (X.first == EndTry->getParent() && X.second == EndTry)
2452       break;
2453     ++Depth;
2454   }
2455   assert(Depth < Stack.size() && "Delegate destination should be in scope");
2456   return Depth;
2457 }
2458 
2459 unsigned WebAssemblyCFGStackify::getRethrowDepth(
2460     const SmallVectorImpl<EndMarkerInfo> &Stack,
2461     const SmallVectorImpl<const MachineBasicBlock *> &EHPadStack) {
2462   unsigned Depth = 0;
2463   // In our current implementation, rethrows always rethrow the exception caught
2464   // by the innermost enclosing catch. This means while traversing Stack in the
2465   // reverse direction, when we encounter END_TRY, we should check if the
2466   // END_TRY corresponds to the current innermost EH pad. For example:
2467   // try
2468   //   ...
2469   // catch         ;; (a)
2470   //   try
2471   //     rethrow 1 ;; (b)
2472   //   catch       ;; (c)
2473   //     rethrow 0 ;; (d)
2474   //   end         ;; (e)
2475   // end           ;; (f)
2476   //
2477   // When we are at 'rethrow' (d), while reversely traversing Stack the first
2478   // 'end' we encounter is the 'end' (e), which corresponds to the 'catch' (c).
2479   // And 'rethrow' (d) rethrows the exception caught by 'catch' (c), so we stop
2480   // there and the depth should be 0. But when we are at 'rethrow' (b), it
2481   // rethrows the exception caught by 'catch' (a), so when traversing Stack
2482   // reversely, we should skip the 'end' (e) and choose 'end' (f), which
2483   // corresponds to 'catch' (a).
2484   for (auto X : reverse(Stack)) {
2485     const MachineInstr *End = X.second;
2486     if (End->getOpcode() == WebAssembly::END_TRY) {
2487       auto *EHPad = TryToEHPad[EndToBegin[End]];
2488       if (EHPadStack.back() == EHPad)
2489         break;
2490     }
2491     ++Depth;
2492   }
2493   assert(Depth < Stack.size() && "Rethrow destination should be in scope");
2494   return Depth;
2495 }
2496 
2497 void WebAssemblyCFGStackify::rewriteDepthImmediates(MachineFunction &MF) {
2498   // Now rewrite references to basic blocks to be depth immediates.
2499   SmallVector<EndMarkerInfo, 8> Stack;
2500   SmallVector<const MachineBasicBlock *, 8> EHPadStack;
2501 
2502   auto RewriteOperands = [&](MachineInstr &MI) {
2503     // Rewrite MBB operands to be depth immediates.
2504     SmallVector<MachineOperand, 4> Ops(MI.operands());
2505     while (MI.getNumOperands() > 0)
2506       MI.removeOperand(MI.getNumOperands() - 1);
2507     for (auto MO : Ops) {
2508       if (MO.isMBB()) {
2509         if (MI.getOpcode() == WebAssembly::DELEGATE)
2510           MO = MachineOperand::CreateImm(getDelegateDepth(Stack, MO.getMBB()));
2511         else
2512           MO = MachineOperand::CreateImm(getBranchDepth(Stack, MO.getMBB()));
2513       }
2514       MI.addOperand(MF, MO);
2515     }
2516   };
2517 
2518   for (auto &MBB : reverse(MF)) {
2519     for (MachineInstr &MI : llvm::reverse(MBB)) {
2520       switch (MI.getOpcode()) {
2521       case WebAssembly::BLOCK:
2522       case WebAssembly::TRY:
2523         assert(ScopeTops[Stack.back().first->getNumber()]->getNumber() <=
2524                    MBB.getNumber() &&
2525                "Block/try/try_table marker should be balanced");
2526         Stack.pop_back();
2527         break;
2528 
2529       case WebAssembly::TRY_TABLE:
2530         assert(ScopeTops[Stack.back().first->getNumber()]->getNumber() <=
2531                    MBB.getNumber() &&
2532                "Block/try/try_table marker should be balanced");
2533         Stack.pop_back();
2534         RewriteOperands(MI);
2535         break;
2536 
2537       case WebAssembly::LOOP:
2538         assert(Stack.back().first == &MBB && "Loop top should be balanced");
2539         Stack.pop_back();
2540         break;
2541 
2542       case WebAssembly::END_TRY: {
2543         auto *EHPad = TryToEHPad[EndToBegin[&MI]];
2544         EHPadStack.push_back(EHPad);
2545         [[fallthrough]];
2546       }
2547       case WebAssembly::END_BLOCK:
2548       case WebAssembly::END_TRY_TABLE:
2549         Stack.push_back(std::make_pair(&MBB, &MI));
2550         break;
2551 
2552       case WebAssembly::END_LOOP:
2553         Stack.push_back(std::make_pair(EndToBegin[&MI]->getParent(), &MI));
2554         break;
2555 
2556       case WebAssembly::CATCH_LEGACY:
2557       case WebAssembly::CATCH_ALL_LEGACY:
2558         EHPadStack.pop_back();
2559         break;
2560 
2561       case WebAssembly::RETHROW:
2562         MI.getOperand(0).setImm(getRethrowDepth(Stack, EHPadStack));
2563         break;
2564 
2565       case WebAssembly::DELEGATE:
2566         RewriteOperands(MI);
2567         Stack.push_back(std::make_pair(&MBB, &MI));
2568         break;
2569 
2570       default:
2571         if (MI.isTerminator())
2572           RewriteOperands(MI);
2573         break;
2574       }
2575     }
2576   }
2577   assert(Stack.empty() && "Control flow should be balanced");
2578 }
2579 
2580 void WebAssemblyCFGStackify::cleanupFunctionData(MachineFunction &MF) {
2581   if (FakeCallerBB)
2582     MF.deleteMachineBasicBlock(FakeCallerBB);
2583   AppendixBB = FakeCallerBB = CallerTrampolineBB = nullptr;
2584 }
2585 
2586 void WebAssemblyCFGStackify::releaseMemory() {
2587   ScopeTops.clear();
2588   BeginToEnd.clear();
2589   EndToBegin.clear();
2590   TryToEHPad.clear();
2591   EHPadToTry.clear();
2592   UnwindDestToTrampoline.clear();
2593 }
2594 
2595 bool WebAssemblyCFGStackify::runOnMachineFunction(MachineFunction &MF) {
2596   LLVM_DEBUG(dbgs() << "********** CFG Stackifying **********\n"
2597                        "********** Function: "
2598                     << MF.getName() << '\n');
2599   const MCAsmInfo *MCAI = MF.getTarget().getMCAsmInfo();
2600   MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
2601 
2602   releaseMemory();
2603 
2604   // Liveness is not tracked for VALUE_STACK physreg.
2605   MF.getRegInfo().invalidateLiveness();
2606 
2607   // Place the BLOCK/LOOP/TRY/TRY_TABLE markers to indicate the beginnings of
2608   // scopes.
2609   placeMarkers(MF);
2610 
2611   // Remove unnecessary instructions possibly introduced by try/end_trys.
2612   if (MCAI->getExceptionHandlingType() == ExceptionHandling::Wasm &&
2613       MF.getFunction().hasPersonalityFn() && !WebAssembly::WasmEnableExnref)
2614     removeUnnecessaryInstrs(MF);
2615 
2616   // Convert MBB operands in terminators to relative depth immediates.
2617   rewriteDepthImmediates(MF);
2618 
2619   // Fix up block/loop/try/try_table signatures at the end of the function to
2620   // conform to WebAssembly's rules.
2621   fixEndsAtEndOfFunction(MF);
2622 
2623   // Add an end instruction at the end of the function body.
2624   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
2625   appendEndToFunction(MF, TII);
2626 
2627   cleanupFunctionData(MF);
2628 
2629   MF.getInfo<WebAssemblyFunctionInfo>()->setCFGStackified();
2630   return true;
2631 }
2632