28 #define DEBUG_TYPE "legalizer" 36 : MIRBuilder(Builder),
MRI(MF.getRegInfo()),
37 LI(*MF.getSubtarget().getLegalizerInfo()), Observer(Observer) {
45 :
MIRBuilder(B), MRI(MF.getRegInfo()), LI(LI), Observer(Observer) {
54 switch (Step.Action) {
69 return lower(MI, Step.TypeIdx, Step.NewType);
83 void LegalizerHelper::extractParts(
unsigned Reg,
LLT Ty,
int NumParts,
85 for (
int i = 0; i < NumParts; ++i)
92 case TargetOpcode::G_SDIV:
93 assert((Size == 32 || Size == 64) &&
"Unsupported size");
94 return Size == 64 ? RTLIB::SDIV_I64 : RTLIB::SDIV_I32;
95 case TargetOpcode::G_UDIV:
96 assert((Size == 32 || Size == 64) &&
"Unsupported size");
97 return Size == 64 ? RTLIB::UDIV_I64 : RTLIB::UDIV_I32;
98 case TargetOpcode::G_SREM:
99 assert((Size == 32 || Size == 64) &&
"Unsupported size");
100 return Size == 64 ? RTLIB::SREM_I64 : RTLIB::SREM_I32;
101 case TargetOpcode::G_UREM:
102 assert((Size == 32 || Size == 64) &&
"Unsupported size");
103 return Size == 64 ? RTLIB::UREM_I64 : RTLIB::UREM_I32;
104 case TargetOpcode::G_CTLZ_ZERO_UNDEF:
105 assert(Size == 32 &&
"Unsupported size");
106 return RTLIB::CTLZ_I32;
107 case TargetOpcode::G_FADD:
108 assert((Size == 32 || Size == 64) &&
"Unsupported size");
109 return Size == 64 ? RTLIB::ADD_F64 : RTLIB::ADD_F32;
110 case TargetOpcode::G_FSUB:
111 assert((Size == 32 || Size == 64) &&
"Unsupported size");
112 return Size == 64 ? RTLIB::SUB_F64 : RTLIB::SUB_F32;
113 case TargetOpcode::G_FMUL:
114 assert((Size == 32 || Size == 64) &&
"Unsupported size");
115 return Size == 64 ? RTLIB::MUL_F64 : RTLIB::MUL_F32;
116 case TargetOpcode::G_FDIV:
117 assert((Size == 32 || Size == 64) &&
"Unsupported size");
118 return Size == 64 ? RTLIB::DIV_F64 : RTLIB::DIV_F32;
119 case TargetOpcode::G_FREM:
120 return Size == 64 ? RTLIB::REM_F64 : RTLIB::REM_F32;
121 case TargetOpcode::G_FPOW:
122 return Size == 64 ? RTLIB::POW_F64 : RTLIB::POW_F32;
123 case TargetOpcode::G_FMA:
124 assert((Size == 32 || Size == 64) &&
"Unsupported size");
125 return Size == 64 ? RTLIB::FMA_F64 : RTLIB::FMA_F32;
136 const char *
Name = TLI.getLibcallName(Libcall);
139 if (!CLI.lowerCall(MIRBuilder, TLI.getLibcallCallingConv(Libcall),
154 Args.push_back({MI.getOperand(i).getReg(), OpType});
165 case TargetOpcode::G_FPEXT:
167 case TargetOpcode::G_FPTRUNC:
169 case TargetOpcode::G_FPTOSI:
171 case TargetOpcode::G_FPTOUI:
173 case TargetOpcode::G_SITOFP:
175 case TargetOpcode::G_UITOFP:
200 case TargetOpcode::G_SDIV:
201 case TargetOpcode::G_UDIV:
202 case TargetOpcode::G_SREM:
203 case TargetOpcode::G_UREM:
204 case TargetOpcode::G_CTLZ_ZERO_UNDEF: {
211 case TargetOpcode::G_FADD:
212 case TargetOpcode::G_FSUB:
213 case TargetOpcode::G_FMUL:
214 case TargetOpcode::G_FDIV:
215 case TargetOpcode::G_FMA:
216 case TargetOpcode::G_FPOW:
217 case TargetOpcode::G_FREM: {
224 case TargetOpcode::G_FPEXT: {
228 if (ToSize != 64 || FromSize != 32)
236 case TargetOpcode::G_FPTRUNC: {
240 if (ToSize != 32 || FromSize != 64)
248 case TargetOpcode::G_FPTOSI:
249 case TargetOpcode::G_FPTOUI: {
253 if (ToSize != 32 || (FromSize != 32 && FromSize != 64))
262 case TargetOpcode::G_SITOFP:
263 case TargetOpcode::G_UITOFP: {
267 if (FromSize != 32 || (ToSize != 32 && ToSize != 64))
287 if (TypeIdx != 0 && MI.
getOpcode() != TargetOpcode::G_EXTRACT)
298 case TargetOpcode::G_IMPLICIT_DEF: {
301 if (SizeOp0 % NarrowSize != 0)
303 int NumParts = SizeOp0 / NarrowSize;
306 for (
int i = 0; i < NumParts; ++i)
318 case TargetOpcode::G_ADD: {
321 if (SizeOp0 % NarrowSize != 0)
333 for (
int i = 0; i < NumParts; ++i) {
338 Src2Regs[i], CarryIn);
351 case TargetOpcode::G_EXTRACT: {
358 if (SizeOp1 % NarrowSize != 0)
360 int NumParts = SizeOp1 / NarrowSize;
369 for (
int i = 0; i < NumParts; ++i) {
370 unsigned SrcStart = i * NarrowSize;
372 if (SrcStart + NarrowSize <= OpStart || SrcStart >= OpStart + OpSize) {
375 }
else if (SrcStart == OpStart && NarrowTy == MRI.
getType(OpReg)) {
383 int64_t ExtractOffset;
385 if (OpStart < SrcStart) {
387 SegSize = std::min(NarrowSize, OpStart + OpSize - SrcStart);
389 ExtractOffset = OpStart - SrcStart;
390 SegSize = std::min(SrcStart + NarrowSize - OpStart, OpSize);
393 unsigned SegReg = SrcRegs[i];
394 if (ExtractOffset != 0 || SegSize != NarrowSize) {
411 case TargetOpcode::G_INSERT: {
414 if (SizeOp0 % NarrowSize != 0)
417 int NumParts = SizeOp0 / NarrowSize;
426 for (
int i = 0; i < NumParts; ++i) {
427 unsigned DstStart = i * NarrowSize;
429 if (DstStart + NarrowSize <= OpStart || DstStart >= OpStart + OpSize) {
433 }
else if (DstStart == OpStart && NarrowTy == MRI.
getType(OpReg)) {
442 int64_t ExtractOffset, InsertOffset;
444 if (OpStart < DstStart) {
446 ExtractOffset = DstStart - OpStart;
447 SegSize = std::min(NarrowSize, OpStart + OpSize - DstStart);
449 InsertOffset = OpStart - DstStart;
452 std::min(NarrowSize - InsertOffset, OpStart + OpSize - DstStart);
455 unsigned SegReg = OpReg;
456 if (ExtractOffset != 0 || SegSize != OpSize) {
476 case TargetOpcode::G_LOAD: {
479 if (SizeOp0 % NarrowSize != 0)
489 int NumParts = SizeOp0 / NarrowSize;
494 for (
int i = 0; i < NumParts; ++i) {
497 unsigned Adjustment = i * NarrowSize / 8;
498 unsigned Alignment =
MinAlign(MMO.getAlignment(), Adjustment);
501 MMO.getPointerInfo().getWithOffset(Adjustment), MMO.getFlags(),
502 NarrowSize / 8, Alignment, MMO.getAAInfo(), MMO.getRanges(),
503 MMO.getSyncScopeID(), MMO.getOrdering(), MMO.getFailureOrdering());
510 DstRegs.push_back(DstReg);
520 case TargetOpcode::G_STORE: {
523 if (SizeOp0 % NarrowSize != 0)
533 int NumParts = SizeOp0 / NarrowSize;
540 for (
int i = 0; i < NumParts; ++i) {
542 unsigned Adjustment = i * NarrowSize / 8;
543 unsigned Alignment =
MinAlign(MMO.getAlignment(), Adjustment);
546 MMO.getPointerInfo().getWithOffset(Adjustment), MMO.getFlags(),
547 NarrowSize / 8, Alignment, MMO.getAAInfo(), MMO.getRanges(),
548 MMO.getSyncScopeID(), MMO.getOrdering(), MMO.getFailureOrdering());
558 case TargetOpcode::G_CONSTANT: {
561 if (SizeOp0 % NarrowSize != 0)
563 int NumParts = SizeOp0 / NarrowSize;
568 for (
int i = 0; i < NumParts; ++i) {
583 case TargetOpcode::G_AND:
584 case TargetOpcode::G_OR:
585 case TargetOpcode::G_XOR: {
598 if (SizeOp0 % NarrowSize != 0)
600 int NumParts = SizeOp0 / NarrowSize;
609 for (
int i = 0; i < NumParts; ++i) {
623 for (
int i = 0; i < NumParts; ++i)
625 {SrcsReg1[i], SrcsReg2[i]});
640 unsigned OpIdx,
unsigned ExtOpcode) {
643 MO.
setReg(ExtB->getOperand(0).getReg());
647 unsigned OpIdx,
unsigned TruncOpcode) {
662 case TargetOpcode::G_UADDO:
663 case TargetOpcode::G_USUBO: {
670 unsigned Opcode = MI.
getOpcode() == TargetOpcode::G_UADDO
671 ? TargetOpcode::G_ADD
672 : TargetOpcode::G_SUB;
678 TargetOpcode::G_AND, {WideTy},
688 case TargetOpcode::G_CTTZ:
689 case TargetOpcode::G_CTTZ_ZERO_UNDEF:
690 case TargetOpcode::G_CTLZ:
691 case TargetOpcode::G_CTLZ_ZERO_UNDEF:
692 case TargetOpcode::G_CTPOP: {
696 if (MI.
getOpcode() == TargetOpcode::G_CTTZ) {
703 TargetOpcode::G_OR, {WideTy},
709 if (MI.
getOpcode() == TargetOpcode::G_CTLZ ||
710 MI.
getOpcode() == TargetOpcode::G_CTLZ_ZERO_UNDEF) {
714 TargetOpcode::G_SUB, {WideTy},
726 case TargetOpcode::G_ADD:
727 case TargetOpcode::G_AND:
728 case TargetOpcode::G_MUL:
729 case TargetOpcode::G_OR:
730 case TargetOpcode::G_XOR:
731 case TargetOpcode::G_SUB:
736 widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT);
737 widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ANYEXT);
738 widenScalarDst(MI, WideTy);
742 case TargetOpcode::G_SHL:
744 widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT);
747 widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ZEXT);
748 widenScalarDst(MI, WideTy);
752 case TargetOpcode::G_SDIV:
753 case TargetOpcode::G_SREM:
755 widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_SEXT);
756 widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_SEXT);
757 widenScalarDst(MI, WideTy);
761 case TargetOpcode::G_ASHR:
763 widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_SEXT);
766 widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ZEXT);
767 widenScalarDst(MI, WideTy);
771 case TargetOpcode::G_UDIV:
772 case TargetOpcode::G_UREM:
773 case TargetOpcode::G_LSHR:
775 widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ZEXT);
776 widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ZEXT);
777 widenScalarDst(MI, WideTy);
781 case TargetOpcode::G_SELECT:
787 widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ANYEXT);
788 widenScalarSrc(MI, WideTy, 3, TargetOpcode::G_ANYEXT);
789 widenScalarDst(MI, WideTy);
792 widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ZEXT);
797 case TargetOpcode::G_FPTOSI:
798 case TargetOpcode::G_FPTOUI:
802 widenScalarDst(MI, WideTy);
806 case TargetOpcode::G_SITOFP:
810 widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_SEXT);
814 case TargetOpcode::G_UITOFP:
818 widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ZEXT);
822 case TargetOpcode::G_INSERT:
826 widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT);
827 widenScalarDst(MI, WideTy);
831 case TargetOpcode::G_LOAD:
839 case TargetOpcode::G_SEXTLOAD:
840 case TargetOpcode::G_ZEXTLOAD:
842 widenScalarDst(MI, WideTy);
846 case TargetOpcode::G_STORE: {
852 widenScalarSrc(MI, WideTy, 0, TargetOpcode::G_ZEXT);
856 case TargetOpcode::G_CONSTANT: {
863 widenScalarDst(MI, WideTy);
867 case TargetOpcode::G_FCONSTANT: {
885 widenScalarDst(MI, WideTy, 0, TargetOpcode::G_FPTRUNC);
889 case TargetOpcode::G_IMPLICIT_DEF: {
891 widenScalarDst(MI, WideTy);
895 case TargetOpcode::G_BRCOND:
897 widenScalarSrc(MI, WideTy, 0, TargetOpcode::G_ANYEXT);
901 case TargetOpcode::G_FCMP:
904 widenScalarDst(MI, WideTy);
906 widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_FPEXT);
907 widenScalarSrc(MI, WideTy, 3, TargetOpcode::G_FPEXT);
912 case TargetOpcode::G_ICMP:
915 widenScalarDst(MI, WideTy);
919 ? TargetOpcode::G_SEXT
920 : TargetOpcode::G_ZEXT;
921 widenScalarSrc(MI, WideTy, 2, ExtOpcode);
922 widenScalarSrc(MI, WideTy, 3, ExtOpcode);
927 case TargetOpcode::G_GEP:
928 assert(TypeIdx == 1 &&
"unable to legalize pointer of GEP");
930 widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_SEXT);
934 case TargetOpcode::G_PHI: {
935 assert(TypeIdx == 0 &&
"Expecting only Idx 0");
941 widenScalarSrc(MI, WideTy,
I, TargetOpcode::G_ANYEXT);
946 widenScalarDst(MI, WideTy);
950 case TargetOpcode::G_EXTRACT_VECTOR_ELT:
954 widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_SEXT);
958 case TargetOpcode::G_FCEIL:
962 widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_FPEXT);
963 widenScalarDst(MI, WideTy, 0, TargetOpcode::G_FPTRUNC);
971 using namespace TargetOpcode;
977 case TargetOpcode::G_SREM:
978 case TargetOpcode::G_UREM: {
979 unsigned QuotReg =
MRI.createGenericVirtualRegister(Ty);
985 unsigned ProdReg =
MRI.createGenericVirtualRegister(Ty);
992 case TargetOpcode::G_SMULO:
993 case TargetOpcode::G_UMULO: {
1003 unsigned Opcode = MI.
getOpcode() == TargetOpcode::G_SMULO
1004 ? TargetOpcode::G_SMULH
1005 : TargetOpcode::G_UMULH;
1007 unsigned HiPart =
MRI.createGenericVirtualRegister(Ty);
1013 unsigned Zero =
MRI.createGenericVirtualRegister(Ty);
1018 if (Opcode == TargetOpcode::G_SMULH) {
1019 unsigned Shifted =
MRI.createGenericVirtualRegister(Ty);
1020 unsigned ShiftAmt =
MRI.createGenericVirtualRegister(Ty);
1033 case TargetOpcode::G_FNEG: {
1062 .
addUse(Zero->getOperand(0).getReg())
1067 case TargetOpcode::G_FSUB: {
1071 if (LI.getAction({G_FNEG, {Ty}}).Action ==
Lower)
1076 unsigned Neg =
MRI.createGenericVirtualRegister(Ty);
1085 case TargetOpcode::G_ATOMIC_CMPXCHG_WITH_SUCCESS: {
1097 case TargetOpcode::G_LOAD:
1098 case TargetOpcode::G_SEXTLOAD:
1099 case TargetOpcode::G_ZEXTLOAD: {
1103 LLT DstTy =
MRI.getType(DstReg);
1109 if (MI.
getOpcode() == TargetOpcode::G_LOAD)
1117 unsigned TmpReg =
MRI.createGenericVirtualRegister(
1123 case TargetOpcode::G_LOAD:
1126 case TargetOpcode::G_SEXTLOAD:
1129 case TargetOpcode::G_ZEXTLOAD:
1139 case TargetOpcode::G_CTLZ_ZERO_UNDEF:
1140 case TargetOpcode::G_CTTZ_ZERO_UNDEF:
1141 case TargetOpcode::G_CTLZ:
1142 case TargetOpcode::G_CTTZ:
1143 case TargetOpcode::G_CTPOP:
1144 return lowerBitCount(MI, TypeIdx, Ty);
1152 unsigned TmpRes =
MRI.createGenericVirtualRegister(Ty);
1153 unsigned ZExtCarryIn =
MRI.createGenericVirtualRegister(Ty);
1177 case TargetOpcode::G_IMPLICIT_DEF: {
1182 unsigned Size =
MRI.getType(DstReg).getSizeInBits();
1183 int NumParts = Size / NarrowSize;
1186 if (Size % NarrowSize != 0)
1189 for (
int i = 0; i < NumParts; ++i) {
1190 unsigned TmpReg =
MRI.createGenericVirtualRegister(NarrowTy);
1203 case TargetOpcode::G_ADD: {
1206 unsigned Size =
MRI.getType(DstReg).getSizeInBits();
1207 int NumParts = Size / NarrowSize;
1210 if (Size % NarrowSize != 0)
1217 for (
int i = 0; i < NumParts; ++i) {
1218 unsigned DstReg =
MRI.createGenericVirtualRegister(NarrowTy);
1227 case TargetOpcode::G_LOAD:
1228 case TargetOpcode::G_STORE: {
1229 bool IsLoad = MI.
getOpcode() == TargetOpcode::G_LOAD;
1233 unsigned Size =
MRI.getType(ValReg).getSizeInBits();
1234 unsigned NumParts = Size / NarrowSize;
1238 extractParts(ValReg, NarrowTy, NumParts, NarrowRegs);
1240 const LLT OffsetTy =
1244 for (
unsigned Idx = 0; Idx < NumParts; ++Idx) {
1247 unsigned NewAddrReg = 0;
1253 unsigned Dst =
MRI.createGenericVirtualRegister(NarrowTy);
1273 LegalizerHelper::lowerBitCount(
MachineInstr &MI,
unsigned TypeIdx,
LLT Ty) {
1277 auto QAction = LI.getAction(Q).Action;
1283 case TargetOpcode::G_CTLZ_ZERO_UNDEF: {
1285 Observer.changingInstr(MI);
1287 Observer.changedInstr(MI);
1290 case TargetOpcode::G_CTLZ: {
1293 if (isSupported({TargetOpcode::G_CTLZ_ZERO_UNDEF, {Ty}})) {
1317 unsigned Op = SrcReg;
1319 for (
unsigned i = 0; (1U << i) <= (NewLen / 2); ++i) {
1322 TargetOpcode::G_OR, {Ty},
1324 {
Op, MIBShiftAmt})});
1325 Op = MIBOp->getOperand(0).getReg();
1333 case TargetOpcode::G_CTTZ_ZERO_UNDEF: {
1335 Observer.changingInstr(MI);
1337 Observer.changedInstr(MI);
1340 case TargetOpcode::G_CTTZ: {
1343 if (isSupported({TargetOpcode::G_CTTZ_ZERO_UNDEF, {Ty}})) {
1365 TargetOpcode::G_AND, {Ty},
1367 {SrcReg, MIBCstNeg1})});
1368 if (!isSupported({TargetOpcode::G_CTPOP, {Ty}}) &&
1369 isSupported({TargetOpcode::G_CTLZ, {Ty}})) {
static LegalizerHelper::LegalizeResult simpleLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, unsigned Size, Type *OpType)
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
static Type * getDoubleTy(LLVMContext &C)
uint64_t getZExtValue() const
Get zero extended value.
APInt sext(unsigned width) const
Sign extend to a new width.
MachineInstrBuilder buildUnmerge(ArrayRef< LLT > Res, const SrcOp &Op)
Build and insert Res0, ...
static APInt getAllOnesValue(unsigned numBits)
Get the all-ones value.
MachineBasicBlock * getMBB() const
const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
This class represents lattice values for constants.
The operation should be implemented in terms of a wider scalar base-type.
void setFPImm(const ConstantFP *CFP)
void push_back(const T &Elt)
The LegalityQuery object bundles together all the information that's needed to decide whether a given...
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
unsigned getReg() const
getReg - Returns the register number.
The (vector) operation should be implemented by splitting it into sub-vectors where the operation is ...
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit...
virtual const TargetLowering * getTargetLowering() const
LLT getType(unsigned Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register...
MachineInstrBuilder buildConcatVectors(const DstOp &Res, ArrayRef< unsigned > Ops)
Build and insert Res = G_CONCAT_VECTORS Op0, ...
APInt trunc(unsigned width) const
Truncate to new width.
uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
MachineInstrBuilder buildExtract(unsigned Res, unsigned Src, uint64_t Index)
Build and insert `Res0, ...
Libcall getFPROUND(EVT OpVT, EVT RetVT)
getFPROUND - Return the FPROUND_*_* value for the given types, or UNKNOWN_LIBCALL if there is none...
Libcall getUINTTOFP(EVT OpVT, EVT RetVT)
getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none...
The operation should be synthesized from multiple instructions acting on a narrower scalar base-type...
MachineInstrBuilder buildStore(unsigned Val, unsigned Addr, MachineMemOperand &MMO)
Build and insert G_STORE Val, Addr, MMO.
void setMF(MachineFunction &MF)
LegalizeActionStep getAction(const LegalityQuery &Query) const
Determine what action should be taken to legalize the described instruction.
A description of a memory reference used in the backend.
amdgpu Simplify well known AMD library false Value Value const Twine & Name
void setInsertPt(MachineBasicBlock &MBB, MachineBasicBlock::iterator II)
Set the insertion point before the specified position.
MachineIRBuilder & MIRBuilder
Expose MIRBuilder so clients can set their own RecordInsertInstruction functions. ...
MachineInstrBuilder buildAnyExt(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_ANYEXT Op0.
LegalizeResult widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy)
Legalize an instruction by performing the operation on a wider scalar type (for example a 16-bit addi...
const HexagonInstrInfo * TII
static Type * getFloatTy(LLVMContext &C)
const ConstantFP * getFPImm() const
unsigned getNumOperands() const
Retuns the total number of operands.
MachineInstrBuilder buildUAdde(const DstOp &Res, const DstOp &CarryOut, const SrcOp &Op0, const SrcOp &Op1, const SrcOp &CarryIn)
Build and insert Res, CarryOut = G_UADDE Op0, Op1, CarryIn.
const MachineInstrBuilder & addUse(unsigned RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned 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.
LegalizerHelper::LegalizeResult createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall, const CallLowering::ArgInfo &Result, ArrayRef< CallLowering::ArgInfo > Args)
Helper function that creates the given libcall.
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
MachineFunction & getMF()
Getter for the function we currently build.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
const APInt & getValue() const
Return the constant as an APInt value reference.
virtual const TargetInstrInfo * getInstrInfo() const
static const fltSemantics & IEEEdouble() LLVM_READNONE
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
MachineInstrBuilder buildSub(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, Optional< unsigned > Flags=None)
Build and insert Res = G_SUB Op0, Op1.
void setChangeObserver(GISelChangeObserver &Observer)
MachineBasicBlock::iterator getInsertPt()
Current insertion point for new instructions.
LegalizerHelper(MachineFunction &MF, GISelChangeObserver &Observer, MachineIRBuilder &B)
constexpr uint64_t MinAlign(uint64_t A, uint64_t B)
A and B are either alignments or offsets.
MachineInstrBuilder buildSExt(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_SEXT Op.
Abstract class that contains various methods for clients to notify about changes. ...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
unsigned const MachineRegisterInfo * MRI
LegalizeResult legalizeInstrStep(MachineInstr &MI)
Replace MI by a sequence of legal instructions that can implement the same operation.
The instances of the Type class are immutable: once they are created, they are never changed...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
This is an important class for using LLVM in a threaded context.
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineInstrBuilder buildZExt(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_ZEXT Op.
ConstantFP - Floating Point Values [float, double].
Helper class to build MachineInstr.
Libcall getFPTOSINT(EVT OpVT, EVT RetVT)
getFPTOSINT - Return the FPTOSINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none...
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
void setInstr(MachineInstr &MI)
Set the insertion point to before MI.
MachineInstrBuilder buildInsert(unsigned Res, unsigned Src, unsigned Op, unsigned Index)
virtual const CallLowering * getCallLowering() const
static MVT getVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
void print(raw_ostream &OS, bool IsStandalone=true, bool SkipOpers=false, bool SkipDebugLoc=false, bool AddNewLine=true, const TargetInstrInfo *TII=nullptr) const
Print this MI to OS.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
Some kind of error has occurred and we could not legalize this instruction.
MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_TRUNC Op.
Instruction was already legal and no change was made to the MachineFunction.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
uint64_t getAlignment() const
Return the minimum known alignment in bytes of the actual memory reference.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
static Type * getFP128Ty(LLVMContext &C)
const APFloat & getValueAPF() const
Libcall getFPEXT(EVT OpVT, EVT RetVT)
getFPEXT - Return the FPEXT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none...
unsigned createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
static Type * getHalfTy(LLVMContext &C)
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
static const fltSemantics & IEEEsingle() LLVM_READNONE
MachineInstrBuilder buildMerge(const DstOp &Res, ArrayRef< unsigned > Ops)
Build and insert Res = G_MERGE_VALUES Op0, ...
MachineInstrBuilder buildMul(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, Optional< unsigned > Flags=None)
Build and insert Res = G_MUL Op0, Op1.
MachineInstrBuilder buildICmp(CmpInst::Predicate Pred, const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1)
Build and insert a Res = G_ICMP Pred, Op0, Op1.
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
This is the shared class of boolean and integer constants.
virtual MachineInstrBuilder buildFConstant(const DstOp &Res, const ConstantFP &Val)
Build and insert Res = G_FCONSTANT Val.
LegalizeResult libcall(MachineInstr &MI)
Legalize an instruction by emiting a runtime library call instead.
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
static RTLIB::Libcall getRTLibDesc(unsigned Opcode, unsigned Size)
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
unsigned getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
The target wants to do something special with this combination of operand and type.
LegalizeResult lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty)
Legalize an instruction by splitting it into simpler parts, hopefully understood by the target...
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
MachineInstrBuilder buildSelect(const DstOp &Res, const SrcOp &Tst, const SrcOp &Op0, const SrcOp &Op1)
Build and insert a Res = G_SELECT Tst, Op0, Op1.
static Constant * get(Type *Ty, double V)
This returns a ConstantFP, or a vector containing a splat of a ConstantFP, for the specified value in...
LegalizeResult fewerElementsVector(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy)
Legalize a vector instruction by splitting into multiple components, each acting on the same scalar t...
const Function & getFunction() const
Return the LLVM function that this machine code represents.
virtual bool legalizeCustom(MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &MIRBuilder, GISelChangeObserver &Observer) const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
MachinePointerInfo getWithOffset(int64_t O) const
Class for arbitrary precision integers.
static RTLIB::Libcall getConvRTLibDesc(unsigned Opcode, Type *ToType, Type *FromType)
virtual void changingInstr(MachineInstr &MI)=0
This instruction is about to be mutated in some way.
static MachineOperand CreateES(const char *SymName, unsigned char TargetFlags=0)
static LegalizerHelper::LegalizeResult conversionLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, Type *ToType, Type *FromType)
const MachineBasicBlock * getParent() const
Representation of each machine instruction.
Instruction has been legalized and the MachineFunction changed.
Libcall getFPTOUINT(EVT OpVT, EVT RetVT)
getFPTOUINT - Return the FPTOUINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none...
const MachinePointerInfo & getPointerInfo() const
static IntegerType * getInt32Ty(LLVMContext &C)
MachineInstrBuilder buildAdd(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, Optional< unsigned > Flags=None)
Build and insert Res = G_ADD Op0, Op1.
MachineInstrBuilder buildBuildVector(const DstOp &Res, ArrayRef< unsigned > Ops)
Build and insert Res = G_BUILD_VECTOR Op0, ...
const MachineBasicBlock & getMBB() const
Getter for the basic block we currently build.
void setReg(unsigned Reg)
Change the register this operand corresponds to.
Flags getFlags() const
Return the raw flags of the source value,.
static Constant * getZeroValueForNegation(Type *Ty)
Floating point negation must be implemented with f(x) = -0.0 - x.
void setCImm(const ConstantInt *CI)
iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
Optional< MachineInstrBuilder > materializeGEP(unsigned &Res, unsigned Op0, const LLT &ValueTy, uint64_t Value)
Materialize and insert Res = G_GEP Op0, (G_CONSTANT Value)
Libcall getSINTTOFP(EVT OpVT, EVT RetVT)
getSINTTOFP - Return the SINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none...
LegalizeResult narrowScalar(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy)
Legalize an instruction by reducing the width of the underlying scalar type.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
unsigned getSizeInBits(unsigned Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI) const
Get the size in bits of Reg.
This file describes how to lower LLVM calls to machine code calls.
MachineInstrBuilder buildLoad(unsigned Res, unsigned Addr, MachineMemOperand &MMO)
Build and insert Res = G_LOAD Addr, MMO.
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
MachineInstrBuilder buildAtomicCmpXchg(unsigned OldValRes, unsigned Addr, unsigned CmpVal, unsigned NewVal, MachineMemOperand &MMO)
Build and insert OldValRes<def> = G_ATOMIC_CMPXCHG Addr, CmpVal, NewVal, MMO.
const MachineInstrBuilder & addDef(unsigned RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
MachineInstrBuilder buildUndef(const DstOp &Res)
Build and insert Res = IMPLICIT_DEF.
const MachineOperand & getOperand(unsigned i) const
const ConstantInt * getCImm() const
The operation is expected to be selectable directly by the target, and no transformation is necessary...
virtual void changedInstr(MachineInstr &MI)=0
This instruction was mutated in some way.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
uint64_t PowerOf2Ceil(uint64_t A)
Returns the power of two which is greater than or equal to the given value.
This file describes how to lower LLVM code to machine code.
unsigned getPredicate() const