blob: 3d9651c406d93ed14093e7576095953617387ee9 [file] [log] [blame]
Dan Gohman950a13c2015-09-16 16:51:30 +00001//===-- WebAssemblyCFGStackify.cpp - CFG Stackification -------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// \brief This file implements a CFG stacking pass.
12///
Dan Gohmanf52ee172017-02-27 22:38:58 +000013/// This pass inserts BLOCK and LOOP markers to mark the start of scopes, since
Dan Gohman950a13c2015-09-16 16:51:30 +000014/// scope boundaries serve as the labels for WebAssembly's 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///
Dan Gohman950a13c2015-09-16 16:51:30 +000019//===----------------------------------------------------------------------===//
20
Dan Gohman950a13c2015-09-16 16:51:30 +000021#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000022#include "WebAssembly.h"
Dan Gohmaned0f1132016-01-30 05:01:06 +000023#include "WebAssemblyMachineFunctionInfo.h"
Dan Gohman950a13c2015-09-16 16:51:30 +000024#include "WebAssemblySubtarget.h"
Dan Gohman4fc4e422016-10-24 19:49:43 +000025#include "WebAssemblyUtilities.h"
Dan Gohman32807932015-11-23 16:19:56 +000026#include "llvm/CodeGen/MachineDominators.h"
Dan Gohman950a13c2015-09-16 16:51:30 +000027#include "llvm/CodeGen/MachineFunction.h"
28#include "llvm/CodeGen/MachineInstrBuilder.h"
29#include "llvm/CodeGen/MachineLoopInfo.h"
Derek Schuff9c3bf312016-01-13 17:10:28 +000030#include "llvm/CodeGen/MachineRegisterInfo.h"
Dan Gohman950a13c2015-09-16 16:51:30 +000031#include "llvm/CodeGen/Passes.h"
32#include "llvm/Support/Debug.h"
33#include "llvm/Support/raw_ostream.h"
34using namespace llvm;
35
36#define DEBUG_TYPE "wasm-cfg-stackify"
37
38namespace {
39class WebAssemblyCFGStackify final : public MachineFunctionPass {
Mehdi Amini117296c2016-10-01 02:56:57 +000040 StringRef getPassName() const override { return "WebAssembly CFG Stackify"; }
Dan Gohman950a13c2015-09-16 16:51:30 +000041
42 void getAnalysisUsage(AnalysisUsage &AU) const override {
43 AU.setPreservesCFG();
Dan Gohman32807932015-11-23 16:19:56 +000044 AU.addRequired<MachineDominatorTree>();
45 AU.addPreserved<MachineDominatorTree>();
Dan Gohman950a13c2015-09-16 16:51:30 +000046 AU.addRequired<MachineLoopInfo>();
47 AU.addPreserved<MachineLoopInfo>();
48 MachineFunctionPass::getAnalysisUsage(AU);
49 }
50
51 bool runOnMachineFunction(MachineFunction &MF) override;
52
53public:
54 static char ID; // Pass identification, replacement for typeid
55 WebAssemblyCFGStackify() : MachineFunctionPass(ID) {}
56};
57} // end anonymous namespace
58
59char WebAssemblyCFGStackify::ID = 0;
Jacob Gravelle40926452018-03-30 20:36:58 +000060INITIALIZE_PASS(WebAssemblyCFGStackify, DEBUG_TYPE,
61 "Insert BLOCK and LOOP markers for WebAssembly scopes",
62 false, false)
63
Dan Gohman950a13c2015-09-16 16:51:30 +000064FunctionPass *llvm::createWebAssemblyCFGStackify() {
65 return new WebAssemblyCFGStackify();
66}
67
Dan Gohmanb3aa1ec2015-12-16 19:06:41 +000068/// Test whether Pred has any terminators explicitly branching to MBB, as
69/// opposed to falling through. Note that it's possible (eg. in unoptimized
70/// code) for a branch instruction to both branch to a block and fallthrough
71/// to it, so we check the actual branch operands to see if there are any
72/// explicit mentions.
Dan Gohman35e4a282016-01-08 01:06:00 +000073static bool ExplicitlyBranchesTo(MachineBasicBlock *Pred,
74 MachineBasicBlock *MBB) {
Dan Gohmanb3aa1ec2015-12-16 19:06:41 +000075 for (MachineInstr &MI : Pred->terminators())
76 for (MachineOperand &MO : MI.explicit_operands())
77 if (MO.isMBB() && MO.getMBB() == MBB)
78 return true;
79 return false;
80}
81
Dan Gohman32807932015-11-23 16:19:56 +000082/// Insert a BLOCK marker for branches to MBB (if needed).
Dan Gohman3a643e82016-10-06 22:10:23 +000083static void PlaceBlockMarker(
84 MachineBasicBlock &MBB, MachineFunction &MF,
85 SmallVectorImpl<MachineBasicBlock *> &ScopeTops,
Dan Gohman2726b882016-10-06 22:29:32 +000086 DenseMap<const MachineInstr *, MachineInstr *> &BlockTops,
87 DenseMap<const MachineInstr *, MachineInstr *> &LoopTops,
Dan Gohman3a643e82016-10-06 22:10:23 +000088 const WebAssemblyInstrInfo &TII,
89 const MachineLoopInfo &MLI,
90 MachineDominatorTree &MDT,
91 WebAssemblyFunctionInfo &MFI) {
Dan Gohman8fe7e862015-12-14 22:51:54 +000092 // First compute the nearest common dominator of all forward non-fallthrough
93 // predecessors so that we minimize the time that the BLOCK is on the stack,
94 // which reduces overall stack height.
Dan Gohman32807932015-11-23 16:19:56 +000095 MachineBasicBlock *Header = nullptr;
96 bool IsBranchedTo = false;
97 int MBBNumber = MBB.getNumber();
98 for (MachineBasicBlock *Pred : MBB.predecessors())
99 if (Pred->getNumber() < MBBNumber) {
100 Header = Header ? MDT.findNearestCommonDominator(Header, Pred) : Pred;
Dan Gohmanb3aa1ec2015-12-16 19:06:41 +0000101 if (ExplicitlyBranchesTo(Pred, &MBB))
Dan Gohman32807932015-11-23 16:19:56 +0000102 IsBranchedTo = true;
103 }
104 if (!Header)
105 return;
106 if (!IsBranchedTo)
Dan Gohman950a13c2015-09-16 16:51:30 +0000107 return;
108
Dan Gohman8fe7e862015-12-14 22:51:54 +0000109 assert(&MBB != &MF.front() && "Header blocks shouldn't have predecessors");
Benjamin Krameref0a45a2016-09-05 12:06:47 +0000110 MachineBasicBlock *LayoutPred = &*std::prev(MachineFunction::iterator(&MBB));
Dan Gohman8fe7e862015-12-14 22:51:54 +0000111
112 // If the nearest common dominator is inside a more deeply nested context,
113 // walk out to the nearest scope which isn't more deeply nested.
114 for (MachineFunction::iterator I(LayoutPred), E(Header); I != E; --I) {
115 if (MachineBasicBlock *ScopeTop = ScopeTops[I->getNumber()]) {
116 if (ScopeTop->getNumber() > Header->getNumber()) {
117 // Skip over an intervening scope.
Benjamin Krameref0a45a2016-09-05 12:06:47 +0000118 I = std::next(MachineFunction::iterator(ScopeTop));
Dan Gohman8fe7e862015-12-14 22:51:54 +0000119 } else {
120 // We found a scope level at an appropriate depth.
121 Header = ScopeTop;
122 break;
123 }
124 }
125 }
126
Dan Gohman8fe7e862015-12-14 22:51:54 +0000127 // Decide where in Header to put the BLOCK.
Dan Gohman32807932015-11-23 16:19:56 +0000128 MachineBasicBlock::iterator InsertPos;
129 MachineLoop *HeaderLoop = MLI.getLoopFor(Header);
Dan Gohman8fe7e862015-12-14 22:51:54 +0000130 if (HeaderLoop && MBB.getNumber() > LoopBottom(HeaderLoop)->getNumber()) {
131 // Header is the header of a loop that does not lexically contain MBB, so
Dan Gohmana187ab22016-02-12 21:19:25 +0000132 // the BLOCK needs to be above the LOOP, after any END constructs.
Dan Gohman32807932015-11-23 16:19:56 +0000133 InsertPos = Header->begin();
Dan Gohman3a643e82016-10-06 22:10:23 +0000134 while (InsertPos->getOpcode() == WebAssembly::END_BLOCK ||
135 InsertPos->getOpcode() == WebAssembly::END_LOOP)
Dan Gohmana187ab22016-02-12 21:19:25 +0000136 ++InsertPos;
Dan Gohman32807932015-11-23 16:19:56 +0000137 } else {
Dan Gohman8887d1f2015-12-25 00:31:02 +0000138 // Otherwise, insert the BLOCK as late in Header as we can, but before the
139 // beginning of the local expression tree and any nested BLOCKs.
Dan Gohman32807932015-11-23 16:19:56 +0000140 InsertPos = Header->getFirstTerminator();
Benjamin Krameref0a45a2016-09-05 12:06:47 +0000141 while (InsertPos != Header->begin() &&
Dan Gohman4fc4e422016-10-24 19:49:43 +0000142 WebAssembly::isChild(*std::prev(InsertPos), MFI) &&
Benjamin Krameref0a45a2016-09-05 12:06:47 +0000143 std::prev(InsertPos)->getOpcode() != WebAssembly::LOOP &&
144 std::prev(InsertPos)->getOpcode() != WebAssembly::END_BLOCK &&
145 std::prev(InsertPos)->getOpcode() != WebAssembly::END_LOOP)
Dan Gohman32807932015-11-23 16:19:56 +0000146 --InsertPos;
Dan Gohman950a13c2015-09-16 16:51:30 +0000147 }
148
Dan Gohman8fe7e862015-12-14 22:51:54 +0000149 // Add the BLOCK.
Derek Schuff10b31352018-03-15 22:06:51 +0000150 MachineInstr *Begin = BuildMI(*Header, InsertPos, MBB.findDebugLoc(InsertPos),
Dan Gohman2726b882016-10-06 22:29:32 +0000151 TII.get(WebAssembly::BLOCK))
Derek Schuff10b31352018-03-15 22:06:51 +0000152 .addImm(int64_t(WebAssembly::ExprType::Void));
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000153
154 // Mark the end of the block.
155 InsertPos = MBB.begin();
156 while (InsertPos != MBB.end() &&
Dan Gohman3a643e82016-10-06 22:10:23 +0000157 InsertPos->getOpcode() == WebAssembly::END_LOOP &&
Dan Gohman2726b882016-10-06 22:29:32 +0000158 LoopTops[&*InsertPos]->getParent()->getNumber() >= Header->getNumber())
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000159 ++InsertPos;
Derek Schuff10b31352018-03-15 22:06:51 +0000160 MachineInstr *End = BuildMI(MBB, InsertPos, MBB.findPrevDebugLoc(InsertPos),
Dan Gohman2726b882016-10-06 22:29:32 +0000161 TII.get(WebAssembly::END_BLOCK));
162 BlockTops[End] = Begin;
Dan Gohman8fe7e862015-12-14 22:51:54 +0000163
164 // Track the farthest-spanning scope that ends at this point.
165 int Number = MBB.getNumber();
166 if (!ScopeTops[Number] ||
167 ScopeTops[Number]->getNumber() > Header->getNumber())
168 ScopeTops[Number] = Header;
169}
170
171/// Insert a LOOP marker for a loop starting at MBB (if it's a loop header).
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000172static void PlaceLoopMarker(
173 MachineBasicBlock &MBB, MachineFunction &MF,
174 SmallVectorImpl<MachineBasicBlock *> &ScopeTops,
Dan Gohman2726b882016-10-06 22:29:32 +0000175 DenseMap<const MachineInstr *, MachineInstr *> &LoopTops,
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000176 const WebAssemblyInstrInfo &TII, const MachineLoopInfo &MLI) {
Dan Gohman8fe7e862015-12-14 22:51:54 +0000177 MachineLoop *Loop = MLI.getLoopFor(&MBB);
178 if (!Loop || Loop->getHeader() != &MBB)
179 return;
180
181 // The operand of a LOOP is the first block after the loop. If the loop is the
182 // bottom of the function, insert a dummy block at the end.
183 MachineBasicBlock *Bottom = LoopBottom(Loop);
Benjamin Krameref0a45a2016-09-05 12:06:47 +0000184 auto Iter = std::next(MachineFunction::iterator(Bottom));
Dan Gohman8fe7e862015-12-14 22:51:54 +0000185 if (Iter == MF.end()) {
186 MachineBasicBlock *Label = MF.CreateMachineBasicBlock();
187 // Give it a fake predecessor so that AsmPrinter prints its label.
188 Label->addSuccessor(Label);
189 MF.push_back(Label);
Benjamin Krameref0a45a2016-09-05 12:06:47 +0000190 Iter = std::next(MachineFunction::iterator(Bottom));
Dan Gohman8fe7e862015-12-14 22:51:54 +0000191 }
192 MachineBasicBlock *AfterLoop = &*Iter;
Dan Gohman8fe7e862015-12-14 22:51:54 +0000193
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000194 // Mark the beginning of the loop (after the end of any existing loop that
195 // ends here).
196 auto InsertPos = MBB.begin();
197 while (InsertPos != MBB.end() &&
198 InsertPos->getOpcode() == WebAssembly::END_LOOP)
199 ++InsertPos;
Derek Schuff10b31352018-03-15 22:06:51 +0000200 MachineInstr *Begin = BuildMI(MBB, InsertPos, MBB.findDebugLoc(InsertPos),
Dan Gohman2726b882016-10-06 22:29:32 +0000201 TII.get(WebAssembly::LOOP))
Derek Schuff10b31352018-03-15 22:06:51 +0000202 .addImm(int64_t(WebAssembly::ExprType::Void));
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000203
Derek Schuff10b31352018-03-15 22:06:51 +0000204 // Mark the end of the loop (using arbitrary debug location that branched
205 // to the loop end as its location).
206 DebugLoc EndDL = (*AfterLoop->pred_rbegin())->findBranchDebugLoc();
207 MachineInstr *End = BuildMI(*AfterLoop, AfterLoop->begin(), EndDL,
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000208 TII.get(WebAssembly::END_LOOP));
Dan Gohman2726b882016-10-06 22:29:32 +0000209 LoopTops[End] = Begin;
Dan Gohman8fe7e862015-12-14 22:51:54 +0000210
211 assert((!ScopeTops[AfterLoop->getNumber()] ||
212 ScopeTops[AfterLoop->getNumber()]->getNumber() < MBB.getNumber()) &&
Dan Gohman442bfce2016-02-16 16:22:41 +0000213 "With block sorting the outermost loop for a block should be first.");
Dan Gohman8fe7e862015-12-14 22:51:54 +0000214 if (!ScopeTops[AfterLoop->getNumber()])
215 ScopeTops[AfterLoop->getNumber()] = &MBB;
Dan Gohman950a13c2015-09-16 16:51:30 +0000216}
217
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000218static unsigned
219GetDepth(const SmallVectorImpl<const MachineBasicBlock *> &Stack,
220 const MachineBasicBlock *MBB) {
221 unsigned Depth = 0;
222 for (auto X : reverse(Stack)) {
223 if (X == MBB)
224 break;
225 ++Depth;
226 }
227 assert(Depth < Stack.size() && "Branch destination should be in scope");
228 return Depth;
229}
230
Dan Gohman2726b882016-10-06 22:29:32 +0000231/// In normal assembly languages, when the end of a function is unreachable,
232/// because the function ends in an infinite loop or a noreturn call or similar,
233/// it isn't necessary to worry about the function return type at the end of
234/// the function, because it's never reached. However, in WebAssembly, blocks
235/// that end at the function end need to have a return type signature that
236/// matches the function signature, even though it's unreachable. This function
237/// checks for such cases and fixes up the signatures.
238static void FixEndsAtEndOfFunction(
239 MachineFunction &MF,
240 const WebAssemblyFunctionInfo &MFI,
241 DenseMap<const MachineInstr *, MachineInstr *> &BlockTops,
242 DenseMap<const MachineInstr *, MachineInstr *> &LoopTops) {
243 assert(MFI.getResults().size() <= 1);
244
245 if (MFI.getResults().empty())
246 return;
247
248 WebAssembly::ExprType retType;
249 switch (MFI.getResults().front().SimpleTy) {
Dan Gohman4fc4e422016-10-24 19:49:43 +0000250 case MVT::i32: retType = WebAssembly::ExprType::I32; break;
251 case MVT::i64: retType = WebAssembly::ExprType::I64; break;
252 case MVT::f32: retType = WebAssembly::ExprType::F32; break;
253 case MVT::f64: retType = WebAssembly::ExprType::F64; break;
254 case MVT::v16i8: retType = WebAssembly::ExprType::I8x16; break;
255 case MVT::v8i16: retType = WebAssembly::ExprType::I16x8; break;
256 case MVT::v4i32: retType = WebAssembly::ExprType::I32x4; break;
Dan Gohman4fc4e422016-10-24 19:49:43 +0000257 case MVT::v4f32: retType = WebAssembly::ExprType::F32x4; break;
Heejin Ahn0de58722018-03-08 04:05:37 +0000258 case MVT::ExceptRef: retType = WebAssembly::ExprType::ExceptRef; break;
Dan Gohman2726b882016-10-06 22:29:32 +0000259 default: llvm_unreachable("unexpected return type");
260 }
261
262 for (MachineBasicBlock &MBB : reverse(MF)) {
263 for (MachineInstr &MI : reverse(MBB)) {
264 if (MI.isPosition() || MI.isDebugValue())
265 continue;
266 if (MI.getOpcode() == WebAssembly::END_BLOCK) {
267 BlockTops[&MI]->getOperand(0).setImm(int32_t(retType));
268 continue;
269 }
270 if (MI.getOpcode() == WebAssembly::END_LOOP) {
271 LoopTops[&MI]->getOperand(0).setImm(int32_t(retType));
272 continue;
273 }
274 // Something other than an `end`. We're done.
275 return;
276 }
277 }
278}
279
Dan Gohmand934cb82017-02-24 23:18:00 +0000280// WebAssembly functions end with an end instruction, as if the function body
281// were a block.
282static void AppendEndToFunction(
283 MachineFunction &MF,
284 const WebAssemblyInstrInfo &TII) {
Derek Schuff10b31352018-03-15 22:06:51 +0000285 BuildMI(MF.back(), MF.back().end(),
286 MF.back().findPrevDebugLoc(MF.back().end()),
Dan Gohmand934cb82017-02-24 23:18:00 +0000287 TII.get(WebAssembly::END_FUNCTION));
288}
289
Dan Gohman950a13c2015-09-16 16:51:30 +0000290/// Insert LOOP and BLOCK markers at appropriate places.
291static void PlaceMarkers(MachineFunction &MF, const MachineLoopInfo &MLI,
Dan Gohman32807932015-11-23 16:19:56 +0000292 const WebAssemblyInstrInfo &TII,
Dan Gohmaned0f1132016-01-30 05:01:06 +0000293 MachineDominatorTree &MDT,
294 WebAssemblyFunctionInfo &MFI) {
Dan Gohman8fe7e862015-12-14 22:51:54 +0000295 // For each block whose label represents the end of a scope, record the block
296 // which holds the beginning of the scope. This will allow us to quickly skip
297 // over scoped regions when walking blocks. We allocate one more than the
298 // number of blocks in the function to accommodate for the possible fake block
299 // we may insert at the end.
300 SmallVector<MachineBasicBlock *, 8> ScopeTops(MF.getNumBlockIDs() + 1);
301
Dan Gohman2726b882016-10-06 22:29:32 +0000302 // For each LOOP_END, the corresponding LOOP.
303 DenseMap<const MachineInstr *, MachineInstr *> LoopTops;
304
305 // For each END_BLOCK, the corresponding BLOCK.
306 DenseMap<const MachineInstr *, MachineInstr *> BlockTops;
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000307
Dan Gohman950a13c2015-09-16 16:51:30 +0000308 for (auto &MBB : MF) {
Dan Gohman32807932015-11-23 16:19:56 +0000309 // Place the LOOP for MBB if MBB is the header of a loop.
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000310 PlaceLoopMarker(MBB, MF, ScopeTops, LoopTops, TII, MLI);
Dan Gohman950a13c2015-09-16 16:51:30 +0000311
Dan Gohman32807932015-11-23 16:19:56 +0000312 // Place the BLOCK for MBB if MBB is branched to from above.
Dan Gohman2726b882016-10-06 22:29:32 +0000313 PlaceBlockMarker(MBB, MF, ScopeTops, BlockTops, LoopTops, TII, MLI, MDT, MFI);
Dan Gohman950a13c2015-09-16 16:51:30 +0000314 }
Dan Gohman950a13c2015-09-16 16:51:30 +0000315
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000316 // Now rewrite references to basic blocks to be depth immediates.
317 SmallVector<const MachineBasicBlock *, 8> Stack;
318 for (auto &MBB : reverse(MF)) {
319 for (auto &MI : reverse(MBB)) {
320 switch (MI.getOpcode()) {
321 case WebAssembly::BLOCK:
Dan Gohman3a643e82016-10-06 22:10:23 +0000322 assert(ScopeTops[Stack.back()->getNumber()]->getNumber() <= MBB.getNumber() &&
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000323 "Block should be balanced");
324 Stack.pop_back();
325 break;
326 case WebAssembly::LOOP:
327 assert(Stack.back() == &MBB && "Loop top should be balanced");
328 Stack.pop_back();
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000329 break;
330 case WebAssembly::END_BLOCK:
331 Stack.push_back(&MBB);
332 break;
333 case WebAssembly::END_LOOP:
Dan Gohman2726b882016-10-06 22:29:32 +0000334 Stack.push_back(LoopTops[&MI]->getParent());
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000335 break;
336 default:
337 if (MI.isTerminator()) {
338 // Rewrite MBB operands to be depth immediates.
339 SmallVector<MachineOperand, 4> Ops(MI.operands());
340 while (MI.getNumOperands() > 0)
341 MI.RemoveOperand(MI.getNumOperands() - 1);
342 for (auto MO : Ops) {
343 if (MO.isMBB())
344 MO = MachineOperand::CreateImm(GetDepth(Stack, MO.getMBB()));
345 MI.addOperand(MF, MO);
346 }
347 }
348 break;
349 }
350 }
351 }
352 assert(Stack.empty() && "Control flow should be balanced");
Dan Gohman2726b882016-10-06 22:29:32 +0000353
354 // Fix up block/loop signatures at the end of the function to conform to
355 // WebAssembly's rules.
356 FixEndsAtEndOfFunction(MF, MFI, BlockTops, LoopTops);
Dan Gohmand934cb82017-02-24 23:18:00 +0000357
358 // Add an end instruction at the end of the function body.
359 if (!MF.getSubtarget<WebAssemblySubtarget>()
360 .getTargetTriple().isOSBinFormatELF())
361 AppendEndToFunction(MF, TII);
Dan Gohman32807932015-11-23 16:19:56 +0000362}
Dan Gohman32807932015-11-23 16:19:56 +0000363
Dan Gohman950a13c2015-09-16 16:51:30 +0000364bool WebAssemblyCFGStackify::runOnMachineFunction(MachineFunction &MF) {
365 DEBUG(dbgs() << "********** CFG Stackifying **********\n"
366 "********** Function: "
367 << MF.getName() << '\n');
368
369 const auto &MLI = getAnalysis<MachineLoopInfo>();
Dan Gohman32807932015-11-23 16:19:56 +0000370 auto &MDT = getAnalysis<MachineDominatorTree>();
Dan Gohmane0405332016-10-03 22:43:53 +0000371 // Liveness is not tracked for VALUE_STACK physreg.
Dan Gohman950a13c2015-09-16 16:51:30 +0000372 const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
Dan Gohmaned0f1132016-01-30 05:01:06 +0000373 WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
Derek Schuff9c3bf312016-01-13 17:10:28 +0000374 MF.getRegInfo().invalidateLiveness();
Dan Gohman950a13c2015-09-16 16:51:30 +0000375
Dan Gohman950a13c2015-09-16 16:51:30 +0000376 // Place the BLOCK and LOOP markers to indicate the beginnings of scopes.
Dan Gohmaned0f1132016-01-30 05:01:06 +0000377 PlaceMarkers(MF, MLI, TII, MDT, MFI);
Dan Gohman32807932015-11-23 16:19:56 +0000378
Dan Gohman950a13c2015-09-16 16:51:30 +0000379 return true;
380}