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, and TRY markers to mark the start of scopes,
13 /// since scope boundaries serve as the labels for WebAssembly's control
14 /// 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 "WebAssembly.h"
25 #include "WebAssemblyExceptionInfo.h"
26 #include "WebAssemblyMachineFunctionInfo.h"
27 #include "WebAssemblySortRegion.h"
28 #include "WebAssemblySubtarget.h"
29 #include "WebAssemblyUtilities.h"
30 #include "llvm/ADT/Statistic.h"
31 #include "llvm/CodeGen/MachineDominators.h"
32 #include "llvm/CodeGen/MachineInstrBuilder.h"
33 #include "llvm/CodeGen/MachineLoopInfo.h"
34 #include "llvm/MC/MCAsmInfo.h"
35 #include "llvm/Target/TargetMachine.h"
36 using namespace llvm;
37 using WebAssembly::SortRegionInfo;
38 
39 #define DEBUG_TYPE "wasm-cfg-stackify"
40 
41 STATISTIC(NumUnwindMismatches, "Number of EH pad unwind mismatches found");
42 
43 namespace {
44 class WebAssemblyCFGStackify final : public MachineFunctionPass {
45   StringRef getPassName() const override { return "WebAssembly CFG Stackify"; }
46 
47   void getAnalysisUsage(AnalysisUsage &AU) const override {
48     AU.addRequired<MachineDominatorTree>();
49     AU.addRequired<MachineLoopInfo>();
50     AU.addRequired<WebAssemblyExceptionInfo>();
51     MachineFunctionPass::getAnalysisUsage(AU);
52   }
53 
54   bool runOnMachineFunction(MachineFunction &MF) override;
55 
56   // For each block whose label represents the end of a scope, record the block
57   // which holds the beginning of the scope. This will allow us to quickly skip
58   // over scoped regions when walking blocks.
59   SmallVector<MachineBasicBlock *, 8> ScopeTops;
60 
61   // Placing markers.
62   void placeMarkers(MachineFunction &MF);
63   void placeBlockMarker(MachineBasicBlock &MBB);
64   void placeLoopMarker(MachineBasicBlock &MBB);
65   void placeTryMarker(MachineBasicBlock &MBB);
66   void removeUnnecessaryInstrs(MachineFunction &MF);
67   bool fixUnwindMismatches(MachineFunction &MF);
68   void rewriteDepthImmediates(MachineFunction &MF);
69   void fixEndsAtEndOfFunction(MachineFunction &MF);
70 
71   // For each BLOCK|LOOP|TRY, the corresponding END_(BLOCK|LOOP|TRY).
72   DenseMap<const MachineInstr *, MachineInstr *> BeginToEnd;
73   // For each END_(BLOCK|LOOP|TRY), the corresponding BLOCK|LOOP|TRY.
74   DenseMap<const MachineInstr *, MachineInstr *> EndToBegin;
75   // <TRY marker, EH pad> map
76   DenseMap<const MachineInstr *, MachineBasicBlock *> TryToEHPad;
77   // <EH pad, TRY marker> map
78   DenseMap<const MachineBasicBlock *, MachineInstr *> EHPadToTry;
79 
80   // There can be an appendix block at the end of each function, shared for:
81   // - creating a correct signature for fallthrough returns
82   // - target for rethrows that need to unwind to the caller, but are trapped
83   //   inside another try/catch
84   MachineBasicBlock *AppendixBB = nullptr;
85   MachineBasicBlock *getAppendixBlock(MachineFunction &MF) {
86     if (!AppendixBB) {
87       AppendixBB = MF.CreateMachineBasicBlock();
88       // Give it a fake predecessor so that AsmPrinter prints its label.
89       AppendixBB->addSuccessor(AppendixBB);
90       MF.push_back(AppendixBB);
91     }
92     return AppendixBB;
93   }
94 
95   // Helper functions to register / unregister scope information created by
96   // marker instructions.
97   void registerScope(MachineInstr *Begin, MachineInstr *End);
98   void registerTryScope(MachineInstr *Begin, MachineInstr *End,
99                         MachineBasicBlock *EHPad);
100   void unregisterScope(MachineInstr *Begin);
101 
102 public:
103   static char ID; // Pass identification, replacement for typeid
104   WebAssemblyCFGStackify() : MachineFunctionPass(ID) {}
105   ~WebAssemblyCFGStackify() override { releaseMemory(); }
106   void releaseMemory() override;
107 };
108 } // end anonymous namespace
109 
110 char WebAssemblyCFGStackify::ID = 0;
111 INITIALIZE_PASS(WebAssemblyCFGStackify, DEBUG_TYPE,
112                 "Insert BLOCK/LOOP/TRY markers for WebAssembly scopes", false,
113                 false)
114 
115 FunctionPass *llvm::createWebAssemblyCFGStackify() {
116   return new WebAssemblyCFGStackify();
117 }
118 
119 /// Test whether Pred has any terminators explicitly branching to MBB, as
120 /// opposed to falling through. Note that it's possible (eg. in unoptimized
121 /// code) for a branch instruction to both branch to a block and fallthrough
122 /// to it, so we check the actual branch operands to see if there are any
123 /// explicit mentions.
124 static bool explicitlyBranchesTo(MachineBasicBlock *Pred,
125                                  MachineBasicBlock *MBB) {
126   for (MachineInstr &MI : Pred->terminators())
127     for (MachineOperand &MO : MI.explicit_operands())
128       if (MO.isMBB() && MO.getMBB() == MBB)
129         return true;
130   return false;
131 }
132 
133 // Returns an iterator to the earliest position possible within the MBB,
134 // satisfying the restrictions given by BeforeSet and AfterSet. BeforeSet
135 // contains instructions that should go before the marker, and AfterSet contains
136 // ones that should go after the marker. In this function, AfterSet is only
137 // used for sanity checking.
138 static MachineBasicBlock::iterator
139 getEarliestInsertPos(MachineBasicBlock *MBB,
140                      const SmallPtrSet<const MachineInstr *, 4> &BeforeSet,
141                      const SmallPtrSet<const MachineInstr *, 4> &AfterSet) {
142   auto InsertPos = MBB->end();
143   while (InsertPos != MBB->begin()) {
144     if (BeforeSet.count(&*std::prev(InsertPos))) {
145 #ifndef NDEBUG
146       // Sanity check
147       for (auto Pos = InsertPos, E = MBB->begin(); Pos != E; --Pos)
148         assert(!AfterSet.count(&*std::prev(Pos)));
149 #endif
150       break;
151     }
152     --InsertPos;
153   }
154   return InsertPos;
155 }
156 
157 // Returns an iterator to the latest position possible within the MBB,
158 // satisfying the restrictions given by BeforeSet and AfterSet. BeforeSet
159 // contains instructions that should go before the marker, and AfterSet contains
160 // ones that should go after the marker. In this function, BeforeSet is only
161 // used for sanity checking.
162 static MachineBasicBlock::iterator
163 getLatestInsertPos(MachineBasicBlock *MBB,
164                    const SmallPtrSet<const MachineInstr *, 4> &BeforeSet,
165                    const SmallPtrSet<const MachineInstr *, 4> &AfterSet) {
166   auto InsertPos = MBB->begin();
167   while (InsertPos != MBB->end()) {
168     if (AfterSet.count(&*InsertPos)) {
169 #ifndef NDEBUG
170       // Sanity check
171       for (auto Pos = InsertPos, E = MBB->end(); Pos != E; ++Pos)
172         assert(!BeforeSet.count(&*Pos));
173 #endif
174       break;
175     }
176     ++InsertPos;
177   }
178   return InsertPos;
179 }
180 
181 void WebAssemblyCFGStackify::registerScope(MachineInstr *Begin,
182                                            MachineInstr *End) {
183   BeginToEnd[Begin] = End;
184   EndToBegin[End] = Begin;
185 }
186 
187 void WebAssemblyCFGStackify::registerTryScope(MachineInstr *Begin,
188                                               MachineInstr *End,
189                                               MachineBasicBlock *EHPad) {
190   registerScope(Begin, End);
191   TryToEHPad[Begin] = EHPad;
192   EHPadToTry[EHPad] = Begin;
193 }
194 
195 void WebAssemblyCFGStackify::unregisterScope(MachineInstr *Begin) {
196   assert(BeginToEnd.count(Begin));
197   MachineInstr *End = BeginToEnd[Begin];
198   assert(EndToBegin.count(End));
199   BeginToEnd.erase(Begin);
200   EndToBegin.erase(End);
201   MachineBasicBlock *EHPad = TryToEHPad.lookup(Begin);
202   if (EHPad) {
203     assert(EHPadToTry.count(EHPad));
204     TryToEHPad.erase(Begin);
205     EHPadToTry.erase(EHPad);
206   }
207 }
208 
209 /// Insert a BLOCK marker for branches to MBB (if needed).
210 // TODO Consider a more generalized way of handling block (and also loop and
211 // try) signatures when we implement the multi-value proposal later.
212 void WebAssemblyCFGStackify::placeBlockMarker(MachineBasicBlock &MBB) {
213   assert(!MBB.isEHPad());
214   MachineFunction &MF = *MBB.getParent();
215   auto &MDT = getAnalysis<MachineDominatorTree>();
216   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
217   const auto &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
218 
219   // First compute the nearest common dominator of all forward non-fallthrough
220   // predecessors so that we minimize the time that the BLOCK is on the stack,
221   // which reduces overall stack height.
222   MachineBasicBlock *Header = nullptr;
223   bool IsBranchedTo = false;
224   bool IsBrOnExn = false;
225   MachineInstr *BrOnExn = nullptr;
226   int MBBNumber = MBB.getNumber();
227   for (MachineBasicBlock *Pred : MBB.predecessors()) {
228     if (Pred->getNumber() < MBBNumber) {
229       Header = Header ? MDT.findNearestCommonDominator(Header, Pred) : Pred;
230       if (explicitlyBranchesTo(Pred, &MBB)) {
231         IsBranchedTo = true;
232         if (Pred->getFirstTerminator()->getOpcode() == WebAssembly::BR_ON_EXN) {
233           IsBrOnExn = true;
234           assert(!BrOnExn && "There should be only one br_on_exn per block");
235           BrOnExn = &*Pred->getFirstTerminator();
236         }
237       }
238     }
239   }
240   if (!Header)
241     return;
242   if (!IsBranchedTo)
243     return;
244 
245   assert(&MBB != &MF.front() && "Header blocks shouldn't have predecessors");
246   MachineBasicBlock *LayoutPred = MBB.getPrevNode();
247 
248   // If the nearest common dominator is inside a more deeply nested context,
249   // walk out to the nearest scope which isn't more deeply nested.
250   for (MachineFunction::iterator I(LayoutPred), E(Header); I != E; --I) {
251     if (MachineBasicBlock *ScopeTop = ScopeTops[I->getNumber()]) {
252       if (ScopeTop->getNumber() > Header->getNumber()) {
253         // Skip over an intervening scope.
254         I = std::next(ScopeTop->getIterator());
255       } else {
256         // We found a scope level at an appropriate depth.
257         Header = ScopeTop;
258         break;
259       }
260     }
261   }
262 
263   // Decide where in Header to put the BLOCK.
264 
265   // Instructions that should go before the BLOCK.
266   SmallPtrSet<const MachineInstr *, 4> BeforeSet;
267   // Instructions that should go after the BLOCK.
268   SmallPtrSet<const MachineInstr *, 4> AfterSet;
269   for (const auto &MI : *Header) {
270     // If there is a previously placed LOOP marker and the bottom block of the
271     // loop is above MBB, it should be after the BLOCK, because the loop is
272     // nested in this BLOCK. Otherwise it should be before the BLOCK.
273     if (MI.getOpcode() == WebAssembly::LOOP) {
274       auto *LoopBottom = BeginToEnd[&MI]->getParent()->getPrevNode();
275       if (MBB.getNumber() > LoopBottom->getNumber())
276         AfterSet.insert(&MI);
277 #ifndef NDEBUG
278       else
279         BeforeSet.insert(&MI);
280 #endif
281     }
282 
283     // If there is a previously placed BLOCK/TRY marker and its corresponding
284     // END marker is before the current BLOCK's END marker, that should be
285     // placed after this BLOCK. Otherwise it should be placed before this BLOCK
286     // marker.
287     if (MI.getOpcode() == WebAssembly::BLOCK ||
288         MI.getOpcode() == WebAssembly::TRY) {
289       if (BeginToEnd[&MI]->getParent()->getNumber() <= MBB.getNumber())
290         AfterSet.insert(&MI);
291 #ifndef NDEBUG
292       else
293         BeforeSet.insert(&MI);
294 #endif
295     }
296 
297 #ifndef NDEBUG
298     // All END_(BLOCK|LOOP|TRY) markers should be before the BLOCK.
299     if (MI.getOpcode() == WebAssembly::END_BLOCK ||
300         MI.getOpcode() == WebAssembly::END_LOOP ||
301         MI.getOpcode() == WebAssembly::END_TRY)
302       BeforeSet.insert(&MI);
303 #endif
304 
305     // Terminators should go after the BLOCK.
306     if (MI.isTerminator())
307       AfterSet.insert(&MI);
308   }
309 
310   // Local expression tree should go after the BLOCK.
311   for (auto I = Header->getFirstTerminator(), E = Header->begin(); I != E;
312        --I) {
313     if (std::prev(I)->isDebugInstr() || std::prev(I)->isPosition())
314       continue;
315     if (WebAssembly::isChild(*std::prev(I), MFI))
316       AfterSet.insert(&*std::prev(I));
317     else
318       break;
319   }
320 
321   // Add the BLOCK.
322 
323   // 'br_on_exn' extracts exnref object and pushes variable number of values
324   // depending on its tag. For C++ exception, its a single i32 value, and the
325   // generated code will be in the form of:
326   // block i32
327   //   br_on_exn 0, $__cpp_exception
328   //   rethrow
329   // end_block
330   WebAssembly::BlockType ReturnType = WebAssembly::BlockType::Void;
331   if (IsBrOnExn) {
332     const char *TagName = BrOnExn->getOperand(1).getSymbolName();
333     if (std::strcmp(TagName, "__cpp_exception") != 0)
334       llvm_unreachable("Only C++ exception is supported");
335     ReturnType = WebAssembly::BlockType::I32;
336   }
337 
338   auto InsertPos = getLatestInsertPos(Header, BeforeSet, AfterSet);
339   MachineInstr *Begin =
340       BuildMI(*Header, InsertPos, Header->findDebugLoc(InsertPos),
341               TII.get(WebAssembly::BLOCK))
342           .addImm(int64_t(ReturnType));
343 
344   // Decide where in Header to put the END_BLOCK.
345   BeforeSet.clear();
346   AfterSet.clear();
347   for (auto &MI : MBB) {
348 #ifndef NDEBUG
349     // END_BLOCK should precede existing LOOP and TRY markers.
350     if (MI.getOpcode() == WebAssembly::LOOP ||
351         MI.getOpcode() == WebAssembly::TRY)
352       AfterSet.insert(&MI);
353 #endif
354 
355     // If there is a previously placed END_LOOP marker and the header of the
356     // loop is above this block's header, the END_LOOP should be placed after
357     // the BLOCK, because the loop contains this block. Otherwise the END_LOOP
358     // should be placed before the BLOCK. The same for END_TRY.
359     if (MI.getOpcode() == WebAssembly::END_LOOP ||
360         MI.getOpcode() == WebAssembly::END_TRY) {
361       if (EndToBegin[&MI]->getParent()->getNumber() >= Header->getNumber())
362         BeforeSet.insert(&MI);
363 #ifndef NDEBUG
364       else
365         AfterSet.insert(&MI);
366 #endif
367     }
368   }
369 
370   // Mark the end of the block.
371   InsertPos = getEarliestInsertPos(&MBB, BeforeSet, AfterSet);
372   MachineInstr *End = BuildMI(MBB, InsertPos, MBB.findPrevDebugLoc(InsertPos),
373                               TII.get(WebAssembly::END_BLOCK));
374   registerScope(Begin, End);
375 
376   // Track the farthest-spanning scope that ends at this point.
377   int Number = MBB.getNumber();
378   if (!ScopeTops[Number] ||
379       ScopeTops[Number]->getNumber() > Header->getNumber())
380     ScopeTops[Number] = Header;
381 }
382 
383 /// Insert a LOOP marker for a loop starting at MBB (if it's a loop header).
384 void WebAssemblyCFGStackify::placeLoopMarker(MachineBasicBlock &MBB) {
385   MachineFunction &MF = *MBB.getParent();
386   const auto &MLI = getAnalysis<MachineLoopInfo>();
387   const auto &WEI = getAnalysis<WebAssemblyExceptionInfo>();
388   SortRegionInfo SRI(MLI, WEI);
389   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
390 
391   MachineLoop *Loop = MLI.getLoopFor(&MBB);
392   if (!Loop || Loop->getHeader() != &MBB)
393     return;
394 
395   // The operand of a LOOP is the first block after the loop. If the loop is the
396   // bottom of the function, insert a dummy block at the end.
397   MachineBasicBlock *Bottom = SRI.getBottom(Loop);
398   auto Iter = std::next(Bottom->getIterator());
399   if (Iter == MF.end()) {
400     getAppendixBlock(MF);
401     Iter = std::next(Bottom->getIterator());
402   }
403   MachineBasicBlock *AfterLoop = &*Iter;
404 
405   // Decide where in Header to put the LOOP.
406   SmallPtrSet<const MachineInstr *, 4> BeforeSet;
407   SmallPtrSet<const MachineInstr *, 4> AfterSet;
408   for (const auto &MI : MBB) {
409     // LOOP marker should be after any existing loop that ends here. Otherwise
410     // we assume the instruction belongs to the loop.
411     if (MI.getOpcode() == WebAssembly::END_LOOP)
412       BeforeSet.insert(&MI);
413 #ifndef NDEBUG
414     else
415       AfterSet.insert(&MI);
416 #endif
417   }
418 
419   // Mark the beginning of the loop.
420   auto InsertPos = getEarliestInsertPos(&MBB, BeforeSet, AfterSet);
421   MachineInstr *Begin = BuildMI(MBB, InsertPos, MBB.findDebugLoc(InsertPos),
422                                 TII.get(WebAssembly::LOOP))
423                             .addImm(int64_t(WebAssembly::BlockType::Void));
424 
425   // Decide where in Header to put the END_LOOP.
426   BeforeSet.clear();
427   AfterSet.clear();
428 #ifndef NDEBUG
429   for (const auto &MI : MBB)
430     // Existing END_LOOP markers belong to parent loops of this loop
431     if (MI.getOpcode() == WebAssembly::END_LOOP)
432       AfterSet.insert(&MI);
433 #endif
434 
435   // Mark the end of the loop (using arbitrary debug location that branched to
436   // the loop end as its location).
437   InsertPos = getEarliestInsertPos(AfterLoop, BeforeSet, AfterSet);
438   DebugLoc EndDL = AfterLoop->pred_empty()
439                        ? DebugLoc()
440                        : (*AfterLoop->pred_rbegin())->findBranchDebugLoc();
441   MachineInstr *End =
442       BuildMI(*AfterLoop, InsertPos, EndDL, TII.get(WebAssembly::END_LOOP));
443   registerScope(Begin, End);
444 
445   assert((!ScopeTops[AfterLoop->getNumber()] ||
446           ScopeTops[AfterLoop->getNumber()]->getNumber() < MBB.getNumber()) &&
447          "With block sorting the outermost loop for a block should be first.");
448   if (!ScopeTops[AfterLoop->getNumber()])
449     ScopeTops[AfterLoop->getNumber()] = &MBB;
450 }
451 
452 void WebAssemblyCFGStackify::placeTryMarker(MachineBasicBlock &MBB) {
453   assert(MBB.isEHPad());
454   MachineFunction &MF = *MBB.getParent();
455   auto &MDT = getAnalysis<MachineDominatorTree>();
456   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
457   const auto &MLI = getAnalysis<MachineLoopInfo>();
458   const auto &WEI = getAnalysis<WebAssemblyExceptionInfo>();
459   SortRegionInfo SRI(MLI, WEI);
460   const auto &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
461 
462   // Compute the nearest common dominator of all unwind predecessors
463   MachineBasicBlock *Header = nullptr;
464   int MBBNumber = MBB.getNumber();
465   for (auto *Pred : MBB.predecessors()) {
466     if (Pred->getNumber() < MBBNumber) {
467       Header = Header ? MDT.findNearestCommonDominator(Header, Pred) : Pred;
468       assert(!explicitlyBranchesTo(Pred, &MBB) &&
469              "Explicit branch to an EH pad!");
470     }
471   }
472   if (!Header)
473     return;
474 
475   // If this try is at the bottom of the function, insert a dummy block at the
476   // end.
477   WebAssemblyException *WE = WEI.getExceptionFor(&MBB);
478   assert(WE);
479   MachineBasicBlock *Bottom = SRI.getBottom(WE);
480 
481   auto Iter = std::next(Bottom->getIterator());
482   if (Iter == MF.end()) {
483     getAppendixBlock(MF);
484     Iter = std::next(Bottom->getIterator());
485   }
486   MachineBasicBlock *Cont = &*Iter;
487 
488   assert(Cont != &MF.front());
489   MachineBasicBlock *LayoutPred = Cont->getPrevNode();
490 
491   // If the nearest common dominator is inside a more deeply nested context,
492   // walk out to the nearest scope which isn't more deeply nested.
493   for (MachineFunction::iterator I(LayoutPred), E(Header); I != E; --I) {
494     if (MachineBasicBlock *ScopeTop = ScopeTops[I->getNumber()]) {
495       if (ScopeTop->getNumber() > Header->getNumber()) {
496         // Skip over an intervening scope.
497         I = std::next(ScopeTop->getIterator());
498       } else {
499         // We found a scope level at an appropriate depth.
500         Header = ScopeTop;
501         break;
502       }
503     }
504   }
505 
506   // Decide where in Header to put the TRY.
507 
508   // Instructions that should go before the TRY.
509   SmallPtrSet<const MachineInstr *, 4> BeforeSet;
510   // Instructions that should go after the TRY.
511   SmallPtrSet<const MachineInstr *, 4> AfterSet;
512   for (const auto &MI : *Header) {
513     // If there is a previously placed LOOP marker and the bottom block of the
514     // loop is above MBB, it should be after the TRY, because the loop is nested
515     // in this TRY. Otherwise it should be before the TRY.
516     if (MI.getOpcode() == WebAssembly::LOOP) {
517       auto *LoopBottom = BeginToEnd[&MI]->getParent()->getPrevNode();
518       if (MBB.getNumber() > LoopBottom->getNumber())
519         AfterSet.insert(&MI);
520 #ifndef NDEBUG
521       else
522         BeforeSet.insert(&MI);
523 #endif
524     }
525 
526     // All previously inserted BLOCK/TRY markers should be after the TRY because
527     // they are all nested trys.
528     if (MI.getOpcode() == WebAssembly::BLOCK ||
529         MI.getOpcode() == WebAssembly::TRY)
530       AfterSet.insert(&MI);
531 
532 #ifndef NDEBUG
533     // All END_(BLOCK/LOOP/TRY) markers should be before the TRY.
534     if (MI.getOpcode() == WebAssembly::END_BLOCK ||
535         MI.getOpcode() == WebAssembly::END_LOOP ||
536         MI.getOpcode() == WebAssembly::END_TRY)
537       BeforeSet.insert(&MI);
538 #endif
539 
540     // Terminators should go after the TRY.
541     if (MI.isTerminator())
542       AfterSet.insert(&MI);
543   }
544 
545   // If Header unwinds to MBB (= Header contains 'invoke'), the try block should
546   // contain the call within it. So the call should go after the TRY. The
547   // exception is when the header's terminator is a rethrow instruction, in
548   // which case that instruction, not a call instruction before it, is gonna
549   // throw.
550   MachineInstr *ThrowingCall = nullptr;
551   if (MBB.isPredecessor(Header)) {
552     auto TermPos = Header->getFirstTerminator();
553     if (TermPos == Header->end() ||
554         TermPos->getOpcode() != WebAssembly::RETHROW) {
555       for (auto &MI : reverse(*Header)) {
556         if (MI.isCall()) {
557           AfterSet.insert(&MI);
558           ThrowingCall = &MI;
559           // Possibly throwing calls are usually wrapped by EH_LABEL
560           // instructions. We don't want to split them and the call.
561           if (MI.getIterator() != Header->begin() &&
562               std::prev(MI.getIterator())->isEHLabel()) {
563             AfterSet.insert(&*std::prev(MI.getIterator()));
564             ThrowingCall = &*std::prev(MI.getIterator());
565           }
566           break;
567         }
568       }
569     }
570   }
571 
572   // Local expression tree should go after the TRY.
573   // For BLOCK placement, we start the search from the previous instruction of a
574   // BB's terminator, but in TRY's case, we should start from the previous
575   // instruction of a call that can throw, or a EH_LABEL that precedes the call,
576   // because the return values of the call's previous instructions can be
577   // stackified and consumed by the throwing call.
578   auto SearchStartPt = ThrowingCall ? MachineBasicBlock::iterator(ThrowingCall)
579                                     : Header->getFirstTerminator();
580   for (auto I = SearchStartPt, E = Header->begin(); I != E; --I) {
581     if (std::prev(I)->isDebugInstr() || std::prev(I)->isPosition())
582       continue;
583     if (WebAssembly::isChild(*std::prev(I), MFI))
584       AfterSet.insert(&*std::prev(I));
585     else
586       break;
587   }
588 
589   // Add the TRY.
590   auto InsertPos = getLatestInsertPos(Header, BeforeSet, AfterSet);
591   MachineInstr *Begin =
592       BuildMI(*Header, InsertPos, Header->findDebugLoc(InsertPos),
593               TII.get(WebAssembly::TRY))
594           .addImm(int64_t(WebAssembly::BlockType::Void));
595 
596   // Decide where in Header to put the END_TRY.
597   BeforeSet.clear();
598   AfterSet.clear();
599   for (const auto &MI : *Cont) {
600 #ifndef NDEBUG
601     // END_TRY should precede existing LOOP and BLOCK markers.
602     if (MI.getOpcode() == WebAssembly::LOOP ||
603         MI.getOpcode() == WebAssembly::BLOCK)
604       AfterSet.insert(&MI);
605 
606     // All END_TRY markers placed earlier belong to exceptions that contains
607     // this one.
608     if (MI.getOpcode() == WebAssembly::END_TRY)
609       AfterSet.insert(&MI);
610 #endif
611 
612     // If there is a previously placed END_LOOP marker and its header is after
613     // where TRY marker is, this loop is contained within the 'catch' part, so
614     // the END_TRY marker should go after that. Otherwise, the whole try-catch
615     // is contained within this loop, so the END_TRY should go before that.
616     if (MI.getOpcode() == WebAssembly::END_LOOP) {
617       // For a LOOP to be after TRY, LOOP's BB should be after TRY's BB; if they
618       // are in the same BB, LOOP is always before TRY.
619       if (EndToBegin[&MI]->getParent()->getNumber() > Header->getNumber())
620         BeforeSet.insert(&MI);
621 #ifndef NDEBUG
622       else
623         AfterSet.insert(&MI);
624 #endif
625     }
626 
627     // It is not possible for an END_BLOCK to be already in this block.
628   }
629 
630   // Mark the end of the TRY.
631   InsertPos = getEarliestInsertPos(Cont, BeforeSet, AfterSet);
632   MachineInstr *End =
633       BuildMI(*Cont, InsertPos, Bottom->findBranchDebugLoc(),
634               TII.get(WebAssembly::END_TRY));
635   registerTryScope(Begin, End, &MBB);
636 
637   // Track the farthest-spanning scope that ends at this point. We create two
638   // mappings: (BB with 'end_try' -> BB with 'try') and (BB with 'catch' -> BB
639   // with 'try'). We need to create 'catch' -> 'try' mapping here too because
640   // markers should not span across 'catch'. For example, this should not
641   // happen:
642   //
643   // try
644   //   block     --|  (X)
645   // catch         |
646   //   end_block --|
647   // end_try
648   for (int Number : {Cont->getNumber(), MBB.getNumber()}) {
649     if (!ScopeTops[Number] ||
650         ScopeTops[Number]->getNumber() > Header->getNumber())
651       ScopeTops[Number] = Header;
652   }
653 }
654 
655 void WebAssemblyCFGStackify::removeUnnecessaryInstrs(MachineFunction &MF) {
656   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
657 
658   // When there is an unconditional branch right before a catch instruction and
659   // it branches to the end of end_try marker, we don't need the branch, because
660   // it there is no exception, the control flow transfers to that point anyway.
661   // bb0:
662   //   try
663   //     ...
664   //     br bb2      <- Not necessary
665   // bb1:
666   //   catch
667   //     ...
668   // bb2:
669   //   end
670   for (auto &MBB : MF) {
671     if (!MBB.isEHPad())
672       continue;
673 
674     MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
675     SmallVector<MachineOperand, 4> Cond;
676     MachineBasicBlock *EHPadLayoutPred = MBB.getPrevNode();
677     MachineBasicBlock *Cont = BeginToEnd[EHPadToTry[&MBB]]->getParent();
678     bool Analyzable = !TII.analyzeBranch(*EHPadLayoutPred, TBB, FBB, Cond);
679     // This condition means either
680     // 1. This BB ends with a single unconditional branch whose destinaion is
681     //    Cont.
682     // 2. This BB ends with a conditional branch followed by an unconditional
683     //    branch, and the unconditional branch's destination is Cont.
684     // In both cases, we want to remove the last (= unconditional) branch.
685     if (Analyzable && ((Cond.empty() && TBB && TBB == Cont) ||
686                        (!Cond.empty() && FBB && FBB == Cont))) {
687       bool ErasedUncondBr = false;
688       (void)ErasedUncondBr;
689       for (auto I = EHPadLayoutPred->end(), E = EHPadLayoutPred->begin();
690            I != E; --I) {
691         auto PrevI = std::prev(I);
692         if (PrevI->isTerminator()) {
693           assert(PrevI->getOpcode() == WebAssembly::BR);
694           PrevI->eraseFromParent();
695           ErasedUncondBr = true;
696           break;
697         }
698       }
699       assert(ErasedUncondBr && "Unconditional branch not erased!");
700     }
701   }
702 
703   // When there are block / end_block markers that overlap with try / end_try
704   // markers, and the block and try markers' return types are the same, the
705   // block /end_block markers are not necessary, because try / end_try markers
706   // also can serve as boundaries for branches.
707   // block         <- Not necessary
708   //   try
709   //     ...
710   //   catch
711   //     ...
712   //   end
713   // end           <- Not necessary
714   SmallVector<MachineInstr *, 32> ToDelete;
715   for (auto &MBB : MF) {
716     for (auto &MI : MBB) {
717       if (MI.getOpcode() != WebAssembly::TRY)
718         continue;
719 
720       MachineInstr *Try = &MI, *EndTry = BeginToEnd[Try];
721       MachineBasicBlock *TryBB = Try->getParent();
722       MachineBasicBlock *Cont = EndTry->getParent();
723       int64_t RetType = Try->getOperand(0).getImm();
724       for (auto B = Try->getIterator(), E = std::next(EndTry->getIterator());
725            B != TryBB->begin() && E != Cont->end() &&
726            std::prev(B)->getOpcode() == WebAssembly::BLOCK &&
727            E->getOpcode() == WebAssembly::END_BLOCK &&
728            std::prev(B)->getOperand(0).getImm() == RetType;
729            --B, ++E) {
730         ToDelete.push_back(&*std::prev(B));
731         ToDelete.push_back(&*E);
732       }
733     }
734   }
735   for (auto *MI : ToDelete) {
736     if (MI->getOpcode() == WebAssembly::BLOCK)
737       unregisterScope(MI);
738     MI->eraseFromParent();
739   }
740 }
741 
742 // Get the appropriate copy opcode for the given register class.
743 static unsigned getCopyOpcode(const TargetRegisterClass *RC) {
744   if (RC == &WebAssembly::I32RegClass)
745     return WebAssembly::COPY_I32;
746   if (RC == &WebAssembly::I64RegClass)
747     return WebAssembly::COPY_I64;
748   if (RC == &WebAssembly::F32RegClass)
749     return WebAssembly::COPY_F32;
750   if (RC == &WebAssembly::F64RegClass)
751     return WebAssembly::COPY_F64;
752   if (RC == &WebAssembly::V128RegClass)
753     return WebAssembly::COPY_V128;
754   if (RC == &WebAssembly::EXNREFRegClass)
755     return WebAssembly::COPY_EXNREF;
756   llvm_unreachable("Unexpected register class");
757 }
758 
759 // When MBB is split into MBB and Split, we should unstackify defs in MBB that
760 // have their uses in Split.
761 static void unstackifyVRegsUsedInSplitBB(MachineBasicBlock &MBB,
762                                          MachineBasicBlock &Split,
763                                          WebAssemblyFunctionInfo &MFI,
764                                          MachineRegisterInfo &MRI,
765                                          const WebAssemblyInstrInfo &TII) {
766   for (auto &MI : Split) {
767     for (auto &MO : MI.explicit_uses()) {
768       if (!MO.isReg() || Register::isPhysicalRegister(MO.getReg()))
769         continue;
770       if (MachineInstr *Def = MRI.getUniqueVRegDef(MO.getReg()))
771         if (Def->getParent() == &MBB)
772           MFI.unstackifyVReg(MO.getReg());
773     }
774   }
775 
776   // In RegStackify, when a register definition is used multiple times,
777   //    Reg = INST ...
778   //    INST ..., Reg, ...
779   //    INST ..., Reg, ...
780   //    INST ..., Reg, ...
781   //
782   // we introduce a TEE, which has the following form:
783   //    DefReg = INST ...
784   //    TeeReg, Reg = TEE_... DefReg
785   //    INST ..., TeeReg, ...
786   //    INST ..., Reg, ...
787   //    INST ..., Reg, ...
788   // with DefReg and TeeReg stackified but Reg not stackified.
789   //
790   // But the invariant that TeeReg should be stackified can be violated while we
791   // unstackify registers in the split BB above. In this case, we convert TEEs
792   // into two COPYs. This COPY will be eventually eliminated in ExplicitLocals.
793   //    DefReg = INST ...
794   //    TeeReg = COPY DefReg
795   //    Reg = COPY DefReg
796   //    INST ..., TeeReg, ...
797   //    INST ..., Reg, ...
798   //    INST ..., Reg, ...
799   for (auto I = MBB.begin(), E = MBB.end(); I != E;) {
800     MachineInstr &MI = *I++;
801     if (!WebAssembly::isTee(MI.getOpcode()))
802       continue;
803     Register TeeReg = MI.getOperand(0).getReg();
804     Register Reg = MI.getOperand(1).getReg();
805     Register DefReg = MI.getOperand(2).getReg();
806     if (!MFI.isVRegStackified(TeeReg)) {
807       // Now we are not using TEE anymore, so unstackify DefReg too
808       MFI.unstackifyVReg(DefReg);
809       unsigned CopyOpc = getCopyOpcode(MRI.getRegClass(DefReg));
810       BuildMI(MBB, &MI, MI.getDebugLoc(), TII.get(CopyOpc), TeeReg)
811           .addReg(DefReg);
812       BuildMI(MBB, &MI, MI.getDebugLoc(), TII.get(CopyOpc), Reg).addReg(DefReg);
813       MI.eraseFromParent();
814     }
815   }
816 }
817 
818 bool WebAssemblyCFGStackify::fixUnwindMismatches(MachineFunction &MF) {
819   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
820   auto &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
821   MachineRegisterInfo &MRI = MF.getRegInfo();
822 
823   // Linearizing the control flow by placing TRY / END_TRY markers can create
824   // mismatches in unwind destinations. There are two kinds of mismatches we
825   // try to solve here.
826 
827   // 1. When an instruction may throw, but the EH pad it will unwind to can be
828   //    different from the original CFG.
829   //
830   // Example: we have the following CFG:
831   // bb0:
832   //   call @foo (if it throws, unwind to bb2)
833   // bb1:
834   //   call @bar (if it throws, unwind to bb3)
835   // bb2 (ehpad):
836   //   catch
837   //   ...
838   // bb3 (ehpad)
839   //   catch
840   //   handler body
841   //
842   // And the CFG is sorted in this order. Then after placing TRY markers, it
843   // will look like: (BB markers are omitted)
844   // try $label1
845   //   try
846   //     call @foo
847   //     call @bar   (if it throws, unwind to bb3)
848   //   catch         <- ehpad (bb2)
849   //     ...
850   //   end_try
851   // catch           <- ehpad (bb3)
852   //   handler body
853   // end_try
854   //
855   // Now if bar() throws, it is going to end up ip in bb2, not bb3, where it
856   // is supposed to end up. We solve this problem by
857   // a. Split the target unwind EH pad (here bb3) so that the handler body is
858   //    right after 'end_try', which means we extract the handler body out of
859   //    the catch block. We do this because this handler body should be
860   //    somewhere branch-eable from the inner scope.
861   // b. Wrap the call that has an incorrect unwind destination ('call @bar'
862   //    here) with a nested try/catch/end_try scope, and within the new catch
863   //    block, branches to the handler body.
864   // c. Place a branch after the newly inserted nested end_try so it can bypass
865   //    the handler body, which is now outside of a catch block.
866   //
867   // The result will like as follows. (new: a) means this instruction is newly
868   // created in the process of doing 'a' above.
869   //
870   // block $label0                 (new: placeBlockMarker)
871   //   try $label1
872   //     try
873   //       call @foo
874   //       try                     (new: b)
875   //         call @bar
876   //       catch                   (new: b)
877   //         local.set n / drop    (new: b)
878   //         br $label1            (new: b)
879   //       end_try                 (new: b)
880   //     catch                     <- ehpad (bb2)
881   //     end_try
882   //     br $label0                (new: c)
883   //   catch                       <- ehpad (bb3)
884   //   end_try                     (hoisted: a)
885   //   handler body
886   // end_block                     (new: placeBlockMarker)
887   //
888   // Note that the new wrapping block/end_block will be generated later in
889   // placeBlockMarker.
890   //
891   // TODO Currently local.set and local.gets are generated to move exnref value
892   // created by catches. That's because we don't support yielding values from a
893   // block in LLVM machine IR yet, even though it is supported by wasm. Delete
894   // unnecessary local.get/local.sets once yielding values from a block is
895   // supported. The full EH spec requires multi-value support to do this, but
896   // for C++ we don't yet need it because we only throw a single i32.
897   //
898   // ---
899   // 2. The same as 1, but in this case an instruction unwinds to a caller
900   //    function and not another EH pad.
901   //
902   // Example: we have the following CFG:
903   // bb0:
904   //   call @foo (if it throws, unwind to bb2)
905   // bb1:
906   //   call @bar (if it throws, unwind to caller)
907   // bb2 (ehpad):
908   //   catch
909   //   ...
910   //
911   // And the CFG is sorted in this order. Then after placing TRY markers, it
912   // will look like:
913   // try
914   //   call @foo
915   //   call @bar   (if it throws, unwind to caller)
916   // catch         <- ehpad (bb2)
917   //   ...
918   // end_try
919   //
920   // Now if bar() throws, it is going to end up ip in bb2, when it is supposed
921   // throw up to the caller.
922   // We solve this problem by
923   // a. Create a new 'appendix' BB at the end of the function and put a single
924   //    'rethrow' instruction (+ local.get) in there.
925   // b. Wrap the call that has an incorrect unwind destination ('call @bar'
926   //    here) with a nested try/catch/end_try scope, and within the new catch
927   //    block, branches to the new appendix block.
928   //
929   // block $label0          (new: placeBlockMarker)
930   //   try
931   //     call @foo
932   //     try                (new: b)
933   //       call @bar
934   //     catch              (new: b)
935   //       local.set n      (new: b)
936   //       br $label0       (new: b)
937   //     end_try            (new: b)
938   //   catch                <- ehpad (bb2)
939   //     ...
940   //   end_try
941   // ...
942   // end_block              (new: placeBlockMarker)
943   // local.get n            (new: a)  <- appendix block
944   // rethrow                (new: a)
945   //
946   // In case there are multiple calls in a BB that may throw to the caller, they
947   // can be wrapped together in one nested try scope. (In 1, this couldn't
948   // happen, because may-throwing instruction there had an unwind destination,
949   // i.e., it was an invoke before, and there could be only one invoke within a
950   // BB.)
951 
952   SmallVector<const MachineBasicBlock *, 8> EHPadStack;
953   // Range of intructions to be wrapped in a new nested try/catch
954   using TryRange = std::pair<MachineInstr *, MachineInstr *>;
955   // In original CFG, <unwind destination BB, a vector of try ranges>
956   DenseMap<MachineBasicBlock *, SmallVector<TryRange, 4>> UnwindDestToTryRanges;
957   // In new CFG, <destination to branch to, a vector of try ranges>
958   DenseMap<MachineBasicBlock *, SmallVector<TryRange, 4>> BrDestToTryRanges;
959   // In new CFG, <destination to branch to, register containing exnref>
960   DenseMap<MachineBasicBlock *, unsigned> BrDestToExnReg;
961 
962   // Destinations for branches that will be newly added, for which a new
963   // BLOCK/END_BLOCK markers are necessary.
964   SmallVector<MachineBasicBlock *, 8> BrDests;
965 
966   // Gather possibly throwing calls (i.e., previously invokes) whose current
967   // unwind destination is not the same as the original CFG.
968   for (auto &MBB : reverse(MF)) {
969     bool SeenThrowableInstInBB = false;
970     for (auto &MI : reverse(MBB)) {
971       if (MI.getOpcode() == WebAssembly::TRY)
972         EHPadStack.pop_back();
973       else if (MI.getOpcode() == WebAssembly::CATCH)
974         EHPadStack.push_back(MI.getParent());
975 
976       // In this loop we only gather calls that have an EH pad to unwind. So
977       // there will be at most 1 such call (= invoke) in a BB, so after we've
978       // seen one, we can skip the rest of BB. Also if MBB has no EH pad
979       // successor or MI does not throw, this is not an invoke.
980       if (SeenThrowableInstInBB || !MBB.hasEHPadSuccessor() ||
981           !WebAssembly::mayThrow(MI))
982         continue;
983       SeenThrowableInstInBB = true;
984 
985       // If the EH pad on the stack top is where this instruction should unwind
986       // next, we're good.
987       MachineBasicBlock *UnwindDest = nullptr;
988       for (auto *Succ : MBB.successors()) {
989         if (Succ->isEHPad()) {
990           UnwindDest = Succ;
991           break;
992         }
993       }
994       if (EHPadStack.back() == UnwindDest)
995         continue;
996 
997       // If not, record the range.
998       UnwindDestToTryRanges[UnwindDest].push_back(TryRange(&MI, &MI));
999     }
1000   }
1001 
1002   assert(EHPadStack.empty());
1003 
1004   // Gather possibly throwing calls that are supposed to unwind up to the caller
1005   // if they throw, but currently unwind to an incorrect destination. Unlike the
1006   // loop above, there can be multiple calls within a BB that unwind to the
1007   // caller, which we should group together in a range.
1008   bool NeedAppendixBlock = false;
1009   for (auto &MBB : reverse(MF)) {
1010     MachineInstr *RangeBegin = nullptr, *RangeEnd = nullptr; // inclusive
1011     for (auto &MI : reverse(MBB)) {
1012       if (MI.getOpcode() == WebAssembly::TRY)
1013         EHPadStack.pop_back();
1014       else if (MI.getOpcode() == WebAssembly::CATCH)
1015         EHPadStack.push_back(MI.getParent());
1016 
1017       // If MBB has an EH pad successor, this inst does not unwind to caller.
1018       if (MBB.hasEHPadSuccessor())
1019         continue;
1020 
1021       // We wrap up the current range when we see a marker even if we haven't
1022       // finished a BB.
1023       if (RangeEnd && WebAssembly::isMarker(MI.getOpcode())) {
1024         NeedAppendixBlock = true;
1025         // Record the range. nullptr here means the unwind destination is the
1026         // caller.
1027         UnwindDestToTryRanges[nullptr].push_back(
1028             TryRange(RangeBegin, RangeEnd));
1029         RangeBegin = RangeEnd = nullptr; // Reset range pointers
1030       }
1031 
1032       // If EHPadStack is empty, that means it is correctly unwind to caller if
1033       // it throws, so we're good. If MI does not throw, we're good too.
1034       if (EHPadStack.empty() || !WebAssembly::mayThrow(MI))
1035         continue;
1036 
1037       // We found an instruction that unwinds to the caller but currently has an
1038       // incorrect unwind destination. Create a new range or increment the
1039       // currently existing range.
1040       if (!RangeEnd)
1041         RangeBegin = RangeEnd = &MI;
1042       else
1043         RangeBegin = &MI;
1044     }
1045 
1046     if (RangeEnd) {
1047       NeedAppendixBlock = true;
1048       // Record the range. nullptr here means the unwind destination is the
1049       // caller.
1050       UnwindDestToTryRanges[nullptr].push_back(TryRange(RangeBegin, RangeEnd));
1051       RangeBegin = RangeEnd = nullptr; // Reset range pointers
1052     }
1053   }
1054 
1055   assert(EHPadStack.empty());
1056   // We don't have any unwind destination mismatches to resolve.
1057   if (UnwindDestToTryRanges.empty())
1058     return false;
1059 
1060   // If we found instructions that should unwind to the caller but currently
1061   // have incorrect unwind destination, we create an appendix block at the end
1062   // of the function with a local.get and a rethrow instruction.
1063   if (NeedAppendixBlock) {
1064     auto *AppendixBB = getAppendixBlock(MF);
1065     Register ExnReg = MRI.createVirtualRegister(&WebAssembly::EXNREFRegClass);
1066     BuildMI(AppendixBB, DebugLoc(), TII.get(WebAssembly::RETHROW))
1067         .addReg(ExnReg);
1068     // These instruction ranges should branch to this appendix BB.
1069     for (auto Range : UnwindDestToTryRanges[nullptr])
1070       BrDestToTryRanges[AppendixBB].push_back(Range);
1071     BrDestToExnReg[AppendixBB] = ExnReg;
1072   }
1073 
1074   // We loop through unwind destination EH pads that are targeted from some
1075   // inner scopes. Because these EH pads are destination of more than one scope
1076   // now, we split them so that the handler body is after 'end_try'.
1077   // - Before
1078   // ehpad:
1079   //   catch
1080   //   local.set n / drop
1081   //   handler body
1082   // ...
1083   // cont:
1084   //   end_try
1085   //
1086   // - After
1087   // ehpad:
1088   //   catch
1089   //   local.set n / drop
1090   // brdest:               (new)
1091   //   end_try             (hoisted from 'cont' BB)
1092   //   handler body        (taken from 'ehpad')
1093   // ...
1094   // cont:
1095   for (auto &P : UnwindDestToTryRanges) {
1096     NumUnwindMismatches += P.second.size();
1097 
1098     // This means the destination is the appendix BB, which was separately
1099     // handled above.
1100     if (!P.first)
1101       continue;
1102 
1103     MachineBasicBlock *EHPad = P.first;
1104 
1105     // Find 'catch' and 'local.set' or 'drop' instruction that follows the
1106     // 'catch'. If -wasm-disable-explicit-locals is not set, 'catch' should be
1107     // always followed by either 'local.set' or a 'drop', because 'br_on_exn' is
1108     // generated after 'catch' in LateEHPrepare and we don't support blocks
1109     // taking values yet.
1110     MachineInstr *Catch = nullptr;
1111     unsigned ExnReg = 0;
1112     for (auto &MI : *EHPad) {
1113       switch (MI.getOpcode()) {
1114       case WebAssembly::CATCH:
1115         Catch = &MI;
1116         ExnReg = Catch->getOperand(0).getReg();
1117         break;
1118       }
1119     }
1120     assert(Catch && "EH pad does not have a catch");
1121     assert(ExnReg != 0 && "Invalid register");
1122 
1123     auto SplitPos = std::next(Catch->getIterator());
1124 
1125     // Create a new BB that's gonna be the destination for branches from the
1126     // inner mismatched scope.
1127     MachineInstr *BeginTry = EHPadToTry[EHPad];
1128     MachineInstr *EndTry = BeginToEnd[BeginTry];
1129     MachineBasicBlock *Cont = EndTry->getParent();
1130     auto *BrDest = MF.CreateMachineBasicBlock();
1131     MF.insert(std::next(EHPad->getIterator()), BrDest);
1132     // Hoist up the existing 'end_try'.
1133     BrDest->insert(BrDest->end(), EndTry->removeFromParent());
1134     // Take out the handler body from EH pad to the new branch destination BB.
1135     BrDest->splice(BrDest->end(), EHPad, SplitPos, EHPad->end());
1136     unstackifyVRegsUsedInSplitBB(*EHPad, *BrDest, MFI, MRI, TII);
1137     // Fix predecessor-successor relationship.
1138     BrDest->transferSuccessors(EHPad);
1139     EHPad->addSuccessor(BrDest);
1140 
1141     // All try ranges that were supposed to unwind to this EH pad now have to
1142     // branch to this new branch dest BB.
1143     for (auto Range : UnwindDestToTryRanges[EHPad])
1144       BrDestToTryRanges[BrDest].push_back(Range);
1145     BrDestToExnReg[BrDest] = ExnReg;
1146 
1147     // In case we fall through to the continuation BB after the catch block, we
1148     // now have to add a branch to it.
1149     // - Before
1150     // try
1151     //   ...
1152     //   (falls through to 'cont')
1153     // catch
1154     //   handler body
1155     // end
1156     //               <-- cont
1157     //
1158     // - After
1159     // try
1160     //   ...
1161     //   br %cont    (new)
1162     // catch
1163     // end
1164     // handler body
1165     //               <-- cont
1166     MachineBasicBlock *EHPadLayoutPred = &*std::prev(EHPad->getIterator());
1167     MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
1168     SmallVector<MachineOperand, 4> Cond;
1169     bool Analyzable = !TII.analyzeBranch(*EHPadLayoutPred, TBB, FBB, Cond);
1170     if (Analyzable && !TBB && !FBB) {
1171       DebugLoc DL = EHPadLayoutPred->empty()
1172                         ? DebugLoc()
1173                         : EHPadLayoutPred->rbegin()->getDebugLoc();
1174       BuildMI(EHPadLayoutPred, DL, TII.get(WebAssembly::BR)).addMBB(Cont);
1175       BrDests.push_back(Cont);
1176     }
1177   }
1178 
1179   // For possibly throwing calls whose unwind destinations are currently
1180   // incorrect because of CFG linearization, we wrap them with a nested
1181   // try/catch/end_try, and within the new catch block, we branch to the correct
1182   // handler.
1183   // - Before
1184   // mbb:
1185   //   call @foo       <- Unwind destination mismatch!
1186   // ehpad:
1187   //   ...
1188   //
1189   // - After
1190   // mbb:
1191   //   try                (new)
1192   //   call @foo
1193   // nested-ehpad:        (new)
1194   //   catch              (new)
1195   //   local.set n / drop (new)
1196   //   br %brdest         (new)
1197   // nested-end:          (new)
1198   //   end_try            (new)
1199   // ehpad:
1200   //   ...
1201   for (auto &P : BrDestToTryRanges) {
1202     MachineBasicBlock *BrDest = P.first;
1203     auto &TryRanges = P.second;
1204     unsigned ExnReg = BrDestToExnReg[BrDest];
1205 
1206     for (auto Range : TryRanges) {
1207       MachineInstr *RangeBegin = nullptr, *RangeEnd = nullptr;
1208       std::tie(RangeBegin, RangeEnd) = Range;
1209       auto *MBB = RangeBegin->getParent();
1210       // Store the first function call from this range, because RangeBegin can
1211       // be moved to point EH_LABEL before the call
1212       MachineInstr *RangeBeginCall = RangeBegin;
1213 
1214       // Include possible EH_LABELs in the range
1215       if (RangeBegin->getIterator() != MBB->begin() &&
1216           std::prev(RangeBegin->getIterator())->isEHLabel())
1217         RangeBegin = &*std::prev(RangeBegin->getIterator());
1218       if (std::next(RangeEnd->getIterator()) != MBB->end() &&
1219           std::next(RangeEnd->getIterator())->isEHLabel())
1220         RangeEnd = &*std::next(RangeEnd->getIterator());
1221 
1222       MachineBasicBlock *EHPad = nullptr;
1223       for (auto *Succ : MBB->successors()) {
1224         if (Succ->isEHPad()) {
1225           EHPad = Succ;
1226           break;
1227         }
1228       }
1229 
1230       // Local expression tree before the first call of this range should go
1231       // after the nested TRY.
1232       SmallPtrSet<const MachineInstr *, 4> AfterSet;
1233       AfterSet.insert(RangeBegin);
1234       AfterSet.insert(RangeBeginCall);
1235       for (auto I = MachineBasicBlock::iterator(RangeBeginCall),
1236                 E = MBB->begin();
1237            I != E; --I) {
1238         if (std::prev(I)->isDebugInstr() || std::prev(I)->isPosition())
1239           continue;
1240         if (WebAssembly::isChild(*std::prev(I), MFI))
1241           AfterSet.insert(&*std::prev(I));
1242         else
1243           break;
1244       }
1245 
1246       // Create the nested try instruction.
1247       auto InsertPos = getLatestInsertPos(
1248           MBB, SmallPtrSet<const MachineInstr *, 4>(), AfterSet);
1249       MachineInstr *NestedTry =
1250           BuildMI(*MBB, InsertPos, RangeBegin->getDebugLoc(),
1251                   TII.get(WebAssembly::TRY))
1252               .addImm(int64_t(WebAssembly::BlockType::Void));
1253 
1254       // Create the nested EH pad and fill instructions in.
1255       MachineBasicBlock *NestedEHPad = MF.CreateMachineBasicBlock();
1256       MF.insert(std::next(MBB->getIterator()), NestedEHPad);
1257       NestedEHPad->setIsEHPad();
1258       NestedEHPad->setIsEHScopeEntry();
1259       BuildMI(NestedEHPad, RangeEnd->getDebugLoc(), TII.get(WebAssembly::CATCH),
1260               ExnReg);
1261       BuildMI(NestedEHPad, RangeEnd->getDebugLoc(), TII.get(WebAssembly::BR))
1262           .addMBB(BrDest);
1263 
1264       // Create the nested continuation BB and end_try instruction.
1265       MachineBasicBlock *NestedCont = MF.CreateMachineBasicBlock();
1266       MF.insert(std::next(NestedEHPad->getIterator()), NestedCont);
1267       MachineInstr *NestedEndTry =
1268           BuildMI(*NestedCont, NestedCont->begin(), RangeEnd->getDebugLoc(),
1269                   TII.get(WebAssembly::END_TRY));
1270       // In case MBB has more instructions after the try range, move them to the
1271       // new nested continuation BB.
1272       NestedCont->splice(NestedCont->end(), MBB,
1273                          std::next(RangeEnd->getIterator()), MBB->end());
1274       unstackifyVRegsUsedInSplitBB(*MBB, *NestedCont, MFI, MRI, TII);
1275       registerTryScope(NestedTry, NestedEndTry, NestedEHPad);
1276 
1277       // Fix predecessor-successor relationship.
1278       NestedCont->transferSuccessors(MBB);
1279       if (EHPad) {
1280         NestedCont->removeSuccessor(EHPad);
1281         // If EHPad does not have any predecessors left after removing
1282         // NextedCont predecessor, remove its successor too, because this EHPad
1283         // is not reachable from the entry BB anyway. We can't remove EHPad BB
1284         // itself because it can contain 'catch' or 'end', which are necessary
1285         // for keeping try-catch-end structure.
1286         if (EHPad->pred_empty())
1287           EHPad->removeSuccessor(BrDest);
1288       }
1289       MBB->addSuccessor(NestedEHPad);
1290       MBB->addSuccessor(NestedCont);
1291       NestedEHPad->addSuccessor(BrDest);
1292     }
1293   }
1294 
1295   // Renumber BBs and recalculate ScopeTop info because new BBs might have been
1296   // created and inserted above.
1297   MF.RenumberBlocks();
1298   ScopeTops.clear();
1299   ScopeTops.resize(MF.getNumBlockIDs());
1300   for (auto &MBB : reverse(MF)) {
1301     for (auto &MI : reverse(MBB)) {
1302       if (ScopeTops[MBB.getNumber()])
1303         break;
1304       switch (MI.getOpcode()) {
1305       case WebAssembly::END_BLOCK:
1306       case WebAssembly::END_LOOP:
1307       case WebAssembly::END_TRY:
1308         ScopeTops[MBB.getNumber()] = EndToBegin[&MI]->getParent();
1309         break;
1310       case WebAssembly::CATCH:
1311         ScopeTops[MBB.getNumber()] = EHPadToTry[&MBB]->getParent();
1312         break;
1313       }
1314     }
1315   }
1316 
1317   // Recompute the dominator tree.
1318   getAnalysis<MachineDominatorTree>().runOnMachineFunction(MF);
1319 
1320   // Place block markers for newly added branches, if necessary.
1321 
1322   // If we've created an appendix BB and a branch to it, place a block/end_block
1323   // marker for that. For some new branches, those branch destination BBs start
1324   // with a hoisted end_try marker, so we don't need a new marker there.
1325   if (AppendixBB)
1326     BrDests.push_back(AppendixBB);
1327 
1328   llvm::sort(BrDests,
1329              [&](const MachineBasicBlock *A, const MachineBasicBlock *B) {
1330                auto ANum = A->getNumber();
1331                auto BNum = B->getNumber();
1332                return ANum < BNum;
1333              });
1334   for (auto *Dest : BrDests)
1335     placeBlockMarker(*Dest);
1336 
1337   return true;
1338 }
1339 
1340 static unsigned
1341 getDepth(const SmallVectorImpl<const MachineBasicBlock *> &Stack,
1342          const MachineBasicBlock *MBB) {
1343   unsigned Depth = 0;
1344   for (auto X : reverse(Stack)) {
1345     if (X == MBB)
1346       break;
1347     ++Depth;
1348   }
1349   assert(Depth < Stack.size() && "Branch destination should be in scope");
1350   return Depth;
1351 }
1352 
1353 /// In normal assembly languages, when the end of a function is unreachable,
1354 /// because the function ends in an infinite loop or a noreturn call or similar,
1355 /// it isn't necessary to worry about the function return type at the end of
1356 /// the function, because it's never reached. However, in WebAssembly, blocks
1357 /// that end at the function end need to have a return type signature that
1358 /// matches the function signature, even though it's unreachable. This function
1359 /// checks for such cases and fixes up the signatures.
1360 void WebAssemblyCFGStackify::fixEndsAtEndOfFunction(MachineFunction &MF) {
1361   const auto &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
1362 
1363   if (MFI.getResults().empty())
1364     return;
1365 
1366   // MCInstLower will add the proper types to multivalue signatures based on the
1367   // function return type
1368   WebAssembly::BlockType RetType =
1369       MFI.getResults().size() > 1
1370           ? WebAssembly::BlockType::Multivalue
1371           : WebAssembly::BlockType(
1372                 WebAssembly::toValType(MFI.getResults().front()));
1373 
1374   for (MachineBasicBlock &MBB : reverse(MF)) {
1375     for (MachineInstr &MI : reverse(MBB)) {
1376       if (MI.isPosition() || MI.isDebugInstr())
1377         continue;
1378       switch (MI.getOpcode()) {
1379       case WebAssembly::END_BLOCK:
1380       case WebAssembly::END_LOOP:
1381       case WebAssembly::END_TRY:
1382         EndToBegin[&MI]->getOperand(0).setImm(int32_t(RetType));
1383         continue;
1384       default:
1385         // Something other than an `end`. We're done.
1386         return;
1387       }
1388     }
1389   }
1390 }
1391 
1392 // WebAssembly functions end with an end instruction, as if the function body
1393 // were a block.
1394 static void appendEndToFunction(MachineFunction &MF,
1395                                 const WebAssemblyInstrInfo &TII) {
1396   BuildMI(MF.back(), MF.back().end(),
1397           MF.back().findPrevDebugLoc(MF.back().end()),
1398           TII.get(WebAssembly::END_FUNCTION));
1399 }
1400 
1401 /// Insert LOOP/TRY/BLOCK markers at appropriate places.
1402 void WebAssemblyCFGStackify::placeMarkers(MachineFunction &MF) {
1403   // We allocate one more than the number of blocks in the function to
1404   // accommodate for the possible fake block we may insert at the end.
1405   ScopeTops.resize(MF.getNumBlockIDs() + 1);
1406   // Place the LOOP for MBB if MBB is the header of a loop.
1407   for (auto &MBB : MF)
1408     placeLoopMarker(MBB);
1409 
1410   const MCAsmInfo *MCAI = MF.getTarget().getMCAsmInfo();
1411   for (auto &MBB : MF) {
1412     if (MBB.isEHPad()) {
1413       // Place the TRY for MBB if MBB is the EH pad of an exception.
1414       if (MCAI->getExceptionHandlingType() == ExceptionHandling::Wasm &&
1415           MF.getFunction().hasPersonalityFn())
1416         placeTryMarker(MBB);
1417     } else {
1418       // Place the BLOCK for MBB if MBB is branched to from above.
1419       placeBlockMarker(MBB);
1420     }
1421   }
1422   // Fix mismatches in unwind destinations induced by linearizing the code.
1423   if (MCAI->getExceptionHandlingType() == ExceptionHandling::Wasm &&
1424       MF.getFunction().hasPersonalityFn())
1425     fixUnwindMismatches(MF);
1426 }
1427 
1428 void WebAssemblyCFGStackify::rewriteDepthImmediates(MachineFunction &MF) {
1429   // Now rewrite references to basic blocks to be depth immediates.
1430   SmallVector<const MachineBasicBlock *, 8> Stack;
1431   for (auto &MBB : reverse(MF)) {
1432     for (auto I = MBB.rbegin(), E = MBB.rend(); I != E; ++I) {
1433       MachineInstr &MI = *I;
1434       switch (MI.getOpcode()) {
1435       case WebAssembly::BLOCK:
1436       case WebAssembly::TRY:
1437         assert(ScopeTops[Stack.back()->getNumber()]->getNumber() <=
1438                    MBB.getNumber() &&
1439                "Block/try marker should be balanced");
1440         Stack.pop_back();
1441         break;
1442 
1443       case WebAssembly::LOOP:
1444         assert(Stack.back() == &MBB && "Loop top should be balanced");
1445         Stack.pop_back();
1446         break;
1447 
1448       case WebAssembly::END_BLOCK:
1449       case WebAssembly::END_TRY:
1450         Stack.push_back(&MBB);
1451         break;
1452 
1453       case WebAssembly::END_LOOP:
1454         Stack.push_back(EndToBegin[&MI]->getParent());
1455         break;
1456 
1457       default:
1458         if (MI.isTerminator()) {
1459           // Rewrite MBB operands to be depth immediates.
1460           SmallVector<MachineOperand, 4> Ops(MI.operands());
1461           while (MI.getNumOperands() > 0)
1462             MI.RemoveOperand(MI.getNumOperands() - 1);
1463           for (auto MO : Ops) {
1464             if (MO.isMBB())
1465               MO = MachineOperand::CreateImm(getDepth(Stack, MO.getMBB()));
1466             MI.addOperand(MF, MO);
1467           }
1468         }
1469         break;
1470       }
1471     }
1472   }
1473   assert(Stack.empty() && "Control flow should be balanced");
1474 }
1475 
1476 void WebAssemblyCFGStackify::releaseMemory() {
1477   ScopeTops.clear();
1478   BeginToEnd.clear();
1479   EndToBegin.clear();
1480   TryToEHPad.clear();
1481   EHPadToTry.clear();
1482   AppendixBB = nullptr;
1483 }
1484 
1485 bool WebAssemblyCFGStackify::runOnMachineFunction(MachineFunction &MF) {
1486   LLVM_DEBUG(dbgs() << "********** CFG Stackifying **********\n"
1487                        "********** Function: "
1488                     << MF.getName() << '\n');
1489   const MCAsmInfo *MCAI = MF.getTarget().getMCAsmInfo();
1490 
1491   releaseMemory();
1492 
1493   // Liveness is not tracked for VALUE_STACK physreg.
1494   MF.getRegInfo().invalidateLiveness();
1495 
1496   // Place the BLOCK/LOOP/TRY markers to indicate the beginnings of scopes.
1497   placeMarkers(MF);
1498 
1499   // Remove unnecessary instructions possibly introduced by try/end_trys.
1500   if (MCAI->getExceptionHandlingType() == ExceptionHandling::Wasm &&
1501       MF.getFunction().hasPersonalityFn())
1502     removeUnnecessaryInstrs(MF);
1503 
1504   // Convert MBB operands in terminators to relative depth immediates.
1505   rewriteDepthImmediates(MF);
1506 
1507   // Fix up block/loop/try signatures at the end of the function to conform to
1508   // WebAssembly's rules.
1509   fixEndsAtEndOfFunction(MF);
1510 
1511   // Add an end instruction at the end of the function body.
1512   const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
1513   if (!MF.getSubtarget<WebAssemblySubtarget>()
1514            .getTargetTriple()
1515            .isOSBinFormatELF())
1516     appendEndToFunction(MF, TII);
1517 
1518   MF.getInfo<WebAssemblyFunctionInfo>()->setCFGStackified();
1519   return true;
1520 }
1521