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;
196 if (ShMask.isSubsetOf(AndMask)) {
197 ShAmtReg = AndSrcReg;
201 KnownBits Known = KB->getKnownBits(AndSrcReg);
202 if (ShMask.isSubsetOf(AndMask | Known.
Zero))
203 ShAmtReg = AndSrcReg;
210 if (Imm != 0 &&
Imm.urem(ShiftWidth) == 0)
215 if (Imm != 0 &&
Imm.urem(ShiftWidth) == 0) {
218 ShAmtReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
219 unsigned NegOpc = Subtarget->is64Bit() ? RISCV::SUBW : RISCV::SUB;
226 if (
Imm.urem(ShiftWidth) == ShiftWidth - 1) {
229 ShAmtReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
244 unsigned ShAmt)
const {
253 const unsigned XLen = STI.getXLen();
272 if (
Mask.isShiftedMask()) {
273 unsigned Leading = XLen -
Mask.getActiveBits();
274 unsigned Trailing =
Mask.countr_zero();
277 if (*LeftShift && Leading == 0 && C2.
ult(Trailing) && Trailing == ShAmt) {
278 Register DstReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
289 if (!*LeftShift && Leading == C2 && Trailing == ShAmt) {
290 Register DstReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
294 .addImm(Leading + Trailing);
315 unsigned Leading = XLen -
Mask.getActiveBits();
316 unsigned Trailing =
Mask.countr_zero();
329 Register DstReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
344 unsigned ShAmt)
const {
364 if (
Mask.isShiftedMask()) {
365 unsigned Leading =
Mask.countl_zero();
366 unsigned Trailing =
Mask.countr_zero();
367 if (Leading == 32 - ShAmt && C2 == Trailing && Trailing > ShAmt) {
368 Register DstReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
383RISCVInstructionSelector::selectAddrRegImm(
MachineOperand &Root)
const {
391 if (RootDef->
getOpcode() == TargetOpcode::G_FRAME_INDEX) {
398 if (isBaseWithConstantOffset(Root,
MRI)) {
405 if (isInt<12>(RHSC)) {
406 if (LHSDef->
getOpcode() == TargetOpcode::G_FRAME_INDEX)
429 case CmpInst::Predicate::ICMP_EQ:
431 case CmpInst::Predicate::ICMP_NE:
433 case CmpInst::Predicate::ICMP_ULT:
435 case CmpInst::Predicate::ICMP_SLT:
437 case CmpInst::Predicate::ICMP_UGE:
439 case CmpInst::Predicate::ICMP_SGE:
461 case CmpInst::Predicate::ICMP_SGT:
469 case CmpInst::Predicate::ICMP_SLT:
486 case CmpInst::Predicate::ICMP_EQ:
487 case CmpInst::Predicate::ICMP_NE:
488 case CmpInst::Predicate::ICMP_ULT:
489 case CmpInst::Predicate::ICMP_SLT:
490 case CmpInst::Predicate::ICMP_UGE:
491 case CmpInst::Predicate::ICMP_SGE:
494 case CmpInst::Predicate::ICMP_SGT:
495 case CmpInst::Predicate::ICMP_SLE:
496 case CmpInst::Predicate::ICMP_UGT:
497 case CmpInst::Predicate::ICMP_ULE:
505 CC = getRISCVCCFromICmp(Pred);
515 preISelLower(
MI, MIB,
MRI);
516 const unsigned Opc =
MI.getOpcode();
518 if (!
MI.isPreISelOpcode() || Opc == TargetOpcode::G_PHI) {
519 if (Opc == TargetOpcode::PHI || Opc == TargetOpcode::G_PHI) {
520 const Register DefReg =
MI.getOperand(0).getReg();
521 const LLT DefTy =
MRI.getType(DefReg);
524 MRI.getRegClassOrRegBank(DefReg);
535 DefRC = getRegClassForTypeOnBank(DefTy, RB);
542 MI.setDesc(
TII.get(TargetOpcode::PHI));
543 return RBI.constrainGenericRegister(DefReg, *DefRC,
MRI);
553 if (selectImpl(
MI, *CoverageInfo))
557 case TargetOpcode::G_ANYEXT:
558 case TargetOpcode::G_PTRTOINT:
559 case TargetOpcode::G_INTTOPTR:
560 case TargetOpcode::G_TRUNC:
562 case TargetOpcode::G_CONSTANT: {
564 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue();
566 if (!materializeImm(DstReg, Imm, MIB))
569 MI.eraseFromParent();
572 case TargetOpcode::G_FCONSTANT: {
576 const APFloat &FPimm =
MI.getOperand(1).getFPImm()->getValueAPF();
578 unsigned Size =
MRI.getType(DstReg).getSizeInBits();
579 if (
Size == 32 || (
Size == 64 && Subtarget->is64Bit())) {
580 Register GPRReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
581 if (!materializeImm(GPRReg,
Imm.getSExtValue(), MIB))
584 unsigned Opcode =
Size == 64 ? RISCV::FMV_D_X : RISCV::FMV_W_X;
585 auto FMV = MIB.buildInstr(Opcode, {DstReg}, {GPRReg});
586 if (!FMV.constrainAllUses(
TII,
TRI, RBI))
590 "Unexpected size or subtarget");
592 Register GPRRegHigh =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
593 Register GPRRegLow =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
594 if (!materializeImm(GPRRegHigh,
Imm.extractBits(32, 32).getSExtValue(),
597 if (!materializeImm(GPRRegLow,
Imm.trunc(32).getSExtValue(), MIB))
600 RISCV::BuildPairF64Pseudo, {DstReg}, {GPRRegLow, GPRRegHigh});
605 MI.eraseFromParent();
608 case TargetOpcode::G_GLOBAL_VALUE: {
609 auto *GV =
MI.getOperand(1).getGlobal();
610 if (GV->isThreadLocal()) {
615 return selectAddr(
MI, MIB,
MRI, GV->isDSOLocal(),
616 GV->hasExternalWeakLinkage());
618 case TargetOpcode::G_JUMP_TABLE:
619 case TargetOpcode::G_CONSTANT_POOL:
620 return selectAddr(
MI, MIB,
MRI);
621 case TargetOpcode::G_BRCOND: {
627 .addMBB(
MI.getOperand(1).getMBB());
628 MI.eraseFromParent();
631 case TargetOpcode::G_BRJT: {
635 assert((EntrySize == 4 || (Subtarget->is64Bit() && EntrySize == 8)) &&
636 "Unsupported jump-table entry size");
641 "Unexpected jump-table entry kind");
644 MIB.buildInstr(RISCV::SLLI, {&RISCV::GPRRegClass}, {
MI.getOperand(2)})
646 if (!SLL.constrainAllUses(
TII,
TRI, RBI))
650 auto ADD = MIB.buildInstr(RISCV::ADD, {&RISCV::GPRRegClass},
651 {
MI.getOperand(0), SLL.getReg(0)});
652 if (!
ADD.constrainAllUses(
TII,
TRI, RBI))
655 unsigned LdOpc = EntrySize == 8 ? RISCV::LD : RISCV::LW;
657 MIB.buildInstr(LdOpc, {&RISCV::GPRRegClass}, {
ADD.getReg(0)})
662 if (!Dest.constrainAllUses(
TII,
TRI, RBI))
669 Dest = MIB.buildInstr(RISCV::ADD, {&RISCV::GPRRegClass},
670 {Dest.getReg(0),
MI.getOperand(0)});
671 if (!Dest.constrainAllUses(
TII,
TRI, RBI))
676 MIB.buildInstr(RISCV::PseudoBRIND, {}, {Dest.getReg(0)}).addImm(0);
680 MI.eraseFromParent();
683 case TargetOpcode::G_BRINDIRECT:
684 MI.setDesc(
TII.get(RISCV::PseudoBRIND));
687 case TargetOpcode::G_SEXT_INREG:
688 return selectSExtInreg(
MI, MIB);
689 case TargetOpcode::G_FRAME_INDEX: {
693 MI.setDesc(
TII.get(RISCV::ADDI));
697 case TargetOpcode::G_SELECT:
698 return selectSelect(
MI, MIB,
MRI);
699 case TargetOpcode::G_FCMP:
700 return selectFPCompare(
MI, MIB,
MRI);
701 case TargetOpcode::G_FENCE: {
706 emitFence(FenceOrdering, FenceSSID, MIB);
707 MI.eraseFromParent();
710 case TargetOpcode::G_IMPLICIT_DEF:
711 return selectImplicitDef(
MI, MIB,
MRI);
712 case TargetOpcode::G_MERGE_VALUES:
714 case TargetOpcode::G_UNMERGE_VALUES:
721bool RISCVInstructionSelector::selectMergeValues(
723 assert(
MI.getOpcode() == TargetOpcode::G_MERGE_VALUES);
726 if (
MI.getNumOperands() != 3)
731 if (!isRegInFprb(Dst,
MRI) || !isRegInGprb(
Lo,
MRI) || !isRegInGprb(
Hi,
MRI))
733 MI.setDesc(
TII.get(RISCV::BuildPairF64Pseudo));
737bool RISCVInstructionSelector::selectUnmergeValues(
739 assert(
MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES);
742 if (
MI.getNumOperands() != 3)
747 if (!isRegInFprb(Src,
MRI) || !isRegInGprb(
Lo,
MRI) || !isRegInGprb(
Hi,
MRI))
749 MI.setDesc(
TII.get(RISCV::SplitF64Pseudo));
757 assert(
MRI.getType(PtrReg).isPointer() &&
"Operand is not a pointer!");
761 MRI.setRegBank(PtrToInt.getReg(0), RBI.getRegBank(RISCV::GPRBRegBankID));
762 Op.setReg(PtrToInt.getReg(0));
763 return select(*PtrToInt);
769 switch (
MI.getOpcode()) {
770 case TargetOpcode::G_PTR_ADD: {
774 replacePtrWithInt(
MI.getOperand(1), MIB,
MRI);
775 MI.setDesc(
TII.get(TargetOpcode::G_ADD));
776 MRI.setType(DstReg, sXLen);
779 case TargetOpcode::G_PTRMASK: {
782 replacePtrWithInt(
MI.getOperand(1), MIB,
MRI);
783 MI.setDesc(
TII.get(TargetOpcode::G_AND));
784 MRI.setType(DstReg, sXLen);
792 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
793 "Expected G_CONSTANT");
794 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
801 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
802 "Expected G_CONSTANT");
803 uint64_t CstVal =
MI.getOperand(1).getCImm()->getZExtValue();
804 MIB.
addImm(STI.getXLen() - CstVal);
810 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
811 "Expected G_CONSTANT");
812 uint64_t CstVal =
MI.getOperand(1).getCImm()->getZExtValue();
819 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
820 "Expected G_CONSTANT");
821 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
828 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
829 "Expected G_CONSTANT");
830 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
837 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
838 "Expected G_CONSTANT");
839 uint64_t C =
MI.getOperand(1).getCImm()->getZExtValue();
845 if (RB.
getID() == RISCV::GPRBRegBankID) {
847 return &RISCV::GPRRegClass;
850 if (RB.
getID() == RISCV::FPRBRegBankID) {
852 return &RISCV::FPR32RegClass;
854 return &RISCV::FPR64RegClass;
857 if (RB.
getID() == RISCV::VRBRegBankID) {
859 return &RISCV::VRRegClass;
862 return &RISCV::VRM2RegClass;
865 return &RISCV::VRM4RegClass;
868 return &RISCV::VRM8RegClass;
874bool RISCVInstructionSelector::isRegInGprb(
Register Reg,
876 return RBI.getRegBank(Reg,
MRI,
TRI)->
getID() == RISCV::GPRBRegBankID;
879bool RISCVInstructionSelector::isRegInFprb(
Register Reg,
881 return RBI.getRegBank(Reg,
MRI,
TRI)->getID() == RISCV::FPRBRegBankID;
892 MRI.getType(DstReg), *RBI.getRegBank(DstReg,
MRI,
TRI));
894 "Register class not available for LLT, register bank combination");
899 if (!RBI.constrainGenericRegister(DstReg, *DstRC,
MRI)) {
905 MI.setDesc(
TII.get(RISCV::COPY));
909bool RISCVInstructionSelector::selectImplicitDef(
911 assert(
MI.getOpcode() == TargetOpcode::G_IMPLICIT_DEF);
913 const Register DstReg =
MI.getOperand(0).getReg();
915 MRI.getType(DstReg), *RBI.getRegBank(DstReg,
MRI,
TRI));
918 "Register class not available for LLT, register bank combination");
920 if (!RBI.constrainGenericRegister(DstReg, *DstRC,
MRI)) {
924 MI.setDesc(
TII.get(TargetOpcode::IMPLICIT_DEF));
928bool RISCVInstructionSelector::materializeImm(
Register DstReg, int64_t Imm,
934 RBI.constrainGenericRegister(DstReg, RISCV::GPRRegClass,
MRI);
939 unsigned NumInsts = Seq.
size();
942 for (
unsigned i = 0; i < NumInsts; i++) {
944 ?
MRI.createVirtualRegister(&RISCV::GPRRegClass)
949 switch (
I.getOpndKind()) {
958 {SrcReg, Register(RISCV::X0)});
982 bool IsExternWeak)
const {
983 assert((
MI.getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
984 MI.getOpcode() == TargetOpcode::G_JUMP_TABLE ||
985 MI.getOpcode() == TargetOpcode::G_CONSTANT_POOL) &&
986 "Unexpected opcode");
991 const LLT DefTy =
MRI.getType(DefReg);
997 if (
TM.isPositionIndependent() || Subtarget->allowTaggedGlobals()) {
998 if (IsLocal && !Subtarget->allowTaggedGlobals()) {
1002 MI.setDesc(
TII.get(RISCV::PseudoLLA));
1024 MI.eraseFromParent();
1028 switch (
TM.getCodeModel()) {
1031 getName(),
"Unsupported code model for lowering",
MI);
1038 Register AddrHiDest =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
1051 MI.eraseFromParent();
1078 MI.eraseFromParent();
1085 MI.setDesc(
TII.get(RISCV::PseudoLLA));
1099 if (!
Size.isImm() ||
Size.getImm() != 32)
1106 MIB.
buildInstr(RISCV::ADDIW, {Dst.getReg()}, {Src.getReg()}).addImm(0U);
1111 MI.eraseFromParent();
1118 auto &SelectMI = cast<GSelect>(
MI);
1124 Register DstReg = SelectMI.getReg(0);
1126 unsigned Opc = RISCV::Select_GPR_Using_CC_GPR;
1127 if (RBI.getRegBank(DstReg,
MRI,
TRI)->getID() == RISCV::FPRBRegBankID) {
1128 unsigned Size =
MRI.getType(DstReg).getSizeInBits();
1129 Opc =
Size == 32 ? RISCV::Select_FPR32_Using_CC_GPR
1130 : RISCV::Select_FPR64_Using_CC_GPR;
1138 .
addReg(SelectMI.getTrueReg())
1139 .
addReg(SelectMI.getFalseReg());
1140 MI.eraseFromParent();
1151 return Size == 32 ? RISCV::FLT_S : RISCV::FLT_D;
1153 return Size == 32 ? RISCV::FLE_S : RISCV::FLE_D;
1155 return Size == 32 ? RISCV::FEQ_S : RISCV::FEQ_D;
1168 assert(!isLegalFCmpPredicate(Pred) &&
"Predicate already legal?");
1171 if (isLegalFCmpPredicate(InvPred)) {
1179 if (isLegalFCmpPredicate(InvPred)) {
1184 if (isLegalFCmpPredicate(InvPred)) {
1199 auto &CmpMI = cast<GFCmp>(
MI);
1206 unsigned Size =
MRI.getType(LHS).getSizeInBits();
1211 bool NeedInvert =
false;
1215 TmpReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
1217 if (!
Cmp.constrainAllUses(
TII,
TRI, RBI))
1223 {&RISCV::GPRRegClass}, {
LHS,
RHS});
1224 if (!Cmp1.constrainAllUses(
TII,
TRI, RBI))
1227 {&RISCV::GPRRegClass}, {
RHS,
LHS});
1228 if (!Cmp2.constrainAllUses(
TII,
TRI, RBI))
1231 TmpReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
1233 MIB.
buildInstr(RISCV::OR, {TmpReg}, {Cmp1.getReg(0), Cmp2.getReg(0)});
1234 if (!
Or.constrainAllUses(
TII,
TRI, RBI))
1241 {&RISCV::GPRRegClass}, {
LHS,
LHS});
1242 if (!Cmp1.constrainAllUses(
TII,
TRI, RBI))
1245 {&RISCV::GPRRegClass}, {
RHS,
RHS});
1246 if (!Cmp2.constrainAllUses(
TII,
TRI, RBI))
1249 TmpReg =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
1251 MIB.
buildInstr(RISCV::AND, {TmpReg}, {Cmp1.getReg(0), Cmp2.getReg(0)});
1252 if (!
And.constrainAllUses(
TII,
TRI, RBI))
1259 auto Xor = MIB.
buildInstr(RISCV::XORI, {DstReg}, {TmpReg}).addImm(1);
1260 if (!
Xor.constrainAllUses(
TII,
TRI, RBI))
1264 MI.eraseFromParent();
1268void RISCVInstructionSelector::emitFence(
AtomicOrdering FenceOrdering,
1271 if (STI.hasStdExtZtso()) {
1274 if (FenceOrdering == AtomicOrdering::SequentiallyConsistent &&
1284 MIB.
buildInstr(TargetOpcode::MEMBARRIER, {}, {});
1292 MIB.
buildInstr(TargetOpcode::MEMBARRIER, {}, {});
1298 unsigned Pred, Succ;
1299 switch (FenceOrdering) {
1302 case AtomicOrdering::AcquireRelease:
1306 case AtomicOrdering::Acquire:
1311 case AtomicOrdering::Release:
1316 case AtomicOrdering::SequentiallyConsistent:
1330 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, bool Imm=false)
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.