blob: 1245ac0372746aa90ed99d9268f1de3f88658107 [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
Adrian Prantl5f8f34e42018-05-01 15:54:18 +000011/// This file implements a CFG stacking pass.
Dan Gohman950a13c2015-09-16 16:51:30 +000012///
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 }
Heejin Ahn2b8158f2018-04-17 21:19:21 +0000148 // The header block in which a 'block' mark will be inserted should have a
149 // terminator because it is branching to a non-layout successor.
150 assert(InsertPos != Header->end());
Dan Gohman950a13c2015-09-16 16:51:30 +0000151
Dan Gohman8fe7e862015-12-14 22:51:54 +0000152 // Add the BLOCK.
Heejin Ahn92401cc2018-04-14 00:12:12 +0000153 MachineInstr *Begin =
154 BuildMI(*Header, InsertPos, Header->findDebugLoc(InsertPos),
155 TII.get(WebAssembly::BLOCK))
156 .addImm(int64_t(WebAssembly::ExprType::Void));
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000157
158 // Mark the end of the block.
159 InsertPos = MBB.begin();
160 while (InsertPos != MBB.end() &&
Dan Gohman3a643e82016-10-06 22:10:23 +0000161 InsertPos->getOpcode() == WebAssembly::END_LOOP &&
Dan Gohman2726b882016-10-06 22:29:32 +0000162 LoopTops[&*InsertPos]->getParent()->getNumber() >= Header->getNumber())
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000163 ++InsertPos;
Derek Schuff10b31352018-03-15 22:06:51 +0000164 MachineInstr *End = BuildMI(MBB, InsertPos, MBB.findPrevDebugLoc(InsertPos),
Dan Gohman2726b882016-10-06 22:29:32 +0000165 TII.get(WebAssembly::END_BLOCK));
166 BlockTops[End] = Begin;
Dan Gohman8fe7e862015-12-14 22:51:54 +0000167
168 // Track the farthest-spanning scope that ends at this point.
169 int Number = MBB.getNumber();
170 if (!ScopeTops[Number] ||
171 ScopeTops[Number]->getNumber() > Header->getNumber())
172 ScopeTops[Number] = Header;
173}
174
175/// Insert a LOOP marker for a loop starting at MBB (if it's a loop header).
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000176static void PlaceLoopMarker(
177 MachineBasicBlock &MBB, MachineFunction &MF,
178 SmallVectorImpl<MachineBasicBlock *> &ScopeTops,
Dan Gohman2726b882016-10-06 22:29:32 +0000179 DenseMap<const MachineInstr *, MachineInstr *> &LoopTops,
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000180 const WebAssemblyInstrInfo &TII, const MachineLoopInfo &MLI) {
Dan Gohman8fe7e862015-12-14 22:51:54 +0000181 MachineLoop *Loop = MLI.getLoopFor(&MBB);
182 if (!Loop || Loop->getHeader() != &MBB)
183 return;
184
185 // The operand of a LOOP is the first block after the loop. If the loop is the
186 // bottom of the function, insert a dummy block at the end.
187 MachineBasicBlock *Bottom = LoopBottom(Loop);
Benjamin Krameref0a45a2016-09-05 12:06:47 +0000188 auto Iter = std::next(MachineFunction::iterator(Bottom));
Dan Gohman8fe7e862015-12-14 22:51:54 +0000189 if (Iter == MF.end()) {
190 MachineBasicBlock *Label = MF.CreateMachineBasicBlock();
191 // Give it a fake predecessor so that AsmPrinter prints its label.
192 Label->addSuccessor(Label);
193 MF.push_back(Label);
Benjamin Krameref0a45a2016-09-05 12:06:47 +0000194 Iter = std::next(MachineFunction::iterator(Bottom));
Dan Gohman8fe7e862015-12-14 22:51:54 +0000195 }
196 MachineBasicBlock *AfterLoop = &*Iter;
Dan Gohman8fe7e862015-12-14 22:51:54 +0000197
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000198 // Mark the beginning of the loop (after the end of any existing loop that
199 // ends here).
200 auto InsertPos = MBB.begin();
201 while (InsertPos != MBB.end() &&
202 InsertPos->getOpcode() == WebAssembly::END_LOOP)
203 ++InsertPos;
Derek Schuff10b31352018-03-15 22:06:51 +0000204 MachineInstr *Begin = BuildMI(MBB, InsertPos, MBB.findDebugLoc(InsertPos),
Dan Gohman2726b882016-10-06 22:29:32 +0000205 TII.get(WebAssembly::LOOP))
Derek Schuff10b31352018-03-15 22:06:51 +0000206 .addImm(int64_t(WebAssembly::ExprType::Void));
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000207
Derek Schuff10b31352018-03-15 22:06:51 +0000208 // Mark the end of the loop (using arbitrary debug location that branched
209 // to the loop end as its location).
210 DebugLoc EndDL = (*AfterLoop->pred_rbegin())->findBranchDebugLoc();
211 MachineInstr *End = BuildMI(*AfterLoop, AfterLoop->begin(), EndDL,
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000212 TII.get(WebAssembly::END_LOOP));
Dan Gohman2726b882016-10-06 22:29:32 +0000213 LoopTops[End] = Begin;
Dan Gohman8fe7e862015-12-14 22:51:54 +0000214
215 assert((!ScopeTops[AfterLoop->getNumber()] ||
216 ScopeTops[AfterLoop->getNumber()]->getNumber() < MBB.getNumber()) &&
Dan Gohman442bfce2016-02-16 16:22:41 +0000217 "With block sorting the outermost loop for a block should be first.");
Dan Gohman8fe7e862015-12-14 22:51:54 +0000218 if (!ScopeTops[AfterLoop->getNumber()])
219 ScopeTops[AfterLoop->getNumber()] = &MBB;
Dan Gohman950a13c2015-09-16 16:51:30 +0000220}
221
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000222static unsigned
223GetDepth(const SmallVectorImpl<const MachineBasicBlock *> &Stack,
224 const MachineBasicBlock *MBB) {
225 unsigned Depth = 0;
226 for (auto X : reverse(Stack)) {
227 if (X == MBB)
228 break;
229 ++Depth;
230 }
231 assert(Depth < Stack.size() && "Branch destination should be in scope");
232 return Depth;
233}
234
Dan Gohman2726b882016-10-06 22:29:32 +0000235/// In normal assembly languages, when the end of a function is unreachable,
236/// because the function ends in an infinite loop or a noreturn call or similar,
237/// it isn't necessary to worry about the function return type at the end of
238/// the function, because it's never reached. However, in WebAssembly, blocks
239/// that end at the function end need to have a return type signature that
240/// matches the function signature, even though it's unreachable. This function
241/// checks for such cases and fixes up the signatures.
242static void FixEndsAtEndOfFunction(
243 MachineFunction &MF,
244 const WebAssemblyFunctionInfo &MFI,
245 DenseMap<const MachineInstr *, MachineInstr *> &BlockTops,
246 DenseMap<const MachineInstr *, MachineInstr *> &LoopTops) {
247 assert(MFI.getResults().size() <= 1);
248
249 if (MFI.getResults().empty())
250 return;
251
252 WebAssembly::ExprType retType;
253 switch (MFI.getResults().front().SimpleTy) {
Dan Gohman4fc4e422016-10-24 19:49:43 +0000254 case MVT::i32: retType = WebAssembly::ExprType::I32; break;
255 case MVT::i64: retType = WebAssembly::ExprType::I64; break;
256 case MVT::f32: retType = WebAssembly::ExprType::F32; break;
257 case MVT::f64: retType = WebAssembly::ExprType::F64; break;
258 case MVT::v16i8: retType = WebAssembly::ExprType::I8x16; break;
259 case MVT::v8i16: retType = WebAssembly::ExprType::I16x8; break;
260 case MVT::v4i32: retType = WebAssembly::ExprType::I32x4; break;
Dan Gohman4fc4e422016-10-24 19:49:43 +0000261 case MVT::v4f32: retType = WebAssembly::ExprType::F32x4; break;
Heejin Ahn0de58722018-03-08 04:05:37 +0000262 case MVT::ExceptRef: retType = WebAssembly::ExprType::ExceptRef; break;
Dan Gohman2726b882016-10-06 22:29:32 +0000263 default: llvm_unreachable("unexpected return type");
264 }
265
266 for (MachineBasicBlock &MBB : reverse(MF)) {
267 for (MachineInstr &MI : reverse(MBB)) {
Shiva Chen801bf7e2018-05-09 02:42:00 +0000268 if (MI.isPosition() || MI.isDebugInstr())
Dan Gohman2726b882016-10-06 22:29:32 +0000269 continue;
270 if (MI.getOpcode() == WebAssembly::END_BLOCK) {
271 BlockTops[&MI]->getOperand(0).setImm(int32_t(retType));
272 continue;
273 }
274 if (MI.getOpcode() == WebAssembly::END_LOOP) {
275 LoopTops[&MI]->getOperand(0).setImm(int32_t(retType));
276 continue;
277 }
278 // Something other than an `end`. We're done.
279 return;
280 }
281 }
282}
283
Dan Gohmand934cb82017-02-24 23:18:00 +0000284// WebAssembly functions end with an end instruction, as if the function body
285// were a block.
286static void AppendEndToFunction(
287 MachineFunction &MF,
288 const WebAssemblyInstrInfo &TII) {
Derek Schuff10b31352018-03-15 22:06:51 +0000289 BuildMI(MF.back(), MF.back().end(),
290 MF.back().findPrevDebugLoc(MF.back().end()),
Dan Gohmand934cb82017-02-24 23:18:00 +0000291 TII.get(WebAssembly::END_FUNCTION));
292}
293
Dan Gohman950a13c2015-09-16 16:51:30 +0000294/// Insert LOOP and BLOCK markers at appropriate places.
295static void PlaceMarkers(MachineFunction &MF, const MachineLoopInfo &MLI,
Dan Gohman32807932015-11-23 16:19:56 +0000296 const WebAssemblyInstrInfo &TII,
Dan Gohmaned0f1132016-01-30 05:01:06 +0000297 MachineDominatorTree &MDT,
298 WebAssemblyFunctionInfo &MFI) {
Dan Gohman8fe7e862015-12-14 22:51:54 +0000299 // For each block whose label represents the end of a scope, record the block
300 // which holds the beginning of the scope. This will allow us to quickly skip
301 // over scoped regions when walking blocks. We allocate one more than the
302 // number of blocks in the function to accommodate for the possible fake block
303 // we may insert at the end.
304 SmallVector<MachineBasicBlock *, 8> ScopeTops(MF.getNumBlockIDs() + 1);
305
Dan Gohman2726b882016-10-06 22:29:32 +0000306 // For each LOOP_END, the corresponding LOOP.
307 DenseMap<const MachineInstr *, MachineInstr *> LoopTops;
308
309 // For each END_BLOCK, the corresponding BLOCK.
310 DenseMap<const MachineInstr *, MachineInstr *> BlockTops;
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000311
Dan Gohman950a13c2015-09-16 16:51:30 +0000312 for (auto &MBB : MF) {
Dan Gohman32807932015-11-23 16:19:56 +0000313 // Place the LOOP for MBB if MBB is the header of a loop.
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000314 PlaceLoopMarker(MBB, MF, ScopeTops, LoopTops, TII, MLI);
Dan Gohman950a13c2015-09-16 16:51:30 +0000315
Dan Gohman32807932015-11-23 16:19:56 +0000316 // Place the BLOCK for MBB if MBB is branched to from above.
Dan Gohman2726b882016-10-06 22:29:32 +0000317 PlaceBlockMarker(MBB, MF, ScopeTops, BlockTops, LoopTops, TII, MLI, MDT, MFI);
Dan Gohman950a13c2015-09-16 16:51:30 +0000318 }
Dan Gohman950a13c2015-09-16 16:51:30 +0000319
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000320 // Now rewrite references to basic blocks to be depth immediates.
321 SmallVector<const MachineBasicBlock *, 8> Stack;
322 for (auto &MBB : reverse(MF)) {
323 for (auto &MI : reverse(MBB)) {
324 switch (MI.getOpcode()) {
325 case WebAssembly::BLOCK:
Dan Gohman3a643e82016-10-06 22:10:23 +0000326 assert(ScopeTops[Stack.back()->getNumber()]->getNumber() <= MBB.getNumber() &&
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000327 "Block should be balanced");
328 Stack.pop_back();
329 break;
330 case WebAssembly::LOOP:
331 assert(Stack.back() == &MBB && "Loop top should be balanced");
332 Stack.pop_back();
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000333 break;
334 case WebAssembly::END_BLOCK:
335 Stack.push_back(&MBB);
336 break;
337 case WebAssembly::END_LOOP:
Dan Gohman2726b882016-10-06 22:29:32 +0000338 Stack.push_back(LoopTops[&MI]->getParent());
Dan Gohman1d68e80f2016-01-12 19:14:46 +0000339 break;
340 default:
341 if (MI.isTerminator()) {
342 // Rewrite MBB operands to be depth immediates.
343 SmallVector<MachineOperand, 4> Ops(MI.operands());
344 while (MI.getNumOperands() > 0)
345 MI.RemoveOperand(MI.getNumOperands() - 1);
346 for (auto MO : Ops) {
347 if (MO.isMBB())
348 MO = MachineOperand::CreateImm(GetDepth(Stack, MO.getMBB()));
349 MI.addOperand(MF, MO);
350 }
351 }
352 break;
353 }
354 }
355 }
356 assert(Stack.empty() && "Control flow should be balanced");
Dan Gohman2726b882016-10-06 22:29:32 +0000357
358 // Fix up block/loop signatures at the end of the function to conform to
359 // WebAssembly's rules.
360 FixEndsAtEndOfFunction(MF, MFI, BlockTops, LoopTops);
Dan Gohmand934cb82017-02-24 23:18:00 +0000361
362 // Add an end instruction at the end of the function body.
363 if (!MF.getSubtarget<WebAssemblySubtarget>()
364 .getTargetTriple().isOSBinFormatELF())
365 AppendEndToFunction(MF, TII);
Dan Gohman32807932015-11-23 16:19:56 +0000366}
Dan Gohman32807932015-11-23 16:19:56 +0000367
Dan Gohman950a13c2015-09-16 16:51:30 +0000368bool WebAssemblyCFGStackify::runOnMachineFunction(MachineFunction &MF) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000369 LLVM_DEBUG(dbgs() << "********** CFG Stackifying **********\n"
370 "********** Function: "
371 << MF.getName() << '\n');
Dan Gohman950a13c2015-09-16 16:51:30 +0000372
373 const auto &MLI = getAnalysis<MachineLoopInfo>();
Dan Gohman32807932015-11-23 16:19:56 +0000374 auto &MDT = getAnalysis<MachineDominatorTree>();
Dan Gohmane0405332016-10-03 22:43:53 +0000375 // Liveness is not tracked for VALUE_STACK physreg.
Dan Gohman950a13c2015-09-16 16:51:30 +0000376 const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
Dan Gohmaned0f1132016-01-30 05:01:06 +0000377 WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
Derek Schuff9c3bf312016-01-13 17:10:28 +0000378 MF.getRegInfo().invalidateLiveness();
Dan Gohman950a13c2015-09-16 16:51:30 +0000379
Dan Gohman950a13c2015-09-16 16:51:30 +0000380 // Place the BLOCK and LOOP markers to indicate the beginnings of scopes.
Dan Gohmaned0f1132016-01-30 05:01:06 +0000381 PlaceMarkers(MF, MLI, TII, MDT, MFI);
Dan Gohman32807932015-11-23 16:19:56 +0000382
Dan Gohman950a13c2015-09-16 16:51:30 +0000383 return true;
384}