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