LLVM 20.0.0git
WebAssemblyRegStackify.cpp
Go to the documentation of this file.
1//===-- WebAssemblyRegStackify.cpp - Register Stackification --------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file implements a register stacking pass.
11///
12/// This pass reorders instructions to put register uses and defs in an order
13/// such that they form single-use expression trees. Registers fitting this form
14/// are then marked as "stackified", meaning references to them are replaced by
15/// "push" and "pop" from the value stack.
16///
17/// This is primarily a code size optimization, since temporary values on the
18/// value stack don't need to be named.
19///
20//===----------------------------------------------------------------------===//
21
22#include "MCTargetDesc/WebAssemblyMCTargetDesc.h" // for WebAssembly::ARGUMENT_*
23#include "WebAssembly.h"
33#include "llvm/CodeGen/Passes.h"
34#include "llvm/IR/GlobalAlias.h"
35#include "llvm/Support/Debug.h"
37#include <iterator>
38using namespace llvm;
39
40#define DEBUG_TYPE "wasm-reg-stackify"
41
42namespace {
43class 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();
58 }
59
60 bool runOnMachineFunction(MachineFunction &MF) override;
61
62public:
63 static char ID; // Pass identification, replacement for typeid
64 WebAssemblyRegStackify() : MachineFunctionPass(ID) {}
65};
66} // end anonymous namespace
67
68char WebAssemblyRegStackify::ID = 0;
69INITIALIZE_PASS(WebAssemblyRegStackify, DEBUG_TYPE,
70 "Reorder instructions to use the WebAssembly value stack",
71 false, false)
72
74 return new WebAssemblyRegStackify();
75}
76
77// Decorate the given instruction with implicit operands that enforce the
78// expression stack ordering constraints for an instruction which is on
79// the expression stack.
81 // Write the opaque VALUE_STACK register.
82 if (!MI->definesRegister(WebAssembly::VALUE_STACK, /*TRI=*/nullptr))
83 MI->addOperand(MachineOperand::CreateReg(WebAssembly::VALUE_STACK,
84 /*isDef=*/true,
85 /*isImp=*/true));
86
87 // Also read the opaque VALUE_STACK register.
88 if (!MI->readsRegister(WebAssembly::VALUE_STACK, /*TRI=*/nullptr))
89 MI->addOperand(MachineOperand::CreateReg(WebAssembly::VALUE_STACK,
90 /*isDef=*/false,
91 /*isImp=*/true));
92}
93
94// Convert an IMPLICIT_DEF instruction into an instruction which defines
95// a constant zero value.
98 const TargetInstrInfo *TII,
100 LiveIntervals &LIS) {
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));
106 MI->addOperand(MachineOperand::CreateImm(0));
107 } else if (RegClass == &WebAssembly::I64RegClass) {
108 MI->setDesc(TII->get(WebAssembly::CONST_I64));
109 MI->addOperand(MachineOperand::CreateImm(0));
110 } else if (RegClass == &WebAssembly::F32RegClass) {
111 MI->setDesc(TII->get(WebAssembly::CONST_F32));
112 auto *Val = cast<ConstantFP>(Constant::getNullValue(
114 MI->addOperand(MachineOperand::CreateFPImm(Val));
115 } else if (RegClass == &WebAssembly::F64RegClass) {
116 MI->setDesc(TII->get(WebAssembly::CONST_F64));
117 auto *Val = cast<ConstantFP>(Constant::getNullValue(
119 MI->addOperand(MachineOperand::CreateFPImm(Val));
120 } else if (RegClass == &WebAssembly::V128RegClass) {
121 MI->setDesc(TII->get(WebAssembly::CONST_V128_I64x2));
122 MI->addOperand(MachineOperand::CreateImm(0));
123 MI->addOperand(MachineOperand::CreateImm(0));
124 } else {
125 llvm_unreachable("Unexpected reg class");
126 }
127}
128
129// Determine whether a call to the callee referenced by
130// MI->getOperand(CalleeOpNo) reads memory, writes memory, and/or has side
131// effects.
132static void queryCallee(const MachineInstr &MI, bool &Read, bool &Write,
133 bool &Effects, bool &StackPointer) {
134 // All calls can use the stack pointer.
135 StackPointer = true;
136
138 if (MO.isGlobal()) {
139 const Constant *GV = MO.getGlobal();
140 if (const auto *GA = dyn_cast<GlobalAlias>(GV))
141 if (!GA->isInterposable())
142 GV = GA->getAliasee();
143
144 if (const auto *F = dyn_cast<Function>(GV)) {
145 if (!F->doesNotThrow())
146 Effects = true;
147 if (F->doesNotAccessMemory())
148 return;
149 if (F->onlyReadsMemory()) {
150 Read = true;
151 return;
152 }
153 }
154 }
155
156 // Assume the worst.
157 Write = true;
158 Read = true;
159 Effects = true;
160}
161
162// Determine whether MI reads memory, writes memory, has side effects,
163// and/or uses the stack pointer value.
164static void query(const MachineInstr &MI, bool &Read, bool &Write,
165 bool &Effects, bool &StackPointer) {
166 assert(!MI.isTerminator());
167
168 if (MI.isDebugInstr() || MI.isPosition())
169 return;
170
171 // Check for loads.
172 if (MI.mayLoad() && !MI.isDereferenceableInvariantLoad())
173 Read = true;
174
175 // Check for stores.
176 if (MI.mayStore()) {
177 Write = true;
178 } else if (MI.hasOrderedMemoryRef()) {
179 switch (MI.getOpcode()) {
180 case WebAssembly::DIV_S_I32:
181 case WebAssembly::DIV_S_I64:
182 case WebAssembly::REM_S_I32:
183 case WebAssembly::REM_S_I64:
184 case WebAssembly::DIV_U_I32:
185 case WebAssembly::DIV_U_I64:
186 case WebAssembly::REM_U_I32:
187 case WebAssembly::REM_U_I64:
188 case WebAssembly::I32_TRUNC_S_F32:
189 case WebAssembly::I64_TRUNC_S_F32:
190 case WebAssembly::I32_TRUNC_S_F64:
191 case WebAssembly::I64_TRUNC_S_F64:
192 case WebAssembly::I32_TRUNC_U_F32:
193 case WebAssembly::I64_TRUNC_U_F32:
194 case WebAssembly::I32_TRUNC_U_F64:
195 case WebAssembly::I64_TRUNC_U_F64:
196 // These instruction have hasUnmodeledSideEffects() returning true
197 // because they trap on overflow and invalid so they can't be arbitrarily
198 // moved, however hasOrderedMemoryRef() interprets this plus their lack
199 // of memoperands as having a potential unknown memory reference.
200 break;
201 default:
202 // Record volatile accesses, unless it's a call, as calls are handled
203 // specially below.
204 if (!MI.isCall()) {
205 Write = true;
206 Effects = true;
207 }
208 break;
209 }
210 }
211
212 // Check for side effects.
213 if (MI.hasUnmodeledSideEffects()) {
214 switch (MI.getOpcode()) {
215 case WebAssembly::DIV_S_I32:
216 case WebAssembly::DIV_S_I64:
217 case WebAssembly::REM_S_I32:
218 case WebAssembly::REM_S_I64:
219 case WebAssembly::DIV_U_I32:
220 case WebAssembly::DIV_U_I64:
221 case WebAssembly::REM_U_I32:
222 case WebAssembly::REM_U_I64:
223 case WebAssembly::I32_TRUNC_S_F32:
224 case WebAssembly::I64_TRUNC_S_F32:
225 case WebAssembly::I32_TRUNC_S_F64:
226 case WebAssembly::I64_TRUNC_S_F64:
227 case WebAssembly::I32_TRUNC_U_F32:
228 case WebAssembly::I64_TRUNC_U_F32:
229 case WebAssembly::I32_TRUNC_U_F64:
230 case WebAssembly::I64_TRUNC_U_F64:
231 // These instructions have hasUnmodeledSideEffects() returning true
232 // because they trap on overflow and invalid so they can't be arbitrarily
233 // moved, however in the specific case of register stackifying, it is safe
234 // to move them because overflow and invalid are Undefined Behavior.
235 break;
236 default:
237 Effects = true;
238 break;
239 }
240 }
241
242 // Check for writes to __stack_pointer global.
243 if ((MI.getOpcode() == WebAssembly::GLOBAL_SET_I32 ||
244 MI.getOpcode() == WebAssembly::GLOBAL_SET_I64) &&
245 strcmp(MI.getOperand(0).getSymbolName(), "__stack_pointer") == 0)
246 StackPointer = true;
247
248 // Analyze calls.
249 if (MI.isCall()) {
250 queryCallee(MI, Read, Write, Effects, StackPointer);
251 }
252}
253
254// Test whether Def is safe and profitable to rematerialize.
255static bool shouldRematerialize(const MachineInstr &Def,
256 const WebAssemblyInstrInfo *TII) {
257 return Def.isAsCheapAsAMove() && TII->isTriviallyReMaterializable(Def);
258}
259
260// Identify the definition for this register at this point. This is a
261// generalization of MachineRegisterInfo::getUniqueVRegDef that uses
262// LiveIntervals to handle complex cases.
263static MachineInstr *getVRegDef(unsigned Reg, const MachineInstr *Insert,
265 const LiveIntervals &LIS) {
266 // Most registers are in SSA form here so we try a quick MRI query first.
267 if (MachineInstr *Def = MRI.getUniqueVRegDef(Reg))
268 return Def;
269
270 // MRI doesn't know what the Def is. Try asking LIS.
271 if (const VNInfo *ValNo = LIS.getInterval(Reg).getVNInfoBefore(
272 LIS.getInstructionIndex(*Insert)))
273 return LIS.getInstructionFromIndex(ValNo->def);
274
275 return nullptr;
276}
277
278// Test whether Reg, as defined at Def, has exactly one use. This is a
279// generalization of MachineRegisterInfo::hasOneNonDBGUse that uses
280// LiveIntervals to handle complex cases.
281static bool hasOneNonDBGUse(unsigned Reg, MachineInstr *Def,
283 LiveIntervals &LIS) {
284 // Most registers are in SSA form here so we try a quick MRI query first.
285 if (MRI.hasOneNonDBGUse(Reg))
286 return true;
287
288 bool HasOne = false;
289 const LiveInterval &LI = LIS.getInterval(Reg);
290 const VNInfo *DefVNI =
292 assert(DefVNI);
293 for (auto &I : MRI.use_nodbg_operands(Reg)) {
294 const auto &Result = LI.Query(LIS.getInstructionIndex(*I.getParent()));
295 if (Result.valueIn() == DefVNI) {
296 if (!Result.isKill())
297 return false;
298 if (HasOne)
299 return false;
300 HasOne = true;
301 }
302 }
303 return HasOne;
304}
305
306// Test whether it's safe to move Def to just before Insert.
307// TODO: Compute memory dependencies in a way that doesn't require always
308// walking the block.
309// TODO: Compute memory dependencies in a way that uses AliasAnalysis to be
310// more precise.
311static bool isSafeToMove(const MachineOperand *Def, const MachineOperand *Use,
312 const MachineInstr *Insert,
313 const WebAssemblyFunctionInfo &MFI,
314 const MachineRegisterInfo &MRI) {
315 const MachineInstr *DefI = Def->getParent();
316 const MachineInstr *UseI = Use->getParent();
317 assert(DefI->getParent() == Insert->getParent());
318 assert(UseI->getParent() == Insert->getParent());
319
320 // The first def of a multivalue instruction can be stackified by moving,
321 // since the later defs can always be placed into locals if necessary. Later
322 // defs can only be stackified if all previous defs are already stackified
323 // since ExplicitLocals will not know how to place a def in a local if a
324 // subsequent def is stackified. But only one def can be stackified by moving
325 // the instruction, so it must be the first one.
326 //
327 // TODO: This could be loosened to be the first *live* def, but care would
328 // have to be taken to ensure the drops of the initial dead defs can be
329 // placed. This would require checking that no previous defs are used in the
330 // same instruction as subsequent defs.
331 if (Def != DefI->defs().begin())
332 return false;
333
334 // If any subsequent def is used prior to the current value by the same
335 // instruction in which the current value is used, we cannot
336 // stackify. Stackifying in this case would require that def moving below the
337 // current def in the stack, which cannot be achieved, even with locals.
338 // Also ensure we don't sink the def past any other prior uses.
339 for (const auto &SubsequentDef : drop_begin(DefI->defs())) {
340 auto I = std::next(MachineBasicBlock::const_iterator(DefI));
341 auto E = std::next(MachineBasicBlock::const_iterator(UseI));
342 for (; I != E; ++I) {
343 for (const auto &PriorUse : I->uses()) {
344 if (&PriorUse == Use)
345 break;
346 if (PriorUse.isReg() && SubsequentDef.getReg() == PriorUse.getReg())
347 return false;
348 }
349 }
350 }
351
352 // If moving is a semantic nop, it is always allowed
353 const MachineBasicBlock *MBB = DefI->getParent();
354 auto NextI = std::next(MachineBasicBlock::const_iterator(DefI));
355 for (auto E = MBB->end(); NextI != E && NextI->isDebugInstr(); ++NextI)
356 ;
357 if (NextI == Insert)
358 return true;
359
360 // 'catch' and 'catch_all' should be the first instruction of a BB and cannot
361 // move.
362 if (WebAssembly::isCatch(DefI->getOpcode()))
363 return false;
364
365 // Check for register dependencies.
366 SmallVector<unsigned, 4> MutableRegisters;
367 for (const MachineOperand &MO : DefI->operands()) {
368 if (!MO.isReg() || MO.isUndef())
369 continue;
370 Register Reg = MO.getReg();
371
372 // If the register is dead here and at Insert, ignore it.
373 if (MO.isDead() && Insert->definesRegister(Reg, /*TRI=*/nullptr) &&
374 !Insert->readsRegister(Reg, /*TRI=*/nullptr))
375 continue;
376
377 if (Reg.isPhysical()) {
378 // Ignore ARGUMENTS; it's just used to keep the ARGUMENT_* instructions
379 // from moving down, and we've already checked for that.
380 if (Reg == WebAssembly::ARGUMENTS)
381 continue;
382 // If the physical register is never modified, ignore it.
383 if (!MRI.isPhysRegModified(Reg))
384 continue;
385 // Otherwise, it's a physical register with unknown liveness.
386 return false;
387 }
388
389 // If one of the operands isn't in SSA form, it has different values at
390 // different times, and we need to make sure we don't move our use across
391 // a different def.
392 if (!MO.isDef() && !MRI.hasOneDef(Reg))
393 MutableRegisters.push_back(Reg);
394 }
395
396 bool Read = false, Write = false, Effects = false, StackPointer = false;
397 query(*DefI, Read, Write, Effects, StackPointer);
398
399 // If the instruction does not access memory and has no side effects, it has
400 // no additional dependencies.
401 bool HasMutableRegisters = !MutableRegisters.empty();
402 if (!Read && !Write && !Effects && !StackPointer && !HasMutableRegisters)
403 return true;
404
405 // Scan through the intervening instructions between DefI and Insert.
407 for (--I; I != D; --I) {
408 bool InterveningRead = false;
409 bool InterveningWrite = false;
410 bool InterveningEffects = false;
411 bool InterveningStackPointer = false;
412 query(*I, InterveningRead, InterveningWrite, InterveningEffects,
413 InterveningStackPointer);
414 if (Effects && InterveningEffects)
415 return false;
416 if (Read && InterveningWrite)
417 return false;
418 if (Write && (InterveningRead || InterveningWrite))
419 return false;
420 if (StackPointer && InterveningStackPointer)
421 return false;
422
423 for (unsigned Reg : MutableRegisters)
424 for (const MachineOperand &MO : I->operands())
425 if (MO.isReg() && MO.isDef() && MO.getReg() == Reg)
426 return false;
427 }
428
429 return true;
430}
431
432/// Test whether OneUse, a use of Reg, dominates all of Reg's other uses.
433static bool oneUseDominatesOtherUses(unsigned Reg, const MachineOperand &OneUse,
434 const MachineBasicBlock &MBB,
436 const MachineDominatorTree &MDT,
437 LiveIntervals &LIS,
439 const LiveInterval &LI = LIS.getInterval(Reg);
440
441 const MachineInstr *OneUseInst = OneUse.getParent();
442 VNInfo *OneUseVNI = LI.getVNInfoBefore(LIS.getInstructionIndex(*OneUseInst));
443
444 for (const MachineOperand &Use : MRI.use_nodbg_operands(Reg)) {
445 if (&Use == &OneUse)
446 continue;
447
448 const MachineInstr *UseInst = Use.getParent();
449 VNInfo *UseVNI = LI.getVNInfoBefore(LIS.getInstructionIndex(*UseInst));
450
451 if (UseVNI != OneUseVNI)
452 continue;
453
454 if (UseInst == OneUseInst) {
455 // Another use in the same instruction. We need to ensure that the one
456 // selected use happens "before" it.
457 if (&OneUse > &Use)
458 return false;
459 } else {
460 // Test that the use is dominated by the one selected use.
461 while (!MDT.dominates(OneUseInst, UseInst)) {
462 // Actually, dominating is over-conservative. Test that the use would
463 // happen after the one selected use in the stack evaluation order.
464 //
465 // This is needed as a consequence of using implicit local.gets for
466 // uses and implicit local.sets for defs.
467 if (UseInst->getDesc().getNumDefs() == 0)
468 return false;
469 const MachineOperand &MO = UseInst->getOperand(0);
470 if (!MO.isReg())
471 return false;
472 Register DefReg = MO.getReg();
473 if (!DefReg.isVirtual() || !MFI.isVRegStackified(DefReg))
474 return false;
475 assert(MRI.hasOneNonDBGUse(DefReg));
476 const MachineOperand &NewUse = *MRI.use_nodbg_begin(DefReg);
477 const MachineInstr *NewUseInst = NewUse.getParent();
478 if (NewUseInst == OneUseInst) {
479 if (&OneUse > &NewUse)
480 return false;
481 break;
482 }
483 UseInst = NewUseInst;
484 }
485 }
486 }
487 return true;
488}
489
490/// Get the appropriate tee opcode for the given register class.
491static unsigned getTeeOpcode(const TargetRegisterClass *RC) {
492 if (RC == &WebAssembly::I32RegClass)
493 return WebAssembly::TEE_I32;
494 if (RC == &WebAssembly::I64RegClass)
495 return WebAssembly::TEE_I64;
496 if (RC == &WebAssembly::F32RegClass)
497 return WebAssembly::TEE_F32;
498 if (RC == &WebAssembly::F64RegClass)
499 return WebAssembly::TEE_F64;
500 if (RC == &WebAssembly::V128RegClass)
501 return WebAssembly::TEE_V128;
502 if (RC == &WebAssembly::EXTERNREFRegClass)
503 return WebAssembly::TEE_EXTERNREF;
504 if (RC == &WebAssembly::FUNCREFRegClass)
505 return WebAssembly::TEE_FUNCREF;
506 if (RC == &WebAssembly::EXNREFRegClass)
507 return WebAssembly::TEE_EXNREF;
508 llvm_unreachable("Unexpected register class");
509}
510
511// Shrink LI to its uses, cleaning up LI.
513 if (LIS.shrinkToUses(&LI)) {
515 LIS.splitSeparateComponents(LI, SplitLIs);
516 }
517}
518
519/// A single-use def in the same block with no intervening memory or register
520/// dependencies; move the def down and nest it with the current instruction.
523 MachineInstr *Insert, LiveIntervals &LIS,
526 LLVM_DEBUG(dbgs() << "Move for single use: "; Def->dump());
527
529 DefDIs.sink(Insert);
530 LIS.handleMove(*Def);
531
532 if (MRI.hasOneDef(Reg) && MRI.hasOneNonDBGUse(Reg)) {
533 // No one else is using this register for anything so we can just stackify
534 // it in place.
535 MFI.stackifyVReg(MRI, Reg);
536 } else {
537 // The register may have unrelated uses or defs; create a new register for
538 // just our one def and use so that we can stackify it.
539 Register NewReg = MRI.createVirtualRegister(MRI.getRegClass(Reg));
540 Op.setReg(NewReg);
541 DefDIs.updateReg(NewReg);
542
543 // Tell LiveIntervals about the new register.
545
546 // Tell LiveIntervals about the changes to the old register.
547 LiveInterval &LI = LIS.getInterval(Reg);
549 LIS.getInstructionIndex(*Op.getParent()).getRegSlot(),
550 /*RemoveDeadValNo=*/true);
551
552 MFI.stackifyVReg(MRI, NewReg);
553
554 LLVM_DEBUG(dbgs() << " - Replaced register: "; Def->dump());
555 }
556
558 return Def;
559}
560
562 for (auto *I = MI->getPrevNode(); I; I = I->getPrevNode())
563 if (!I->isDebugInstr())
564 return I;
565 return nullptr;
566}
567
568/// A trivially cloneable instruction; clone it and nest the new copy with the
569/// current instruction.
571 unsigned Reg, MachineOperand &Op, MachineInstr &Def, MachineBasicBlock &MBB,
575 LLVM_DEBUG(dbgs() << "Rematerializing cheap def: "; Def.dump());
576 LLVM_DEBUG(dbgs() << " - for use in "; Op.getParent()->dump());
577
578 WebAssemblyDebugValueManager DefDIs(&Def);
579
580 Register NewReg = MRI.createVirtualRegister(MRI.getRegClass(Reg));
581 DefDIs.cloneSink(&*Insert, NewReg);
582 Op.setReg(NewReg);
583 MachineInstr *Clone = getPrevNonDebugInst(&*Insert);
584 assert(Clone);
585 LIS.InsertMachineInstrInMaps(*Clone);
587 MFI.stackifyVReg(MRI, NewReg);
588 imposeStackOrdering(Clone);
589
590 LLVM_DEBUG(dbgs() << " - Cloned to "; Clone->dump());
591
592 // Shrink the interval.
593 bool IsDead = MRI.use_empty(Reg);
594 if (!IsDead) {
595 LiveInterval &LI = LIS.getInterval(Reg);
596 shrinkToUses(LI, LIS);
598 }
599
600 // If that was the last use of the original, delete the original.
601 if (IsDead) {
602 LLVM_DEBUG(dbgs() << " - Deleting original\n");
604 LIS.removePhysRegDefAt(MCRegister::from(WebAssembly::ARGUMENTS), Idx);
605 LIS.removeInterval(Reg);
607 DefDIs.removeDef();
608 }
609
610 return Clone;
611}
612
613/// A multiple-use def in the same block with no intervening memory or register
614/// dependencies; move the def down, nest it with the current instruction, and
615/// insert a tee to satisfy the rest of the uses. As an illustration, rewrite
616/// this:
617///
618/// Reg = INST ... // Def
619/// INST ..., Reg, ... // Insert
620/// INST ..., Reg, ...
621/// INST ..., Reg, ...
622///
623/// to this:
624///
625/// DefReg = INST ... // Def (to become the new Insert)
626/// TeeReg, Reg = TEE_... DefReg
627/// INST ..., TeeReg, ... // Insert
628/// INST ..., Reg, ...
629/// INST ..., Reg, ...
630///
631/// with DefReg and TeeReg stackified. This eliminates a local.get from the
632/// resulting code.
634 unsigned Reg, MachineOperand &Op, MachineInstr *Def, MachineBasicBlock &MBB,
637 LLVM_DEBUG(dbgs() << "Move and tee for multi-use:"; Def->dump());
638
639 const auto *RegClass = MRI.getRegClass(Reg);
640 Register TeeReg = MRI.createVirtualRegister(RegClass);
641 Register DefReg = MRI.createVirtualRegister(RegClass);
642
643 // Move Def into place.
645 DefDIs.sink(Insert);
646 LIS.handleMove(*Def);
647
648 // Create the Tee and attach the registers.
649 MachineOperand &DefMO = Def->getOperand(0);
650 MachineInstr *Tee = BuildMI(MBB, Insert, Insert->getDebugLoc(),
651 TII->get(getTeeOpcode(RegClass)), TeeReg)
653 .addReg(DefReg, getUndefRegState(DefMO.isDead()));
654 Op.setReg(TeeReg);
655 DefDIs.updateReg(DefReg);
656 SlotIndex TeeIdx = LIS.InsertMachineInstrInMaps(*Tee).getRegSlot();
657 SlotIndex DefIdx = LIS.getInstructionIndex(*Def).getRegSlot();
658
659 // Tell LiveIntervals we moved the original vreg def from Def to Tee.
660 LiveInterval &LI = LIS.getInterval(Reg);
662 VNInfo *ValNo = LI.getVNInfoAt(DefIdx);
663 I->start = TeeIdx;
664 ValNo->def = TeeIdx;
665 shrinkToUses(LI, LIS);
666
667 // Finish stackifying the new regs.
670 MFI.stackifyVReg(MRI, DefReg);
671 MFI.stackifyVReg(MRI, TeeReg);
674
675 // Even though 'TeeReg, Reg = TEE ...', has two defs, we don't need to clone
676 // DBG_VALUEs for both of them, given that the latter will cancel the former
677 // anyway. Here we only clone DBG_VALUEs for TeeReg, which will be converted
678 // to a local index in ExplicitLocals pass.
679 DefDIs.cloneSink(Insert, TeeReg, /* CloneDef */ false);
680
681 LLVM_DEBUG(dbgs() << " - Replaced register: "; Def->dump());
682 LLVM_DEBUG(dbgs() << " - Tee instruction: "; Tee->dump());
683 return Def;
684}
685
686namespace {
687/// A stack for walking the tree of instructions being built, visiting the
688/// MachineOperands in DFS order.
689class TreeWalkerState {
690 using mop_iterator = MachineInstr::mop_iterator;
691 using mop_reverse_iterator = std::reverse_iterator<mop_iterator>;
694
695public:
696 explicit TreeWalkerState(MachineInstr *Insert) {
697 const iterator_range<mop_iterator> &Range = Insert->explicit_uses();
698 if (!Range.empty())
699 Worklist.push_back(reverse(Range));
700 }
701
702 bool done() const { return Worklist.empty(); }
703
704 MachineOperand &pop() {
705 RangeTy &Range = Worklist.back();
706 MachineOperand &Op = *Range.begin();
708 if (Range.empty())
709 Worklist.pop_back();
710 assert((Worklist.empty() || !Worklist.back().empty()) &&
711 "Empty ranges shouldn't remain in the worklist");
712 return Op;
713 }
714
715 /// Push Instr's operands onto the stack to be visited.
716 void pushOperands(MachineInstr *Instr) {
717 const iterator_range<mop_iterator> &Range(Instr->explicit_uses());
718 if (!Range.empty())
719 Worklist.push_back(reverse(Range));
720 }
721
722 /// Some of Instr's operands are on the top of the stack; remove them and
723 /// re-insert them starting from the beginning (because we've commuted them).
724 void resetTopOperands(MachineInstr *Instr) {
725 assert(hasRemainingOperands(Instr) &&
726 "Reseting operands should only be done when the instruction has "
727 "an operand still on the stack");
728 Worklist.back() = reverse(Instr->explicit_uses());
729 }
730
731 /// Test whether Instr has operands remaining to be visited at the top of
732 /// the stack.
733 bool hasRemainingOperands(const MachineInstr *Instr) const {
734 if (Worklist.empty())
735 return false;
736 const RangeTy &Range = Worklist.back();
737 return !Range.empty() && Range.begin()->getParent() == Instr;
738 }
739
740 /// Test whether the given register is present on the stack, indicating an
741 /// operand in the tree that we haven't visited yet. Moving a definition of
742 /// Reg to a point in the tree after that would change its value.
743 ///
744 /// This is needed as a consequence of using implicit local.gets for
745 /// uses and implicit local.sets for defs.
746 bool isOnStack(unsigned Reg) const {
747 for (const RangeTy &Range : Worklist)
748 for (const MachineOperand &MO : Range)
749 if (MO.isReg() && MO.getReg() == Reg)
750 return true;
751 return false;
752 }
753};
754
755/// State to keep track of whether commuting is in flight or whether it's been
756/// tried for the current instruction and didn't work.
757class CommutingState {
758 /// There are effectively three states: the initial state where we haven't
759 /// started commuting anything and we don't know anything yet, the tentative
760 /// state where we've commuted the operands of the current instruction and are
761 /// revisiting it, and the declined state where we've reverted the operands
762 /// back to their original order and will no longer commute it further.
763 bool TentativelyCommuting = false;
764 bool Declined = false;
765
766 /// During the tentative state, these hold the operand indices of the commuted
767 /// operands.
768 unsigned Operand0, Operand1;
769
770public:
771 /// Stackification for an operand was not successful due to ordering
772 /// constraints. If possible, and if we haven't already tried it and declined
773 /// it, commute Insert's operands and prepare to revisit it.
774 void maybeCommute(MachineInstr *Insert, TreeWalkerState &TreeWalker,
775 const WebAssemblyInstrInfo *TII) {
776 if (TentativelyCommuting) {
777 assert(!Declined &&
778 "Don't decline commuting until you've finished trying it");
779 // Commuting didn't help. Revert it.
780 TII->commuteInstruction(*Insert, /*NewMI=*/false, Operand0, Operand1);
781 TentativelyCommuting = false;
782 Declined = true;
783 } else if (!Declined && TreeWalker.hasRemainingOperands(Insert)) {
786 if (TII->findCommutedOpIndices(*Insert, Operand0, Operand1)) {
787 // Tentatively commute the operands and try again.
788 TII->commuteInstruction(*Insert, /*NewMI=*/false, Operand0, Operand1);
789 TreeWalker.resetTopOperands(Insert);
790 TentativelyCommuting = true;
791 Declined = false;
792 }
793 }
794 }
795
796 /// Stackification for some operand was successful. Reset to the default
797 /// state.
798 void reset() {
799 TentativelyCommuting = false;
800 Declined = false;
801 }
802};
803} // end anonymous namespace
804
805bool WebAssemblyRegStackify::runOnMachineFunction(MachineFunction &MF) {
806 LLVM_DEBUG(dbgs() << "********** Register Stackifying **********\n"
807 "********** Function: "
808 << MF.getName() << '\n');
809
810 bool Changed = false;
813 const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
814 const auto *TRI = MF.getSubtarget<WebAssemblySubtarget>().getRegisterInfo();
815 auto &MDT = getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
816 auto &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
817
818 // Walk the instructions from the bottom up. Currently we don't look past
819 // block boundaries, and the blocks aren't ordered so the block visitation
820 // order isn't significant, but we may want to change this in the future.
821 for (MachineBasicBlock &MBB : MF) {
822 // Don't use a range-based for loop, because we modify the list as we're
823 // iterating over it and the end iterator may change.
824 for (auto MII = MBB.rbegin(); MII != MBB.rend(); ++MII) {
825 MachineInstr *Insert = &*MII;
826 // Don't nest anything inside an inline asm, because we don't have
827 // constraints for $push inputs.
828 if (Insert->isInlineAsm())
829 continue;
830
831 // Ignore debugging intrinsics.
832 if (Insert->isDebugValue())
833 continue;
834
835 // Iterate through the inputs in reverse order, since we'll be pulling
836 // operands off the stack in LIFO order.
837 CommutingState Commuting;
838 TreeWalkerState TreeWalker(Insert);
839 while (!TreeWalker.done()) {
840 MachineOperand &Use = TreeWalker.pop();
841
842 // We're only interested in explicit virtual register operands.
843 if (!Use.isReg())
844 continue;
845
846 Register Reg = Use.getReg();
847 assert(Use.isUse() && "explicit_uses() should only iterate over uses");
848 assert(!Use.isImplicit() &&
849 "explicit_uses() should only iterate over explicit operands");
850 if (Reg.isPhysical())
851 continue;
852
853 // Identify the definition for this register at this point.
854 MachineInstr *DefI = getVRegDef(Reg, Insert, MRI, LIS);
855 if (!DefI)
856 continue;
857
858 // Don't nest an INLINE_ASM def into anything, because we don't have
859 // constraints for $pop outputs.
860 if (DefI->isInlineAsm())
861 continue;
862
863 // Argument instructions represent live-in registers and not real
864 // instructions.
866 continue;
867
869 DefI->findRegisterDefOperand(Reg, /*TRI=*/nullptr);
870 assert(Def != nullptr);
871
872 // Decide which strategy to take. Prefer to move a single-use value
873 // over cloning it, and prefer cloning over introducing a tee.
874 // For moving, we require the def to be in the same block as the use;
875 // this makes things simpler (LiveIntervals' handleMove function only
876 // supports intra-block moves) and it's MachineSink's job to catch all
877 // the sinking opportunities anyway.
878 bool SameBlock = DefI->getParent() == &MBB;
879 bool CanMove = SameBlock && isSafeToMove(Def, &Use, Insert, MFI, MRI) &&
880 !TreeWalker.isOnStack(Reg);
881 if (CanMove && hasOneNonDBGUse(Reg, DefI, MRI, MDT, LIS)) {
882 Insert = moveForSingleUse(Reg, Use, DefI, MBB, Insert, LIS, MFI, MRI);
883
884 // If we are removing the frame base reg completely, remove the debug
885 // info as well.
886 // TODO: Encode this properly as a stackified value.
887 if (MFI.isFrameBaseVirtual() && MFI.getFrameBaseVreg() == Reg)
888 MFI.clearFrameBaseVreg();
889 } else if (shouldRematerialize(*DefI, TII)) {
890 Insert =
891 rematerializeCheapDef(Reg, Use, *DefI, MBB, Insert->getIterator(),
892 LIS, MFI, MRI, TII, TRI);
893 } else if (CanMove && oneUseDominatesOtherUses(Reg, Use, MBB, MRI, MDT,
894 LIS, MFI)) {
895 Insert = moveAndTeeForMultiUse(Reg, Use, DefI, MBB, Insert, LIS, MFI,
896 MRI, TII);
897 } else {
898 // We failed to stackify the operand. If the problem was ordering
899 // constraints, Commuting may be able to help.
900 if (!CanMove && SameBlock)
901 Commuting.maybeCommute(Insert, TreeWalker, TII);
902 // Proceed to the next operand.
903 continue;
904 }
905
906 // Stackifying a multivalue def may unlock in-place stackification of
907 // subsequent defs. TODO: Handle the case where the consecutive uses are
908 // not all in the same instruction.
909 auto *SubsequentDef = Insert->defs().begin();
910 auto *SubsequentUse = &Use;
911 while (SubsequentDef != Insert->defs().end() &&
912 SubsequentUse != Use.getParent()->uses().end()) {
913 if (!SubsequentDef->isReg() || !SubsequentUse->isReg())
914 break;
915 Register DefReg = SubsequentDef->getReg();
916 Register UseReg = SubsequentUse->getReg();
917 // TODO: This single-use restriction could be relaxed by using tees
918 if (DefReg != UseReg || !MRI.hasOneNonDBGUse(DefReg))
919 break;
920 MFI.stackifyVReg(MRI, DefReg);
921 ++SubsequentDef;
922 ++SubsequentUse;
923 }
924
925 // If the instruction we just stackified is an IMPLICIT_DEF, convert it
926 // to a constant 0 so that the def is explicit, and the push/pop
927 // correspondence is maintained.
928 if (Insert->getOpcode() == TargetOpcode::IMPLICIT_DEF)
929 convertImplicitDefToConstZero(Insert, MRI, TII, MF, LIS);
930
931 // We stackified an operand. Add the defining instruction's operands to
932 // the worklist stack now to continue to build an ever deeper tree.
933 Commuting.reset();
934 TreeWalker.pushOperands(Insert);
935 }
936
937 // If we stackified any operands, skip over the tree to start looking for
938 // the next instruction we can build a tree on.
939 if (Insert != &*MII) {
940 imposeStackOrdering(&*MII);
942 Changed = true;
943 }
944 }
945 }
946
947 // If we used VALUE_STACK anywhere, add it to the live-in sets everywhere so
948 // that it never looks like a use-before-def.
949 if (Changed) {
950 MF.getRegInfo().addLiveIn(WebAssembly::VALUE_STACK);
951 for (MachineBasicBlock &MBB : MF)
952 MBB.addLiveIn(WebAssembly::VALUE_STACK);
953 }
954
955#ifndef NDEBUG
956 // Verify that pushes and pops are performed in LIFO order.
958 for (MachineBasicBlock &MBB : MF) {
959 for (MachineInstr &MI : MBB) {
960 if (MI.isDebugInstr())
961 continue;
962 for (MachineOperand &MO : reverse(MI.explicit_uses())) {
963 if (!MO.isReg())
964 continue;
965 Register Reg = MO.getReg();
966 if (MFI.isVRegStackified(Reg))
967 assert(Stack.pop_back_val() == Reg &&
968 "Register stack pop should be paired with a push");
969 }
970 for (MachineOperand &MO : MI.defs()) {
971 if (!MO.isReg())
972 continue;
973 Register Reg = MO.getReg();
974 if (MFI.isVRegStackified(Reg))
975 Stack.push_back(MO.getReg());
976 }
977 }
978 // TODO: Generalize this code to support keeping values on the stack across
979 // basic block boundaries.
980 assert(Stack.empty() &&
981 "Register stack pushes and pops should be balanced");
982 }
983#endif
984
985 return Changed;
986}
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock & MBB
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
#define LLVM_DEBUG(...)
Definition: Debug.h:106
static Register UseReg(const MachineOperand &MO)
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:38
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool IsDead
This file contains the declaration of the WebAssembly-specific manager for DebugValues associated wit...
This file provides WebAssembly-specific target descriptions.
This file declares WebAssembly-specific per-machine-function information.
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.
static unsigned getTeeOpcode(const TargetRegisterClass *RC)
Get the appropriate tee opcode for the given register class.
static MachineInstr * getVRegDef(unsigned Reg, const MachineInstr *Insert, const MachineRegisterInfo &MRI, const LiveIntervals &LIS)
static void convertImplicitDefToConstZero(MachineInstr *MI, MachineRegisterInfo &MRI, const TargetInstrInfo *TII, MachineFunction &MF, LiveIntervals &LIS)
static bool hasOneNonDBGUse(unsigned Reg, MachineInstr *Def, MachineRegisterInfo &MRI, MachineDominatorTree &MDT, LiveIntervals &LIS)
static bool isSafeToMove(const MachineOperand *Def, const MachineOperand *Use, const MachineInstr *Insert, const WebAssemblyFunctionInfo &MFI, const MachineRegisterInfo &MRI)
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 ...
static void imposeStackOrdering(MachineInstr *MI)
static void query(const MachineInstr &MI, bool &Read, bool &Write, bool &Effects, bool &StackPointer)
static void shrinkToUses(LiveInterval &LI, LiveIntervals &LIS)
static MachineInstr * getPrevNonDebugInst(MachineInstr *MI)
static bool shouldRematerialize(const MachineInstr &Def, const WebAssemblyInstrInfo *TII)
#define DEBUG_TYPE
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 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's other uses.
static void queryCallee(const MachineInstr &MI, bool &Read, bool &Write, bool &Effects, bool &StackPointer)
This file declares the WebAssembly-specific subclass of TargetSubtarget.
This file contains the declaration of the WebAssembly-specific utility functions.
This file contains the entry points for global functions defined in the LLVM WebAssembly back-end.
Represent the analysis usage information of a pass.
AnalysisUsage & addPreservedID(const void *ID)
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:256
This is an important base class in LLVM.
Definition: Constant.h:42
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Definition: Constants.cpp:373
This class represents an Operation in the Expression.
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:310
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition: Function.cpp:369
LiveInterval - This class represents the liveness of a register, or stack slot.
Definition: LiveInterval.h:687
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction associated with the given index.
SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)
void handleMove(MachineInstr &MI, bool UpdateFlags=false)
Call this method to notify LiveIntervals that instruction MI has been moved within a basic block.
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
void RemoveMachineInstrFromMaps(MachineInstr &MI)
LiveInterval & getInterval(Register Reg)
void removeInterval(Register Reg)
Interval removal.
bool shrinkToUses(LiveInterval *li, SmallVectorImpl< MachineInstr * > *dead=nullptr)
After removing some uses of a register, shrink its live range to just the remaining uses.
void removePhysRegDefAt(MCRegister Reg, SlotIndex Pos)
Remove value numbers and related live segments starting at position Pos that are part of any liverang...
void splitSeparateComponents(LiveInterval &LI, SmallVectorImpl< LiveInterval * > &SplitLIs)
Split separate components in LiveInterval LI into separate intervals.
LiveInterval & createAndComputeVirtRegInterval(Register Reg)
bool liveAt(SlotIndex index) const
Definition: LiveInterval.h:401
LiveQueryResult Query(SlotIndex Idx) const
Query Liveness at Idx.
Definition: LiveInterval.h:542
VNInfo * getVNInfoBefore(SlotIndex Idx) const
getVNInfoBefore - Return the VNInfo that is live up to but not necessarily including Idx,...
Definition: LiveInterval.h:429
iterator FindSegmentContaining(SlotIndex Idx)
Return an iterator to the segment that contains the specified index, or end() if there is none.
Definition: LiveInterval.h:436
void removeSegment(SlotIndex Start, SlotIndex End, bool RemoveDeadValNo=false)
Remove the specified interval from this live range.
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
Definition: LiveInterval.h:421
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
Definition: MCInstrDesc.h:248
static MCRegister from(unsigned Val)
Check the provided unsigned value is a valid MCRegister.
Definition: MCRegister.h:74
reverse_iterator rend()
Instructions::iterator instr_iterator
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
reverse_iterator rbegin()
MachineInstrBundleIterator< MachineInstr > iterator
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool dominates(const MachineInstr *A, const MachineInstr *B) const
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
reverse_iterator getReverse() const
Get a reverse iterator to the same node.
Representation of each machine instruction.
Definition: MachineInstr.h:69
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:575
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:347
bool isInlineAsm() const
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
Definition: MachineInstr.h:572
iterator_range< mop_iterator > operands()
Definition: MachineInstr.h:691
iterator_range< mop_iterator > defs()
Returns a range over all explicit operands that are register definitions.
Definition: MachineInstr.h:728
MachineOperand * mop_iterator
iterator/begin/end - Iterate over all operands of a machine instruction.
Definition: MachineInstr.h:682
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:585
MachineOperand * findRegisterDefOperand(Register Reg, const TargetRegisterInfo *TRI, bool isDead=false, bool Overlap=false)
Wrapper for findRegisterDefOperandIdx, it returns a pointer to the MachineOperand rather than an inde...
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
static MachineOperand CreateFPImm(const ConstantFP *CFP)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
static MachineOperand CreateImm(int64_t Val)
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateReg(Register 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)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Definition: Pass.cpp:81
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:91
SlotIndex - An opaque wrapper around machine indexes.
Definition: SlotIndexes.h:65
SlotIndex getDeadSlot() const
Returns the dead def kill slot for the current instruction.
Definition: SlotIndexes.h:242
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:237
bool empty() const
Definition: SmallVector.h:81
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
TargetInstrInfo - Interface to description of machine instruction set.
static const unsigned CommuteAnyOperandIndex
static Type * getDoubleTy(LLVMContext &C)
static Type * getFloatTy(LLVMContext &C)
A Use represents the edge between a Value definition and its users.
Definition: Use.h:43
VNInfo - Value Number Information.
Definition: LiveInterval.h:53
SlotIndex def
The index of the defining instruction.
Definition: LiveInterval.h:61
iterator_range< use_iterator > uses()
Definition: Value.h:376
void cloneSink(MachineInstr *Insert, Register NewReg=Register(), bool CloneDef=true) const
This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...
void stackifyVReg(MachineRegisterInfo &MRI, unsigned VReg)
A range adaptor for a pair of iterators.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
@ Define
Register definition.
bool isArgument(unsigned Opc)
const MachineOperand & getCalleeOp(const MachineInstr &MI)
Returns the operand number of a callee, assuming the argument is a call instruction.
bool isCatch(unsigned Opc)
Reg
All possible values of the reg field in the ModR/M byte.
NodeAddr< InstrNode * > Instr
Definition: RDFGraph.h:389
NodeAddr< DefNode * > Def
Definition: RDFGraph.h:384
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:329
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
@ Read
Definition: CodeGenData.h:107
@ Write
Definition: CodeGenData.h:108
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:420
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
unsigned getUndefRegState(bool B)
DWARFExpression::Operation Op
char & LiveVariablesID
LiveVariables pass - This pass computes the set of blocks in which each variable is life and sets mac...
FunctionPass * createWebAssemblyRegStackify()