blob: 12664e62a0670b37748274db12c2ab1269ee8f28 [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.
Heejin Ahn92401cc2018-04-14 00:12:12 +0000150 MachineInstr *Begin =
151 BuildMI(*Header, InsertPos, Header->findDebugLoc(InsertPos),
152 TII.get(WebAssembly::BLOCK))
153 .addImm(int64_t(WebAssembly::ExprType::Void));
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000154
155 // Mark the end of the block.
156 InsertPos = MBB.begin();
157 while (InsertPos != MBB.end() &&
Dan Gohman3a643e82016-10-06 22:10:23 +0000158 InsertPos->getOpcode() == WebAssembly::END_LOOP &&
Dan Gohman2726b882016-10-06 22:29:32 +0000159 LoopTops[&*InsertPos]->getParent()->getNumber() >= Header->getNumber())
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000160 ++InsertPos;
Derek Schuff10b31352018-03-15 22:06:51 +0000161 MachineInstr *End = BuildMI(MBB, InsertPos, MBB.findPrevDebugLoc(InsertPos),
Dan Gohman2726b882016-10-06 22:29:32 +0000162 TII.get(WebAssembly::END_BLOCK));
163 BlockTops[End] = Begin;
Dan Gohman8fe7e862015-12-14 22:51:54 +0000164
165 // Track the farthest-spanning scope that ends at this point.
166 int Number = MBB.getNumber();
167 if (!ScopeTops[Number] ||
168 ScopeTops[Number]->getNumber() > Header->getNumber())
169 ScopeTops[Number] = Header;
170}
171
172/// Insert a LOOP marker for a loop starting at MBB (if it's a loop header).
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000173static void PlaceLoopMarker(
174 MachineBasicBlock &MBB, MachineFunction &MF,
175 SmallVectorImpl<MachineBasicBlock *> &ScopeTops,
Dan Gohman2726b882016-10-06 22:29:32 +0000176 DenseMap<const MachineInstr *, MachineInstr *> &LoopTops,
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000177 const WebAssemblyInstrInfo &TII, const MachineLoopInfo &MLI) {
Dan Gohman8fe7e862015-12-14 22:51:54 +0000178 MachineLoop *Loop = MLI.getLoopFor(&MBB);
179 if (!Loop || Loop->getHeader() != &MBB)
180 return;
181
182 // The operand of a LOOP is the first block after the loop. If the loop is the
183 // bottom of the function, insert a dummy block at the end.
184 MachineBasicBlock *Bottom = LoopBottom(Loop);
Benjamin Krameref0a45a2016-09-05 12:06:47 +0000185 auto Iter = std::next(MachineFunction::iterator(Bottom));
Dan Gohman8fe7e862015-12-14 22:51:54 +0000186 if (Iter == MF.end()) {
187 MachineBasicBlock *Label = MF.CreateMachineBasicBlock();
188 // Give it a fake predecessor so that AsmPrinter prints its label.
189 Label->addSuccessor(Label);
190 MF.push_back(Label);
Benjamin Krameref0a45a2016-09-05 12:06:47 +0000191 Iter = std::next(MachineFunction::iterator(Bottom));
Dan Gohman8fe7e862015-12-14 22:51:54 +0000192 }
193 MachineBasicBlock *AfterLoop = &*Iter;
Dan Gohman8fe7e862015-12-14 22:51:54 +0000194
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000195 // Mark the beginning of the loop (after the end of any existing loop that
196 // ends here).
197 auto InsertPos = MBB.begin();
198 while (InsertPos != MBB.end() &&
199 InsertPos->getOpcode() == WebAssembly::END_LOOP)
200 ++InsertPos;
Derek Schuff10b31352018-03-15 22:06:51 +0000201 MachineInstr *Begin = BuildMI(MBB, InsertPos, MBB.findDebugLoc(InsertPos),
Dan Gohman2726b882016-10-06 22:29:32 +0000202 TII.get(WebAssembly::LOOP))
Derek Schuff10b31352018-03-15 22:06:51 +0000203 .addImm(int64_t(WebAssembly::ExprType::Void));
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000204
Derek Schuff10b31352018-03-15 22:06:51 +0000205 // Mark the end of the loop (using arbitrary debug location that branched
206 // to the loop end as its location).
207 DebugLoc EndDL = (*AfterLoop->pred_rbegin())->findBranchDebugLoc();
208 MachineInstr *End = BuildMI(*AfterLoop, AfterLoop->begin(), EndDL,
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000209 TII.get(WebAssembly::END_LOOP));
Dan Gohman2726b882016-10-06 22:29:32 +0000210 LoopTops[End] = Begin;
Dan Gohman8fe7e862015-12-14 22:51:54 +0000211
212 assert((!ScopeTops[AfterLoop->getNumber()] ||
213 ScopeTops[AfterLoop->getNumber()]->getNumber() < MBB.getNumber()) &&
Dan Gohman442bfce2016-02-16 16:22:41 +0000214 "With block sorting the outermost loop for a block should be first.");
Dan Gohman8fe7e862015-12-14 22:51:54 +0000215 if (!ScopeTops[AfterLoop->getNumber()])
216 ScopeTops[AfterLoop->getNumber()] = &MBB;
Dan Gohman950a13c2015-09-16 16:51:30 +0000217}
218
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000219static unsigned
220GetDepth(const SmallVectorImpl<const MachineBasicBlock *> &Stack,
221 const MachineBasicBlock *MBB) {
222 unsigned Depth = 0;
223 for (auto X : reverse(Stack)) {
224 if (X == MBB)
225 break;
226 ++Depth;
227 }
228 assert(Depth < Stack.size() && "Branch destination should be in scope");
229 return Depth;
230}
231
Dan Gohman2726b882016-10-06 22:29:32 +0000232/// In normal assembly languages, when the end of a function is unreachable,
233/// because the function ends in an infinite loop or a noreturn call or similar,
234/// it isn't necessary to worry about the function return type at the end of
235/// the function, because it's never reached. However, in WebAssembly, blocks
236/// that end at the function end need to have a return type signature that
237/// matches the function signature, even though it's unreachable. This function
238/// checks for such cases and fixes up the signatures.
239static void FixEndsAtEndOfFunction(
240 MachineFunction &MF,
241 const WebAssemblyFunctionInfo &MFI,
242 DenseMap<const MachineInstr *, MachineInstr *> &BlockTops,
243 DenseMap<const MachineInstr *, MachineInstr *> &LoopTops) {
244 assert(MFI.getResults().size() <= 1);
245
246 if (MFI.getResults().empty())
247 return;
248
249 WebAssembly::ExprType retType;
250 switch (MFI.getResults().front().SimpleTy) {
Dan Gohman4fc4e422016-10-24 19:49:43 +0000251 case MVT::i32: retType = WebAssembly::ExprType::I32; break;
252 case MVT::i64: retType = WebAssembly::ExprType::I64; break;
253 case MVT::f32: retType = WebAssembly::ExprType::F32; break;
254 case MVT::f64: retType = WebAssembly::ExprType::F64; break;
255 case MVT::v16i8: retType = WebAssembly::ExprType::I8x16; break;
256 case MVT::v8i16: retType = WebAssembly::ExprType::I16x8; break;
257 case MVT::v4i32: retType = WebAssembly::ExprType::I32x4; break;
Dan Gohman4fc4e422016-10-24 19:49:43 +0000258 case MVT::v4f32: retType = WebAssembly::ExprType::F32x4; break;
Heejin Ahn0de58722018-03-08 04:05:37 +0000259 case MVT::ExceptRef: retType = WebAssembly::ExprType::ExceptRef; break;
Dan Gohman2726b882016-10-06 22:29:32 +0000260 default: llvm_unreachable("unexpected return type");
261 }
262
263 for (MachineBasicBlock &MBB : reverse(MF)) {
264 for (MachineInstr &MI : reverse(MBB)) {
265 if (MI.isPosition() || MI.isDebugValue())
266 continue;
267 if (MI.getOpcode() == WebAssembly::END_BLOCK) {
268 BlockTops[&MI]->getOperand(0).setImm(int32_t(retType));
269 continue;
270 }
271 if (MI.getOpcode() == WebAssembly::END_LOOP) {
272 LoopTops[&MI]->getOperand(0).setImm(int32_t(retType));
273 continue;
274 }
275 // Something other than an `end`. We're done.
276 return;
277 }
278 }
279}
280
Dan Gohmand934cb82017-02-24 23:18:00 +0000281// WebAssembly functions end with an end instruction, as if the function body
282// were a block.
283static void AppendEndToFunction(
284 MachineFunction &MF,
285 const WebAssemblyInstrInfo &TII) {
Derek Schuff10b31352018-03-15 22:06:51 +0000286 BuildMI(MF.back(), MF.back().end(),
287 MF.back().findPrevDebugLoc(MF.back().end()),
Dan Gohmand934cb82017-02-24 23:18:00 +0000288 TII.get(WebAssembly::END_FUNCTION));
289}
290
Dan Gohman950a13c2015-09-16 16:51:30 +0000291/// Insert LOOP and BLOCK markers at appropriate places.
292static void PlaceMarkers(MachineFunction &MF, const MachineLoopInfo &MLI,
Dan Gohman32807932015-11-23 16:19:56 +0000293 const WebAssemblyInstrInfo &TII,
Dan Gohmaned0f1132016-01-30 05:01:06 +0000294 MachineDominatorTree &MDT,
295 WebAssemblyFunctionInfo &MFI) {
Dan Gohman8fe7e862015-12-14 22:51:54 +0000296 // For each block whose label represents the end of a scope, record the block
297 // which holds the beginning of the scope. This will allow us to quickly skip
298 // over scoped regions when walking blocks. We allocate one more than the
299 // number of blocks in the function to accommodate for the possible fake block
300 // we may insert at the end.
301 SmallVector<MachineBasicBlock *, 8> ScopeTops(MF.getNumBlockIDs() + 1);
302
Dan Gohman2726b882016-10-06 22:29:32 +0000303 // For each LOOP_END, the corresponding LOOP.
304 DenseMap<const MachineInstr *, MachineInstr *> LoopTops;
305
306 // For each END_BLOCK, the corresponding BLOCK.
307 DenseMap<const MachineInstr *, MachineInstr *> BlockTops;
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000308
Dan Gohman950a13c2015-09-16 16:51:30 +0000309 for (auto &MBB : MF) {
Dan Gohman32807932015-11-23 16:19:56 +0000310 // Place the LOOP for MBB if MBB is the header of a loop.
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000311 PlaceLoopMarker(MBB, MF, ScopeTops, LoopTops, TII, MLI);
Dan Gohman950a13c2015-09-16 16:51:30 +0000312
Dan Gohman32807932015-11-23 16:19:56 +0000313 // Place the BLOCK for MBB if MBB is branched to from above.
Dan Gohman2726b882016-10-06 22:29:32 +0000314 PlaceBlockMarker(MBB, MF, ScopeTops, BlockTops, LoopTops, TII, MLI, MDT, MFI);
Dan Gohman950a13c2015-09-16 16:51:30 +0000315 }
Dan Gohman950a13c2015-09-16 16:51:30 +0000316
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000317 // Now rewrite references to basic blocks to be depth immediates.
318 SmallVector<const MachineBasicBlock *, 8> Stack;
319 for (auto &MBB : reverse(MF)) {
320 for (auto &MI : reverse(MBB)) {
321 switch (MI.getOpcode()) {
322 case WebAssembly::BLOCK:
Dan Gohman3a643e82016-10-06 22:10:23 +0000323 assert(ScopeTops[Stack.back()->getNumber()]->getNumber() <= MBB.getNumber() &&
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000324 "Block should be balanced");
325 Stack.pop_back();
326 break;
327 case WebAssembly::LOOP:
328 assert(Stack.back() == &MBB && "Loop top should be balanced");
329 Stack.pop_back();
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000330 break;
331 case WebAssembly::END_BLOCK:
332 Stack.push_back(&MBB);
333 break;
334 case WebAssembly::END_LOOP:
Dan Gohman2726b882016-10-06 22:29:32 +0000335 Stack.push_back(LoopTops[&MI]->getParent());
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000336 break;
337 default:
338 if (MI.isTerminator()) {
339 // Rewrite MBB operands to be depth immediates.
340 SmallVector<MachineOperand, 4> Ops(MI.operands());
341 while (MI.getNumOperands() > 0)
342 MI.RemoveOperand(MI.getNumOperands() - 1);
343 for (auto MO : Ops) {
344 if (MO.isMBB())
345 MO = MachineOperand::CreateImm(GetDepth(Stack, MO.getMBB()));
346 MI.addOperand(MF, MO);
347 }
348 }
349 break;
350 }
351 }
352 }
353 assert(Stack.empty() && "Control flow should be balanced");
Dan Gohman2726b882016-10-06 22:29:32 +0000354
355 // Fix up block/loop signatures at the end of the function to conform to
356 // WebAssembly's rules.
357 FixEndsAtEndOfFunction(MF, MFI, BlockTops, LoopTops);
Dan Gohmand934cb82017-02-24 23:18:00 +0000358
359 // Add an end instruction at the end of the function body.
360 if (!MF.getSubtarget<WebAssemblySubtarget>()
361 .getTargetTriple().isOSBinFormatELF())
362 AppendEndToFunction(MF, TII);
Dan Gohman32807932015-11-23 16:19:56 +0000363}
Dan Gohman32807932015-11-23 16:19:56 +0000364
Dan Gohman950a13c2015-09-16 16:51:30 +0000365bool WebAssemblyCFGStackify::runOnMachineFunction(MachineFunction &MF) {
366 DEBUG(dbgs() << "********** CFG Stackifying **********\n"
367 "********** Function: "
368 << MF.getName() << '\n');
369
370 const auto &MLI = getAnalysis<MachineLoopInfo>();
Dan Gohman32807932015-11-23 16:19:56 +0000371 auto &MDT = getAnalysis<MachineDominatorTree>();
Dan Gohmane0405332016-10-03 22:43:53 +0000372 // Liveness is not tracked for VALUE_STACK physreg.
Dan Gohman950a13c2015-09-16 16:51:30 +0000373 const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
Dan Gohmaned0f1132016-01-30 05:01:06 +0000374 WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
Derek Schuff9c3bf312016-01-13 17:10:28 +0000375 MF.getRegInfo().invalidateLiveness();
Dan Gohman950a13c2015-09-16 16:51:30 +0000376
Dan Gohman950a13c2015-09-16 16:51:30 +0000377 // Place the BLOCK and LOOP markers to indicate the beginnings of scopes.
Dan Gohmaned0f1132016-01-30 05:01:06 +0000378 PlaceMarkers(MF, MLI, TII, MDT, MFI);
Dan Gohman32807932015-11-23 16:19:56 +0000379
Dan Gohman950a13c2015-09-16 16:51:30 +0000380 return true;
381}