23#define DEBUG_TYPE "arm-isel"
29#define GET_GLOBALISEL_PREDICATE_BITSET
30#include "ARMGenGlobalISel.inc"
31#undef GET_GLOBALISEL_PREDICATE_BITSET
53 bool insertComparison(CmpConstants Helper, InsertInfo
I,
unsigned ResReg,
55 unsigned PrevRes)
const;
58 void putConstant(InsertInfo
I,
unsigned DestReg,
unsigned Constant)
const;
67 unsigned ExpectedSize,
unsigned ExpectedRegBankID)
const;
71 unsigned ExpectedRegBankID)
const;
122 unsigned ConstPoolLoad;
123 unsigned MOV_ga_pcrel;
124 unsigned LDRLIT_ga_pcrel;
125 unsigned LDRLIT_ga_abs;
134 unsigned selectSimpleExtOpc(
unsigned Opc,
unsigned Size)
const;
138 unsigned selectLoadStoreOpCode(
unsigned Opc,
unsigned RegBank,
139 unsigned Size)
const;
142 int OpIdx = -1)
const;
144 int OpIdx = -1)
const;
146 int OpIdx = -1)
const;
148#define GET_GLOBALISEL_PREDICATES_DECL
149#include "ARMGenGlobalISel.inc"
150#undef GET_GLOBALISEL_PREDICATES_DECL
154#define GET_GLOBALISEL_TEMPORARIES_DECL
155#include "ARMGenGlobalISel.inc"
156#undef GET_GLOBALISEL_TEMPORARIES_DECL
165 return new ARMInstructionSelector(TM, STI, RBI);
169#define GET_GLOBALISEL_IMPL
170#include "ARMGenGlobalISel.inc"
171#undef GET_GLOBALISEL_IMPL
176 :
TII(*STI.getInstrInfo()),
TRI(*STI.getRegisterInfo()), TM(TM), RBI(RBI),
177 STI(STI), Opcodes(STI),
179#include
"ARMGenGlobalISel.inc"
182#include
"ARMGenGlobalISel.inc"
192 assert(RegBank &&
"Can't get reg bank for virtual register");
194 const unsigned Size =
MRI.getType(
Reg).getSizeInBits();
196 RegBank->
getID() == ARM::FPRRegBankID) &&
197 "Unsupported reg bank");
199 if (RegBank->
getID() == ARM::FPRRegBankID) {
201 return &ARM::SPRRegClass;
203 return &ARM::DPRRegClass;
204 else if (
Size == 128)
205 return &ARM::QPRRegClass;
210 return &ARM::GPRRegClass;
216 Register DstReg =
I.getOperand(0).getReg();
239 "Can't select merge without FP Regs");
245 assert(
MRI.getType(VReg0).getSizeInBits() == 64 &&
247 "Unsupported operand for G_MERGE_VALUES");
250 assert(
MRI.getType(VReg1).getSizeInBits() == 32 &&
252 "Unsupported operand for G_MERGE_VALUES");
255 assert(
MRI.getType(VReg2).getSizeInBits() == 32 &&
257 "Unsupported operand for G_MERGE_VALUES");
271 "Can't select unmerge without FP Regs");
277 assert(
MRI.getType(VReg0).getSizeInBits() == 32 &&
279 "Unsupported operand for G_UNMERGE_VALUES");
282 assert(
MRI.getType(VReg1).getSizeInBits() == 32 &&
284 "Unsupported operand for G_UNMERGE_VALUES");
287 assert(
MRI.getType(VReg2).getSizeInBits() == 64 &&
289 "Unsupported operand for G_UNMERGE_VALUES");
297ARMInstructionSelector::OpcodeCache::OpcodeCache(
const ARMSubtarget &STI) {
300 using namespace TargetOpcode;
302#define STORE_OPCODE(VAR, OPC) VAR = isThumb ? ARM::t2##OPC : ARM::OPC
316 STORE16 =
isThumb ? ARM::t2STRHi12 : ARM::STRH;
317 LOAD16 =
isThumb ? ARM::t2LDRHi12 : ARM::LDRH;
335 ConstPoolLoad =
isThumb ? ARM::t2LDRpci : ARM::LDRi12;
337 LDRLIT_ga_pcrel =
isThumb ? ARM::tLDRLIT_ga_pcrel : ARM::LDRLIT_ga_pcrel;
338 LDRLIT_ga_abs =
isThumb ? ARM::tLDRLIT_ga_abs : ARM::LDRLIT_ga_abs;
342unsigned ARMInstructionSelector::selectSimpleExtOpc(
unsigned Opc,
343 unsigned Size)
const {
344 using namespace TargetOpcode;
350 return Size == 8 ? Opcodes.SEXT8 : Opcodes.SEXT16;
353 return Size == 8 ? Opcodes.ZEXT8 : Opcodes.ZEXT16;
358unsigned ARMInstructionSelector::selectLoadStoreOpCode(
unsigned Opc,
360 unsigned Size)
const {
363 if (RegBank == ARM::GPRRegBankID) {
367 return isStore ? Opcodes.STORE8 : Opcodes.LOAD8;
369 return isStore ? Opcodes.STORE16 : Opcodes.LOAD16;
371 return isStore ? Opcodes.STORE32 : Opcodes.LOAD32;
377 if (RegBank == ARM::FPRRegBankID) {
380 return isStore ? ARM::VSTRS : ARM::VLDRS;
382 return isStore ? ARM::VSTRD : ARM::VLDRD;
394static std::pair<ARMCC::CondCodes, ARMCC::CondCodes>
462 CmpConstants(
unsigned CmpOpcode,
unsigned FlagsOpcode,
unsigned SelectOpcode,
463 unsigned OpRegBank,
unsigned OpSize)
495void ARMInstructionSelector::putConstant(
InsertInfo I,
unsigned DestReg,
497 (void)
BuildMI(
I.MBB,
I.InsertBefore,
I.DbgLoc, TII.get(Opcodes.MOVi))
505 unsigned LHSReg,
unsigned RHSReg,
506 unsigned ExpectedSize,
507 unsigned ExpectedRegBankID)
const {
508 return MRI.getType(LHSReg) ==
MRI.getType(RHSReg) &&
509 validReg(
MRI, LHSReg, ExpectedSize, ExpectedRegBankID) &&
510 validReg(
MRI, RHSReg, ExpectedSize, ExpectedRegBankID);
513bool ARMInstructionSelector::validReg(MachineRegisterInfo &
MRI,
unsigned Reg,
514 unsigned ExpectedSize,
515 unsigned ExpectedRegBankID)
const {
529bool ARMInstructionSelector::selectCmp(CmpConstants Helper,
530 MachineInstrBuilder &MIB,
531 MachineRegisterInfo &
MRI)
const {
532 const InsertInfo
I(MIB);
534 auto ResReg = MIB.
getReg(0);
535 if (!validReg(
MRI, ResReg, 1, ARM::GPRRegBankID))
546 auto LHSReg = MIB.
getReg(2);
547 auto RHSReg = MIB.
getReg(3);
548 if (!validOpRegPair(
MRI, LHSReg, RHSReg, Helper.OperandSize,
549 Helper.OperandRegBankID))
554 putConstant(
I, ZeroReg, 0);
558 if (!insertComparison(Helper,
I, ResReg, ARMConds.first, LHSReg, RHSReg,
564 if (!insertComparison(Helper,
I, IntermediateRes, ARMConds.first, LHSReg,
567 if (!insertComparison(Helper,
I, ResReg, ARMConds.second, LHSReg, RHSReg,
576bool ARMInstructionSelector::insertComparison(CmpConstants Helper, InsertInfo
I,
579 unsigned LHSReg,
unsigned RHSReg,
580 unsigned PrevRes)
const {
583 BuildMI(
I.MBB,
I.InsertBefore,
I.DbgLoc,
TII.get(Helper.ComparisonOpcode))
590 if (Helper.ReadFlagsOpcode != ARM::INSTRUCTION_LIST_END) {
591 auto ReadI =
BuildMI(
I.MBB,
I.InsertBefore,
I.DbgLoc,
592 TII.get(Helper.ReadFlagsOpcode))
598 auto Mov1I =
BuildMI(
I.MBB,
I.InsertBefore,
I.DbgLoc,
599 TII.get(Helper.SelectResultOpcode))
609bool ARMInstructionSelector::selectGlobal(MachineInstrBuilder &MIB,
610 MachineRegisterInfo &
MRI)
const {
617 if (GV->isThreadLocal()) {
630 auto addOpsForConstantPoolLoad = [&MF,
Alignment, PtrTy](
631 MachineInstrBuilder &MIB,
632 const GlobalValue *GV,
bool IsSBREL) {
633 assert((MIB->getOpcode() == ARM::LDRi12 ||
634 MIB->getOpcode() == ARM::t2LDRpci) &&
635 "Unsupported instruction");
636 auto ConstPool = MF.getConstantPool();
641 ? ConstPool->getConstantPoolIndex(
643 : ConstPool->getConstantPoolIndex(GV, Alignment);
644 MIB.addConstantPoolIndex(CPIndex, 0, 0)
645 .addMemOperand(MF.getMachineMemOperand(
648 if (MIB->getOpcode() == ARM::LDRi12)
653 auto addGOTMemOperand = [&MF,
Alignment](MachineInstrBuilder &MIB) {
654 const DataLayout &
DL = MF.getDataLayout();
655 MIB.addMemOperand(MF.getMachineMemOperand(
657 DL.getPointerSize(
DL.getProgramAddressSpace()), Alignment));
668 bool UseOpcodeThatLoads =
Indirect && !STI.isThumb();
674 ? (UseOpcodeThatLoads ? (unsigned)ARM::MOV_ga_pcrel_ldr
675 : Opcodes.MOV_ga_pcrel)
676 : (UseOpcodeThatLoads ? (unsigned)
ARM::LDRLIT_ga_pcrel_ldr
677 : Opcodes.LDRLIT_ga_pcrel);
678 MIB->setDesc(
TII.get(
Opc));
685 MIB->getOperand(1).setTargetFlags(TargetFlags);
688 if (!UseOpcodeThatLoads) {
689 auto ResultReg = MIB.getReg(0);
692 MIB->getOperand(0).setReg(AddressReg);
694 auto InsertBefore = std::next(MIB->getIterator());
695 auto MIBLoad =
BuildMI(
MBB, InsertBefore, MIB->getDebugLoc(),
696 TII.get(Opcodes.LOAD32))
701 addGOTMemOperand(MIBLoad);
705 addGOTMemOperand(MIB);
714 if (STI.
isROPI() && isReadOnly) {
715 unsigned Opc = UseMovt ? Opcodes.MOV_ga_pcrel : Opcodes.LDRLIT_ga_pcrel;
716 MIB->setDesc(
TII.get(
Opc));
720 if (STI.
isRWPI() && !isReadOnly) {
722 MachineInstrBuilder OffsetMIB;
724 OffsetMIB =
BuildMI(
MBB, *MIB, MIB->getDebugLoc(),
729 OffsetMIB =
BuildMI(
MBB, *MIB, MIB->getDebugLoc(),
731 addOpsForConstantPoolLoad(OffsetMIB, GV,
true);
736 MIB->setDesc(
TII.get(Opcodes.ADDrr));
737 MIB->removeOperand(1);
749 MIB->setDesc(
TII.get(Opcodes.MOVi32imm));
752 MIB->setDesc(
TII.get(Opcodes.ConstPoolLoad));
753 MIB->removeOperand(1);
754 addOpsForConstantPoolLoad(MIB, GV,
false);
758 MIB->setDesc(
TII.get(Opcodes.MOVi32imm));
760 MIB->setDesc(
TII.get(Opcodes.LDRLIT_ga_abs));
770bool ARMInstructionSelector::selectSelect(MachineInstrBuilder &MIB,
771 MachineRegisterInfo &
MRI)
const {
777 auto CondReg = MIB.
getReg(1);
778 assert(validReg(
MRI, CondReg, 1, ARM::GPRRegBankID) &&
779 "Unsupported types for select operation");
780 auto CmpI =
BuildMI(
MBB, InsertBefore, DbgLoc,
TII.get(Opcodes.TSTri))
788 auto ResReg = MIB.
getReg(0);
789 auto TrueReg = MIB.
getReg(2);
790 auto FalseReg = MIB.
getReg(3);
791 assert(validOpRegPair(
MRI, ResReg, TrueReg, 32, ARM::GPRRegBankID) &&
792 validOpRegPair(
MRI, TrueReg, FalseReg, 32, ARM::GPRRegBankID) &&
793 "Unsupported types for select operation");
794 auto Mov1I =
BuildMI(
MBB, InsertBefore, DbgLoc,
TII.get(Opcodes.MOVCCr))
805bool ARMInstructionSelector::selectShift(
unsigned ShiftOpc,
806 MachineInstrBuilder &MIB)
const {
807 assert(!STI.isThumb() &&
"Unsupported subtarget");
815void ARMInstructionSelector::renderVFPF32Imm(
816 MachineInstrBuilder &NewInstBuilder,
const MachineInstr &OldInst,
819 OpIdx == -1 &&
"Expected G_FCONSTANT");
823 assert(FPImmEncoding != -1 &&
"Invalid immediate value");
825 NewInstBuilder.
addImm(FPImmEncoding);
828void ARMInstructionSelector::renderVFPF64Imm(
829 MachineInstrBuilder &NewInstBuilder,
const MachineInstr &OldInst,
int OpIdx)
const {
831 OpIdx == -1 &&
"Expected G_FCONSTANT");
835 assert(FPImmEncoding != -1 &&
"Invalid immediate value");
837 NewInstBuilder.
addImm(FPImmEncoding);
840void ARMInstructionSelector::renderInvertedImm(MachineInstrBuilder &MIB,
841 const MachineInstr &
MI,
843 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
844 "Expected G_CONSTANT");
845 int64_t CVal =
MI.getOperand(1).getCImm()->getSExtValue();
849bool ARMInstructionSelector::select(MachineInstr &
I) {
850 assert(
I.getParent() &&
"Instruction should be in a basic block!");
851 assert(
I.getParent()->getParent() &&
"Instruction should be in a function!");
855 auto &
MRI = MF.getRegInfo();
864 using namespace TargetOpcode;
866 if (selectImpl(
I, *CoverageInfo))
869 MachineInstrBuilder MIB{MF,
I};
872 switch (
I.getOpcode()) {
873 case TargetOpcode::G_BITCAST:
874 I.setDesc(
TII.get(COPY));
881 "Unsupported destination size for extension");
888 I.setDesc(
TII.get(Opcodes.AND));
892 Register SExtResult =
I.getOperand(0).getReg();
896 I.getOperand(0).setReg(AndResult);
898 auto InsertBefore = std::next(
I.getIterator());
912 unsigned NewOpc = selectSimpleExtOpc(
I.getOpcode(), SrcSize);
913 if (NewOpc ==
I.getOpcode())
915 I.setDesc(
TII.get(NewOpc));
929 auto SrcReg =
I.getOperand(1).getReg();
930 auto DstReg =
I.getOperand(0).getReg();
935 if (SrcRegBank.getID() == ARM::FPRRegBankID) {
939 assert(
I.getOpcode() == G_TRUNC &&
"Unsupported operand for G_ANYEXT");
940 assert(DstRegBank.getID() == ARM::GPRRegBankID &&
941 "Unsupported combination of register banks");
946 auto InsertBefore = std::next(
I.getIterator());
948 BuildMI(
MBB, InsertBefore,
I.getDebugLoc(),
TII.get(ARM::VMOVRRD))
959 if (SrcRegBank.getID() != DstRegBank.getID()) {
961 dbgs() <<
"G_TRUNC/G_ANYEXT operands on different register banks\n");
965 if (SrcRegBank.getID() != ARM::GPRRegBankID) {
966 LLVM_DEBUG(
dbgs() <<
"G_TRUNC/G_ANYEXT on non-GPR not supported yet\n");
970 I.setDesc(
TII.get(COPY));
980 auto &Val =
I.getOperand(1);
982 if (!Val.getCImm()->isZero()) {
986 Val.ChangeToImmediate(0);
988 assert(Val.isImm() &&
"Unexpected operand for G_CONSTANT");
989 if (Val.getImm() != 0) {
995 assert(!STI.isThumb() &&
"Unsupported subtarget");
996 I.setDesc(
TII.get(ARM::MOVi));
1005 assert((
Size == 4 ||
Size == 8) &&
"Unsupported FP constant type");
1006 auto LoadOpcode =
Size == 4 ? ARM::VLDRS : ARM::VLDRD;
1008 auto ConstPool = MF.getConstantPool();
1010 ConstPool->getConstantPoolIndex(
I.getOperand(1).getFPImm(), Alignment);
1023 auto SrcReg =
I.getOperand(1).getReg();
1024 auto DstReg =
I.getOperand(0).getReg();
1029 if (SrcRegBank.getID() != DstRegBank.getID()) {
1032 <<
"G_INTTOPTR/G_PTRTOINT operands on different register banks\n");
1036 if (SrcRegBank.getID() != ARM::GPRRegBankID) {
1038 dbgs() <<
"G_INTTOPTR/G_PTRTOINT on non-GPR not supported yet\n");
1042 I.setDesc(
TII.get(COPY));
1046 return selectSelect(MIB,
MRI);
1048 CmpConstants Helper(Opcodes.CMPrr, ARM::INSTRUCTION_LIST_END,
1049 Opcodes.MOVCCi, ARM::GPRRegBankID, 32);
1050 return selectCmp(Helper, MIB,
MRI);
1055 Register OpReg =
I.getOperand(2).getReg();
1058 if (
Size == 64 && !STI.hasFP64()) {
1059 LLVM_DEBUG(
dbgs() <<
"Subtarget only supports single precision");
1067 CmpConstants Helper(
Size == 32 ? ARM::VCMPS : ARM::VCMPD, ARM::FMSTAT,
1068 Opcodes.MOVCCi, ARM::FPRRegBankID,
Size);
1069 return selectCmp(Helper, MIB,
MRI);
1072 return selectShift(ARM_AM::ShiftOpc::lsr, MIB);
1074 return selectShift(ARM_AM::ShiftOpc::asr, MIB);
1076 return selectShift(ARM_AM::ShiftOpc::lsl, MIB);
1079 I.setDesc(
TII.get(Opcodes.ADDrr));
1085 I.setDesc(
TII.get(Opcodes.ADDri));
1088 case G_GLOBAL_VALUE:
1089 return selectGlobal(MIB,
MRI);
1092 auto &MemOp = **
I.memoperands_begin();
1093 if (MemOp.isAtomic()) {
1105 "Don't know how to load/store 64-bit value without VFP");
1108 Register PtrReg = LoadMI->getPointerReg();
1110 if (Ptr->
getOpcode() == TargetOpcode::G_CONSTANT_POOL) {
1112 unsigned Opcode =
Subtarget->isThumb() ? ARM::tLDRpci : ARM::LDRcp;
1121 I.eraseFromParent();
1126 const auto NewOpc = selectLoadStoreOpCode(
I.getOpcode(), RegBank, ValSize);
1127 if (NewOpc == G_LOAD || NewOpc == G_STORE)
1130 I.setDesc(
TII.get(NewOpc));
1132 if (NewOpc == ARM::LDRH || NewOpc == ARM::STRH)
1138 case G_MERGE_VALUES: {
1143 case G_UNMERGE_VALUES: {
1149 if (!validReg(
MRI,
I.getOperand(0).getReg(), 1, ARM::GPRRegBankID)) {
1150 LLVM_DEBUG(
dbgs() <<
"Unsupported condition register for G_BRCOND");
1156 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Opcodes.TSTri))
1157 .
addReg(
I.getOperand(0).getReg())
1164 BuildMI(*
I.getParent(),
I,
I.getDebugLoc(),
TII.get(Opcodes.Bcc))
1165 .
add(
I.getOperand(1))
1168 I.eraseFromParent();
1174 Register DstReg =
I.getOperand(0).getReg();
const AArch64Subtarget & Subtarget
#define GET_GLOBALISEL_PREDICATES_INIT
#define GET_GLOBALISEL_TEMPORARIES_INIT
static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isStore(int Opcode)
static bool isThumb(const MCSubtargetInfo &STI)
static std::pair< ARMCC::CondCodes, ARMCC::CondCodes > getComparePreds(CmpInst::Predicate Pred)
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)
static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
#define STORE_OPCODE(VAR, OPC)
This file declares the targeting of the RegisterBankInfo class for ARM.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static const Function * getParent(const Value *V)
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
const HexagonInstrInfo * TII
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first DebugLoc that has line number information, given a range of instructions.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static StringRef getName(Value *V)
SmallVector< MachineOperand, 4 > Cond
MachineRegisterInfo & MRI
static ARMConstantPoolConstant * Create(const Constant *C, unsigned ID)
This class provides the information for the target register banks.
bool isTargetMachO() const
bool isGVIndirectSymbol(const GlobalValue *GV) const
True if the GV will be accessed via an indirect symbol.
const ARMTargetLowering * getTargetLowering() const override
bool isTargetDarwin() const
bool isGVInGOT(const GlobalValue *GV) const
Returns the constant pool modifier needed to access the GV.
bool isReadOnly(const GlobalValue *GV) const
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ FCMP_ULT
1 1 0 0 True if unordered or 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
@ ICMP_ULT
unsigned less than
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
@ 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)
@ ICMP_SGE
signed greater or equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ ICMP_ULE
unsigned less or equal
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
const APFloat & getValueAPF() const
This is an important base class in LLVM.
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
constexpr bool isPointer() const
Instructions::iterator instr_iterator
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Register getReg(unsigned Idx) const
Get the register for the operand index.
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
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 & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
LLVM_ABI void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
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 MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
@ MOLoad
The memory access reads data.
const GlobalValue * getGlobal() const
Register getReg() const
getReg - Returns the register number.
const ConstantFP * getFPImm() const
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
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...
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
Holds all the information related to register banks.
static const TargetRegisterClass * constrainGenericRegister(Register Reg, const TargetRegisterClass &RC, MachineRegisterInfo &MRI)
Constrain the (possibly generic) virtual register Reg to RC.
const RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
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.
TargetInstrInfo - Interface to description of machine instruction set.
bool isPositionIndependent() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
@ SBREL
Section Relative (Windows TLS)
@ MO_NONLAZY
MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it represents a symbol which,...
@ MO_SBREL
MO_SBREL - On a symbol operand, this represents a static base relative relocation.
@ MO_GOT
MO_GOT - On a symbol operand, this represents a GOT relative relocation.
int getFP32Imm(const APInt &Imm)
getFP32Imm - Return an 8-bit floating-point version of the 32-bit floating-point value.
int getFP64Imm(const APInt &Imm)
getFP64Imm - Return an 8-bit floating-point version of the 64-bit floating-point value.
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
NodeAddr< InstrNode * > Instr
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
InstructionSelector * createARMInstructionSelector(const ARMBaseTargetMachine &TM, const ARMSubtarget &STI, const ARMRegisterBankInfo &RBI)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI void 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...
bool isPreISelGenericOpcode(unsigned Opcode)
Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel.
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static MachineOperand condCodeOp(unsigned CCReg=0)
Get the operand corresponding to the conditional code result.
MCRegisterClass TargetRegisterClass
Implement std::hash so that hash_code can be used in STL containers.
CmpConstants(unsigned CmpOpcode, unsigned FlagsOpcode, unsigned SelectOpcode, unsigned OpRegBank, unsigned OpSize)
const unsigned OperandRegBankID
const unsigned ReadFlagsOpcode
const unsigned SelectResultOpcode
const unsigned ComparisonOpcode
const unsigned OperandSize
const MachineBasicBlock::instr_iterator InsertBefore
InsertInfo(MachineInstrBuilder &MIB)
static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.