44#define DEBUG_TYPE "wasm-reg-stackify"
51 return "WebAssembly Register Stackify";
71 WebAssemblyRegStackifyLegacy()
76char WebAssemblyRegStackifyLegacy::ID = 0;
78 "Reorder instructions to use the WebAssembly value stack",
83 return new WebAssemblyRegStackifyLegacy(OptLevel);
91 if (!
MI->definesRegister(WebAssembly::VALUE_STACK,
nullptr))
97 if (!
MI->readsRegister(WebAssembly::VALUE_STACK,
nullptr))
109 assert(
MI->getOpcode() == TargetOpcode::IMPLICIT_DEF);
111 const auto *RegClass = MRI.
getRegClass(
MI->getOperand(0).getReg());
112 if (RegClass == &WebAssembly::I32RegClass) {
113 MI->setDesc(
TII->get(WebAssembly::CONST_I32));
115 }
else if (RegClass == &WebAssembly::I64RegClass) {
116 MI->setDesc(
TII->get(WebAssembly::CONST_I64));
118 }
else if (RegClass == &WebAssembly::F32RegClass) {
119 MI->setDesc(
TII->get(WebAssembly::CONST_F32));
123 }
else if (RegClass == &WebAssembly::F64RegClass) {
124 MI->setDesc(
TII->get(WebAssembly::CONST_F64));
128 }
else if (RegClass == &WebAssembly::V128RegClass) {
129 MI->setDesc(
TII->get(WebAssembly::CONST_V128_I64x2));
141 bool &Effects,
bool &StackPointer) {
149 if (!GA->isInterposable())
150 GV = GA->getAliasee();
153 if (!
F->doesNotThrow())
155 if (
F->doesNotAccessMemory())
157 if (
F->onlyReadsMemory()) {
173 bool &Effects,
bool &StackPointer) {
176 if (
MI.isDebugInstr() ||
MI.isPosition())
180 if (
MI.mayLoad() && !
MI.isDereferenceableInvariantLoad())
186 }
else if (
MI.hasOrderedMemoryRef()) {
187 switch (
MI.getOpcode()) {
188 case WebAssembly::DIV_S_I32:
189 case WebAssembly::DIV_S_I64:
190 case WebAssembly::REM_S_I32:
191 case WebAssembly::REM_S_I64:
192 case WebAssembly::DIV_U_I32:
193 case WebAssembly::DIV_U_I64:
194 case WebAssembly::REM_U_I32:
195 case WebAssembly::REM_U_I64:
196 case WebAssembly::I32_TRUNC_S_F32:
197 case WebAssembly::I64_TRUNC_S_F32:
198 case WebAssembly::I32_TRUNC_S_F64:
199 case WebAssembly::I64_TRUNC_S_F64:
200 case WebAssembly::I32_TRUNC_U_F32:
201 case WebAssembly::I64_TRUNC_U_F32:
202 case WebAssembly::I32_TRUNC_U_F64:
203 case WebAssembly::I64_TRUNC_U_F64:
221 if (
MI.hasUnmodeledSideEffects()) {
222 switch (
MI.getOpcode()) {
223 case WebAssembly::DIV_S_I32:
224 case WebAssembly::DIV_S_I64:
225 case WebAssembly::REM_S_I32:
226 case WebAssembly::REM_S_I64:
227 case WebAssembly::DIV_U_I32:
228 case WebAssembly::DIV_U_I64:
229 case WebAssembly::REM_U_I32:
230 case WebAssembly::REM_U_I64:
231 case WebAssembly::I32_TRUNC_S_F32:
232 case WebAssembly::I64_TRUNC_S_F32:
233 case WebAssembly::I32_TRUNC_S_F64:
234 case WebAssembly::I64_TRUNC_S_F64:
235 case WebAssembly::I32_TRUNC_U_F32:
236 case WebAssembly::I64_TRUNC_U_F32:
237 case WebAssembly::I32_TRUNC_U_F64:
238 case WebAssembly::I64_TRUNC_U_F64:
251 if ((
MI.getOpcode() == WebAssembly::GLOBAL_SET_I32 ||
252 MI.getOpcode() == WebAssembly::GLOBAL_SET_I64) &&
253 MI.getOperand(0).isSymbol() &&
254 !strcmp(
MI.getOperand(0).getSymbolName(),
"__stack_pointer"))
257 if (
MI.isCall() &&
MI.getOperand(0).isSymbol() &&
258 !strcmp(
MI.getOperand(0).getSymbolName(),
"__wasm_get_stack_pointer"))
270 return Def.isAsCheapAsAMove() &&
TII->isTriviallyReMaterializable(Def);
284 if (LIS !=
nullptr) {
301 if (MFI.isFrameBaseVirtual() && MFI.getFrameBaseVreg() ==
Reg) {
307 bool NeedsRegForDebug =
336 if (Result.valueIn() == DefVNI) {
337 if (!Result.isKill())
358 assert(
Use->getParent()->getParent() == Insert->getParent());
373 for (
auto E =
MBB->end(); NextI !=
E && NextI->isDebugInstr(); ++NextI)
392 if (!MO.isReg() || MO.isUndef())
397 if (MO.isDead() && Insert->definesRegister(
Reg,
nullptr) &&
398 !Insert->readsRegister(
Reg,
nullptr))
401 if (
Reg.isPhysical()) {
404 if (
Reg == WebAssembly::ARGUMENTS)
420 bool Read =
false,
Write =
false, Effects =
false, StackPointer =
false;
425 bool HasMutableRegisters = !MutableRegisters.
empty();
426 if (!
Read && !
Write && !Effects && !StackPointer && !HasMutableRegisters)
431 for (--
I;
I !=
D; --
I) {
432 bool InterveningRead =
false;
433 bool InterveningWrite =
false;
434 bool InterveningEffects =
false;
435 bool InterveningStackPointer =
false;
436 query(*
I, InterveningRead, InterveningWrite, InterveningEffects,
437 InterveningStackPointer);
438 if (Effects && InterveningEffects)
440 if (
Read && InterveningWrite)
442 if (
Write && (InterveningRead || InterveningWrite))
444 if (StackPointer && InterveningStackPointer)
447 for (
unsigned Reg : MutableRegisters)
449 if (MO.isReg() && MO.isDef() && MO.getReg() ==
Reg)
472 if (OneUseInst == UseI)
484 if (UseVNI != OneUseVNI)
487 if (UseInst == OneUseInst) {
494 while (!OneUseDominates(UseInst)) {
511 if (NewUseInst == OneUseInst) {
512 if (&OneUse > &NewUse)
516 UseInst = NewUseInst;
525 if (RC == &WebAssembly::I32RegClass)
526 return WebAssembly::TEE_I32;
527 if (RC == &WebAssembly::I64RegClass)
528 return WebAssembly::TEE_I64;
529 if (RC == &WebAssembly::F32RegClass)
530 return WebAssembly::TEE_F32;
531 if (RC == &WebAssembly::F64RegClass)
532 return WebAssembly::TEE_F64;
533 if (RC == &WebAssembly::V128RegClass)
534 return WebAssembly::TEE_V128;
535 if (RC == &WebAssembly::EXTERNREFRegClass)
536 return WebAssembly::TEE_EXTERNREF;
537 if (RC == &WebAssembly::FUNCREFRegClass)
538 return WebAssembly::TEE_FUNCREF;
539 if (RC == &WebAssembly::EXNREFRegClass)
540 return WebAssembly::TEE_EXNREF;
577 if (LIS !=
nullptr) {
597 for (
auto *
I =
MI->getPrevNode();
I;
I =
I->getPrevNode())
598 if (!
I->isDebugInstr())
725class TreeWalkerState {
727 using mop_reverse_iterator = std::reverse_iterator<mop_iterator>;
728 using RangeTy = iterator_range<mop_reverse_iterator>;
732 explicit TreeWalkerState(MachineInstr *Insert) {
733 const iterator_range<mop_iterator> &
Range =
Insert->explicit_uses();
738 bool done()
const {
return Worklist.empty(); }
740 MachineOperand &pop() {
741 RangeTy &
Range = Worklist.back();
742 MachineOperand &
Op = *
Range.begin();
746 assert((Worklist.empty() || !Worklist.back().empty()) &&
747 "Empty ranges shouldn't remain in the worklist");
752 void pushOperands(MachineInstr *Instr) {
753 const iterator_range<mop_iterator> &
Range(
Instr->explicit_uses());
760 void resetTopOperands(MachineInstr *Instr) {
761 assert(hasRemainingOperands(Instr) &&
762 "Resetting operands should only be done when the instruction has "
763 "an operand still on the stack");
769 bool hasRemainingOperands(
const MachineInstr *Instr)
const {
770 if (Worklist.empty())
772 const RangeTy &
Range = Worklist.back();
782 bool isOnStack(
unsigned Reg)
const {
783 for (
const RangeTy &
Range : Worklist)
784 for (
const MachineOperand &MO :
Range)
785 if (MO.isReg() && MO.getReg() ==
Reg)
793class CommutingState {
799 bool TentativelyCommuting =
false;
800 bool Declined =
false;
804 unsigned Operand0, Operand1;
810 void maybeCommute(MachineInstr *Insert, TreeWalkerState &TreeWalker,
811 const WebAssemblyInstrInfo *
TII) {
812 if (TentativelyCommuting) {
814 "Don't decline commuting until you've finished trying it");
816 TII->commuteInstruction(*Insert,
false, Operand0, Operand1);
817 TentativelyCommuting =
false;
819 }
else if (!Declined && TreeWalker.hasRemainingOperands(Insert)) {
822 if (
TII->findCommutedOpIndices(*Insert, Operand0, Operand1)) {
824 TII->commuteInstruction(*Insert,
false, Operand0, Operand1);
825 TreeWalker.resetTopOperands(Insert);
826 TentativelyCommuting =
true;
835 TentativelyCommuting =
false;
843 LLVM_DEBUG(
dbgs() <<
"********** Register Stackifying **********\n"
844 "********** Function: "
852 assert(MDT &&
"expected MDT to be available");
853 assert(LIS &&
"expected LIS to be available");
862 for (
auto MII =
MBB.rbegin(); MII !=
MBB.rend(); ++MII) {
866 if (Insert->isInlineAsm())
870 if (Insert->isDebugValue())
874 if (Insert->isFakeUse())
879 CommutingState Commuting;
880 TreeWalkerState TreeWalker(Insert);
881 while (!TreeWalker.done()) {
889 assert(
Use.isUse() &&
"explicit_uses() should only iterate over uses");
891 "explicit_uses() should only iterate over explicit operands");
892 if (
Reg.isPhysical())
921 bool CanMove = SameBlock &&
923 !TreeWalker.isOnStack(
Reg);
933 "Stackifying away frame base in unoptimized code not expected");
938 *LIS, MFI, MRI,
TII);
947 if (!CanMove && SameBlock)
948 Commuting.maybeCommute(Insert, TreeWalker,
TII);
956 auto *SubsequentDef = Insert->defs().begin();
957 auto *SubsequentUse = &
Use;
958 while (SubsequentDef != Insert->defs().end() &&
959 SubsequentUse !=
Use.getParent()->
uses().end()) {
960 if (!SubsequentDef->isReg() || !SubsequentUse->isReg())
962 Register DefReg = SubsequentDef->getReg();
976 if (Insert->getOpcode() == TargetOpcode::IMPLICIT_DEF)
982 TreeWalker.pushOperands(Insert);
987 if (Insert != &*MII) {
1000 MBB.addLiveIn(WebAssembly::VALUE_STACK);
1008 if (
MI.isDebugInstr())
1016 "Register stack pop should be paired with a push");
1023 Stack.push_back(MO.getReg());
1029 "Register stack pushes and pops should be balanced");
1036bool WebAssemblyRegStackifyLegacy::runOnMachineFunction(
MachineFunction &MF) {
1037 MachineDominatorTree *MDT =
nullptr;
1038 LiveIntervals *LIS =
nullptr;
1040 MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
1041 LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
1060 .preserve<LiveIntervalsAnalysis>()
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static Register UseReg(const MachineOperand &MO)
const HexagonInstrInfo * TII
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
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 bool isSafeToMove(const MachineOperand *Def, const MachineOperand *Use, const MachineInstr *Insert, const WebAssemblyFunctionInfo &MFI, const MachineRegisterInfo &MRI, bool Optimize)
static unsigned getTeeOpcode(const TargetRegisterClass *RC)
Get the appropriate tee opcode for the given register class.
static MachineInstr * rematerializeCheapDef(unsigned Reg, MachineOperand &Op, MachineInstr &Def, MachineBasicBlock::instr_iterator Insert, LiveIntervals &LIS, WebAssemblyFunctionInfo &MFI, MachineRegisterInfo &MRI, const WebAssemblyInstrInfo *TII)
A trivially cloneable instruction; clone it and nest the new copy with the current instruction.
static bool hasSingleUse(unsigned Reg, MachineRegisterInfo &MRI, const MachineFunction &MF, bool Optimize, MachineInstr *Def, LiveIntervals *LIS)
static bool regStackify(MachineFunction &MF, bool Optimize, MachineDominatorTree *MDT, LiveIntervals *LIS)
static void imposeStackOrdering(MachineInstr *MI)
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 query(const MachineInstr &MI, bool &Read, bool &Write, bool &Effects, bool &StackPointer)
static void shrinkToUses(LiveInterval &LI, LiveIntervals &LIS)
static void convertImplicitDefToConstZero(MachineInstr *MI, MachineRegisterInfo &MRI, const TargetInstrInfo *TII, MachineFunction &MF)
static MachineInstr * getPrevNonDebugInst(MachineInstr *MI)
static bool shouldRematerialize(const MachineInstr &Def, const WebAssemblyInstrInfo *TII)
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.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Represents analyses that only rely on functions' control flow.
This is an important base class in LLVM.
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
FunctionPass class - This class is used to implement most global optimizations.
DISubprogram * getSubprogram() const
Get the attached subprogram.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
LiveInterval - This class represents the liveness of a register, or stack slot.
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction associated with the given index.
SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)
LLVM_ABI 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.
LLVM_ABI bool shrinkToUses(LiveInterval *li, SmallVectorImpl< MachineInstr * > *dead=nullptr)
After removing some uses of a register, shrink its live range to just the remaining uses.
LLVM_ABI void removePhysRegDefAt(MCRegister Reg, SlotIndex Pos)
Remove value numbers and related live segments starting at position Pos that are part of any liverang...
LLVM_ABI void splitSeparateComponents(LiveInterval &LI, SmallVectorImpl< LiveInterval * > &SplitLIs)
Split separate components in LiveInterval LI into separate intervals.
LiveInterval & createAndComputeVirtRegInterval(Register Reg)
Segments::iterator iterator
bool liveAt(SlotIndex index) const
LiveQueryResult Query(SlotIndex Idx) const
Query Liveness at Idx.
VNInfo * getVNInfoBefore(SlotIndex Idx) const
getVNInfoBefore - Return the VNInfo that is live up to but not necessarily including Idx,...
iterator FindSegmentContaining(SlotIndex Idx)
Return an iterator to the segment that contains the specified index, or end() if there is none.
LLVM_ABI 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.
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
static MCRegister from(unsigned Val)
Check the provided unsigned value is a valid MCRegister.
MachineInstrBundleIterator< const MachineInstr > const_iterator
Instructions::iterator instr_iterator
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineInstrBundleIterator< MachineInstr > iterator
Analysis pass which computes a MachineDominatorTree.
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.
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, RegState Flags={}, 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.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
LLVM_ABI unsigned getNumExplicitDefs() const
Returns the number of non-implicit definitions.
MachineOperand * mop_iterator
iterator/begin/end - Iterate over all operands of a machine instruction.
LLVM_ABI void dump() const
const MachineOperand & getOperand(unsigned i) const
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,...
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
use_nodbg_iterator use_nodbg_begin(Register RegNo) const
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
iterator_range< use_nodbg_iterator > use_nodbg_operands(Register Reg) const
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool hasOneUse(Register RegNo) const
hasOneUse - Return true if there is exactly one instruction using the specified register.
bool hasOneDef(Register RegNo) const
Return true if there is exactly one operand defining the specified register.
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
bool use_empty(Register RegNo) const
use_empty - Return true if there are no instructions using the specified register.
LLVM_ABI bool isPhysRegModified(MCRegister PhysReg, bool SkipNoReturnDef=false) const
Return true if the specified register is modified in this function.
LLVM_ABI LLVM_READONLY MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
SlotIndex - An opaque wrapper around machine indexes.
SlotIndex getDeadSlot() const
Returns the dead def kill slot for the current instruction.
static bool isEarlierInstr(SlotIndex A, SlotIndex B)
isEarlierInstr - Return true if A refers to an instruction earlier than B.
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
TargetInstrInfo - Interface to description of machine instruction set.
static const unsigned CommuteAnyOperandIndex
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
A Use represents the edge between a Value definition and its users.
VNInfo - Value Number Information.
SlotIndex def
The index of the defining instruction.
iterator_range< use_iterator > uses()
void updateReg(Register Reg)
void cloneSink(MachineInstr *Insert, Register NewReg=Register(), bool CloneDef=true) const
void sink(MachineInstr *Insert)
This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...
void stackifyVReg(MachineRegisterInfo &MRI, Register VReg)
unsigned getFrameBaseVreg() const
bool isVRegStackified(Register VReg) const
void clearFrameBaseVreg()
bool isFrameBaseVirtual() const
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
Pass manager infrastructure for declaring and invalidating analyses.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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)
NodeAddr< InstrNode * > Instr
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
@ Define
Register definition.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
CodeGenOptLevel
Code generation optimization level.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
FunctionPass * createWebAssemblyRegStackifyLegacyPass(CodeGenOptLevel OptLevel)
MachineInstr * getVRegDef(MachineRegisterInfo &MRI, Register Reg)
constexpr RegState getUndefRegState(bool B)
MCRegisterClass TargetRegisterClass