40#define DEBUG_TYPE "riscv-vector-peephole"
44class RISCVVectorPeepholeImpl {
69 lookThruCopies(
Register Reg,
bool OneUseOnly =
false,
85 return "RISC-V Vector Peephole Optimization";
97char RISCVVectorPeepholeLegacy::ID = 0;
106 unsigned UserLog2SEW =
108 unsigned SrcLog2SEW =
112 return SrcLog2EEW == UserLog2SEW;
116std::optional<unsigned>
117RISCVVectorPeepholeImpl::getConstant(
const MachineOperand &VL)
const {
124 if (!Def ||
Def->getOpcode() != RISCV::ADDI || !
Def->getOperand(1).isReg() ||
125 Def->getOperand(1).getReg() != RISCV::X0)
127 return Def->getOperand(2).getImm();
131bool RISCVVectorPeepholeImpl::convertToVLMAX(MachineInstr &
MI)
const {
138 unsigned LMULFixed = LMUL.second ? (8 / LMUL.first) : 8 * LMUL.first;
141 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8;
143 assert(8 * LMULFixed / SEW > 0);
148 VLen && AVL && (*VLen * LMULFixed) / SEW == *AVL * 8) {
164 if (
Def->getOpcode() == RISCV::SLLI) {
165 assert(
Def->getOperand(2).getImm() < 64);
166 ScaleFixed <<=
Def->getOperand(2).getImm();
168 }
else if (
Def->getOpcode() == RISCV::SRLI) {
169 assert(
Def->getOperand(2).getImm() < 64);
170 ScaleFixed >>=
Def->getOperand(2).getImm();
174 if (!Def ||
Def->getOpcode() != RISCV::PseudoReadVLENB)
184 if (ScaleFixed != 8 * LMULFixed / SEW)
192bool RISCVVectorPeepholeImpl::isAllOnesMask(
const MachineInstr *MaskDef)
const {
200 case RISCV::PseudoVMSET_M_B1:
201 case RISCV::PseudoVMSET_M_B2:
202 case RISCV::PseudoVMSET_M_B4:
203 case RISCV::PseudoVMSET_M_B8:
204 case RISCV::PseudoVMSET_M_B16:
205 case RISCV::PseudoVMSET_M_B32:
206 case RISCV::PseudoVMSET_M_B64:
223bool RISCVVectorPeepholeImpl::convertToWholeRegister(MachineInstr &
MI)
const {
224#define CASE_WHOLE_REGISTER_LMUL_SEW(lmul, sew) \
225 case RISCV::PseudoVLE##sew##_V_M##lmul: \
226 NewOpc = RISCV::VL##lmul##RE##sew##_V; \
228 case RISCV::PseudoVSE##sew##_V_M##lmul: \
229 NewOpc = RISCV::VS##lmul##R_V; \
231#define CASE_WHOLE_REGISTER_LMUL(lmul) \
232 CASE_WHOLE_REGISTER_LMUL_SEW(lmul, 8) \
233 CASE_WHOLE_REGISTER_LMUL_SEW(lmul, 16) \
234 CASE_WHOLE_REGISTER_LMUL_SEW(lmul, 32) \
235 CASE_WHOLE_REGISTER_LMUL_SEW(lmul, 64)
238 switch (
MI.getOpcode()) {
247 MachineOperand &VLOp =
MI.getOperand(RISCVII::getVLOpNum(
MI.getDesc()));
248 if (!VLOp.isImm() || VLOp.
getImm() != RISCV::VLMaxSentinel)
253 if (RISCVII::hasVecPolicyOp(
MI.getDesc().TSFlags))
254 MI.removeOperand(RISCVII::getVecPolicyOpNum(
MI.getDesc()));
255 MI.removeOperand(RISCVII::getSEWOpNum(
MI.getDesc()));
256 MI.removeOperand(RISCVII::getVLOpNum(
MI.getDesc()));
257 if (RISCVII::isFirstDefTiedToFirstUse(
MI.getDesc()))
265static
unsigned getVMV_V_VOpcodeForVMERGE_VVM(
const MachineInstr &
MI) {
266#define CASE_VMERGE_TO_VMV(lmul) \
267 case RISCV::PseudoVMERGE_VVM_##lmul: \
268 return RISCV::PseudoVMV_V_V_##lmul;
269 switch (
MI.getOpcode()) {
272 CASE_VMERGE_TO_VMV(MF8)
273 CASE_VMERGE_TO_VMV(MF4)
274 CASE_VMERGE_TO_VMV(MF2)
275 CASE_VMERGE_TO_VMV(M1)
276 CASE_VMERGE_TO_VMV(M2)
277 CASE_VMERGE_TO_VMV(M4)
278 CASE_VMERGE_TO_VMV(M8)
287bool RISCVVectorPeepholeImpl::convertAllOnesVMergeToVMv(
288 MachineInstr &
MI)
const {
289 unsigned NewOpc = getVMV_V_VOpcodeForVMERGE_VVM(
MI);
292 if (!isAllOnesMask(MRI->
getVRegDef(
MI.getOperand(4).getReg())))
295 MI.setDesc(
TII->get(NewOpc));
304 if (
MI.getOperand(1).getReg().isValid())
311Register RISCVVectorPeepholeImpl::lookThruCopies(
313 SmallVectorImpl<MachineInstr *> *
Copies)
const {
315 if (!
Def->isFullCopy())
318 if (!Src.isVirtual())
338bool RISCVVectorPeepholeImpl::convertSameMaskVMergeToVMv(MachineInstr &
MI) {
339 unsigned NewOpc = getVMV_V_VOpcodeForVMERGE_VVM(
MI);
342 MachineInstr *True = MRI->
getVRegDef(
MI.getOperand(3).getReg());
347 auto *TrueMaskedInfo = RISCV::getMaskedPseudoInfo(True->
getOpcode());
348 if (!TrueMaskedInfo || !hasSameEEW(
MI, *True))
351 Register TrueMaskReg = lookThruCopies(
354 Register MIMaskReg = lookThruCopies(
MI.getOperand(4).getReg());
355 if (!TrueMaskReg.
isVirtual() || TrueMaskReg != MIMaskReg)
363 const MachineOperand &TrueVL =
365 Register FalseReg =
MI.getOperand(2).getReg();
367 Register PassthruReg =
MI.getOperand(1).getReg();
368 if (FalseReg.
isValid() && FalseReg != PassthruReg)
380 if (TruePassthruReg != FalseReg) {
382 if (TruePassthruReg.
isValid() ||
384 !ensureDominates(&
MI.getOperand(2), *True))
394 MachineOperand &PolicyOp =
399 MI.setDesc(
TII->get(NewOpc));
408 if (
MI.getOperand(1).getReg().isValid())
413bool RISCVVectorPeepholeImpl::convertToUnmasked(MachineInstr &
MI)
const {
414 const RISCV::RISCVMaskedPseudoInfo *
I =
415 RISCV::getMaskedPseudoInfo(
MI.getOpcode());
420 MI.getOperand(
I->MaskOpIdx +
MI.getNumExplicitDefs()).getReg())))
425 const unsigned Opc =
I->UnmaskedPseudo;
426 const MCInstrDesc &MCID =
TII->get(
Opc);
427 [[maybe_unused]]
const bool HasPolicyOp =
430 const MCInstrDesc &MaskedMCID =
TII->get(
MI.getOpcode());
433 "Unmasked pseudo has policy but masked pseudo doesn't?");
434 assert(HasPolicyOp == HasPassthru &&
"Unexpected pseudo structure");
436 "Unmasked with passthru but masked with no passthru?");
447 unsigned MaskOpIdx =
I->MaskOpIdx +
MI.getNumExplicitDefs();
448 MI.removeOperand(MaskOpIdx);
456 unsigned PassthruOpIdx =
MI.getNumExplicitDefs();
458 if (
MI.getOperand(PassthruOpIdx).getReg())
461 MI.removeOperand(PassthruOpIdx);
470 assert(
A->getParent() ==
B->getParent());
474 auto MBBEnd =
MBB->end();
479 for (; &*
I !=
A && &*
I !=
B; ++
I)
488bool RISCVVectorPeepholeImpl::ensureDominates(
490 MachineInstr *Dest = &
Use;
492 for (
const MachineOperand *MO : Defs) {
493 assert(MO->getParent()->getParent() ==
Use.getParent());
494 if (!MO->isReg() || !MO->getReg().isValid())
502 Dest =
Def->getNextNode();
507 Use.moveBefore(Dest);
513bool RISCVVectorPeepholeImpl::foldUndefPassthruVMV_V_V(MachineInstr &
MI) {
516 if (
MI.getOperand(1).getReg().isValid())
521 MachineInstr *Src = MRI->
getVRegDef(
MI.getOperand(2).getReg());
522 if (Src && !Src->hasUnmodeledSideEffects() &&
526 const MachineOperand &MIVL =
MI.getOperand(3);
527 const MachineOperand &SrcVL =
530 MachineOperand &SrcPolicy =
541 MI.eraseFromParent();
555bool RISCVVectorPeepholeImpl::foldVMV_V_V(MachineInstr &
MI) {
559 MachineOperand &Passthru =
MI.getOperand(1);
564 MachineInstr *Src = MRI->
getVRegDef(
MI.getOperand(2).getReg());
565 if (!Src || Src->hasUnmodeledSideEffects() ||
566 Src->getParent() !=
MI.getParent() ||
572 if (!hasSameEEW(
MI, *Src))
575 std::optional<std::pair<unsigned, unsigned>> NeedsCommute;
578 MachineOperand &SrcPassthru = Src->getOperand(Src->getNumExplicitDefs());
583 int OtherIdx = Src->findRegisterUseOperandIdx(Passthru.
getReg(),
TRI);
586 unsigned OpIdx1 = OtherIdx;
587 unsigned OpIdx2 = Src->getNumExplicitDefs();
588 if (!
TII->findCommutedOpIndices(*Src, OpIdx1, OpIdx2))
590 NeedsCommute = {OpIdx1, OpIdx2};
601 if (!ensureDominates(&Passthru, *Src))
605 auto [OpIdx1, OpIdx2] = *NeedsCommute;
606 [[maybe_unused]]
bool Commuted =
607 TII->commuteInstruction(*Src,
false, OpIdx1, OpIdx2);
608 assert(Commuted &&
"Failed to commute Src?");
631 MRI->
replaceRegWith(
MI.getOperand(0).getReg(), Src->getOperand(0).getReg());
632 MI.eraseFromParent();
655bool RISCVVectorPeepholeImpl::foldVMergeToMask(MachineInstr &
MI)
const {
660 SmallVector<MachineInstr *, 4> TrueCopies;
661 Register PassthruReg = lookThruCopies(
MI.getOperand(1).getReg());
662 const MachineOperand &FalseOp =
MI.getOperand(2);
664 Register TrueReg = lookThruCopies(
MI.getOperand(3).getReg(),
668 MachineInstr *TrueDef = MRI->
getVRegDef(TrueReg);
671 MachineInstr &True = *TrueDef;
678 const RISCV::RISCVMaskedPseudoInfo *
Info =
679 RISCV::lookupMaskedIntrinsicByUnmasked(True.
getOpcode());
684 if (!hasSameEEW(
MI, True))
689 if (PassthruReg && !(PassthruReg.
isVirtual() && PassthruReg == FalseReg))
692 std::optional<std::pair<unsigned, unsigned>> NeedsCommute;
700 if (TruePassthru && !(TruePassthru.
isVirtual() && TruePassthru == FalseReg)) {
706 unsigned OpIdx1 = OtherIdx;
708 if (!
TII->findCommutedOpIndices(True, OpIdx1, OpIdx2))
710 NeedsCommute = {OpIdx1, OpIdx2};
718 const MachineOperand &VMergeVL =
720 const MachineOperand &TrueVL =
734 unsigned RVVTSFlags =
753 "Foldable unmasked pseudo should have a policy op already");
757 if (!ensureDominates({&MaskOp, &FalseOp, &MinVL}, True))
761 auto [OpIdx1, OpIdx2] = *NeedsCommute;
762 [[maybe_unused]]
bool Commuted =
763 TII->commuteInstruction(True,
false, OpIdx1, OpIdx2);
764 assert(Commuted &&
"Failed to commute True?");
765 Info = RISCV::lookupMaskedIntrinsicByUnmasked(True.
getOpcode());
786 if (!MO.isReg() || !MO.getReg().isVirtual())
793 MI.eraseFromParent();
797 for (MachineInstr *TrueCopy : TrueCopies)
798 TrueCopy->eraseFromParent();
819bool RISCVVectorPeepholeImpl::foldVMANDToMaskedCompare(MachineInstr &
MI)
const {
833 for (
unsigned CmpIdx : {1, 2}) {
834 unsigned MaskIdx = CmpIdx == 1 ? 2 : 1;
838 SmallVector<MachineInstr *, 4> CmpCopies;
839 Register CmpReg = lookThruCopies(
MI.getOperand(CmpIdx).getReg(),
844 if (
Cmp.getParent() !=
MI.getParent())
846 if (!RISCVInstrInfo::isRVVCompare(Cmp))
850 const RISCV::RISCVMaskedPseudoInfo *
Info =
851 RISCV::lookupMaskedIntrinsicByUnmasked(
Cmp.getOpcode());
856 if (!hasSameEEW(
MI, Cmp))
861 if (
Cmp.hasUnmodeledSideEffects() ||
Cmp.mayRaiseFPException())
868 const MachineOperand &CmpVL =
870 const MachineOperand &MIVL =
875 const MachineOperand &MaskOp =
MI.getOperand(MaskIdx);
878 unsigned MaskedOpc =
Info->MaskedPseudo;
879 const MCInstrDesc &MaskedDesc =
TII->get(MaskedOpc);
889 if (!
TII->getRegClass(MaskedDesc, 0)->contains(RISCV::V0))
893 if (!ensureDominates({&MaskOp, &MIVL},
Cmp))
902 TII->get(TargetOpcode::COPY), MaskV0Reg)
908 TII->get(TargetOpcode::COPY), PassthruReg)
918 BuildMI(*
MI.getParent(), Cmp, MIMetadata(Cmp), MaskedDesc, DestReg)
933 for (MachineOperand &MO :
Masked->explicit_operands()) {
934 if (!MO.isReg() || !MO.getReg().isVirtual())
937 Masked->getRegClassConstraint(MO.getOperandNo(),
TII,
TRI))
941 MI.eraseFromParent();
942 Cmp.eraseFromParent();
943 for (MachineInstr *CmpCopy : CmpCopies)
944 CmpCopy->eraseFromParent();
964 for (MachineBasicBlock &
MBB : MF) {
975 Changed |= convertAllOnesVMergeToVMv(
MI);
976 Changed |= convertSameMaskVMergeToVMv(
MI);
977 if (foldUndefPassthruVMV_V_V(
MI)) {
988bool RISCVVectorPeepholeLegacy::runOnMachineFunction(
MachineFunction &MF) {
991 return RISCVVectorPeepholeImpl().run(MF);
998 bool Changed = RISCVVectorPeepholeImpl().run(MF);
1009 return new RISCVVectorPeepholeLegacy();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static uint64_t getConstant(const Value *IndexValue)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static bool strictlyDominates(MachineBasicBlock::const_iterator A, MachineBasicBlock::const_iterator B)
Given A and B are in the same MBB, returns true if A comes before B.
#define CASE_WHOLE_REGISTER_LMUL(lmul)
Represent the analysis usage information of a pass.
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:
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Represents analyses that only rely on functions' control flow.
FunctionPass class - This class is used to implement most global optimizations.
An RAII based helper class to modify MachineFunctionProperties when running pass.
MachineInstrBundleIterator< const MachineInstr > const_iterator
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
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.
Properties which a MachineFunction may have at a given point in time.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
Representation of each machine instruction.
mop_iterator operands_begin()
bool mayRaiseFPException() const
Return true if this instruction could possibly raise a floating-point exception.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
const MachineBasicBlock * getParent() const
LLVM_ABI int findRegisterUseOperandIdx(Register Reg, const TargetRegisterInfo *TRI, bool isKill=false) const
Returns the operand index that is a use of the specific register or -1 if it is not found.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
LLVM_ABI bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore,...
LLVM_ABI void insert(mop_iterator InsertBefore, ArrayRef< MachineOperand > Ops)
Inserts Ops BEFORE It. Can untie/retie tied operands.
LLVM_ABI void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
LLVM_ABI unsigned getNumExplicitDefs() const
Returns the number of non-implicit definitions.
mop_range explicit_operands()
LLVM_ABI void removeOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI const TargetRegisterClass * getRegClassConstraint(unsigned OpIdx, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const
Compute the static register class constraint for operand OpIdx.
MachineOperand class - Representation of each machine instruction operand.
LLVM_ABI unsigned getOperandNo() const
Returns the index of this operand in the instruction that it belongs to.
void setImm(int64_t immVal)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
LLVM_ABI void ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags=0)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value.
static MachineOperand CreateImm(int64_t Val)
Register getReg() const
getReg - Returns the register number.
LLVM_ABI bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
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.
LLVM_ABI bool recomputeRegClass(Register Reg)
recomputeRegClass - Try to find a legal super-class of Reg's register class that still satisfies the ...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI void clearKillFlags(Register Reg) const
clearKillFlags - Iterate over all the uses of the given register and clear the kill flag from the Mac...
LLVM_ABI LLVM_READONLY MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
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.
const TargetRegisterInfo * getTargetRegisterInfo() const
LLVM_ABI const TargetRegisterClass * constrainRegClass(Register Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
LLVM_ABI void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
LLVM_ABI LLVM_READONLY MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
static bool isSafeToMove(const MachineInstr &From, const MachineBasicBlock::iterator &To)
Return true if moving From down to To won't cause any physical register reads or writes to be clobber...
bool hasVInstructions() const
std::optional< unsigned > getRealVLen() const
const RISCVInstrInfo * getInstrInfo() const override
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
Wrapper class representing virtual and physical registers.
constexpr bool isValid() const
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Represent a constant reference to a string, i.e.
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
static unsigned getVecPolicyOpNum(const MCInstrDesc &Desc)
static RISCVVType::VLMUL getLMul(uint64_t TSFlags)
static unsigned getVLOpNum(const MCInstrDesc &Desc)
static bool hasVLOp(uint64_t TSFlags)
static bool elementsDependOnMask(uint64_t TSFlags)
static bool hasVecPolicyOp(uint64_t TSFlags)
static unsigned getSEWOpNum(const MCInstrDesc &Desc)
static bool elementsDependOnVL(uint64_t TSFlags)
static bool hasSEWOp(uint64_t TSFlags)
static bool isFirstDefTiedToFirstUse(const MCInstrDesc &Desc)
@ TAIL_UNDISTURBED_MASK_UNDISTURBED
LLVM_ABI std::pair< unsigned, bool > decodeVLMUL(VLMUL VLMul)
static bool isValidSEW(unsigned SEW)
bool isVLKnownLE(const MachineOperand &LHS, const MachineOperand &RHS)
Given two VL operands, do we know that LHS <= RHS?
unsigned getRVVMCOpcode(unsigned RVVPseudoOpcode)
unsigned getDestLog2EEW(const MCInstrDesc &Desc, unsigned Log2SEW)
static constexpr int64_t VLMaxSentinel
NodeAddr< DefNode * > Def
NodeAddr< UseNode * > Use
This is an optimization pass for GlobalISel generic memory operations.
FunctionPass * createRISCVVectorPeepholeLegacyPass()
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
ArrayRef(const T &OneElt) -> ArrayRef< T >
MCRegisterClass TargetRegisterClass