25#include "llvm/IR/IntrinsicsRISCV.h"
28#define DEBUG_TYPE "riscv-isel"
31using namespace MIPatternMatch;
33#define GET_GLOBALISEL_PREDICATE_BITSET
34#include "RISCVGenGlobalISel.inc"
35#undef GET_GLOBALISEL_PREDICATE_BITSET
74 bool IsExternWeak =
false)
const;
90 ComplexRendererFns selectSHXADDOp(
MachineOperand &Root,
unsigned ShAmt)
const;
91 template <
unsigned ShAmt>
93 return selectSHXADDOp(Root, ShAmt);
97 unsigned ShAmt)
const;
98 template <
unsigned ShAmt>
100 return selectSHXADD_UWOp(Root, ShAmt);
129#define GET_GLOBALISEL_PREDICATES_DECL
130#include "RISCVGenGlobalISel.inc"
131#undef GET_GLOBALISEL_PREDICATES_DECL
133#define GET_GLOBALISEL_TEMPORARIES_DECL
134#include "RISCVGenGlobalISel.inc"
135#undef GET_GLOBALISEL_TEMPORARIES_DECL
140#define GET_GLOBALISEL_IMPL
141#include "RISCVGenGlobalISel.inc"
142#undef GET_GLOBALISEL_IMPL
144RISCVInstructionSelector::RISCVInstructionSelector(
147 : STI(STI),
TII(*STI.getInstrInfo()),
TRI(*STI.getRegisterInfo()), RBI(RBI),
151#include
"RISCVGenGlobalISel.inc"
154#include
"RISCVGenGlobalISel.inc"
160RISCVInstructionSelector::selectShiftMask(
MachineOperand &Root)
const {
169 const LLT ShiftLLT =
MRI.getType(RootReg);
175 ShAmtReg = ZExtSrcReg;
182 if (ShMask.isSubsetOf(AndMask)) {
183 ShAmtReg = AndSrcReg;
187 KnownBits Known = KB->getKnownBits(ShAmtReg);
188 if (ShMask.isSubsetOf(AndMask | Known.
Zero))
189 ShAmtReg = AndSrcReg;
196 if (Imm != 0 &&
Imm.urem(ShiftWidth) == 0)
201 if (Imm != 0 &&
Imm.urem(ShiftWidth) == 0) {
204 ShAmtReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
205 unsigned NegOpc = Subtarget->is64Bit() ? RISCV::SUBW : RISCV::SUB;
212 if (
Imm.urem(ShiftWidth) == ShiftWidth - 1) {
215 ShAmtReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
230 unsigned ShAmt)
const {
239 const unsigned XLen = STI.getXLen();
258 if (
Mask.isShiftedMask()) {
259 unsigned Leading = XLen -
Mask.getActiveBits();
260 unsigned Trailing =
Mask.countr_zero();
263 if (*LeftShift && Leading == 0 && C2.
ult(Trailing) && Trailing == ShAmt) {
264 Register DstReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
275 if (!*LeftShift && Leading == C2 && Trailing == ShAmt) {
276 Register DstReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
280 .addImm(Leading + Trailing);
301 unsigned Leading = XLen -
Mask.getActiveBits();
302 unsigned Trailing =
Mask.countr_zero();
315 Register DstReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
330 unsigned ShAmt)
const {
350 if (
Mask.isShiftedMask()) {
351 unsigned Leading =
Mask.countl_zero();
352 unsigned Trailing =
Mask.countr_zero();
353 if (Leading == 32 - ShAmt && C2 == Trailing && Trailing > ShAmt) {
354 Register DstReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
369RISCVInstructionSelector::selectAddrRegImm(
MachineOperand &Root)
const {
377 if (RootDef->
getOpcode() == TargetOpcode::G_FRAME_INDEX) {
384 if (isBaseWithConstantOffset(Root,
MRI)) {
391 if (isInt<12>(RHSC)) {
392 if (LHSDef->
getOpcode() == TargetOpcode::G_FRAME_INDEX)
415 case CmpInst::Predicate::ICMP_EQ:
417 case CmpInst::Predicate::ICMP_NE:
419 case CmpInst::Predicate::ICMP_ULT:
421 case CmpInst::Predicate::ICMP_SLT:
423 case CmpInst::Predicate::ICMP_UGE:
425 case CmpInst::Predicate::ICMP_SGE:
447 case CmpInst::Predicate::ICMP_SGT:
455 case CmpInst::Predicate::ICMP_SLT:
472 case CmpInst::Predicate::ICMP_EQ:
473 case CmpInst::Predicate::ICMP_NE:
474 case CmpInst::Predicate::ICMP_ULT:
475 case CmpInst::Predicate::ICMP_SLT:
476 case CmpInst::Predicate::ICMP_UGE:
477 case CmpInst::Predicate::ICMP_SGE:
480 case CmpInst::Predicate::ICMP_SGT:
481 case CmpInst::Predicate::ICMP_SLE:
482 case CmpInst::Predicate::ICMP_UGT:
483 case CmpInst::Predicate::ICMP_ULE:
491 CC = getRISCVCCFromICmp(Pred);
501 preISelLower(
MI, MIB,
MRI);
502 const unsigned Opc =
MI.getOpcode();
504 if (!
MI.isPreISelOpcode() || Opc == TargetOpcode::G_PHI) {
505 if (Opc == TargetOpcode::PHI || Opc == TargetOpcode::G_PHI) {
506 const Register DefReg =
MI.getOperand(0).getReg();
507 const LLT DefTy =
MRI.getType(DefReg);
510 MRI.getRegClassOrRegBank(DefReg);
521 DefRC = getRegClassForTypeOnBank(DefTy, RB);
528 MI.setDesc(
TII.get(TargetOpcode::PHI));
529 return RBI.constrainGenericRegister(DefReg, *DefRC,
MRI);
539 if (selectImpl(
MI, *CoverageInfo))
543 case TargetOpcode::G_ANYEXT:
544 case TargetOpcode::G_PTRTOINT:
545 case TargetOpcode::G_INTTOPTR:
546 case TargetOpcode::G_TRUNC:
548 case TargetOpcode::G_CONSTANT: {
550 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue();
552 if (!materializeImm(DstReg, Imm, MIB))
555 MI.eraseFromParent();
558 case TargetOpcode::G_FCONSTANT: {
562 const APFloat &FPimm =
MI.getOperand(1).getFPImm()->getValueAPF();
564 unsigned Size =
MRI.getType(DstReg).getSizeInBits();
565 if (
Size == 32 || (
Size == 64 && Subtarget->is64Bit())) {
566 Register GPRReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
567 if (!materializeImm(GPRReg,
Imm.getSExtValue(), MIB))
570 unsigned Opcode =
Size == 64 ? RISCV::FMV_D_X : RISCV::FMV_W_X;
571 auto FMV = MIB.buildInstr(Opcode, {DstReg}, {GPRReg});
572 if (!FMV.constrainAllUses(
TII,
TRI, RBI))
576 "Unexpected size or subtarget");
578 Register GPRRegHigh =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
579 Register GPRRegLow =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
580 if (!materializeImm(GPRRegHigh,
Imm.extractBits(32, 32).getSExtValue(),
583 if (!materializeImm(GPRRegLow,
Imm.trunc(32).getSExtValue(), MIB))
586 RISCV::BuildPairF64Pseudo, {DstReg}, {GPRRegLow, GPRRegHigh});
591 MI.eraseFromParent();
594 case TargetOpcode::G_GLOBAL_VALUE: {
595 auto *GV =
MI.getOperand(1).getGlobal();
596 if (GV->isThreadLocal()) {
601 return selectAddr(
MI, MIB,
MRI, GV->isDSOLocal(),
602 GV->hasExternalWeakLinkage());
604 case TargetOpcode::G_JUMP_TABLE:
605 case TargetOpcode::G_CONSTANT_POOL:
606 return selectAddr(
MI, MIB,
MRI);
607 case TargetOpcode::G_BRCOND: {
613 .addMBB(
MI.getOperand(1).getMBB());
614 MI.eraseFromParent();
617 case TargetOpcode::G_BRJT: {
621 assert((EntrySize == 4 || (Subtarget->is64Bit() && EntrySize == 8)) &&
622 "Unsupported jump-table entry size");
627 "Unexpected jump-table entry kind");
630 MIB.buildInstr(RISCV::SLLI, {&RISCV::GPRRegClass}, {
MI.getOperand(2)})
632 if (!SLL.constrainAllUses(
TII,
TRI, RBI))
636 auto ADD = MIB.buildInstr(RISCV::ADD, {&RISCV::GPRRegClass},
637 {
MI.getOperand(0), SLL.getReg(0)});
638 if (!
ADD.constrainAllUses(
TII,
TRI, RBI))
641 unsigned LdOpc = EntrySize == 8 ? RISCV::LD : RISCV::LW;
643 MIB.buildInstr(LdOpc, {&RISCV::GPRRegClass}, {
ADD.getReg(0)})
648 if (!Dest.constrainAllUses(
TII,
TRI, RBI))
655 Dest = MIB.buildInstr(RISCV::ADD, {&RISCV::GPRRegClass},
656 {Dest.getReg(0),
MI.getOperand(0)});
657 if (!Dest.constrainAllUses(
TII,
TRI, RBI))
662 MIB.buildInstr(RISCV::PseudoBRIND, {}, {Dest.getReg(0)}).addImm(0);
666 MI.eraseFromParent();
669 case TargetOpcode::G_BRINDIRECT:
670 MI.setDesc(
TII.get(RISCV::PseudoBRIND));
673 case TargetOpcode::G_SEXT_INREG:
674 return selectSExtInreg(
MI, MIB);
675 case TargetOpcode::G_FRAME_INDEX: {
679 MI.setDesc(
TII.get(RISCV::ADDI));
683 case TargetOpcode::G_SELECT:
684 return selectSelect(
MI, MIB,
MRI);
685 case TargetOpcode::G_FCMP:
686 return selectFPCompare(
MI, MIB,
MRI);
687 case TargetOpcode::G_FENCE: {
692 emitFence(FenceOrdering, FenceSSID, MIB);
693 MI.eraseFromParent();
696 case TargetOpcode::G_IMPLICIT_DEF:
697 return selectImplicitDef(
MI, MIB,
MRI);
698 case TargetOpcode::G_MERGE_VALUES:
700 case TargetOpcode::G_UNMERGE_VALUES:
707bool RISCVInstructionSelector::selectMergeValues(
709 assert(
MI.getOpcode() == TargetOpcode::G_MERGE_VALUES);
712 if (
MI.getNumOperands() != 3)
717 if (!isRegInFprb(Dst,
MRI) || !isRegInGprb(
Lo,
MRI) || !isRegInGprb(
Hi,
MRI))
719 MI.setDesc(
TII.get(RISCV::BuildPairF64Pseudo));
723bool RISCVInstructionSelector::selectUnmergeValues(
725 assert(
MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES);
728 if (
MI.getNumOperands() != 3)
733 if (!isRegInFprb(Src,
MRI) || !isRegInGprb(
Lo,
MRI) || !isRegInGprb(
Hi,
MRI))
735 MI.setDesc(
TII.get(RISCV::SplitF64Pseudo));
743 assert(
MRI.getType(PtrReg).isPointer() &&
"Operand is not a pointer!");
747 MRI.setRegBank(PtrToInt.getReg(0), RBI.getRegBank(RISCV::GPRBRegBankID));
748 Op.setReg(PtrToInt.getReg(0));
749 return select(*PtrToInt);
755 switch (
MI.getOpcode()) {
756 case TargetOpcode::G_PTR_ADD: {
760 replacePtrWithInt(
MI.getOperand(1), MIB,
MRI);
761 MI.setDesc(
TII.get(TargetOpcode::G_ADD));
762 MRI.setType(DstReg, sXLen);
765 case TargetOpcode::G_PTRMASK: {
768 replacePtrWithInt(
MI.getOperand(1), MIB,
MRI);
769 MI.setDesc(
TII.get(TargetOpcode::G_AND));
770 MRI.setType(DstReg, sXLen);
778 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
779 "Expected G_CONSTANT");
780 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
787 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
788 "Expected G_CONSTANT");
789 uint64_t CstVal =
MI.getOperand(1).getCImm()->getZExtValue();
790 MIB.
addImm(STI.getXLen() - CstVal);
796 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
797 "Expected G_CONSTANT");
798 uint64_t CstVal =
MI.getOperand(1).getCImm()->getZExtValue();
805 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
806 "Expected G_CONSTANT");
807 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
814 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
815 "Expected G_CONSTANT");
816 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
823 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
824 "Expected G_CONSTANT");
825 uint64_t C =
MI.getOperand(1).getCImm()->getZExtValue();
831 if (RB.
getID() == RISCV::GPRBRegBankID) {
833 return &RISCV::GPRRegClass;
836 if (RB.
getID() == RISCV::FPRBRegBankID) {
838 return &RISCV::FPR32RegClass;
840 return &RISCV::FPR64RegClass;
843 if (RB.
getID() == RISCV::VRBRegBankID) {
845 return &RISCV::VRRegClass;
848 return &RISCV::VRM2RegClass;
851 return &RISCV::VRM4RegClass;
854 return &RISCV::VRM8RegClass;
860bool RISCVInstructionSelector::isRegInGprb(
Register Reg,
862 return RBI.getRegBank(Reg,
MRI,
TRI)->
getID() == RISCV::GPRBRegBankID;
865bool RISCVInstructionSelector::isRegInFprb(
Register Reg,
867 return RBI.getRegBank(Reg,
MRI,
TRI)->getID() == RISCV::FPRBRegBankID;
878 MRI.getType(DstReg), *RBI.getRegBank(DstReg,
MRI,
TRI));
880 "Register class not available for LLT, register bank combination");
885 if (!RBI.constrainGenericRegister(DstReg, *DstRC,
MRI)) {
891 MI.setDesc(
TII.get(RISCV::COPY));
895bool RISCVInstructionSelector::selectImplicitDef(
897 assert(
MI.getOpcode() == TargetOpcode::G_IMPLICIT_DEF);
899 const Register DstReg =
MI.getOperand(0).getReg();
901 MRI.getType(DstReg), *RBI.getRegBank(DstReg,
MRI,
TRI));
904 "Register class not available for LLT, register bank combination");
906 if (!RBI.constrainGenericRegister(DstReg, *DstRC,
MRI)) {
910 MI.setDesc(
TII.get(TargetOpcode::IMPLICIT_DEF));
914bool RISCVInstructionSelector::materializeImm(
Register DstReg, int64_t Imm,
920 RBI.constrainGenericRegister(DstReg, RISCV::GPRRegClass,
MRI);
925 unsigned NumInsts = Seq.
size();
928 for (
unsigned i = 0; i < NumInsts; i++) {
930 ?
MRI.createVirtualRegister(&RISCV::GPRRegClass)
935 switch (
I.getOpndKind()) {
944 {SrcReg, Register(RISCV::X0)});
968 bool IsExternWeak)
const {
969 assert((
MI.getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
970 MI.getOpcode() == TargetOpcode::G_JUMP_TABLE ||
971 MI.getOpcode() == TargetOpcode::G_CONSTANT_POOL) &&
972 "Unexpected opcode");
977 const LLT DefTy =
MRI.getType(DefReg);
983 if (
TM.isPositionIndependent() || Subtarget->allowTaggedGlobals()) {
984 if (IsLocal && !Subtarget->allowTaggedGlobals()) {
988 MI.setDesc(
TII.get(RISCV::PseudoLLA));
1010 MI.eraseFromParent();
1014 switch (
TM.getCodeModel()) {
1017 getName(),
"Unsupported code model for lowering",
MI);
1024 Register AddrHiDest =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
1037 MI.eraseFromParent();
1064 MI.eraseFromParent();
1071 MI.setDesc(
TII.get(RISCV::PseudoLLA));
1085 if (!
Size.isImm() ||
Size.getImm() != 32)
1092 MIB.
buildInstr(RISCV::ADDIW, {Dst.getReg()}, {Src.getReg()}).addImm(0U);
1097 MI.eraseFromParent();
1104 auto &SelectMI = cast<GSelect>(
MI);
1110 Register DstReg = SelectMI.getReg(0);
1112 unsigned Opc = RISCV::Select_GPR_Using_CC_GPR;
1113 if (RBI.getRegBank(DstReg,
MRI,
TRI)->getID() == RISCV::FPRBRegBankID) {
1114 unsigned Size =
MRI.getType(DstReg).getSizeInBits();
1115 Opc =
Size == 32 ? RISCV::Select_FPR32_Using_CC_GPR
1116 : RISCV::Select_FPR64_Using_CC_GPR;
1124 .
addReg(SelectMI.getTrueReg())
1125 .
addReg(SelectMI.getFalseReg());
1126 MI.eraseFromParent();
1137 return Size == 32 ? RISCV::FLT_S : RISCV::FLT_D;
1139 return Size == 32 ? RISCV::FLE_S : RISCV::FLE_D;
1141 return Size == 32 ? RISCV::FEQ_S : RISCV::FEQ_D;
1154 assert(!isLegalFCmpPredicate(Pred) &&
"Predicate already legal?");
1157 if (isLegalFCmpPredicate(InvPred)) {
1165 if (isLegalFCmpPredicate(InvPred)) {
1170 if (isLegalFCmpPredicate(InvPred)) {
1185 auto &CmpMI = cast<GFCmp>(
MI);
1192 unsigned Size =
MRI.getType(LHS).getSizeInBits();
1197 bool NeedInvert =
false;
1201 TmpReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
1203 if (!
Cmp.constrainAllUses(
TII,
TRI, RBI))
1209 {&RISCV::GPRRegClass}, {
LHS,
RHS});
1210 if (!Cmp1.constrainAllUses(
TII,
TRI, RBI))
1213 {&RISCV::GPRRegClass}, {
RHS,
LHS});
1214 if (!Cmp2.constrainAllUses(
TII,
TRI, RBI))
1217 TmpReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
1219 MIB.
buildInstr(RISCV::OR, {TmpReg}, {Cmp1.getReg(0), Cmp2.getReg(0)});
1220 if (!
Or.constrainAllUses(
TII,
TRI, RBI))
1227 {&RISCV::GPRRegClass}, {
LHS,
LHS});
1228 if (!Cmp1.constrainAllUses(
TII,
TRI, RBI))
1231 {&RISCV::GPRRegClass}, {
RHS,
RHS});
1232 if (!Cmp2.constrainAllUses(
TII,
TRI, RBI))
1235 TmpReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
1237 MIB.
buildInstr(RISCV::AND, {TmpReg}, {Cmp1.getReg(0), Cmp2.getReg(0)});
1238 if (!
And.constrainAllUses(
TII,
TRI, RBI))
1245 auto Xor = MIB.
buildInstr(RISCV::XORI, {DstReg}, {TmpReg}).addImm(1);
1246 if (!
Xor.constrainAllUses(
TII,
TRI, RBI))
1250 MI.eraseFromParent();
1254void RISCVInstructionSelector::emitFence(
AtomicOrdering FenceOrdering,
1257 if (STI.hasStdExtZtso()) {
1260 if (FenceOrdering == AtomicOrdering::SequentiallyConsistent &&
1270 MIB.
buildInstr(TargetOpcode::MEMBARRIER, {}, {});
1278 MIB.
buildInstr(TargetOpcode::MEMBARRIER, {}, {});
1284 unsigned Pred, Succ;
1285 switch (FenceOrdering) {
1288 case AtomicOrdering::AcquireRelease:
1292 case AtomicOrdering::Acquire:
1297 case AtomicOrdering::Release:
1302 case AtomicOrdering::SequentiallyConsistent:
1316 return new RISCVInstructionSelector(
TM, Subtarget, RBI);
unsigned const MachineRegisterInfo * MRI
static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
static bool selectMergeValues(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
static bool selectUnmergeValues(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
Provides analysis for querying information about KnownBits during GISel passes.
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
const HexagonInstrInfo * TII
Contains matchers for matching SSA Machine Instructions.
This file declares the MachineIRBuilder class.
unsigned const TargetRegisterInfo * TRI
const char LLVMTargetMachineRef TM
static StringRef getName(Value *V)
#define GET_GLOBALISEL_PREDICATES_INIT
#define GET_GLOBALISEL_TEMPORARIES_INIT
static void getOperandsForBranch(Register CondReg, MachineRegisterInfo &MRI, RISCVCC::CondCode &CC, Register &LHS, Register &RHS)
static unsigned getFCmpOpcode(CmpInst::Predicate Pred, unsigned Size)
static bool legalizeFCmpPredicate(Register &LHS, Register &RHS, CmpInst::Predicate &Pred, bool &NeedInvert)
const SmallVectorImpl< MachineOperand > & Cond
This file declares the targeting of the RegisterBankInfo class for RISC-V.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
support::ulittle16_t & Lo
support::ulittle16_t & Hi
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
This is an important base class in LLVM.
This class represents an Operation in the Expression.
std::optional< SmallVector< std::function< void(MachineInstrBuilder &)>, 4 > > ComplexRendererFns
virtual bool select(MachineInstr &I)=0
Select the (possibly generic) instruction I to only use target-specific opcodes.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
constexpr bool isValid() const
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
const MachineJumpTableInfo * getJumpTableInfo() const
getJumpTableInfo - Return the jump table info object for the current function.
Helper class to build MachineInstr.
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
MachineRegisterInfo * getMRI()
Getter for MRI.
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
MachineInstrBuilder buildPtrToInt(const DstOp &Dst, const SrcOp &Src)
Build and insert a G_PTRTOINT instruction.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
bool constrainAllUses(const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
const MachineOperand & getOperand(unsigned i) const
unsigned getEntrySize(const DataLayout &TD) const
getEntrySize - Return the size of each entry in the jump table.
@ EK_LabelDifference32
EK_LabelDifference32 - Each entry is the address of the block minus the address of the jump table.
@ EK_Custom32
EK_Custom32 - Each entry is a 32-bit value that is custom lowered by the TargetLowering::LowerCustomJ...
@ EK_BlockAddress
EK_BlockAddress - Each entry is a plain address of block, e.g.: .word LBB123.
unsigned getEntryAlignment(const DataLayout &TD) const
getEntryAlignment - Return the alignment of each entry in the jump table.
JTEntryKind getEntryKind() const
A description of a memory reference used in the backend.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
MachineOperand class - Representation of each machine instruction operand.
const ConstantInt * getCImm() const
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)
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
T get() const
Returns the value of the specified pointer type.
T dyn_cast() const
Returns the current pointer if it is of the specified pointer type, otherwise returns null.
This class provides the information for the target register banks.
This class implements the register bank concept.
unsigned getID() const
Get the identifier of this register bank.
Wrapper class representing virtual and physical registers.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
unsigned getID() const
Return the register class ID number.
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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.
@ C
The default llvm calling convention, compatible with C.
@ ADD
Simple integer binary arithmetic operators.
operand_type_match m_Reg()
operand_type_match m_Pred()
UnaryOp_match< SrcTy, TargetOpcode::G_ZEXT > m_GZExt(const SrcTy &Src)
ConstantMatch< APInt > m_ICst(APInt &Cst)
BinaryOp_match< LHS, RHS, TargetOpcode::G_ADD, true > m_GAdd(const LHS &L, const RHS &R)
OneNonDBGUse_match< SubPat > m_OneNonDBGUse(const SubPat &SP)
CompareOp_match< Pred, LHS, RHS, TargetOpcode::G_ICMP > m_GICmp(const Pred &P, const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, TargetOpcode::G_SUB > m_GSub(const LHS &L, const RHS &R)
bool mi_match(Reg R, const MachineRegisterInfo &MRI, Pattern &&P)
BinaryOp_match< LHS, RHS, TargetOpcode::G_SHL, false > m_GShl(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, TargetOpcode::G_AND, true > m_GAnd(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, TargetOpcode::G_LSHR, false > m_GLShr(const LHS &L, const RHS &R)
unsigned getBrCond(CondCode CC)
InstSeq generateInstSeq(int64_t Val, const MCSubtargetInfo &STI)
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
@ System
Synchronized with respect to all concurrently executing threads.
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
bool constrainSelectedInstRegOperands(MachineInstr &I, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
Mutate the newly-selected instruction I to constrain its (possibly generic) virtual register operands...
std::optional< int64_t > getIConstantVRegSExtVal(Register VReg, const MachineRegisterInfo &MRI)
If VReg is defined by a G_CONSTANT fits in int64_t returns it.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
void reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC, MachineOptimizationRemarkEmitter &MORE, MachineOptimizationRemarkMissed &R)
Report an ISel error as a missed optimization remark to the LLVMContext's diagnostic stream.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ Xor
Bitwise or logical XOR of integers.
InstructionSelector * createRISCVInstructionSelector(const RISCVTargetMachine &TM, RISCVSubtarget &Subtarget, RISCVRegisterBankInfo &RBI)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
static MachinePointerInfo getJumpTable(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a jump table entry.
static MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.