20#define DEBUG_TYPE "si-shrink-instructions"
23 "Number of 64-bit instruction reduced to 32-bit.");
25 "Number of literal constants folded into 32-bit instructions.");
31enum ChangeKind {
None, UpdateHint, UpdateInst };
33class SIShrinkInstructions {
35 MachineRegisterInfo *MRI;
36 const GCNSubtarget *ST;
37 const SIInstrInfo *TII;
38 const SIRegisterInfo *TRI;
41 bool foldImmediates(MachineInstr &
MI,
bool TryToCommute =
true)
const;
42 bool shouldShrinkTrue16(MachineInstr &
MI)
const;
44 bool isKUImmOperand(
const MachineOperand &Src)
const;
45 bool isKImmOrKUImmOperand(
const MachineOperand &Src,
bool &IsUnsigned)
const;
46 void copyExtraImplicitOps(MachineInstr &NewMI, MachineInstr &
MI)
const;
47 bool shrinkScalarCompare(MachineInstr &
MI)
const;
48 bool shrinkMIMG(MachineInstr &
MI)
const;
49 bool shrinkMadFma(MachineInstr &
MI)
const;
50 ChangeKind shrinkScalarLogicOp(MachineInstr &
MI)
const;
51 bool tryReplaceDeadSDST(MachineInstr &
MI)
const;
53 unsigned SubReg)
const;
54 bool instReadsReg(
const MachineInstr *
MI,
unsigned Reg,
55 unsigned SubReg)
const;
56 bool instModifiesReg(
const MachineInstr *
MI,
unsigned Reg,
57 unsigned SubReg)
const;
58 TargetInstrInfo::RegSubRegPair getSubRegForIndex(
Register Reg,
unsigned Sub,
60 void dropInstructionKeepingImpDefs(MachineInstr &
MI)
const;
61 MachineInstr *matchSwap(MachineInstr &MovT)
const;
64 SIShrinkInstructions() =
default;
65 bool run(MachineFunction &MF);
73 SIShrinkInstructionsLegacy() : MachineFunctionPass(ID) {}
75 bool runOnMachineFunction(MachineFunction &MF)
override;
77 StringRef getPassName()
const override {
return "SI Shrink Instructions"; }
79 void getAnalysisUsage(AnalysisUsage &AU)
const override {
89 "SI Shrink Instructions",
false,
false)
91char SIShrinkInstructionsLegacy::
ID = 0;
94 return new SIShrinkInstructionsLegacy();
101 bool TryToCommute)
const {
104 int Src0Idx = AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::src0);
107 MachineOperand &Src0 =
MI.getOperand(Src0Idx);
112 if (Def &&
Def->isMoveImmediate()) {
113 MachineOperand &MovSrc =
Def->getOperand(1);
114 bool ConstantFolded =
false;
116 if (
TII->isOperandLegal(
MI, Src0Idx, &MovSrc)) {
117 if (MovSrc.
isImm()) {
119 ConstantFolded =
true;
120 }
else if (MovSrc.
isFI()) {
122 ConstantFolded =
true;
126 ConstantFolded =
true;
130 if (ConstantFolded) {
132 Def->eraseFromParent();
133 ++NumLiteralConstantsFolded;
141 if (TryToCommute &&
MI.isCommutable()) {
142 if (
TII->commuteInstruction(
MI)) {
143 if (foldImmediates(
MI,
false))
147 TII->commuteInstruction(
MI);
156bool SIShrinkInstructions::shouldShrinkTrue16(MachineInstr &
MI)
const {
157 for (
unsigned I = 0,
E =
MI.getNumExplicitOperands();
I !=
E; ++
I) {
158 const MachineOperand &MO =
MI.getOperand(
I);
162 "True16 Instructions post-RA");
175bool SIShrinkInstructions::isKImmOperand(
const MachineOperand &Src)
const {
177 !
TII->isInlineConstant(*Src.getParent(), Src.getOperandNo());
180bool SIShrinkInstructions::isKUImmOperand(
const MachineOperand &Src)
const {
182 !
TII->isInlineConstant(*Src.getParent(), Src.getOperandNo());
185bool SIShrinkInstructions::isKImmOrKUImmOperand(
const MachineOperand &Src,
186 bool &IsUnsigned)
const {
189 return !
TII->isInlineConstant(Src);
194 return !
TII->isInlineConstant(Src);
211 int32_t &ModifiedImm,
bool Scalar) {
212 if (
TII->isInlineConstant(Src))
214 int32_t SrcImm =
static_cast<int32_t
>(Src.getImm());
220 ModifiedImm = ~SrcImm;
221 if (
TII->isInlineConstant(
APInt(32, ModifiedImm,
true)))
222 return AMDGPU::V_NOT_B32_e32;
226 if (
TII->isInlineConstant(
APInt(32, ModifiedImm,
true)))
227 return Scalar ? AMDGPU::S_BREV_B32 : AMDGPU::V_BFREV_B32_e32;
234void SIShrinkInstructions::copyExtraImplicitOps(MachineInstr &NewMI,
235 MachineInstr &
MI)
const {
236 MachineFunction &MF = *
MI.getMF();
237 for (
unsigned i =
MI.getDesc().getNumOperands() +
238 MI.getDesc().implicit_uses().size() +
239 MI.getDesc().implicit_defs().size(),
240 e =
MI.getNumOperands();
242 const MachineOperand &MO =
MI.getOperand(i);
248bool SIShrinkInstructions::shrinkScalarCompare(MachineInstr &
MI)
const {
255 if (!
MI.getOperand(0).isReg()) {
256 if (
TII->commuteInstruction(
MI,
false, 0, 1))
261 const MachineOperand &Src0 =
MI.getOperand(0);
265 MachineOperand &Src1 =
MI.getOperand(1);
275 if (SOPKOpc == AMDGPU::S_CMPK_EQ_U32 || SOPKOpc == AMDGPU::S_CMPK_LG_U32) {
277 if (isKImmOrKUImmOperand(Src1, HasUImm)) {
279 SOPKOpc = (SOPKOpc == AMDGPU::S_CMPK_EQ_U32) ?
280 AMDGPU::S_CMPK_EQ_I32 : AMDGPU::S_CMPK_LG_I32;
284 MI.setDesc(
TII->get(SOPKOpc));
291 const MCInstrDesc &NewDesc =
TII->get(SOPKOpc);
304bool SIShrinkInstructions::shrinkMIMG(MachineInstr &
MI)
const {
310 switch (
Info->MIMGEncoding) {
311 case AMDGPU::MIMGEncGfx10NSA:
312 NewEncoding = AMDGPU::MIMGEncGfx10Default;
314 case AMDGPU::MIMGEncGfx11NSA:
315 NewEncoding = AMDGPU::MIMGEncGfx11Default;
322 AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::vaddr0);
323 unsigned NewAddrDwords =
Info->VAddrDwords;
326 if (
Info->VAddrDwords == 2) {
327 RC = &AMDGPU::VReg_64RegClass;
328 }
else if (
Info->VAddrDwords == 3) {
329 RC = &AMDGPU::VReg_96RegClass;
330 }
else if (
Info->VAddrDwords == 4) {
331 RC = &AMDGPU::VReg_128RegClass;
332 }
else if (
Info->VAddrDwords == 5) {
333 RC = &AMDGPU::VReg_160RegClass;
334 }
else if (
Info->VAddrDwords == 6) {
335 RC = &AMDGPU::VReg_192RegClass;
336 }
else if (
Info->VAddrDwords == 7) {
337 RC = &AMDGPU::VReg_224RegClass;
338 }
else if (
Info->VAddrDwords == 8) {
339 RC = &AMDGPU::VReg_256RegClass;
340 }
else if (
Info->VAddrDwords == 9) {
341 RC = &AMDGPU::VReg_288RegClass;
342 }
else if (
Info->VAddrDwords == 10) {
343 RC = &AMDGPU::VReg_320RegClass;
344 }
else if (
Info->VAddrDwords == 11) {
345 RC = &AMDGPU::VReg_352RegClass;
346 }
else if (
Info->VAddrDwords == 12) {
347 RC = &AMDGPU::VReg_384RegClass;
349 RC = &AMDGPU::VReg_512RegClass;
353 unsigned VgprBase = 0;
354 unsigned NextVgpr = 0;
356 bool IsKill = NewAddrDwords ==
Info->VAddrDwords;
358 const bool IsPartialNSA = NewAddrDwords > NSAMaxSize;
359 const unsigned EndVAddr = IsPartialNSA ? NSAMaxSize :
Info->VAddrOperands;
360 for (
unsigned Idx = 0; Idx < EndVAddr; ++Idx) {
361 const MachineOperand &
Op =
MI.getOperand(VAddr0Idx + Idx);
362 unsigned Vgpr =
TRI->getHWRegIndex(
Op.getReg());
363 unsigned Dwords =
TRI->getRegSizeInBits(
Op.getReg(), *MRI) / 32;
364 assert(Dwords > 0 &&
"Un-implemented for less than 32 bit regs");
368 NextVgpr = Vgpr + Dwords;
369 }
else if (Vgpr == NextVgpr) {
370 NextVgpr = Vgpr + Dwords;
381 if (VgprBase + NewAddrDwords > 256)
386 int TFEIdx = AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::tfe);
387 int LWEIdx = AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::lwe);
388 unsigned TFEVal = (TFEIdx == -1) ? 0 :
MI.getOperand(TFEIdx).
getImm();
389 unsigned LWEVal = (LWEIdx == -1) ? 0 :
MI.getOperand(LWEIdx).
getImm();
391 if (TFEVal || LWEVal) {
393 for (
unsigned i = LWEIdx + 1, e =
MI.getNumOperands(); i != e; ++i) {
394 if (
MI.getOperand(i).isReg() &&
MI.getOperand(i).isTied() &&
395 MI.getOperand(i).isImplicit()) {
399 "found more than one tied implicit operand when expecting only 1");
401 MI.untieRegOperand(ToUntie);
407 Info->VDataDwords, NewAddrDwords);
408 MI.setDesc(
TII->get(NewOpcode));
410 MI.getOperand(VAddr0Idx).setIsUndef(IsUndef);
411 MI.getOperand(VAddr0Idx).setIsKill(IsKill);
413 for (
unsigned i = 1; i < EndVAddr; ++i)
414 MI.removeOperand(VAddr0Idx + 1);
418 AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::vdata),
419 ToUntie - (EndVAddr - 1));
425bool SIShrinkInstructions::shrinkMadFma(MachineInstr &
MI)
const {
428 if (!ST->hasVOP3Literal())
435 if (
TII->hasAnyModifiersSet(
MI))
438 const unsigned Opcode =
MI.getOpcode();
439 MachineOperand &Src0 = *
TII->getNamedOperand(
MI, AMDGPU::OpName::src0);
440 MachineOperand &Src1 = *
TII->getNamedOperand(
MI, AMDGPU::OpName::src1);
441 MachineOperand &Src2 = *
TII->getNamedOperand(
MI, AMDGPU::OpName::src2);
442 unsigned NewOpcode = AMDGPU::INSTRUCTION_LIST_END;
447 if (Src2.
isImm() && !
TII->isInlineConstant(Src2)) {
458 case AMDGPU::V_MAD_F32_e64:
459 NewOpcode = AMDGPU::V_MADAK_F32;
461 case AMDGPU::V_FMA_F32_e64:
462 NewOpcode = AMDGPU::V_FMAAK_F32;
464 case AMDGPU::V_MAD_F16_e64:
465 NewOpcode = AMDGPU::V_MADAK_F16;
467 case AMDGPU::V_FMA_F16_e64:
468 case AMDGPU::V_FMA_F16_gfx9_e64:
469 NewOpcode = AMDGPU::V_FMAAK_F16;
471 case AMDGPU::V_FMA_F16_gfx9_t16_e64:
472 NewOpcode = AMDGPU::V_FMAAK_F16_t16;
474 case AMDGPU::V_FMA_F16_gfx9_fake16_e64:
475 NewOpcode = AMDGPU::V_FMAAK_F16_fake16;
477 case AMDGPU::V_FMA_F64_e64:
479 NewOpcode = AMDGPU::V_FMAAK_F64;
486 if (Src1.
isImm() && !
TII->isInlineConstant(Src1))
488 else if (Src0.
isImm() && !
TII->isInlineConstant(Src0))
496 case AMDGPU::V_MAD_F32_e64:
497 NewOpcode = AMDGPU::V_MADMK_F32;
499 case AMDGPU::V_FMA_F32_e64:
500 NewOpcode = AMDGPU::V_FMAMK_F32;
502 case AMDGPU::V_MAD_F16_e64:
503 NewOpcode = AMDGPU::V_MADMK_F16;
505 case AMDGPU::V_FMA_F16_e64:
506 case AMDGPU::V_FMA_F16_gfx9_e64:
507 NewOpcode = AMDGPU::V_FMAMK_F16;
509 case AMDGPU::V_FMA_F16_gfx9_t16_e64:
510 NewOpcode = AMDGPU::V_FMAMK_F16_t16;
512 case AMDGPU::V_FMA_F16_gfx9_fake16_e64:
513 NewOpcode = AMDGPU::V_FMAMK_F16_fake16;
515 case AMDGPU::V_FMA_F64_e64:
517 NewOpcode = AMDGPU::V_FMAMK_F64;
522 if (NewOpcode == AMDGPU::INSTRUCTION_LIST_END)
531 MI.getOperand(0).getReg())
536 MI.eraseFromParent();
538 TII->removeModOperands(
MI);
539 MI.setDesc(
TII->get(NewOpcode));
551ChangeKind SIShrinkInstructions::shrinkScalarLogicOp(MachineInstr &
MI)
const {
552 unsigned Opc =
MI.getOpcode();
553 const MachineOperand *Dest = &
MI.getOperand(0);
554 MachineOperand *Src0 = &
MI.getOperand(1);
555 MachineOperand *Src1 = &
MI.getOperand(2);
556 MachineOperand *SrcReg = Src0;
557 MachineOperand *SrcImm = Src1;
559 if (!SrcImm->
isImm() ||
561 return ChangeKind::None;
563 uint32_t
Imm =
static_cast<uint32_t
>(SrcImm->
getImm());
566 if (
Opc == AMDGPU::S_AND_B32) {
568 MI.findRegisterDefOperand(AMDGPU::SCC,
nullptr)->isDead()) {
570 Opc = AMDGPU::S_BITSET0_B32;
573 Opc = AMDGPU::S_ANDN2_B32;
575 }
else if (
Opc == AMDGPU::S_OR_B32) {
577 MI.findRegisterDefOperand(AMDGPU::SCC,
nullptr)->isDead()) {
579 Opc = AMDGPU::S_BITSET1_B32;
582 Opc = AMDGPU::S_ORN2_B32;
584 }
else if (
Opc == AMDGPU::S_XOR_B32) {
587 Opc = AMDGPU::S_XNOR_B32;
597 return ChangeKind::UpdateHint;
601 const bool IsUndef = SrcReg->
isUndef();
602 const bool IsKill = SrcReg->
isKill();
604 if (
Opc == AMDGPU::S_BITSET0_B32 ||
605 Opc == AMDGPU::S_BITSET1_B32) {
608 MI.getOperand(2).ChangeToRegister(Dest->
getReg(),
false,
611 MI.tieOperands(0, 2);
615 return ChangeKind::UpdateInst;
619 return ChangeKind::None;
624bool SIShrinkInstructions::instAccessReg(
626 unsigned SubReg)
const {
627 for (
const MachineOperand &MO : R) {
632 LaneBitmask Overlap =
TRI->getSubRegIndexLaneMask(SubReg) &
641bool SIShrinkInstructions::instReadsReg(
const MachineInstr *
MI,
unsigned Reg,
642 unsigned SubReg)
const {
643 return instAccessReg(
MI->all_uses(),
Reg, SubReg);
646bool SIShrinkInstructions::instModifiesReg(
const MachineInstr *
MI,
unsigned Reg,
647 unsigned SubReg)
const {
648 return instAccessReg(
MI->all_defs(),
Reg, SubReg);
651TargetInstrInfo::RegSubRegPair
652SIShrinkInstructions::getSubRegForIndex(
Register Reg,
unsigned Sub,
654 if (
TRI->getRegSizeInBits(
Reg, *MRI) != 32) {
658 Sub =
TRI->getSubRegFromChannel(
I +
TRI->getChannelFromSubReg(
Sub));
661 return TargetInstrInfo::RegSubRegPair(
Reg,
Sub);
664void SIShrinkInstructions::dropInstructionKeepingImpDefs(
665 MachineInstr &
MI)
const {
666 for (
unsigned i =
MI.getDesc().getNumOperands() +
667 MI.getDesc().implicit_uses().size() +
668 MI.getDesc().implicit_defs().size(),
669 e =
MI.getNumOperands();
671 const MachineOperand &
Op =
MI.getOperand(i);
675 TII->get(AMDGPU::IMPLICIT_DEF),
Op.getReg());
678 MI.eraseFromParent();
700MachineInstr *SIShrinkInstructions::matchSwap(MachineInstr &MovT)
const {
702 MovT.
getOpcode() == AMDGPU::V_MOV_B16_t16_e32 ||
716 unsigned Size =
TII->getOpSize(MovT, 0);
720 if (
Size == 2 &&
X.isVirtual())
723 if (!
TRI->isVGPR(*MRI,
X))
726 const unsigned SearchLimit = 16;
729 MachineInstr *MovX =
nullptr;
730 MachineInstr *InsertionPt =
nullptr;
731 MachineInstr *MovY =
nullptr;
735 Iter !=
E &&
Count < SearchLimit; ++Iter) {
736 if (Iter->isDebugInstr())
742 if ((Iter->getOpcode() == AMDGPU::V_MOV_B32_e32 ||
743 Iter->getOpcode() == AMDGPU::V_MOV_B16_t16_e32 ||
744 Iter->getOpcode() == AMDGPU::COPY) &&
745 Iter->getOperand(0).getReg() ==
X &&
746 Iter->getOperand(0).getSubReg() == Xsub &&
747 Iter->getOperand(1).isReg()) {
751 }
else if (instModifiesReg(&*Iter,
X, Xsub)) {
758 if ((Iter->getOpcode() == AMDGPU::V_MOV_B32_e32 ||
759 Iter->getOpcode() == AMDGPU::V_MOV_B16_t16_e32 ||
760 Iter->getOpcode() == AMDGPU::COPY) &&
761 Iter->getOperand(0).getReg() ==
Y &&
762 Iter->getOperand(0).getSubReg() == Ysub &&
763 Iter->getOperand(1).isReg() && Iter->getOperand(1).getReg() ==
T &&
764 Iter->getOperand(1).getSubReg() == Tsub) {
773 if (instModifiesReg(&*Iter,
Y, Ysub))
779 (instReadsReg(&*Iter,
X, Xsub) || instModifiesReg(&*Iter,
X, Xsub))) {
780 InsertionPt = &*Iter;
786 if (instReadsReg(&*Iter,
Y, Ysub))
791 if (instModifiesReg(&*Iter,
T, Tsub))
795 LLVM_DEBUG(
dbgs() <<
"Matched v_swap:\n" << MovT << *MovX << *MovY);
798 SmallVector<MachineInstr *, 4> Swaps;
804 TII->get(AMDGPU::V_SWAP_B16))
813 for (
unsigned I = 0;
I <
Size / 4; ++
I) {
814 TargetInstrInfo::RegSubRegPair X1, Y1;
815 X1 = getSubRegForIndex(
X, Xsub,
I);
816 Y1 = getSubRegForIndex(
Y, Ysub,
I);
818 TII->get(AMDGPU::V_SWAP_B32))
829 for (MachineInstr *Swap : Swaps) {
830 Swap->removeOperand(Swap->getNumExplicitOperands());
835 dropInstructionKeepingImpDefs(*MovY);
839 dropInstructionKeepingImpDefs(MovT);
845 if (
Op.isKill() &&
TRI->regsOverlap(
X,
Op.getReg()))
856bool SIShrinkInstructions::tryReplaceDeadSDST(MachineInstr &
MI)
const {
857 if (!ST->hasGFX10_3Insts())
860 MachineOperand *
Op =
TII->getNamedOperand(
MI, AMDGPU::OpName::sdst);
867 Op->setReg(ST->
isWave32() ? AMDGPU::SGPR_NULL : AMDGPU::SGPR_NULL64);
871bool SIShrinkInstructions::run(MachineFunction &MF) {
880 unsigned VCCReg = ST->
isWave32() ? AMDGPU::VCC_LO : AMDGPU::VCC;
883 for (MachineBasicBlock &
MBB : MF) {
887 MachineInstr &
MI = *
I;
889 if (
MI.getOpcode() == AMDGPU::V_MOV_B32_e32) {
897 MachineOperand &Src =
MI.getOperand(1);
898 if (Src.isImm() && IsPostRA) {
902 if (ModOpcode != 0) {
903 MI.setDesc(
TII->get(ModOpcode));
904 Src.setImm(
static_cast<int64_t
>(ModImm));
911 if (ST->
hasSwap() && (
MI.getOpcode() == AMDGPU::V_MOV_B32_e32 ||
912 MI.getOpcode() == AMDGPU::V_MOV_B16_t16_e32 ||
913 MI.getOpcode() == AMDGPU::COPY)) {
914 if (
auto *NextMI = matchSwap(
MI)) {
915 Next = NextMI->getIterator();
922 if (
MI.getOpcode() == AMDGPU::S_AND_B32 ||
923 MI.getOpcode() == AMDGPU::S_OR_B32 ||
924 MI.getOpcode() == AMDGPU::S_XOR_B32) {
925 ChangeKind CK = shrinkScalarLogicOp(
MI);
926 if (CK == ChangeKind::UpdateHint)
928 Changed |= (CK == ChangeKind::UpdateInst);
932 if (
MI.getOpcode() == AMDGPU::S_ADD_I32 ||
933 MI.getOpcode() == AMDGPU::S_MUL_I32 ||
934 (
MI.getOpcode() == AMDGPU::S_OR_B32 &&
935 MI.getFlag(MachineInstr::MIFlag::Disjoint))) {
936 const MachineOperand *Dest = &
MI.getOperand(0);
937 MachineOperand *Src0 = &
MI.getOperand(1);
938 MachineOperand *Src1 = &
MI.getOperand(2);
941 if (
TII->commuteInstruction(
MI,
false, 1, 2)) {
957 unsigned Opc = (
MI.getOpcode() == AMDGPU::S_MUL_I32)
959 : AMDGPU::S_ADDK_I32;
962 MI.tieOperands(0, 1);
969 if (
MI.isCompare() &&
TII->isSOPC(
MI)) {
975 if (
MI.getOpcode() == AMDGPU::S_MOV_B32) {
976 const MachineOperand &Dst =
MI.getOperand(0);
977 MachineOperand &Src =
MI.getOperand(1);
979 if (Src.isImm() && Dst.getReg().isPhysical()) {
983 MI.setDesc(
TII->get(AMDGPU::S_MOVK_I32));
988 MI.setDesc(
TII->get(ModOpc));
989 Src.setImm(
static_cast<int64_t
>(ModImm));
997 if (IsPostRA &&
TII->isMIMG(
MI.getOpcode()) &&
1003 if (!
TII->isVOP3(
MI))
1006 if (
MI.getOpcode() == AMDGPU::V_MAD_F32_e64 ||
1007 MI.getOpcode() == AMDGPU::V_FMA_F32_e64 ||
1008 MI.getOpcode() == AMDGPU::V_MAD_F16_e64 ||
1009 MI.getOpcode() == AMDGPU::V_FMA_F16_e64 ||
1010 MI.getOpcode() == AMDGPU::V_FMA_F16_gfx9_e64 ||
1011 MI.getOpcode() == AMDGPU::V_FMA_F16_gfx9_t16_e64 ||
1012 MI.getOpcode() == AMDGPU::V_FMA_F16_gfx9_fake16_e64 ||
1013 (
MI.getOpcode() == AMDGPU::V_FMA_F64_e64 &&
1021 if (
TII->isVOP3(
MI.getOpcode())) {
1023 if (!
TII->hasVALU32BitEncoding(
MI.getOpcode())) {
1028 if (!
TII->canShrink(
MI, *MRI)) {
1031 if (!
MI.isCommutable() || !
TII->commuteInstruction(
MI) ||
1032 !
TII->canShrink(
MI, *MRI)) {
1043 if (Op32 == AMDGPU::V_CNDMASK_B32_e32) {
1046 const MachineOperand *Src2 =
1047 TII->getNamedOperand(
MI, AMDGPU::OpName::src2);
1051 if (
SReg.isVirtual()) {
1062 const MachineOperand *SDst =
1063 TII->getNamedOperand(
MI, AMDGPU::OpName::sdst);
1068 if (SDst->
getReg() != VCCReg) {
1085 const MachineOperand *Src2 =
TII->getNamedOperand(
MI,
1086 AMDGPU::OpName::src2);
1087 if (Src2 && Src2->
getReg() != VCCReg) {
1103 if (ST->hasVOP3Literal() &&
1109 !shouldShrinkTrue16(
MI))
1115 MachineInstr *Inst32 =
TII->buildShrunkInst(
MI, Op32);
1116 ++NumInstructionsShrunk;
1119 copyExtraImplicitOps(*Inst32,
MI);
1122 if (SDst && SDst->
isDead())
1125 MI.eraseFromParent();
1126 foldImmediates(*Inst32);
1135bool SIShrinkInstructionsLegacy::runOnMachineFunction(MachineFunction &MF) {
1139 return SIShrinkInstructions().run(MF);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Provides AMDGPU specific target descriptions.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
AMD GCN specific subclass of TargetSubtarget.
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static unsigned canModifyToInlineImmOp32(const SIInstrInfo *TII, const MachineOperand &Src, int32_t &ModifiedImm, bool Scalar)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
Class for arbitrary precision integers.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Represents analyses that only rely on functions' control flow.
FunctionPass class - This class is used to implement most global optimizations.
bool hasOptNone() const
Do not optimize this function (-O0).
bool hasFmaakFmamkF64Insts() const
const SIInstrInfo * getInstrInfo() const override
unsigned getNSAMaxSize(bool HasSampler=false) const
Generation getGeneration() const
const HexagonRegisterInfo & getRegisterInfo() const
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
instr_iterator instr_end()
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineFunctionProperties & getProperties() const
Get the function properties.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
unsigned getNumImplicitOperands() const
Returns the implicit operands number.
iterator_range< filter_iterator< const_mop_iterator, bool(*)(const MachineOperand &)> > filtered_const_mop_range
const MachineBasicBlock * getParent() const
LLVM_ABI void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
LLVM_ABI unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
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 bool hasRegisterImplicitUseOperand(Register Reg) const
Returns true if the MachineInstr has an implicit-use operand of exactly the given register (not consi...
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
MachineOperand * findRegisterDefOperand(Register Reg, const TargetRegisterInfo *TRI, bool isDead=false, bool Overlap=false)
Wrapper for findRegisterDefOperandIdx, it returns a pointer to the MachineOperand rather than an inde...
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
const GlobalValue * getGlobal() const
LLVM_ABI void ChangeToFrameIndex(int Idx, unsigned TargetFlags=0)
Replace this operand with a frame index.
void setImm(int64_t immVal)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
void setIsDead(bool Val=true)
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
LLVM_ABI void ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags=0)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value.
LLVM_ABI void ChangeToGA(const GlobalValue *GV, int64_t Offset, unsigned TargetFlags=0)
ChangeToGA - Replace this operand with a new global address operand.
void setIsKill(bool Val=true)
unsigned getTargetFlags() const
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
Register getReg() const
getReg - Returns the register number.
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
int64_t getOffset() const
Return the offset from the symbol in this operand.
bool use_nodbg_empty(Register RegNo) const
use_nodbg_empty - Return true if there are no non-Debug instructions using the specified register.
void setRegAllocationHint(Register VReg, unsigned Type, Register PrefReg)
setRegAllocationHint - Specify a register allocation hint for the specified virtual register.
LLVM_ABI MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
static bool sopkIsZext(unsigned Opcode)
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &)
void push_back(const T &Elt)
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_READONLY const MIMGInfo * getMIMGInfo(unsigned Opc)
LLVM_READONLY int32_t getSOPKOp(uint32_t Opcode)
int getMIMGOpcode(unsigned BaseOpcode, unsigned MIMGEncoding, unsigned VDataDwords, unsigned VAddrDwords)
bool isKImmOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this a KImm operand?
bool isTrue16Inst(unsigned Opc)
bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi)
LLVM_READONLY int32_t getVOPe32(uint32_t Opcode)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
DXILDebugInfoMap run(Module &M)
NodeAddr< DefNode * > Def
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.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
@ Sub
Subtraction of integers.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
DWARFExpression::Operation Op
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
constexpr T reverseBits(T Val)
Reverse the bits in Val.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
FunctionPass * createSIShrinkInstructionsLegacyPass()
MCRegisterClass TargetRegisterClass
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
constexpr bool any() const