blob: 3377ca0979d450f1c972ba5f8986f147005a5128 [file] [log] [blame]
Dan Gohman1462faa2015-11-16 16:18:28 +00001//===-- WebAssemblyRegStackify.cpp - Register 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 register stacking pass.
12///
13/// This pass reorders instructions to put register uses and defs in an order
14/// such that they form single-use expression trees. Registers fitting this form
15/// are then marked as "stackified", meaning references to them are replaced by
16/// "push" and "pop" from the stack.
17///
Dan Gohman31448f12015-12-08 03:43:03 +000018/// This is primarily a code size optimization, since temporary values on the
Dan Gohman1462faa2015-11-16 16:18:28 +000019/// expression don't need to be named.
20///
21//===----------------------------------------------------------------------===//
22
23#include "WebAssembly.h"
Dan Gohman4ba48162015-11-18 16:12:01 +000024#include "MCTargetDesc/WebAssemblyMCTargetDesc.h" // for WebAssembly::ARGUMENT_*
Dan Gohman7a6b9822015-11-29 22:32:02 +000025#include "WebAssemblyMachineFunctionInfo.h"
Dan Gohmanb6fd39a2016-01-19 16:59:23 +000026#include "WebAssemblySubtarget.h"
Dan Gohman81719f82015-11-25 16:55:01 +000027#include "llvm/Analysis/AliasAnalysis.h"
Dan Gohman8887d1f2015-12-25 00:31:02 +000028#include "llvm/CodeGen/LiveIntervalAnalysis.h"
Dan Gohman1462faa2015-11-16 16:18:28 +000029#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
Dan Gohmanadf28172016-01-28 01:22:44 +000030#include "llvm/CodeGen/MachineDominators.h"
31#include "llvm/CodeGen/MachineInstrBuilder.h"
Dan Gohman1462faa2015-11-16 16:18:28 +000032#include "llvm/CodeGen/MachineRegisterInfo.h"
33#include "llvm/CodeGen/Passes.h"
34#include "llvm/Support/Debug.h"
35#include "llvm/Support/raw_ostream.h"
36using namespace llvm;
37
38#define DEBUG_TYPE "wasm-reg-stackify"
39
40namespace {
41class WebAssemblyRegStackify final : public MachineFunctionPass {
42 const char *getPassName() const override {
43 return "WebAssembly Register Stackify";
44 }
45
46 void getAnalysisUsage(AnalysisUsage &AU) const override {
47 AU.setPreservesCFG();
Dan Gohman81719f82015-11-25 16:55:01 +000048 AU.addRequired<AAResultsWrapperPass>();
Dan Gohmanadf28172016-01-28 01:22:44 +000049 AU.addRequired<MachineDominatorTree>();
Dan Gohman8887d1f2015-12-25 00:31:02 +000050 AU.addRequired<LiveIntervals>();
Dan Gohman1462faa2015-11-16 16:18:28 +000051 AU.addPreserved<MachineBlockFrequencyInfo>();
Dan Gohman8887d1f2015-12-25 00:31:02 +000052 AU.addPreserved<SlotIndexes>();
53 AU.addPreserved<LiveIntervals>();
Dan Gohman8887d1f2015-12-25 00:31:02 +000054 AU.addPreservedID(LiveVariablesID);
Dan Gohmanadf28172016-01-28 01:22:44 +000055 AU.addPreserved<MachineDominatorTree>();
Dan Gohman1462faa2015-11-16 16:18:28 +000056 MachineFunctionPass::getAnalysisUsage(AU);
57 }
58
59 bool runOnMachineFunction(MachineFunction &MF) override;
60
61public:
62 static char ID; // Pass identification, replacement for typeid
63 WebAssemblyRegStackify() : MachineFunctionPass(ID) {}
64};
65} // end anonymous namespace
66
67char WebAssemblyRegStackify::ID = 0;
68FunctionPass *llvm::createWebAssemblyRegStackify() {
69 return new WebAssemblyRegStackify();
70}
71
Dan Gohmanb0992da2015-11-20 02:19:12 +000072// Decorate the given instruction with implicit operands that enforce the
Dan Gohman8887d1f2015-12-25 00:31:02 +000073// expression stack ordering constraints for an instruction which is on
74// the expression stack.
75static void ImposeStackOrdering(MachineInstr *MI) {
Dan Gohman4da4abd2015-12-05 00:51:40 +000076 // Write the opaque EXPR_STACK register.
77 if (!MI->definesRegister(WebAssembly::EXPR_STACK))
78 MI->addOperand(MachineOperand::CreateReg(WebAssembly::EXPR_STACK,
79 /*isDef=*/true,
80 /*isImp=*/true));
Dan Gohman4da4abd2015-12-05 00:51:40 +000081
82 // Also read the opaque EXPR_STACK register.
Dan Gohmana712a6c2015-12-14 22:37:23 +000083 if (!MI->readsRegister(WebAssembly::EXPR_STACK))
84 MI->addOperand(MachineOperand::CreateReg(WebAssembly::EXPR_STACK,
85 /*isDef=*/false,
86 /*isImp=*/true));
Dan Gohmanb0992da2015-11-20 02:19:12 +000087}
88
Dan Gohman8887d1f2015-12-25 00:31:02 +000089// Test whether it's safe to move Def to just before Insert.
Dan Gohman81719f82015-11-25 16:55:01 +000090// TODO: Compute memory dependencies in a way that doesn't require always
91// walking the block.
92// TODO: Compute memory dependencies in a way that uses AliasAnalysis to be
93// more precise.
94static bool IsSafeToMove(const MachineInstr *Def, const MachineInstr *Insert,
Dan Gohmanadf28172016-01-28 01:22:44 +000095 AliasAnalysis &AA, const LiveIntervals &LIS,
96 const MachineRegisterInfo &MRI) {
Dan Gohman391a98a2015-12-03 23:07:03 +000097 assert(Def->getParent() == Insert->getParent());
Dan Gohman81719f82015-11-25 16:55:01 +000098 bool SawStore = false, SawSideEffects = false;
99 MachineBasicBlock::const_iterator D(Def), I(Insert);
Dan Gohman8887d1f2015-12-25 00:31:02 +0000100
101 // Check for register dependencies.
102 for (const MachineOperand &MO : Def->operands()) {
103 if (!MO.isReg() || MO.isUndef())
104 continue;
105 unsigned Reg = MO.getReg();
106
107 // If the register is dead here and at Insert, ignore it.
108 if (MO.isDead() && Insert->definesRegister(Reg) &&
109 !Insert->readsRegister(Reg))
110 continue;
111
112 if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
113 // If the physical register is never modified, ignore it.
114 if (!MRI.isPhysRegModified(Reg))
115 continue;
116 // Otherwise, it's a physical register with unknown liveness.
117 return false;
118 }
119
120 // Ask LiveIntervals whether moving this virtual register use or def to
121 // Insert will change value numbers are seen.
122 const LiveInterval &LI = LIS.getInterval(Reg);
Dan Gohmanb6fd39a2016-01-19 16:59:23 +0000123 VNInfo *DefVNI =
124 MO.isDef() ? LI.getVNInfoAt(LIS.getInstructionIndex(Def).getRegSlot())
125 : LI.getVNInfoBefore(LIS.getInstructionIndex(Def));
Dan Gohman8887d1f2015-12-25 00:31:02 +0000126 assert(DefVNI && "Instruction input missing value number");
127 VNInfo *InsVNI = LI.getVNInfoBefore(LIS.getInstructionIndex(Insert));
128 if (InsVNI && DefVNI != InsVNI)
129 return false;
130 }
131
132 // Check for memory dependencies and side effects.
Dan Gohman81719f82015-11-25 16:55:01 +0000133 for (--I; I != D; --I)
Dan Gohman7e649172016-01-20 04:21:16 +0000134 SawSideEffects |= !I->isSafeToMove(&AA, SawStore);
Dan Gohman81719f82015-11-25 16:55:01 +0000135 return !(SawStore && Def->mayLoad() && !Def->isInvariantLoad(&AA)) &&
136 !(SawSideEffects && !Def->isSafeToMove(&AA, SawStore));
137}
138
Dan Gohmanadf28172016-01-28 01:22:44 +0000139/// Test whether OneUse, a use of Reg, dominates all of Reg's other uses.
140static bool OneUseDominatesOtherUses(unsigned Reg, const MachineOperand &OneUse,
141 const MachineBasicBlock &MBB,
142 const MachineRegisterInfo &MRI,
143 const MachineDominatorTree &MDT) {
144 for (const MachineOperand &Use : MRI.use_operands(Reg)) {
145 if (&Use == &OneUse)
146 continue;
147 const MachineInstr *UseInst = Use.getParent();
148 const MachineInstr *OneUseInst = OneUse.getParent();
149 if (UseInst->getOpcode() == TargetOpcode::PHI) {
150 // Test that the PHI use, which happens on the CFG edge rather than
151 // within the PHI's own block, is dominated by the one selected use.
152 const MachineBasicBlock *Pred =
153 UseInst->getOperand(&Use - &UseInst->getOperand(0) + 1).getMBB();
154 if (!MDT.dominates(&MBB, Pred))
155 return false;
156 } else if (UseInst == OneUseInst) {
157 // Another use in the same instruction. We need to ensure that the one
158 // selected use happens "before" it.
159 if (&OneUse > &Use)
160 return false;
161 } else {
162 // Test that the use is dominated by the one selected use.
163 if (!MDT.dominates(OneUseInst, UseInst))
164 return false;
165 }
166 }
167 return true;
168}
169
170/// Get the appropriate tee_local opcode for the given register class.
171static unsigned GetTeeLocalOpcode(const TargetRegisterClass *RC) {
172 if (RC == &WebAssembly::I32RegClass)
173 return WebAssembly::TEE_LOCAL_I32;
174 if (RC == &WebAssembly::I64RegClass)
175 return WebAssembly::TEE_LOCAL_I64;
176 if (RC == &WebAssembly::F32RegClass)
177 return WebAssembly::TEE_LOCAL_F32;
178 if (RC == &WebAssembly::F64RegClass)
179 return WebAssembly::TEE_LOCAL_F64;
180 llvm_unreachable("Unexpected register class");
181}
182
183/// A single-use def in the same block with no intervening memory or register
184/// dependencies; move the def down and nest it with the current instruction.
185static MachineInstr *MoveForSingleUse(unsigned Reg, MachineInstr *Def,
186 MachineBasicBlock &MBB,
187 MachineInstr *Insert, LiveIntervals &LIS,
188 WebAssemblyFunctionInfo &MFI) {
189 MBB.splice(Insert, &MBB, Def);
190 LIS.handleMove(Def);
191 MFI.stackifyVReg(Reg);
192 ImposeStackOrdering(Def);
193 return Def;
194}
195
196/// A trivially cloneable instruction; clone it and nest the new copy with the
197/// current instruction.
198static MachineInstr *
199RematerializeCheapDef(unsigned Reg, MachineOperand &Op, MachineInstr *Def,
200 MachineBasicBlock &MBB, MachineInstr *Insert,
201 LiveIntervals &LIS, WebAssemblyFunctionInfo &MFI,
202 MachineRegisterInfo &MRI, const WebAssemblyInstrInfo *TII,
203 const WebAssemblyRegisterInfo *TRI) {
204 unsigned NewReg = MRI.createVirtualRegister(MRI.getRegClass(Reg));
205 TII->reMaterialize(MBB, Insert, NewReg, 0, Def, *TRI);
206 Op.setReg(NewReg);
207 MachineInstr *Clone = &*std::prev(MachineBasicBlock::instr_iterator(Insert));
208 LIS.InsertMachineInstrInMaps(Clone);
209 LIS.createAndComputeVirtRegInterval(NewReg);
210 MFI.stackifyVReg(NewReg);
211 ImposeStackOrdering(Clone);
212
213 // If that was the last use of the original, delete the original.
214 // Otherwise shrink the LiveInterval.
215 if (MRI.use_empty(Reg)) {
216 SlotIndex Idx = LIS.getInstructionIndex(Def).getRegSlot();
217 LIS.removePhysRegDefAt(WebAssembly::ARGUMENTS, Idx);
218 LIS.removeVRegDefAt(LIS.getInterval(Reg), Idx);
219 LIS.removeInterval(Reg);
220 LIS.RemoveMachineInstrFromMaps(Def);
221 Def->eraseFromParent();
222 } else {
223 LIS.shrinkToUses(&LIS.getInterval(Reg));
224 }
225 return Clone;
226}
227
228/// A multiple-use def in the same block with no intervening memory or register
229/// dependencies; move the def down, nest it with the current instruction, and
230/// insert a tee_local to satisfy the rest of the uses. As an illustration,
231/// rewrite this:
232///
233/// Reg = INST ... // Def
234/// INST ..., Reg, ... // Insert
235/// INST ..., Reg, ...
236/// INST ..., Reg, ...
237///
238/// to this:
239///
240/// Reg = INST ... // Def (to become the new Insert)
241/// TeeReg, NewReg = TEE_LOCAL_... Reg
242/// INST ..., TeeReg, ... // Insert
243/// INST ..., NewReg, ...
244/// INST ..., NewReg, ...
245///
246/// with Reg and TeeReg stackified. This eliminates a get_local from the
247/// resulting code.
248static MachineInstr *MoveAndTeeForMultiUse(
249 unsigned Reg, MachineOperand &Op, MachineInstr *Def, MachineBasicBlock &MBB,
250 MachineInstr *Insert, LiveIntervals &LIS, WebAssemblyFunctionInfo &MFI,
251 MachineRegisterInfo &MRI, const WebAssemblyInstrInfo *TII) {
252 MBB.splice(Insert, &MBB, Def);
253 LIS.handleMove(Def);
254 const auto *RegClass = MRI.getRegClass(Reg);
255 unsigned NewReg = MRI.createVirtualRegister(RegClass);
256 unsigned TeeReg = MRI.createVirtualRegister(RegClass);
257 MRI.replaceRegWith(Reg, NewReg);
258 MachineInstr *Tee = BuildMI(MBB, Insert, Insert->getDebugLoc(),
259 TII->get(GetTeeLocalOpcode(RegClass)), TeeReg)
260 .addReg(NewReg, RegState::Define)
261 .addReg(Reg);
262 Op.setReg(TeeReg);
263 Def->getOperand(0).setReg(Reg);
264 LIS.InsertMachineInstrInMaps(Tee);
265 LIS.shrinkToUses(&LIS.getInterval(Reg));
266 LIS.createAndComputeVirtRegInterval(NewReg);
267 LIS.createAndComputeVirtRegInterval(TeeReg);
268 MFI.stackifyVReg(Reg);
269 MFI.stackifyVReg(TeeReg);
270 ImposeStackOrdering(Def);
271 ImposeStackOrdering(Tee);
272 return Def;
273}
274
275namespace {
276/// A stack for walking the tree of instructions being built, visiting the
277/// MachineOperands in DFS order.
278class TreeWalkerState {
279 typedef MachineInstr::mop_iterator mop_iterator;
280 typedef std::reverse_iterator<mop_iterator> mop_reverse_iterator;
281 typedef iterator_range<mop_reverse_iterator> RangeTy;
282 SmallVector<RangeTy, 4> Worklist;
283
284public:
285 explicit TreeWalkerState(MachineInstr *Insert) {
286 const iterator_range<mop_iterator> &Range = Insert->explicit_uses();
287 if (Range.begin() != Range.end())
288 Worklist.push_back(reverse(Range));
289 }
290
291 bool Done() const { return Worklist.empty(); }
292
293 MachineOperand &Pop() {
294 RangeTy &Range = Worklist.back();
295 MachineOperand &Op = *Range.begin();
296 Range = drop_begin(Range, 1);
297 if (Range.begin() == Range.end())
298 Worklist.pop_back();
299 assert((Worklist.empty() ||
300 Worklist.back().begin() != Worklist.back().end()) &&
301 "Empty ranges shouldn't remain in the worklist");
302 return Op;
303 }
304
305 /// Push Instr's operands onto the stack to be visited.
306 void PushOperands(MachineInstr *Instr) {
307 const iterator_range<mop_iterator> &Range(Instr->explicit_uses());
308 if (Range.begin() != Range.end())
309 Worklist.push_back(reverse(Range));
310 }
311
312 /// Some of Instr's operands are on the top of the stack; remove them and
313 /// re-insert them starting from the beginning (because we've commuted them).
314 void ResetTopOperands(MachineInstr *Instr) {
315 assert(HasRemainingOperands(Instr) &&
316 "Reseting operands should only be done when the instruction has "
317 "an operand still on the stack");
318 Worklist.back() = reverse(Instr->explicit_uses());
319 }
320
321 /// Test whether Instr has operands remaining to be visited at the top of
322 /// the stack.
323 bool HasRemainingOperands(const MachineInstr *Instr) const {
324 if (Worklist.empty())
325 return false;
326 const RangeTy &Range = Worklist.back();
327 return Range.begin() != Range.end() && Range.begin()->getParent() == Instr;
328 }
329};
330
331/// State to keep track of whether commuting is in flight or whether it's been
332/// tried for the current instruction and didn't work.
333class CommutingState {
334 /// There are effectively three states: the initial state where we haven't
335 /// started commuting anything and we don't know anything yet, the tenative
336 /// state where we've commuted the operands of the current instruction and are
337 /// revisting it, and the declined state where we've reverted the operands
338 /// back to their original order and will no longer commute it further.
339 bool TentativelyCommuting;
340 bool Declined;
341
342 /// During the tentative state, these hold the operand indices of the commuted
343 /// operands.
344 unsigned Operand0, Operand1;
345
346public:
347 CommutingState() : TentativelyCommuting(false), Declined(false) {}
348
349 /// Stackification for an operand was not successful due to ordering
350 /// constraints. If possible, and if we haven't already tried it and declined
351 /// it, commute Insert's operands and prepare to revisit it.
352 void MaybeCommute(MachineInstr *Insert, TreeWalkerState &TreeWalker,
353 const WebAssemblyInstrInfo *TII) {
354 if (TentativelyCommuting) {
355 assert(!Declined &&
356 "Don't decline commuting until you've finished trying it");
357 // Commuting didn't help. Revert it.
358 TII->commuteInstruction(Insert, /*NewMI=*/false, Operand0, Operand1);
359 TentativelyCommuting = false;
360 Declined = true;
361 } else if (!Declined && TreeWalker.HasRemainingOperands(Insert)) {
362 Operand0 = TargetInstrInfo::CommuteAnyOperandIndex;
363 Operand1 = TargetInstrInfo::CommuteAnyOperandIndex;
364 if (TII->findCommutedOpIndices(Insert, Operand0, Operand1)) {
365 // Tentatively commute the operands and try again.
366 TII->commuteInstruction(Insert, /*NewMI=*/false, Operand0, Operand1);
367 TreeWalker.ResetTopOperands(Insert);
368 TentativelyCommuting = true;
369 Declined = false;
370 }
371 }
372 }
373
374 /// Stackification for some operand was successful. Reset to the default
375 /// state.
376 void Reset() {
377 TentativelyCommuting = false;
378 Declined = false;
379 }
380};
381} // end anonymous namespace
382
Dan Gohman1462faa2015-11-16 16:18:28 +0000383bool WebAssemblyRegStackify::runOnMachineFunction(MachineFunction &MF) {
384 DEBUG(dbgs() << "********** Register Stackifying **********\n"
385 "********** Function: "
386 << MF.getName() << '\n');
387
388 bool Changed = false;
389 MachineRegisterInfo &MRI = MF.getRegInfo();
390 WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
Dan Gohmanb6fd39a2016-01-19 16:59:23 +0000391 const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
392 const auto *TRI = MF.getSubtarget<WebAssemblySubtarget>().getRegisterInfo();
Dan Gohman81719f82015-11-25 16:55:01 +0000393 AliasAnalysis &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
Dan Gohmanadf28172016-01-28 01:22:44 +0000394 MachineDominatorTree &MDT = getAnalysis<MachineDominatorTree>();
Dan Gohman8887d1f2015-12-25 00:31:02 +0000395 LiveIntervals &LIS = getAnalysis<LiveIntervals>();
Dan Gohmand70e5902015-12-08 03:30:42 +0000396
Dan Gohman1462faa2015-11-16 16:18:28 +0000397 // Walk the instructions from the bottom up. Currently we don't look past
398 // block boundaries, and the blocks aren't ordered so the block visitation
399 // order isn't significant, but we may want to change this in the future.
400 for (MachineBasicBlock &MBB : MF) {
Dan Gohman8f59cf72016-01-06 18:29:35 +0000401 // Don't use a range-based for loop, because we modify the list as we're
402 // iterating over it and the end iterator may change.
403 for (auto MII = MBB.rbegin(); MII != MBB.rend(); ++MII) {
404 MachineInstr *Insert = &*MII;
Dan Gohman1462faa2015-11-16 16:18:28 +0000405 // Don't nest anything inside a phi.
406 if (Insert->getOpcode() == TargetOpcode::PHI)
407 break;
408
Dan Gohman81719f82015-11-25 16:55:01 +0000409 // Don't nest anything inside an inline asm, because we don't have
410 // constraints for $push inputs.
411 if (Insert->getOpcode() == TargetOpcode::INLINEASM)
412 break;
413
Dan Gohman1462faa2015-11-16 16:18:28 +0000414 // Iterate through the inputs in reverse order, since we'll be pulling
Dan Gohman53d13992015-12-02 18:08:49 +0000415 // operands off the stack in LIFO order.
Dan Gohmanadf28172016-01-28 01:22:44 +0000416 CommutingState Commuting;
417 TreeWalkerState TreeWalker(Insert);
418 while (!TreeWalker.Done()) {
419 MachineOperand &Op = TreeWalker.Pop();
420
Dan Gohman1462faa2015-11-16 16:18:28 +0000421 // We're only interested in explicit virtual register operands.
Dan Gohmanadf28172016-01-28 01:22:44 +0000422 if (!Op.isReg())
Dan Gohman1462faa2015-11-16 16:18:28 +0000423 continue;
424
425 unsigned Reg = Op.getReg();
Dan Gohmanadf28172016-01-28 01:22:44 +0000426 assert(Op.isUse() && "explicit_uses() should only iterate over uses");
427 assert(!Op.isImplicit() &&
428 "explicit_uses() should only iterate over explicit operands");
429 if (TargetRegisterInfo::isPhysicalRegister(Reg))
Dan Gohman1462faa2015-11-16 16:18:28 +0000430 continue;
431
Dan Gohmanadf28172016-01-28 01:22:44 +0000432 // Identify the definition for this register at this point. Most
433 // registers are in SSA form here so we try a quick MRI query first.
434 MachineInstr *Def = MRI.getUniqueVRegDef(Reg);
435 if (!Def) {
436 // MRI doesn't know what the Def is. Try asking LIS.
437 const VNInfo *ValNo = LIS.getInterval(Reg).getVNInfoBefore(
438 LIS.getInstructionIndex(Insert));
439 if (!ValNo)
440 continue;
441 Def = LIS.getInstructionFromIndex(ValNo->def);
442 if (!Def)
443 continue;
444 }
445
Dan Gohman81719f82015-11-25 16:55:01 +0000446 // Don't nest an INLINE_ASM def into anything, because we don't have
447 // constraints for $pop outputs.
448 if (Def->getOpcode() == TargetOpcode::INLINEASM)
449 continue;
450
451 // Don't nest PHIs inside of anything.
452 if (Def->getOpcode() == TargetOpcode::PHI)
453 continue;
454
Dan Gohman4ba48162015-11-18 16:12:01 +0000455 // Argument instructions represent live-in registers and not real
456 // instructions.
457 if (Def->getOpcode() == WebAssembly::ARGUMENT_I32 ||
458 Def->getOpcode() == WebAssembly::ARGUMENT_I64 ||
459 Def->getOpcode() == WebAssembly::ARGUMENT_F32 ||
460 Def->getOpcode() == WebAssembly::ARGUMENT_F64)
461 continue;
462
Dan Gohmanadf28172016-01-28 01:22:44 +0000463 // Decide which strategy to take. Prefer to move a single-use value
464 // over cloning it, and prefer cloning over introducing a tee_local.
465 // For moving, we require the def to be in the same block as the use;
466 // this makes things simpler (LiveIntervals' handleMove function only
467 // supports intra-block moves) and it's MachineSink's job to catch all
468 // the sinking opportunities anyway.
469 bool SameBlock = Def->getParent() == &MBB;
470 bool CanMove = SameBlock && IsSafeToMove(Def, Insert, AA, LIS, MRI);
471 if (CanMove && MRI.hasOneUse(Reg)) {
472 Insert = MoveForSingleUse(Reg, Def, MBB, Insert, LIS, MFI);
Dan Gohmanb6fd39a2016-01-19 16:59:23 +0000473 } else if (Def->isAsCheapAsAMove() &&
474 TII->isTriviallyReMaterializable(Def, &AA)) {
Dan Gohmanadf28172016-01-28 01:22:44 +0000475 Insert = RematerializeCheapDef(Reg, Op, Def, MBB, Insert, LIS, MFI,
476 MRI, TII, TRI);
477 } else if (CanMove &&
478 OneUseDominatesOtherUses(Reg, Op, MBB, MRI, MDT)) {
479 Insert = MoveAndTeeForMultiUse(Reg, Op, Def, MBB, Insert, LIS, MFI,
480 MRI, TII);
481 } else {
482 // We failed to stackify the operand. If the problem was ordering
483 // constraints, Commuting may be able to help.
484 if (!CanMove && SameBlock)
485 Commuting.MaybeCommute(Insert, TreeWalker, TII);
486 // Proceed to the next operand.
487 continue;
Dan Gohmanb6fd39a2016-01-19 16:59:23 +0000488 }
Dan Gohmanadf28172016-01-28 01:22:44 +0000489
490 // We stackified an operand. Add the defining instruction's operands to
491 // the worklist stack now to continue to build an ever deeper tree.
492 Commuting.Reset();
493 TreeWalker.PushOperands(Insert);
Dan Gohman1462faa2015-11-16 16:18:28 +0000494 }
Dan Gohmanadf28172016-01-28 01:22:44 +0000495
496 // If we stackified any operands, skip over the tree to start looking for
497 // the next instruction we can build a tree on.
498 if (Insert != &*MII) {
Dan Gohman8f59cf72016-01-06 18:29:35 +0000499 ImposeStackOrdering(&*MII);
Dan Gohmanadf28172016-01-28 01:22:44 +0000500 MII = std::prev(
501 make_reverse_iterator(MachineBasicBlock::iterator(Insert)));
502 Changed = true;
503 }
Dan Gohman1462faa2015-11-16 16:18:28 +0000504 }
505 }
506
Dan Gohmanadf28172016-01-28 01:22:44 +0000507 // If we used EXPR_STACK anywhere, add it to the live-in sets everywhere so
508 // that it never looks like a use-before-def.
Dan Gohmanb0992da2015-11-20 02:19:12 +0000509 if (Changed) {
510 MF.getRegInfo().addLiveIn(WebAssembly::EXPR_STACK);
511 for (MachineBasicBlock &MBB : MF)
512 MBB.addLiveIn(WebAssembly::EXPR_STACK);
513 }
514
Dan Gohman7bafa0e2015-11-20 02:33:24 +0000515#ifndef NDEBUG
Dan Gohmanb6fd39a2016-01-19 16:59:23 +0000516 // Verify that pushes and pops are performed in LIFO order.
Dan Gohman7bafa0e2015-11-20 02:33:24 +0000517 SmallVector<unsigned, 0> Stack;
518 for (MachineBasicBlock &MBB : MF) {
519 for (MachineInstr &MI : MBB) {
520 for (MachineOperand &MO : reverse(MI.explicit_operands())) {
Dan Gohman7a6b9822015-11-29 22:32:02 +0000521 if (!MO.isReg())
522 continue;
Dan Gohmanadf28172016-01-28 01:22:44 +0000523 unsigned Reg = MO.getReg();
Dan Gohman7bafa0e2015-11-20 02:33:24 +0000524
Dan Gohman35bfb242015-12-04 23:22:35 +0000525 // Don't stackify physregs like SP or FP.
Dan Gohmanadf28172016-01-28 01:22:44 +0000526 if (!TargetRegisterInfo::isVirtualRegister(Reg))
Dan Gohman35bfb242015-12-04 23:22:35 +0000527 continue;
528
Dan Gohmanadf28172016-01-28 01:22:44 +0000529 if (MFI.isVRegStackified(Reg)) {
Dan Gohman7bafa0e2015-11-20 02:33:24 +0000530 if (MO.isDef())
Dan Gohmanadf28172016-01-28 01:22:44 +0000531 Stack.push_back(Reg);
Dan Gohman7bafa0e2015-11-20 02:33:24 +0000532 else
Dan Gohmanadf28172016-01-28 01:22:44 +0000533 assert(Stack.pop_back_val() == Reg &&
534 "Register stack pop should be paired with a push");
Dan Gohman7bafa0e2015-11-20 02:33:24 +0000535 }
536 }
537 }
538 // TODO: Generalize this code to support keeping values on the stack across
539 // basic block boundaries.
Dan Gohmanadf28172016-01-28 01:22:44 +0000540 assert(Stack.empty() &&
541 "Register stack pushes and pops should be balanced");
Dan Gohman7bafa0e2015-11-20 02:33:24 +0000542 }
543#endif
544
Dan Gohman1462faa2015-11-16 16:18:28 +0000545 return Changed;
546}