LLVM  8.0.0svn
WebAssemblyRegStackify.cpp
Go to the documentation of this file.
1 //===-- 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 /// 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 value stack.
17 ///
18 /// This is primarily a code size optimization, since temporary values on the
19 /// value stack don't need to be named.
20 ///
21 //===----------------------------------------------------------------------===//
22 
23 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" // for WebAssembly::ARGUMENT_*
24 #include "WebAssembly.h"
26 #include "WebAssemblySubtarget.h"
27 #include "WebAssemblyUtilities.h"
35 #include "llvm/CodeGen/Passes.h"
36 #include "llvm/Support/Debug.h"
38 using namespace llvm;
39 
40 #define DEBUG_TYPE "wasm-reg-stackify"
41 
42 namespace {
43 class WebAssemblyRegStackify final : public MachineFunctionPass {
44  StringRef getPassName() const override {
45  return "WebAssembly Register Stackify";
46  }
47 
48  void getAnalysisUsage(AnalysisUsage &AU) const override {
49  AU.setPreservesCFG();
59  }
60 
61  bool runOnMachineFunction(MachineFunction &MF) override;
62 
63 public:
64  static char ID; // Pass identification, replacement for typeid
65  WebAssemblyRegStackify() : MachineFunctionPass(ID) {}
66 };
67 } // end anonymous namespace
68 
70 INITIALIZE_PASS(WebAssemblyRegStackify, DEBUG_TYPE,
71  "Reorder instructions to use the WebAssembly value stack",
72  false, false)
73 
75  return new WebAssemblyRegStackify();
76 }
77 
78 // Decorate the given instruction with implicit operands that enforce the
79 // expression stack ordering constraints for an instruction which is on
80 // the expression stack.
82  // Write the opaque VALUE_STACK register.
83  if (!MI->definesRegister(WebAssembly::VALUE_STACK))
84  MI->addOperand(MachineOperand::CreateReg(WebAssembly::VALUE_STACK,
85  /*isDef=*/true,
86  /*isImp=*/true));
87 
88  // Also read the opaque VALUE_STACK register.
89  if (!MI->readsRegister(WebAssembly::VALUE_STACK))
90  MI->addOperand(MachineOperand::CreateReg(WebAssembly::VALUE_STACK,
91  /*isDef=*/false,
92  /*isImp=*/true));
93 }
94 
95 // Convert an IMPLICIT_DEF instruction into an instruction which defines
96 // a constant zero value.
99  const TargetInstrInfo *TII,
100  MachineFunction &MF) {
101  assert(MI->getOpcode() == TargetOpcode::IMPLICIT_DEF);
102 
103  const auto *RegClass = MRI.getRegClass(MI->getOperand(0).getReg());
104  if (RegClass == &WebAssembly::I32RegClass) {
105  MI->setDesc(TII->get(WebAssembly::CONST_I32));
107  } else if (RegClass == &WebAssembly::I64RegClass) {
108  MI->setDesc(TII->get(WebAssembly::CONST_I64));
110  } else if (RegClass == &WebAssembly::F32RegClass) {
111  MI->setDesc(TII->get(WebAssembly::CONST_F32));
112  ConstantFP *Val = cast<ConstantFP>(Constant::getNullValue(
115  } else if (RegClass == &WebAssembly::F64RegClass) {
116  MI->setDesc(TII->get(WebAssembly::CONST_F64));
117  ConstantFP *Val = cast<ConstantFP>(Constant::getNullValue(
120  } else {
121  llvm_unreachable("Unexpected reg class");
122  }
123 }
124 
125 // Determine whether a call to the callee referenced by
126 // MI->getOperand(CalleeOpNo) reads memory, writes memory, and/or has side
127 // effects.
128 static void QueryCallee(const MachineInstr &MI, unsigned CalleeOpNo, bool &Read,
129  bool &Write, bool &Effects, bool &StackPointer) {
130  // All calls can use the stack pointer.
131  StackPointer = true;
132 
133  const MachineOperand &MO = MI.getOperand(CalleeOpNo);
134  if (MO.isGlobal()) {
135  const Constant *GV = MO.getGlobal();
136  if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV))
137  if (!GA->isInterposable())
138  GV = GA->getAliasee();
139 
140  if (const Function *F = dyn_cast<Function>(GV)) {
141  if (!F->doesNotThrow())
142  Effects = true;
143  if (F->doesNotAccessMemory())
144  return;
145  if (F->onlyReadsMemory()) {
146  Read = true;
147  return;
148  }
149  }
150  }
151 
152  // Assume the worst.
153  Write = true;
154  Read = true;
155  Effects = true;
156 }
157 
158 // Determine whether MI reads memory, writes memory, has side effects,
159 // and/or uses the stack pointer value.
160 static void Query(const MachineInstr &MI, AliasAnalysis &AA, bool &Read,
161  bool &Write, bool &Effects, bool &StackPointer) {
162  assert(!MI.isTerminator());
163 
164  if (MI.isDebugInstr() || MI.isPosition())
165  return;
166 
167  // Check for loads.
168  if (MI.mayLoad() && !MI.isDereferenceableInvariantLoad(&AA))
169  Read = true;
170 
171  // Check for stores.
172  if (MI.mayStore()) {
173  Write = true;
174 
175  // Check for stores to __stack_pointer.
176  for (auto MMO : MI.memoperands()) {
177  const MachinePointerInfo &MPI = MMO->getPointerInfo();
178  if (MPI.V.is<const PseudoSourceValue *>()) {
179  auto PSV = MPI.V.get<const PseudoSourceValue *>();
180  if (const ExternalSymbolPseudoSourceValue *EPSV =
181  dyn_cast<ExternalSymbolPseudoSourceValue>(PSV))
182  if (StringRef(EPSV->getSymbol()) == "__stack_pointer") {
183  StackPointer = true;
184  }
185  }
186  }
187  } else if (MI.hasOrderedMemoryRef()) {
188  switch (MI.getOpcode()) {
189  case WebAssembly::DIV_S_I32:
190  case WebAssembly::DIV_S_I64:
191  case WebAssembly::REM_S_I32:
192  case WebAssembly::REM_S_I64:
193  case WebAssembly::DIV_U_I32:
194  case WebAssembly::DIV_U_I64:
195  case WebAssembly::REM_U_I32:
196  case WebAssembly::REM_U_I64:
197  case WebAssembly::I32_TRUNC_S_F32:
198  case WebAssembly::I64_TRUNC_S_F32:
199  case WebAssembly::I32_TRUNC_S_F64:
200  case WebAssembly::I64_TRUNC_S_F64:
201  case WebAssembly::I32_TRUNC_U_F32:
202  case WebAssembly::I64_TRUNC_U_F32:
203  case WebAssembly::I32_TRUNC_U_F64:
204  case WebAssembly::I64_TRUNC_U_F64:
205  // These instruction have hasUnmodeledSideEffects() returning true
206  // because they trap on overflow and invalid so they can't be arbitrarily
207  // moved, however hasOrderedMemoryRef() interprets this plus their lack
208  // of memoperands as having a potential unknown memory reference.
209  break;
210  default:
211  // Record volatile accesses, unless it's a call, as calls are handled
212  // specially below.
213  if (!MI.isCall()) {
214  Write = true;
215  Effects = true;
216  }
217  break;
218  }
219  }
220 
221  // Check for side effects.
222  if (MI.hasUnmodeledSideEffects()) {
223  switch (MI.getOpcode()) {
224  case WebAssembly::DIV_S_I32:
225  case WebAssembly::DIV_S_I64:
226  case WebAssembly::REM_S_I32:
227  case WebAssembly::REM_S_I64:
228  case WebAssembly::DIV_U_I32:
229  case WebAssembly::DIV_U_I64:
230  case WebAssembly::REM_U_I32:
231  case WebAssembly::REM_U_I64:
232  case WebAssembly::I32_TRUNC_S_F32:
233  case WebAssembly::I64_TRUNC_S_F32:
234  case WebAssembly::I32_TRUNC_S_F64:
235  case WebAssembly::I64_TRUNC_S_F64:
236  case WebAssembly::I32_TRUNC_U_F32:
237  case WebAssembly::I64_TRUNC_U_F32:
238  case WebAssembly::I32_TRUNC_U_F64:
239  case WebAssembly::I64_TRUNC_U_F64:
240  // These instructions have hasUnmodeledSideEffects() returning true
241  // because they trap on overflow and invalid so they can't be arbitrarily
242  // moved, however in the specific case of register stackifying, it is safe
243  // to move them because overflow and invalid are Undefined Behavior.
244  break;
245  default:
246  Effects = true;
247  break;
248  }
249  }
250 
251  // Analyze calls.
252  if (MI.isCall()) {
253  unsigned CalleeOpNo = WebAssembly::getCalleeOpNo(MI);
254  QueryCallee(MI, CalleeOpNo, Read, Write, Effects, StackPointer);
255  }
256 }
257 
258 // Test whether Def is safe and profitable to rematerialize.
260  const WebAssemblyInstrInfo *TII) {
261  return Def.isAsCheapAsAMove() && TII->isTriviallyReMaterializable(Def, &AA);
262 }
263 
264 // Identify the definition for this register at this point. This is a
265 // generalization of MachineRegisterInfo::getUniqueVRegDef that uses
266 // LiveIntervals to handle complex cases.
267 static MachineInstr *GetVRegDef(unsigned Reg, const MachineInstr *Insert,
268  const MachineRegisterInfo &MRI,
269  const LiveIntervals &LIS) {
270  // Most registers are in SSA form here so we try a quick MRI query first.
271  if (MachineInstr *Def = MRI.getUniqueVRegDef(Reg))
272  return Def;
273 
274  // MRI doesn't know what the Def is. Try asking LIS.
275  if (const VNInfo *ValNo = LIS.getInterval(Reg).getVNInfoBefore(
276  LIS.getInstructionIndex(*Insert)))
277  return LIS.getInstructionFromIndex(ValNo->def);
278 
279  return nullptr;
280 }
281 
282 // Test whether Reg, as defined at Def, has exactly one use. This is a
283 // generalization of MachineRegisterInfo::hasOneUse that uses LiveIntervals
284 // to handle complex cases.
286  MachineDominatorTree &MDT, LiveIntervals &LIS) {
287  // Most registers are in SSA form here so we try a quick MRI query first.
288  if (MRI.hasOneUse(Reg))
289  return true;
290 
291  bool HasOne = false;
292  const LiveInterval &LI = LIS.getInterval(Reg);
293  const VNInfo *DefVNI =
295  assert(DefVNI);
296  for (auto &I : MRI.use_nodbg_operands(Reg)) {
297  const auto &Result = LI.Query(LIS.getInstructionIndex(*I.getParent()));
298  if (Result.valueIn() == DefVNI) {
299  if (!Result.isKill())
300  return false;
301  if (HasOne)
302  return false;
303  HasOne = true;
304  }
305  }
306  return HasOne;
307 }
308 
309 // Test whether it's safe to move Def to just before Insert.
310 // TODO: Compute memory dependencies in a way that doesn't require always
311 // walking the block.
312 // TODO: Compute memory dependencies in a way that uses AliasAnalysis to be
313 // more precise.
314 static bool IsSafeToMove(const MachineInstr *Def, const MachineInstr *Insert,
315  AliasAnalysis &AA, const MachineRegisterInfo &MRI) {
316  assert(Def->getParent() == Insert->getParent());
317 
318  // Check for register dependencies.
319  SmallVector<unsigned, 4> MutableRegisters;
320  for (const MachineOperand &MO : Def->operands()) {
321  if (!MO.isReg() || MO.isUndef())
322  continue;
323  unsigned Reg = MO.getReg();
324 
325  // If the register is dead here and at Insert, ignore it.
326  if (MO.isDead() && Insert->definesRegister(Reg) &&
327  !Insert->readsRegister(Reg))
328  continue;
329 
331  // Ignore ARGUMENTS; it's just used to keep the ARGUMENT_* instructions
332  // from moving down, and we've already checked for that.
333  if (Reg == WebAssembly::ARGUMENTS)
334  continue;
335  // If the physical register is never modified, ignore it.
336  if (!MRI.isPhysRegModified(Reg))
337  continue;
338  // Otherwise, it's a physical register with unknown liveness.
339  return false;
340  }
341 
342  // If one of the operands isn't in SSA form, it has different values at
343  // different times, and we need to make sure we don't move our use across
344  // a different def.
345  if (!MO.isDef() && !MRI.hasOneDef(Reg))
346  MutableRegisters.push_back(Reg);
347  }
348 
349  bool Read = false, Write = false, Effects = false, StackPointer = false;
350  Query(*Def, AA, Read, Write, Effects, StackPointer);
351 
352  // If the instruction does not access memory and has no side effects, it has
353  // no additional dependencies.
354  bool HasMutableRegisters = !MutableRegisters.empty();
355  if (!Read && !Write && !Effects && !StackPointer && !HasMutableRegisters)
356  return true;
357 
358  // Scan through the intervening instructions between Def and Insert.
359  MachineBasicBlock::const_iterator D(Def), I(Insert);
360  for (--I; I != D; --I) {
361  bool InterveningRead = false;
362  bool InterveningWrite = false;
363  bool InterveningEffects = false;
364  bool InterveningStackPointer = false;
365  Query(*I, AA, InterveningRead, InterveningWrite, InterveningEffects,
366  InterveningStackPointer);
367  if (Effects && InterveningEffects)
368  return false;
369  if (Read && InterveningWrite)
370  return false;
371  if (Write && (InterveningRead || InterveningWrite))
372  return false;
373  if (StackPointer && InterveningStackPointer)
374  return false;
375 
376  for (unsigned Reg : MutableRegisters)
377  for (const MachineOperand &MO : I->operands())
378  if (MO.isReg() && MO.isDef() && MO.getReg() == Reg)
379  return false;
380  }
381 
382  return true;
383 }
384 
385 /// Test whether OneUse, a use of Reg, dominates all of Reg's other uses.
386 static bool OneUseDominatesOtherUses(unsigned Reg, const MachineOperand &OneUse,
387  const MachineBasicBlock &MBB,
388  const MachineRegisterInfo &MRI,
389  const MachineDominatorTree &MDT,
390  LiveIntervals &LIS,
392  const LiveInterval &LI = LIS.getInterval(Reg);
393 
394  const MachineInstr *OneUseInst = OneUse.getParent();
395  VNInfo *OneUseVNI = LI.getVNInfoBefore(LIS.getInstructionIndex(*OneUseInst));
396 
397  for (const MachineOperand &Use : MRI.use_nodbg_operands(Reg)) {
398  if (&Use == &OneUse)
399  continue;
400 
401  const MachineInstr *UseInst = Use.getParent();
402  VNInfo *UseVNI = LI.getVNInfoBefore(LIS.getInstructionIndex(*UseInst));
403 
404  if (UseVNI != OneUseVNI)
405  continue;
406 
407  const MachineInstr *OneUseInst = OneUse.getParent();
408  if (UseInst == OneUseInst) {
409  // Another use in the same instruction. We need to ensure that the one
410  // selected use happens "before" it.
411  if (&OneUse > &Use)
412  return false;
413  } else {
414  // Test that the use is dominated by the one selected use.
415  while (!MDT.dominates(OneUseInst, UseInst)) {
416  // Actually, dominating is over-conservative. Test that the use would
417  // happen after the one selected use in the stack evaluation order.
418  //
419  // This is needed as a consequence of using implicit get_locals for
420  // uses and implicit set_locals for defs.
421  if (UseInst->getDesc().getNumDefs() == 0)
422  return false;
423  const MachineOperand &MO = UseInst->getOperand(0);
424  if (!MO.isReg())
425  return false;
426  unsigned DefReg = MO.getReg();
428  !MFI.isVRegStackified(DefReg))
429  return false;
430  assert(MRI.hasOneUse(DefReg));
431  const MachineOperand &NewUse = *MRI.use_begin(DefReg);
432  const MachineInstr *NewUseInst = NewUse.getParent();
433  if (NewUseInst == OneUseInst) {
434  if (&OneUse > &NewUse)
435  return false;
436  break;
437  }
438  UseInst = NewUseInst;
439  }
440  }
441  }
442  return true;
443 }
444 
445 /// Get the appropriate tee opcode for the given register class.
446 static unsigned GetTeeOpcode(const TargetRegisterClass *RC) {
447  if (RC == &WebAssembly::I32RegClass)
448  return WebAssembly::TEE_I32;
449  if (RC == &WebAssembly::I64RegClass)
450  return WebAssembly::TEE_I64;
451  if (RC == &WebAssembly::F32RegClass)
452  return WebAssembly::TEE_F32;
453  if (RC == &WebAssembly::F64RegClass)
454  return WebAssembly::TEE_F64;
455  if (RC == &WebAssembly::V128RegClass)
456  return WebAssembly::TEE_V128;
457  llvm_unreachable("Unexpected register class");
458 }
459 
460 // Shrink LI to its uses, cleaning up LI.
461 static void ShrinkToUses(LiveInterval &LI, LiveIntervals &LIS) {
462  if (LIS.shrinkToUses(&LI)) {
464  LIS.splitSeparateComponents(LI, SplitLIs);
465  }
466 }
467 
468 /// A single-use def in the same block with no intervening memory or register
469 /// dependencies; move the def down and nest it with the current instruction.
472  MachineInstr *Insert, LiveIntervals &LIS,
475  LLVM_DEBUG(dbgs() << "Move for single use: "; Def->dump());
476 
477  MBB.splice(Insert, &MBB, Def);
478  LIS.handleMove(*Def);
479 
480  if (MRI.hasOneDef(Reg) && MRI.hasOneUse(Reg)) {
481  // No one else is using this register for anything so we can just stackify
482  // it in place.
483  MFI.stackifyVReg(Reg);
484  } else {
485  // The register may have unrelated uses or defs; create a new register for
486  // just our one def and use so that we can stackify it.
487  unsigned NewReg = MRI.createVirtualRegister(MRI.getRegClass(Reg));
488  Def->getOperand(0).setReg(NewReg);
489  Op.setReg(NewReg);
490 
491  // Tell LiveIntervals about the new register.
493 
494  // Tell LiveIntervals about the changes to the old register.
495  LiveInterval &LI = LIS.getInterval(Reg);
497  LIS.getInstructionIndex(*Op.getParent()).getRegSlot(),
498  /*RemoveDeadValNo=*/true);
499 
500  MFI.stackifyVReg(NewReg);
501 
502  LLVM_DEBUG(dbgs() << " - Replaced register: "; Def->dump());
503  }
504 
505  ImposeStackOrdering(Def);
506  return Def;
507 }
508 
509 /// A trivially cloneable instruction; clone it and nest the new copy with the
510 /// current instruction.
516  LLVM_DEBUG(dbgs() << "Rematerializing cheap def: "; Def.dump());
517  LLVM_DEBUG(dbgs() << " - for use in "; Op.getParent()->dump());
518 
519  unsigned NewReg = MRI.createVirtualRegister(MRI.getRegClass(Reg));
520  TII->reMaterialize(MBB, Insert, NewReg, 0, Def, *TRI);
521  Op.setReg(NewReg);
522  MachineInstr *Clone = &*std::prev(Insert);
523  LIS.InsertMachineInstrInMaps(*Clone);
525  MFI.stackifyVReg(NewReg);
526  ImposeStackOrdering(Clone);
527 
528  LLVM_DEBUG(dbgs() << " - Cloned to "; Clone->dump());
529 
530  // Shrink the interval.
531  bool IsDead = MRI.use_empty(Reg);
532  if (!IsDead) {
533  LiveInterval &LI = LIS.getInterval(Reg);
534  ShrinkToUses(LI, LIS);
535  IsDead = !LI.liveAt(LIS.getInstructionIndex(Def).getDeadSlot());
536  }
537 
538  // If that was the last use of the original, delete the original.
539  if (IsDead) {
540  LLVM_DEBUG(dbgs() << " - Deleting original\n");
541  SlotIndex Idx = LIS.getInstructionIndex(Def).getRegSlot();
542  LIS.removePhysRegDefAt(WebAssembly::ARGUMENTS, Idx);
543  LIS.removeInterval(Reg);
545  Def.eraseFromParent();
546  }
547 
548  return Clone;
549 }
550 
551 /// A multiple-use def in the same block with no intervening memory or register
552 /// dependencies; move the def down, nest it with the current instruction, and
553 /// insert a tee to satisfy the rest of the uses. As an illustration, rewrite
554 /// this:
555 ///
556 /// Reg = INST ... // Def
557 /// INST ..., Reg, ... // Insert
558 /// INST ..., Reg, ...
559 /// INST ..., Reg, ...
560 ///
561 /// to this:
562 ///
563 /// DefReg = INST ... // Def (to become the new Insert)
564 /// TeeReg, Reg = TEE_... DefReg
565 /// INST ..., TeeReg, ... // Insert
566 /// INST ..., Reg, ...
567 /// INST ..., Reg, ...
568 ///
569 /// with DefReg and TeeReg stackified. This eliminates a get_local from the
570 /// resulting code.
575  LLVM_DEBUG(dbgs() << "Move and tee for multi-use:"; Def->dump());
576 
577  // Move Def into place.
578  MBB.splice(Insert, &MBB, Def);
579  LIS.handleMove(*Def);
580 
581  // Create the Tee and attach the registers.
582  const auto *RegClass = MRI.getRegClass(Reg);
583  unsigned TeeReg = MRI.createVirtualRegister(RegClass);
584  unsigned DefReg = MRI.createVirtualRegister(RegClass);
585  MachineOperand &DefMO = Def->getOperand(0);
586  MachineInstr *Tee = BuildMI(MBB, Insert, Insert->getDebugLoc(),
587  TII->get(GetTeeOpcode(RegClass)), TeeReg)
588  .addReg(Reg, RegState::Define)
589  .addReg(DefReg, getUndefRegState(DefMO.isDead()));
590  Op.setReg(TeeReg);
591  DefMO.setReg(DefReg);
592  SlotIndex TeeIdx = LIS.InsertMachineInstrInMaps(*Tee).getRegSlot();
593  SlotIndex DefIdx = LIS.getInstructionIndex(*Def).getRegSlot();
594 
595  // Tell LiveIntervals we moved the original vreg def from Def to Tee.
596  LiveInterval &LI = LIS.getInterval(Reg);
598  VNInfo *ValNo = LI.getVNInfoAt(DefIdx);
599  I->start = TeeIdx;
600  ValNo->def = TeeIdx;
601  ShrinkToUses(LI, LIS);
602 
603  // Finish stackifying the new regs.
606  MFI.stackifyVReg(DefReg);
607  MFI.stackifyVReg(TeeReg);
608  ImposeStackOrdering(Def);
609  ImposeStackOrdering(Tee);
610 
611  LLVM_DEBUG(dbgs() << " - Replaced register: "; Def->dump());
612  LLVM_DEBUG(dbgs() << " - Tee instruction: "; Tee->dump());
613  return Def;
614 }
615 
616 namespace {
617 /// A stack for walking the tree of instructions being built, visiting the
618 /// MachineOperands in DFS order.
619 class TreeWalkerState {
620  typedef MachineInstr::mop_iterator mop_iterator;
621  typedef std::reverse_iterator<mop_iterator> mop_reverse_iterator;
622  typedef iterator_range<mop_reverse_iterator> RangeTy;
623  SmallVector<RangeTy, 4> Worklist;
624 
625 public:
626  explicit TreeWalkerState(MachineInstr *Insert) {
627  const iterator_range<mop_iterator> &Range = Insert->explicit_uses();
628  if (Range.begin() != Range.end())
629  Worklist.push_back(reverse(Range));
630  }
631 
632  bool Done() const { return Worklist.empty(); }
633 
634  MachineOperand &Pop() {
635  RangeTy &Range = Worklist.back();
636  MachineOperand &Op = *Range.begin();
637  Range = drop_begin(Range, 1);
638  if (Range.begin() == Range.end())
639  Worklist.pop_back();
640  assert((Worklist.empty() ||
641  Worklist.back().begin() != Worklist.back().end()) &&
642  "Empty ranges shouldn't remain in the worklist");
643  return Op;
644  }
645 
646  /// Push Instr's operands onto the stack to be visited.
647  void PushOperands(MachineInstr *Instr) {
648  const iterator_range<mop_iterator> &Range(Instr->explicit_uses());
649  if (Range.begin() != Range.end())
650  Worklist.push_back(reverse(Range));
651  }
652 
653  /// Some of Instr's operands are on the top of the stack; remove them and
654  /// re-insert them starting from the beginning (because we've commuted them).
655  void ResetTopOperands(MachineInstr *Instr) {
656  assert(HasRemainingOperands(Instr) &&
657  "Reseting operands should only be done when the instruction has "
658  "an operand still on the stack");
659  Worklist.back() = reverse(Instr->explicit_uses());
660  }
661 
662  /// Test whether Instr has operands remaining to be visited at the top of
663  /// the stack.
664  bool HasRemainingOperands(const MachineInstr *Instr) const {
665  if (Worklist.empty())
666  return false;
667  const RangeTy &Range = Worklist.back();
668  return Range.begin() != Range.end() && Range.begin()->getParent() == Instr;
669  }
670 
671  /// Test whether the given register is present on the stack, indicating an
672  /// operand in the tree that we haven't visited yet. Moving a definition of
673  /// Reg to a point in the tree after that would change its value.
674  ///
675  /// This is needed as a consequence of using implicit get_locals for
676  /// uses and implicit set_locals for defs.
677  bool IsOnStack(unsigned Reg) const {
678  for (const RangeTy &Range : Worklist)
679  for (const MachineOperand &MO : Range)
680  if (MO.isReg() && MO.getReg() == Reg)
681  return true;
682  return false;
683  }
684 };
685 
686 /// State to keep track of whether commuting is in flight or whether it's been
687 /// tried for the current instruction and didn't work.
688 class CommutingState {
689  /// There are effectively three states: the initial state where we haven't
690  /// started commuting anything and we don't know anything yet, the tenative
691  /// state where we've commuted the operands of the current instruction and are
692  /// revisting it, and the declined state where we've reverted the operands
693  /// back to their original order and will no longer commute it further.
694  bool TentativelyCommuting;
695  bool Declined;
696 
697  /// During the tentative state, these hold the operand indices of the commuted
698  /// operands.
699  unsigned Operand0, Operand1;
700 
701 public:
702  CommutingState() : TentativelyCommuting(false), Declined(false) {}
703 
704  /// Stackification for an operand was not successful due to ordering
705  /// constraints. If possible, and if we haven't already tried it and declined
706  /// it, commute Insert's operands and prepare to revisit it.
707  void MaybeCommute(MachineInstr *Insert, TreeWalkerState &TreeWalker,
708  const WebAssemblyInstrInfo *TII) {
709  if (TentativelyCommuting) {
710  assert(!Declined &&
711  "Don't decline commuting until you've finished trying it");
712  // Commuting didn't help. Revert it.
713  TII->commuteInstruction(*Insert, /*NewMI=*/false, Operand0, Operand1);
714  TentativelyCommuting = false;
715  Declined = true;
716  } else if (!Declined && TreeWalker.HasRemainingOperands(Insert)) {
719  if (TII->findCommutedOpIndices(*Insert, Operand0, Operand1)) {
720  // Tentatively commute the operands and try again.
721  TII->commuteInstruction(*Insert, /*NewMI=*/false, Operand0, Operand1);
722  TreeWalker.ResetTopOperands(Insert);
723  TentativelyCommuting = true;
724  Declined = false;
725  }
726  }
727  }
728 
729  /// Stackification for some operand was successful. Reset to the default
730  /// state.
731  void Reset() {
732  TentativelyCommuting = false;
733  Declined = false;
734  }
735 };
736 } // end anonymous namespace
737 
738 bool WebAssemblyRegStackify::runOnMachineFunction(MachineFunction &MF) {
739  LLVM_DEBUG(dbgs() << "********** Register Stackifying **********\n"
740  "********** Function: "
741  << MF.getName() << '\n');
742 
743  bool Changed = false;
746  const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
747  const auto *TRI = MF.getSubtarget<WebAssemblySubtarget>().getRegisterInfo();
748  AliasAnalysis &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
749  MachineDominatorTree &MDT = getAnalysis<MachineDominatorTree>();
750  LiveIntervals &LIS = getAnalysis<LiveIntervals>();
751 
752  // Walk the instructions from the bottom up. Currently we don't look past
753  // block boundaries, and the blocks aren't ordered so the block visitation
754  // order isn't significant, but we may want to change this in the future.
755  for (MachineBasicBlock &MBB : MF) {
756  // Don't use a range-based for loop, because we modify the list as we're
757  // iterating over it and the end iterator may change.
758  for (auto MII = MBB.rbegin(); MII != MBB.rend(); ++MII) {
759  MachineInstr *Insert = &*MII;
760  // Don't nest anything inside an inline asm, because we don't have
761  // constraints for $push inputs.
762  if (Insert->getOpcode() == TargetOpcode::INLINEASM)
763  continue;
764 
765  // Ignore debugging intrinsics.
766  if (Insert->getOpcode() == TargetOpcode::DBG_VALUE)
767  continue;
768 
769  // Iterate through the inputs in reverse order, since we'll be pulling
770  // operands off the stack in LIFO order.
771  CommutingState Commuting;
772  TreeWalkerState TreeWalker(Insert);
773  while (!TreeWalker.Done()) {
774  MachineOperand &Op = TreeWalker.Pop();
775 
776  // We're only interested in explicit virtual register operands.
777  if (!Op.isReg())
778  continue;
779 
780  unsigned Reg = Op.getReg();
781  assert(Op.isUse() && "explicit_uses() should only iterate over uses");
782  assert(!Op.isImplicit() &&
783  "explicit_uses() should only iterate over explicit operands");
785  continue;
786 
787  // Identify the definition for this register at this point.
788  MachineInstr *Def = GetVRegDef(Reg, Insert, MRI, LIS);
789  if (!Def)
790  continue;
791 
792  // Don't nest an INLINE_ASM def into anything, because we don't have
793  // constraints for $pop outputs.
794  if (Def->getOpcode() == TargetOpcode::INLINEASM)
795  continue;
796 
797  // Argument instructions represent live-in registers and not real
798  // instructions.
799  if (WebAssembly::isArgument(*Def))
800  continue;
801 
802  // Decide which strategy to take. Prefer to move a single-use value
803  // over cloning it, and prefer cloning over introducing a tee.
804  // For moving, we require the def to be in the same block as the use;
805  // this makes things simpler (LiveIntervals' handleMove function only
806  // supports intra-block moves) and it's MachineSink's job to catch all
807  // the sinking opportunities anyway.
808  bool SameBlock = Def->getParent() == &MBB;
809  bool CanMove = SameBlock && IsSafeToMove(Def, Insert, AA, MRI) &&
810  !TreeWalker.IsOnStack(Reg);
811  if (CanMove && HasOneUse(Reg, Def, MRI, MDT, LIS)) {
812  Insert = MoveForSingleUse(Reg, Op, Def, MBB, Insert, LIS, MFI, MRI);
813  } else if (ShouldRematerialize(*Def, AA, TII)) {
814  Insert =
815  RematerializeCheapDef(Reg, Op, *Def, MBB, Insert->getIterator(),
816  LIS, MFI, MRI, TII, TRI);
817  } else if (CanMove &&
818  OneUseDominatesOtherUses(Reg, Op, MBB, MRI, MDT, LIS, MFI)) {
819  Insert = MoveAndTeeForMultiUse(Reg, Op, Def, MBB, Insert, LIS, MFI,
820  MRI, TII);
821  } else {
822  // We failed to stackify the operand. If the problem was ordering
823  // constraints, Commuting may be able to help.
824  if (!CanMove && SameBlock)
825  Commuting.MaybeCommute(Insert, TreeWalker, TII);
826  // Proceed to the next operand.
827  continue;
828  }
829 
830  // If the instruction we just stackified is an IMPLICIT_DEF, convert it
831  // to a constant 0 so that the def is explicit, and the push/pop
832  // correspondence is maintained.
833  if (Insert->getOpcode() == TargetOpcode::IMPLICIT_DEF)
834  ConvertImplicitDefToConstZero(Insert, MRI, TII, MF);
835 
836  // We stackified an operand. Add the defining instruction's operands to
837  // the worklist stack now to continue to build an ever deeper tree.
838  Commuting.Reset();
839  TreeWalker.PushOperands(Insert);
840  }
841 
842  // If we stackified any operands, skip over the tree to start looking for
843  // the next instruction we can build a tree on.
844  if (Insert != &*MII) {
845  ImposeStackOrdering(&*MII);
846  MII = MachineBasicBlock::iterator(Insert).getReverse();
847  Changed = true;
848  }
849  }
850  }
851 
852  // If we used VALUE_STACK anywhere, add it to the live-in sets everywhere so
853  // that it never looks like a use-before-def.
854  if (Changed) {
855  MF.getRegInfo().addLiveIn(WebAssembly::VALUE_STACK);
856  for (MachineBasicBlock &MBB : MF)
857  MBB.addLiveIn(WebAssembly::VALUE_STACK);
858  }
859 
860 #ifndef NDEBUG
861  // Verify that pushes and pops are performed in LIFO order.
863  for (MachineBasicBlock &MBB : MF) {
864  for (MachineInstr &MI : MBB) {
865  if (MI.isDebugInstr())
866  continue;
867  for (MachineOperand &MO : reverse(MI.explicit_operands())) {
868  if (!MO.isReg())
869  continue;
870  unsigned Reg = MO.getReg();
871 
872  if (MFI.isVRegStackified(Reg)) {
873  if (MO.isDef())
874  Stack.push_back(Reg);
875  else
876  assert(Stack.pop_back_val() == Reg &&
877  "Register stack pop should be paired with a push");
878  }
879  }
880  }
881  // TODO: Generalize this code to support keeping values on the stack across
882  // basic block boundaries.
883  assert(Stack.empty() &&
884  "Register stack pushes and pops should be balanced");
885  }
886 #endif
887 
888  return Changed;
889 }
static MachineInstr * GetVRegDef(unsigned Reg, const MachineInstr *Insert, const MachineRegisterInfo &MRI, const LiveIntervals &LIS)
static Type * getDoubleTy(LLVMContext &C)
Definition: Type.cpp:165
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
bool isCall(QueryType Type=AnyInBundle) const
Definition: MachineInstr.h:633
bool IsDead
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
SlotIndex def
The index of the defining instruction.
Definition: LiveInterval.h:61
void RemoveMachineInstrFromMaps(MachineInstr &MI)
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
void removePhysRegDefAt(unsigned Reg, SlotIndex Pos)
Remove value numbers and related live segments starting at position Pos that are part of any liverang...
Segments::iterator iterator
Definition: LiveInterval.h:208
bool isPhysRegModified(unsigned PhysReg, bool SkipNoReturnDef=false) const
Return true if the specified register is modified in this function.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:383
LiveInterval - This class represents the liveness of a register, or stack slot.
Definition: LiveInterval.h:638
iterator_range< use_nodbg_iterator > use_nodbg_operands(unsigned Reg) const
unsigned getReg() const
getReg - Returns the register number.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
unsigned Reg
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
static MachineInstr * RematerializeCheapDef(unsigned Reg, MachineOperand &Op, MachineInstr &Def, MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator Insert, LiveIntervals &LIS, WebAssemblyFunctionInfo &MFI, MachineRegisterInfo &MRI, const WebAssemblyInstrInfo *TII, const WebAssemblyRegisterInfo *TRI)
A trivially cloneable instruction; clone it and nest the new copy with the current instruction...
unsigned const TargetRegisterInfo * TRI
F(f)
bool hasOneDef(unsigned RegNo) const
Return true if there is exactly one operand defining the specified register.
VNInfo - Value Number Information.
Definition: LiveInterval.h:53
iterator_range< mop_iterator > operands()
Definition: MachineInstr.h:459
This file contains the entry points for global functions defined in the LLVM WebAssembly back-end...
static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
static Constant * getNullValue(Type *Ty)
Constructor to create a &#39;0&#39; constant of arbitrary type.
Definition: Constants.cpp:268
FunctionPass * createWebAssemblyRegStackify()
AnalysisUsage & addRequired()
SlotIndex getDeadSlot() const
Returns the dead def kill slot for the current instruction.
Definition: SlotIndexes.h:260
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
static Type * getFloatTy(LLVMContext &C)
Definition: Type.cpp:164
static void ImposeStackOrdering(MachineInstr *MI)
A Use represents the edge between a Value definition and its users.
Definition: Use.h:56
void eraseFromParent()
Unlink &#39;this&#39; from the containing basic block and delete it.
bool isTerminator(QueryType Type=AnyInBundle) const
Returns true if this instruction part of the terminator for a basic block.
Definition: MachineInstr.h:649
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:409
INLINEASM - Represents an inline asm block.
Definition: ISDOpcodes.h:627
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
Definition: STLExtras.h:251
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction associated with the given index.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
Definition: MachineInstr.h:406
SlotIndexes pass.
Definition: SlotIndexes.h:331
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def...
Definition: SlotIndexes.h:255
SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)
static bool HasOneUse(unsigned Reg, MachineInstr *Def, MachineRegisterInfo &MRI, MachineDominatorTree &MDT, LiveIntervals &LIS)
reverse_iterator getReverse() const
Get a reverse iterator to the same node.
AnalysisUsage & addPreservedID(const void *ID)
static MachineInstr * MoveAndTeeForMultiUse(unsigned Reg, MachineOperand &Op, MachineInstr *Def, MachineBasicBlock &MBB, MachineInstr *Insert, LiveIntervals &LIS, WebAssemblyFunctionInfo &MFI, MachineRegisterInfo &MRI, const WebAssemblyInstrInfo *TII)
A multiple-use def in the same block with no intervening memory or register dependencies; move the de...
static bool ShouldRematerialize(const MachineInstr &Def, AliasAnalysis &AA, const WebAssemblyInstrInfo *TII)
unsigned getUndefRegState(bool B)
bool isDereferenceableInvariantLoad(AliasAnalysis *AA) const
Return true if this load instruction never traps and points to a memory location whose value doesn&#39;t ...
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
static void ConvertImplicitDefToConstZero(MachineInstr *MI, MachineRegisterInfo &MRI, const TargetInstrInfo *TII, MachineFunction &MF)
LiveQueryResult Query(SlotIndex Idx) const
Query Liveness at Idx.
Definition: LiveInterval.h:529
TargetInstrInfo - Interface to description of machine instruction set.
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
Definition: LiveInterval.h:409
This file contains the declaration of the WebAssembly-specific utility functions. ...
char & LiveVariablesID
LiveVariables pass - This pass computes the set of blocks in which each variable is life and sets mac...
static const unsigned CommuteAnyOperandIndex
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
Definition: MachineInstr.h:820
MachineInstrBundleIterator< MachineInstr > iterator
unsigned const MachineRegisterInfo * MRI
ArrayRef< MachineMemOperand * > memoperands() const
Access to memory operands of the instruction.
Definition: MachineInstr.h:516
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
void removeInterval(unsigned Reg)
Interval removal.
bool liveAt(SlotIndex index) const
Definition: LiveInterval.h:389
static MachineOperand CreateFPImm(const ConstantFP *CFP)
PointerUnion< const Value *, const PseudoSourceValue * > V
This is the IR pointer value for the access, or it is null if unknown.
This is an important base class in LLVM.
Definition: Constant.h:42
void splitSeparateComponents(LiveInterval &LI, SmallVectorImpl< LiveInterval *> &SplitLIs)
Split separate components in LiveInterval LI into separate intervals.
const GlobalValue * getGlobal() const
ConstantFP - Floating Point Values [float, double].
Definition: Constants.h:264
This file provides WebAssembly-specific target descriptions.
Represent the analysis usage information of a pass.
bool shrinkToUses(LiveInterval *li, SmallVectorImpl< MachineInstr *> *dead=nullptr)
After removing some uses of a register, shrink its live range to just the remaining uses...
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:285
bool definesRegister(unsigned Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr fully defines the specified register.
self_iterator getIterator()
Definition: ilist_node.h:82
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
Definition: Function.cpp:194
iterator_range< decltype(adl_begin(std::declval< T >)))> drop_begin(T &&t, int n)
bool isDebugInstr() const
Definition: MachineInstr.h:999
This class contains a discriminated union of information about pointers in memory operands...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static void QueryCallee(const MachineInstr &MI, unsigned CalleeOpNo, bool &Read, bool &Write, bool &Effects, bool &StackPointer)
iterator_range< mop_iterator > explicit_uses()
Definition: MachineInstr.h:499
void removeSegment(SlotIndex Start, SlotIndex End, bool RemoveDeadValNo=false)
Remove the specified segment from this range.
This file declares the WebAssembly-specific subclass of TargetSubtarget.
Iterator for intrusive lists based on ilist_node.
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
static unsigned GetTeeOpcode(const TargetRegisterClass *RC)
Get the appropriate tee opcode for the given register class.
bool isArgument(const MachineInstr &MI)
MachineOperand class - Representation of each machine instruction operand.
bool dominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:381
static void ShrinkToUses(LiveInterval &LI, LiveIntervals &LIS)
bool hasOrderedMemoryRef() const
Return true if this instruction may have an ordered or volatile memory reference, or if the informati...
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
Definition: MCInstrDesc.h:225
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:286
LiveInterval & getInterval(unsigned Reg)
static bool IsSafeToMove(const MachineInstr *Def, const MachineInstr *Insert, AliasAnalysis &AA, const MachineRegisterInfo &MRI)
MachineInstr * getUniqueVRegDef(unsigned Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
const Function & getFunction() const
Return the LLVM function that this machine code represents.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:133
VNInfo * getVNInfoBefore(SlotIndex Idx) const
getVNInfoBefore - Return the VNInfo that is live up to but not necessarilly including Idx...
Definition: LiveInterval.h:417
A range adaptor for a pair of iterators.
A specialized pseudo source value for holding external symbol values.
Special value supplied for machine level alias analysis.
bool readsRegister(unsigned Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr reads the specified register.
bool use_empty(unsigned RegNo) const
use_empty - Return true if there are no instructions using the specified register.
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
#define DEBUG_TYPE
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:254
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
Definition: MachineInstr.h:64
INITIALIZE_PASS(WebAssemblyRegStackify, DEBUG_TYPE, "Reorder instructions to use the WebAssembly value stack", false, false) FunctionPass *llvm
This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
bool hasOneUse(unsigned RegNo) const
hasOneUse - Return true if there is exactly one instruction using the specified register.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB &#39;Other&#39; at the position From, and insert it into this MBB right before &#39;...
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
use_iterator use_begin(unsigned RegNo) const
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:56
unsigned getCalleeOpNo(const MachineInstr &MI)
Returns the operand number of a callee, assuming the argument is a call instruction.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Definition: MCInstrInfo.h:45
void setReg(unsigned Reg)
Change the register this operand corresponds to.
static MachineOperand CreateImm(int64_t Val)
#define I(x, y, z)
Definition: MD5.cpp:58
This file declares WebAssembly-specific per-machine-function information.
static void Query(const MachineInstr &MI, AliasAnalysis &AA, bool &Read, bool &Write, bool &Effects, bool &StackPointer)
static bool OneUseDominatesOtherUses(unsigned Reg, const MachineOperand &OneUse, const MachineBasicBlock &MBB, const MachineRegisterInfo &MRI, const MachineDominatorTree &MDT, LiveIntervals &LIS, WebAssemblyFunctionInfo &MFI)
Test whether OneUse, a use of Reg, dominates all of Reg&#39;s other uses.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
T get() const
Returns the value of the specified pointer type.
Definition: PointerUnion.h:135
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
Definition: MachineInstr.h:807
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isPosition() const
Definition: MachineInstr.h:995
IteratorT begin() const
bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore...
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
int is() const
Test if the Union currently holds the type matching T.
Definition: PointerUnion.h:123
iterator FindSegmentContaining(SlotIndex Idx)
Return an iterator to the segment that contains the specified index, or end() if there is none...
Definition: LiveInterval.h:424
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object...
#define LLVM_DEBUG(X)
Definition: Debug.h:123
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:414
SlotIndex - An opaque wrapper around machine indexes.
Definition: SlotIndexes.h:84
IteratorT end() const
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool isAsCheapAsAMove(QueryType Type=AllInBundle) const
Returns true if this instruction has the same cost (or less) than a move instruction.
Definition: MachineInstr.h:906
static MachineInstr * MoveForSingleUse(unsigned Reg, MachineOperand &Op, MachineInstr *Def, MachineBasicBlock &MBB, MachineInstr *Insert, LiveIntervals &LIS, WebAssemblyFunctionInfo &MFI, MachineRegisterInfo &MRI)
A single-use def in the same block with no intervening memory or register dependencies; move the def ...
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
void handleMove(MachineInstr &MI, bool UpdateFlags=false)
Call this method to notify LiveIntervals that instruction MI has been moved within a basic block...
LiveInterval & createAndComputeVirtRegInterval(unsigned Reg)
bool isImplicit() const