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
60 bool isRegInGprb(
Register Reg)
const;
61 bool isRegInFprb(
Register Reg)
const;
78 bool IsExternWeak =
false)
const;
87 unsigned ShiftWidth)
const;
88 ComplexRendererFns selectShiftMaskXLen(
MachineOperand &Root)
const {
89 return selectShiftMask(Root, STI.
getXLen());
92 return selectShiftMask(Root, 32);
96 ComplexRendererFns selectSExtBits(
MachineOperand &Root,
unsigned Bits)
const;
97 template <
unsigned Bits>
99 return selectSExtBits(Root, Bits);
102 ComplexRendererFns selectZExtBits(
MachineOperand &Root,
unsigned Bits)
const;
103 template <
unsigned Bits>
105 return selectZExtBits(Root, Bits);
108 ComplexRendererFns selectSHXADDOp(
MachineOperand &Root,
unsigned ShAmt)
const;
109 template <
unsigned ShAmt>
111 return selectSHXADDOp(Root, ShAmt);
115 unsigned ShAmt)
const;
116 template <
unsigned ShAmt>
117 ComplexRendererFns selectSHXADD_UWOp(
MachineOperand &Root)
const {
118 return selectSHXADD_UWOp(Root, ShAmt);
160#define GET_GLOBALISEL_PREDICATES_DECL
161#include "RISCVGenGlobalISel.inc"
162#undef GET_GLOBALISEL_PREDICATES_DECL
164#define GET_GLOBALISEL_TEMPORARIES_DECL
165#include "RISCVGenGlobalISel.inc"
166#undef GET_GLOBALISEL_TEMPORARIES_DECL
171#define GET_GLOBALISEL_IMPL
172#include "RISCVGenGlobalISel.inc"
173#undef GET_GLOBALISEL_IMPL
175RISCVInstructionSelector::RISCVInstructionSelector(
178 : STI(STI),
TII(*STI.getInstrInfo()),
TRI(*STI.getRegisterInfo()), RBI(RBI),
182#include
"RISCVGenGlobalISel.inc"
185#include
"RISCVGenGlobalISel.inc"
192 unsigned ShiftWidth)
const {
202 ShAmtReg = ZExtSrcReg;
222 if (ShMask.isSubsetOf(AndMask)) {
223 ShAmtReg = AndSrcReg;
227 KnownBits Known = KB->getKnownBits(AndSrcReg);
228 if (ShMask.isSubsetOf(AndMask | Known.
Zero))
229 ShAmtReg = AndSrcReg;
236 if (Imm != 0 &&
Imm.urem(ShiftWidth) == 0)
241 if (Imm != 0 &&
Imm.urem(ShiftWidth) == 0) {
244 ShAmtReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
245 unsigned NegOpc = Subtarget->is64Bit() ? RISCV::SUBW : RISCV::SUB;
252 if (
Imm.urem(ShiftWidth) == ShiftWidth - 1) {
255 ShAmtReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
270 unsigned Bits)
const {
276 if (RootDef->
getOpcode() == TargetOpcode::G_SEXT_INREG &&
282 unsigned Size =
MRI->getType(RootReg).getScalarSizeInBits();
283 if ((
Size - KB->computeNumSignBits(RootReg)) <
Bits)
291 unsigned Bits)
const {
303 MRI->getType(RegX).getScalarSizeInBits() ==
Bits)
306 unsigned Size =
MRI->getType(RootReg).getScalarSizeInBits();
315 unsigned ShAmt)
const {
322 const unsigned XLen = STI.getXLen();
341 if (
Mask.isShiftedMask()) {
342 unsigned Leading = XLen -
Mask.getActiveBits();
343 unsigned Trailing =
Mask.countr_zero();
346 if (*LeftShift && Leading == 0 && C2.
ult(Trailing) && Trailing == ShAmt) {
347 Register DstReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
358 if (!*LeftShift && Leading == C2 && Trailing == ShAmt) {
359 Register DstReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
363 .addImm(Leading + Trailing);
384 unsigned Leading = XLen -
Mask.getActiveBits();
385 unsigned Trailing =
Mask.countr_zero();
398 Register DstReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
413 unsigned ShAmt)
const {
431 if (
Mask.isShiftedMask()) {
432 unsigned Leading =
Mask.countl_zero();
433 unsigned Trailing =
Mask.countr_zero();
434 if (Leading == 32 - ShAmt && C2 == Trailing && Trailing > ShAmt) {
435 Register DstReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
451 assert(Root.
isReg() &&
"Expected operand to be a Register");
454 if (RootDef->
getOpcode() == TargetOpcode::G_CONSTANT) {
456 if (
C->getValue().isAllOnes())
464 if (isUInt<5>(
C->getZExtValue())) {
473RISCVInstructionSelector::selectAddrRegImm(
MachineOperand &Root)
const {
478 if (RootDef->
getOpcode() == TargetOpcode::G_FRAME_INDEX) {
485 if (isBaseWithConstantOffset(Root, *
MRI)) {
492 if (isInt<12>(RHSC)) {
493 if (LHSDef->
getOpcode() == TargetOpcode::G_FRAME_INDEX)
516 case CmpInst::Predicate::ICMP_EQ:
518 case CmpInst::Predicate::ICMP_NE:
520 case CmpInst::Predicate::ICMP_ULT:
522 case CmpInst::Predicate::ICMP_SLT:
524 case CmpInst::Predicate::ICMP_UGE:
526 case CmpInst::Predicate::ICMP_SGE:
548 case CmpInst::Predicate::ICMP_SGT:
556 case CmpInst::Predicate::ICMP_SLT:
573 case CmpInst::Predicate::ICMP_EQ:
574 case CmpInst::Predicate::ICMP_NE:
575 case CmpInst::Predicate::ICMP_ULT:
576 case CmpInst::Predicate::ICMP_SLT:
577 case CmpInst::Predicate::ICMP_UGE:
578 case CmpInst::Predicate::ICMP_SGE:
581 case CmpInst::Predicate::ICMP_SGT:
582 case CmpInst::Predicate::ICMP_SLE:
583 case CmpInst::Predicate::ICMP_UGT:
584 case CmpInst::Predicate::ICMP_ULE:
592 CC = getRISCVCCFromICmp(Pred);
598 preISelLower(
MI, MIB);
599 const unsigned Opc =
MI.getOpcode();
601 if (!
MI.isPreISelOpcode() || Opc == TargetOpcode::G_PHI) {
602 if (Opc == TargetOpcode::PHI || Opc == TargetOpcode::G_PHI) {
603 const Register DefReg =
MI.getOperand(0).getReg();
604 const LLT DefTy =
MRI->getType(DefReg);
607 MRI->getRegClassOrRegBank(DefReg);
610 dyn_cast<const TargetRegisterClass *>(RegClassOrBank);
617 const RegisterBank &RB = *cast<const RegisterBank *>(RegClassOrBank);
618 DefRC = getRegClassForTypeOnBank(DefTy, RB);
625 MI.setDesc(
TII.get(TargetOpcode::PHI));
626 return RBI.constrainGenericRegister(DefReg, *DefRC, *
MRI);
636 if (selectImpl(
MI, *CoverageInfo))
640 case TargetOpcode::G_ANYEXT:
641 case TargetOpcode::G_PTRTOINT:
642 case TargetOpcode::G_INTTOPTR:
643 case TargetOpcode::G_TRUNC:
644 case TargetOpcode::G_FREEZE:
646 case TargetOpcode::G_CONSTANT: {
648 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue();
650 if (!materializeImm(DstReg, Imm, MIB))
653 MI.eraseFromParent();
656 case TargetOpcode::G_FCONSTANT: {
660 const APFloat &FPimm =
MI.getOperand(1).getFPImm()->getValueAPF();
662 unsigned Size =
MRI->getType(DstReg).getSizeInBits();
663 if (
Size == 16 ||
Size == 32 || (
Size == 64 && Subtarget->is64Bit())) {
664 Register GPRReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
665 if (!materializeImm(GPRReg,
Imm.getSExtValue(), MIB))
668 unsigned Opcode =
Size == 64 ? RISCV::FMV_D_X
669 :
Size == 32 ? RISCV::FMV_W_X
671 auto FMV = MIB.buildInstr(Opcode, {DstReg}, {GPRReg});
672 if (!FMV.constrainAllUses(
TII,
TRI, RBI))
676 "Unexpected size or subtarget");
678 Register GPRRegHigh =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
679 Register GPRRegLow =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
680 if (!materializeImm(GPRRegHigh,
Imm.extractBits(32, 32).getSExtValue(),
683 if (!materializeImm(GPRRegLow,
Imm.trunc(32).getSExtValue(), MIB))
686 RISCV::BuildPairF64Pseudo, {DstReg}, {GPRRegLow, GPRRegHigh});
691 MI.eraseFromParent();
694 case TargetOpcode::G_GLOBAL_VALUE: {
695 auto *GV =
MI.getOperand(1).getGlobal();
696 if (GV->isThreadLocal()) {
701 return selectAddr(
MI, MIB, GV->isDSOLocal(), GV->hasExternalWeakLinkage());
703 case TargetOpcode::G_JUMP_TABLE:
704 case TargetOpcode::G_CONSTANT_POOL:
705 return selectAddr(
MI, MIB,
MRI);
706 case TargetOpcode::G_BRCOND: {
712 .addMBB(
MI.getOperand(1).getMBB());
713 MI.eraseFromParent();
716 case TargetOpcode::G_BRINDIRECT:
717 MI.setDesc(
TII.get(RISCV::PseudoBRIND));
720 case TargetOpcode::G_SELECT:
721 return selectSelect(
MI, MIB);
722 case TargetOpcode::G_FCMP:
723 return selectFPCompare(
MI, MIB);
724 case TargetOpcode::G_FENCE: {
729 emitFence(FenceOrdering, FenceSSID, MIB);
730 MI.eraseFromParent();
733 case TargetOpcode::G_IMPLICIT_DEF:
734 return selectImplicitDef(
MI, MIB);
735 case TargetOpcode::G_MERGE_VALUES:
737 case TargetOpcode::G_UNMERGE_VALUES:
746 assert(
MI.getOpcode() == TargetOpcode::G_MERGE_VALUES);
749 if (
MI.getNumOperands() != 3)
754 if (!isRegInFprb(Dst) || !isRegInGprb(
Lo) || !isRegInGprb(
Hi))
756 MI.setDesc(
TII.get(RISCV::BuildPairF64Pseudo));
760bool RISCVInstructionSelector::selectUnmergeValues(
762 assert(
MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES);
765 if (
MI.getNumOperands() != 3)
770 if (!isRegInFprb(Src) || !isRegInGprb(
Lo) || !isRegInGprb(
Hi))
772 MI.setDesc(
TII.get(RISCV::SplitF64Pseudo));
779 assert(
MRI->getType(PtrReg).isPointer() &&
"Operand is not a pointer!");
783 MRI->setRegBank(PtrToInt.getReg(0), RBI.getRegBank(RISCV::GPRBRegBankID));
784 Op.setReg(PtrToInt.getReg(0));
785 return select(*PtrToInt);
790 switch (
MI.getOpcode()) {
791 case TargetOpcode::G_PTR_ADD: {
795 replacePtrWithInt(
MI.getOperand(1), MIB);
796 MI.setDesc(
TII.get(TargetOpcode::G_ADD));
797 MRI->setType(DstReg, sXLen);
800 case TargetOpcode::G_PTRMASK: {
803 replacePtrWithInt(
MI.getOperand(1), MIB);
804 MI.setDesc(
TII.get(TargetOpcode::G_AND));
805 MRI->setType(DstReg, sXLen);
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 CstVal =
MI.getOperand(1).getCImm()->getZExtValue();
826 MIB.
addImm(STI.getXLen() - CstVal);
832 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
833 "Expected G_CONSTANT");
834 uint64_t CstVal =
MI.getOperand(1).getCImm()->getZExtValue();
841 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
842 "Expected G_CONSTANT");
843 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
850 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
851 "Expected G_CONSTANT");
852 int64_t CstVal =
MI.getOperand(1).getCImm()->getSExtValue();
859 assert(
MI.getOpcode() == TargetOpcode::G_FRAME_INDEX && OpIdx == -1 &&
860 "Expected G_FRAME_INDEX");
861 MIB.
add(
MI.getOperand(1));
867 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
868 "Expected G_CONSTANT");
869 uint64_t C =
MI.getOperand(1).getCImm()->getZExtValue();
873void RISCVInstructionSelector::renderXLenSubTrailingOnes(
875 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
876 "Expected G_CONSTANT");
877 uint64_t C =
MI.getOperand(1).getCImm()->getZExtValue();
884 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
885 "Expected G_CONSTANT");
886 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue();
887 int64_t Adj =
Imm < 0 ? -2048 : 2047;
894 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
895 "Expected G_CONSTANT");
896 int64_t
Imm =
MI.getOperand(1).getCImm()->getSExtValue() < 0 ? -2048 : 2047;
902 if (RB.
getID() == RISCV::GPRBRegBankID) {
904 return &RISCV::GPRRegClass;
907 if (RB.
getID() == RISCV::FPRBRegBankID) {
909 return &RISCV::FPR16RegClass;
911 return &RISCV::FPR32RegClass;
913 return &RISCV::FPR64RegClass;
916 if (RB.
getID() == RISCV::VRBRegBankID) {
918 return &RISCV::VRRegClass;
921 return &RISCV::VRM2RegClass;
924 return &RISCV::VRM4RegClass;
927 return &RISCV::VRM8RegClass;
933bool RISCVInstructionSelector::isRegInGprb(
Register Reg)
const {
934 return RBI.getRegBank(Reg, *
MRI,
TRI)->
getID() == RISCV::GPRBRegBankID;
937bool RISCVInstructionSelector::isRegInFprb(
Register Reg)
const {
938 return RBI.getRegBank(Reg, *
MRI,
TRI)->getID() == RISCV::FPRBRegBankID;
941bool RISCVInstructionSelector::selectCopy(
MachineInstr &
MI)
const {
948 MRI->getType(DstReg), *RBI.getRegBank(DstReg, *
MRI,
TRI));
950 "Register class not available for LLT, register bank combination");
955 if (!RBI.constrainGenericRegister(DstReg, *DstRC, *
MRI)) {
961 MI.setDesc(
TII.get(RISCV::COPY));
967 assert(
MI.getOpcode() == TargetOpcode::G_IMPLICIT_DEF);
969 const Register DstReg =
MI.getOperand(0).getReg();
971 MRI->getType(DstReg), *RBI.getRegBank(DstReg, *
MRI,
TRI));
974 "Register class not available for LLT, register bank combination");
976 if (!RBI.constrainGenericRegister(DstReg, *DstRC, *
MRI)) {
980 MI.setDesc(
TII.get(TargetOpcode::IMPLICIT_DEF));
984bool RISCVInstructionSelector::materializeImm(
Register DstReg, int64_t Imm,
988 RBI.constrainGenericRegister(DstReg, RISCV::GPRRegClass, *
MRI);
993 unsigned NumInsts = Seq.
size();
996 for (
unsigned i = 0; i < NumInsts; i++) {
998 ?
MRI->createVirtualRegister(&RISCV::GPRRegClass)
1003 switch (
I.getOpndKind()) {
1012 {SrcReg, Register(RISCV::X0)});
1034 bool IsExternWeak)
const {
1035 assert((
MI.getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
1036 MI.getOpcode() == TargetOpcode::G_JUMP_TABLE ||
1037 MI.getOpcode() == TargetOpcode::G_CONSTANT_POOL) &&
1038 "Unexpected opcode");
1043 const LLT DefTy =
MRI->getType(DefReg);
1049 if (
TM.isPositionIndependent() || Subtarget->allowTaggedGlobals()) {
1050 if (IsLocal && !Subtarget->allowTaggedGlobals()) {
1054 MI.setDesc(
TII.get(RISCV::PseudoLLA));
1076 MI.eraseFromParent();
1080 switch (
TM.getCodeModel()) {
1083 getName(),
"Unsupported code model for lowering",
MI);
1090 Register AddrHiDest =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1103 MI.eraseFromParent();
1130 MI.eraseFromParent();
1137 MI.setDesc(
TII.get(RISCV::PseudoLLA));
1146 auto &SelectMI = cast<GSelect>(
MI);
1152 Register DstReg = SelectMI.getReg(0);
1154 unsigned Opc = RISCV::Select_GPR_Using_CC_GPR;
1155 if (RBI.getRegBank(DstReg, *
MRI,
TRI)->getID() == RISCV::FPRBRegBankID) {
1156 unsigned Size =
MRI->getType(DstReg).getSizeInBits();
1157 Opc =
Size == 32 ? RISCV::Select_FPR32_Using_CC_GPR
1158 : RISCV::Select_FPR64_Using_CC_GPR;
1166 .
addReg(SelectMI.getTrueReg())
1167 .
addReg(SelectMI.getFalseReg());
1168 MI.eraseFromParent();
1179 return Size == 16 ? RISCV::FLT_H :
Size == 32 ? RISCV::FLT_S : RISCV::FLT_D;
1181 return Size == 16 ? RISCV::FLE_H :
Size == 32 ? RISCV::FLE_S : RISCV::FLE_D;
1183 return Size == 16 ? RISCV::FEQ_H :
Size == 32 ? RISCV::FEQ_S : RISCV::FEQ_D;
1196 assert(!isLegalFCmpPredicate(Pred) &&
"Predicate already legal?");
1199 if (isLegalFCmpPredicate(InvPred)) {
1207 if (isLegalFCmpPredicate(InvPred)) {
1212 if (isLegalFCmpPredicate(InvPred)) {
1226 auto &CmpMI = cast<GFCmp>(
MI);
1233 unsigned Size =
MRI->getType(LHS).getSizeInBits();
1238 bool NeedInvert =
false;
1242 TmpReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1244 if (!
Cmp.constrainAllUses(
TII,
TRI, RBI))
1250 {&RISCV::GPRRegClass}, {
LHS,
RHS});
1251 if (!Cmp1.constrainAllUses(
TII,
TRI, RBI))
1254 {&RISCV::GPRRegClass}, {
RHS,
LHS});
1255 if (!Cmp2.constrainAllUses(
TII,
TRI, RBI))
1258 TmpReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1260 MIB.
buildInstr(RISCV::OR, {TmpReg}, {Cmp1.getReg(0), Cmp2.getReg(0)});
1261 if (!
Or.constrainAllUses(
TII,
TRI, RBI))
1268 {&RISCV::GPRRegClass}, {
LHS,
LHS});
1269 if (!Cmp1.constrainAllUses(
TII,
TRI, RBI))
1272 {&RISCV::GPRRegClass}, {
RHS,
RHS});
1273 if (!Cmp2.constrainAllUses(
TII,
TRI, RBI))
1276 TmpReg =
MRI->createVirtualRegister(&RISCV::GPRRegClass);
1278 MIB.
buildInstr(RISCV::AND, {TmpReg}, {Cmp1.getReg(0), Cmp2.getReg(0)});
1279 if (!
And.constrainAllUses(
TII,
TRI, RBI))
1286 auto Xor = MIB.
buildInstr(RISCV::XORI, {DstReg}, {TmpReg}).addImm(1);
1287 if (!
Xor.constrainAllUses(
TII,
TRI, RBI))
1291 MI.eraseFromParent();
1295void RISCVInstructionSelector::emitFence(
AtomicOrdering FenceOrdering,
1298 if (STI.hasStdExtZtso()) {
1301 if (FenceOrdering == AtomicOrdering::SequentiallyConsistent &&
1311 MIB.
buildInstr(TargetOpcode::MEMBARRIER, {}, {});
1319 MIB.
buildInstr(TargetOpcode::MEMBARRIER, {}, {});
1325 unsigned Pred, Succ;
1326 switch (FenceOrdering) {
1329 case AtomicOrdering::AcquireRelease:
1333 case AtomicOrdering::Acquire:
1338 case AtomicOrdering::Release:
1343 case AtomicOrdering::SequentiallyConsistent:
1357 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
static StringRef getName(Value *V)
#define GET_GLOBALISEL_PREDICATES_INIT
#define GET_GLOBALISEL_TEMPORARIES_INIT
static unsigned getFCmpOpcode(CmpInst::Predicate Pred, unsigned Size)
static bool legalizeFCmpPredicate(Register &LHS, Register &RHS, CmpInst::Predicate &Pred, bool &NeedInvert)
static void getOperandsForBranch(Register CondReg, RISCVCC::CondCode &CC, Register &LHS, Register &RHS, MachineRegisterInfo &MRI)
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.
static APInt getBitsSetFrom(unsigned numBits, unsigned loBit)
Constructs an APInt value that has a contiguous range of bits set.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
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 void setupMF(MachineFunction &mf, GISelKnownBits *kb, CodeGenCoverage *covinfo=nullptr, ProfileSummaryInfo *psi=nullptr, BlockFrequencyInfo *bfi=nullptr)
Setup per-MF executor state.
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.
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.
Helper class to build MachineInstr.
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
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 & add(const MachineOperand &MO) const
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 MachineOperand & getOperand(unsigned i) 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.
static MachineOperand CreateImm(int64_t Val)
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Analysis providing profile information.
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.
operand_type_match m_Reg()
SpecificConstantMatch m_SpecificICst(int64_t RequestedValue)
Matches a constant equal to RequestedValue.
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)
static constexpr int64_t VLMaxSentinel
@ 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.
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
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...
InstructionSelector * createRISCVInstructionSelector(const RISCVTargetMachine &TM, const RISCVSubtarget &Subtarget, const RISCVRegisterBankInfo &RBI)
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.
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.
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 getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.