18#define DEBUG_TYPE "si-shrink-instructions"
21 "Number of 64-bit instruction reduced to 32-bit.");
23 "Number of literal constants folded into 32-bit instructions.");
29enum ChangeKind {
None, UpdateHint, UpdateInst };
31class SIShrinkInstructions {
33 MachineRegisterInfo *MRI;
34 const GCNSubtarget *ST;
35 const SIInstrInfo *TII;
36 const SIRegisterInfo *TRI;
39 bool foldImmediates(MachineInstr &
MI,
bool TryToCommute =
true)
const;
40 bool shouldShrinkTrue16(MachineInstr &
MI)
const;
41 bool isKImmOperand(
const MachineInstr &
MI,
const MachineOperand &Src)
const;
42 bool isKUImmOperand(
const MachineInstr &
MI,
const MachineOperand &Src)
const;
43 bool isKImmOrKUImmOperand(
const MachineOperand &Src,
bool &IsUnsigned)
const;
44 void copyExtraImplicitOps(MachineInstr &NewMI, MachineInstr &
MI)
const;
45 bool shrinkScalarCompare(MachineInstr &
MI)
const;
46 bool shrinkMIMG(MachineInstr &
MI)
const;
47 bool shrinkMadFma(MachineInstr &
MI)
const;
48 ChangeKind shrinkScalarLogicOp(MachineInstr &
MI)
const;
49 bool tryReplaceDeadSDST(MachineInstr &
MI)
const;
51 unsigned SubReg)
const;
52 bool instReadsReg(
const MachineInstr *
MI,
unsigned Reg,
53 unsigned SubReg)
const;
54 bool instModifiesReg(
const MachineInstr *
MI,
unsigned Reg,
55 unsigned SubReg)
const;
56 TargetInstrInfo::RegSubRegPair getSubRegForIndex(
Register Reg,
unsigned Sub,
58 void dropInstructionKeepingImpDefs(MachineInstr &
MI)
const;
59 MachineInstr *matchSwap(MachineInstr &MovT)
const;
62 SIShrinkInstructions() =
default;
71 SIShrinkInstructionsLegacy() : MachineFunctionPass(ID) {}
75 StringRef getPassName()
const override {
return "SI Shrink Instructions"; }
77 void getAnalysisUsage(AnalysisUsage &AU)
const override {
86 "SI Shrink Instructions",
false,
false)
88char SIShrinkInstructionsLegacy::ID = 0;
91 return new SIShrinkInstructionsLegacy();
98 bool TryToCommute)
const {
101 int Src0Idx = AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::src0);
104 MachineOperand &
Src0 =
MI.getOperand(Src0Idx);
109 if (Def &&
Def->isMoveImmediate()) {
110 const MachineOperand &MovSrc =
Def->getOperand(1);
111 bool ConstantFolded =
false;
113 if (MovSrc.
isImm()) {
117 if (
TII->isOperandLegal(
MI, Src0Idx, &ImmOp)) {
119 ConstantFolded =
true;
123 if (std::optional<unsigned> Flags =
128 if (
TII->isOperandLegal(
MI, Src0Idx, &GAOp)) {
130 ConstantFolded =
true;
133 }
else if (MovSrc.
isFI() && !
Src0.getSubReg() &&
134 TII->isOperandLegal(
MI, Src0Idx, &MovSrc)) {
136 ConstantFolded =
true;
139 if (ConstantFolded) {
141 Def->eraseFromParent();
142 ++NumLiteralConstantsFolded;
150 if (TryToCommute &&
MI.isCommutable()) {
151 if (
TII->commuteInstruction(
MI)) {
152 if (foldImmediates(
MI,
false))
156 TII->commuteInstruction(
MI);
165bool SIShrinkInstructions::shouldShrinkTrue16(MachineInstr &
MI)
const {
166 for (
unsigned I = 0,
E =
MI.getNumExplicitOperands();
I !=
E; ++
I) {
167 const MachineOperand &MO =
MI.getOperand(
I);
171 "True16 Instructions post-RA");
184bool SIShrinkInstructions::isKImmOperand(
const MachineInstr &
MI,
185 const MachineOperand &Src)
const {
187 !
TII->isInlineConstant(
MI,
MI.getOperandNo(&Src));
190bool SIShrinkInstructions::isKUImmOperand(
const MachineInstr &
MI,
191 const MachineOperand &Src)
const {
193 !
TII->isInlineConstant(
MI,
MI.getOperandNo(&Src));
196bool SIShrinkInstructions::isKImmOrKUImmOperand(
const MachineOperand &Src,
197 bool &IsUnsigned)
const {
200 return !
TII->isInlineConstant(Src);
205 return !
TII->isInlineConstant(Src);
222 int32_t &ModifiedImm,
bool Scalar) {
223 if (
TII->isInlineConstant(Src))
225 int32_t SrcImm =
static_cast<int32_t
>(Src.getImm());
231 ModifiedImm = ~SrcImm;
232 if (
TII->isInlineConstant(
APInt(32, ModifiedImm,
true)))
233 return AMDGPU::V_NOT_B32_e32;
237 if (
TII->isInlineConstant(
APInt(32, ModifiedImm,
true)))
238 return Scalar ? AMDGPU::S_BREV_B32 : AMDGPU::V_BFREV_B32_e32;
245void SIShrinkInstructions::copyExtraImplicitOps(MachineInstr &NewMI,
246 MachineInstr &
MI)
const {
248 for (
unsigned i =
MI.getDesc().getNumOperands() +
249 MI.getDesc().implicit_uses().size() +
250 MI.getDesc().implicit_defs().size(),
251 e =
MI.getNumOperands();
253 const MachineOperand &MO =
MI.getOperand(i);
259bool SIShrinkInstructions::shrinkScalarCompare(MachineInstr &
MI)
const {
266 if (!
MI.getOperand(0).isReg()) {
267 if (
TII->commuteInstruction(
MI,
false, 0, 1))
272 const MachineOperand &
Src0 =
MI.getOperand(0);
276 MachineOperand &
Src1 =
MI.getOperand(1);
286 if (SOPKOpc == AMDGPU::S_CMPK_EQ_U32 || SOPKOpc == AMDGPU::S_CMPK_LG_U32) {
288 if (isKImmOrKUImmOperand(Src1, HasUImm)) {
290 SOPKOpc = (SOPKOpc == AMDGPU::S_CMPK_EQ_U32) ?
291 AMDGPU::S_CMPK_EQ_I32 : AMDGPU::S_CMPK_LG_I32;
295 MI.setDesc(
TII->get(SOPKOpc));
302 const MCInstrDesc &NewDesc =
TII->get(SOPKOpc);
315bool SIShrinkInstructions::shrinkMIMG(MachineInstr &
MI)
const {
321 switch (
Info->MIMGEncoding) {
322 case AMDGPU::MIMGEncGfx10NSA:
323 NewEncoding = AMDGPU::MIMGEncGfx10Default;
325 case AMDGPU::MIMGEncGfx11NSA:
326 NewEncoding = AMDGPU::MIMGEncGfx11Default;
333 AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::vaddr0);
334 unsigned NewAddrDwords =
Info->VAddrDwords;
337 if (
Info->VAddrDwords == 2) {
338 RC = &AMDGPU::VReg_64RegClass;
339 }
else if (
Info->VAddrDwords == 3) {
340 RC = &AMDGPU::VReg_96RegClass;
341 }
else if (
Info->VAddrDwords == 4) {
342 RC = &AMDGPU::VReg_128RegClass;
343 }
else if (
Info->VAddrDwords == 5) {
344 RC = &AMDGPU::VReg_160RegClass;
345 }
else if (
Info->VAddrDwords == 6) {
346 RC = &AMDGPU::VReg_192RegClass;
347 }
else if (
Info->VAddrDwords == 7) {
348 RC = &AMDGPU::VReg_224RegClass;
349 }
else if (
Info->VAddrDwords == 8) {
350 RC = &AMDGPU::VReg_256RegClass;
351 }
else if (
Info->VAddrDwords == 9) {
352 RC = &AMDGPU::VReg_288RegClass;
353 }
else if (
Info->VAddrDwords == 10) {
354 RC = &AMDGPU::VReg_320RegClass;
355 }
else if (
Info->VAddrDwords == 11) {
356 RC = &AMDGPU::VReg_352RegClass;
357 }
else if (
Info->VAddrDwords == 12) {
358 RC = &AMDGPU::VReg_384RegClass;
360 RC = &AMDGPU::VReg_512RegClass;
364 unsigned VgprBase = 0;
365 unsigned NextVgpr = 0;
367 bool IsKill = NewAddrDwords ==
Info->VAddrDwords;
369 const bool IsPartialNSA = NewAddrDwords > NSAMaxSize;
370 const unsigned EndVAddr = IsPartialNSA ? NSAMaxSize :
Info->VAddrOperands;
371 for (
unsigned Idx = 0;
Idx < EndVAddr; ++
Idx) {
372 const MachineOperand &
Op =
MI.getOperand(VAddr0Idx + Idx);
373 unsigned Vgpr =
TRI->getHWRegIndex(
Op.getReg());
374 unsigned Dwords =
TRI->getRegSizeInBits(
Op.getReg(), *
MRI) / 32;
375 assert(Dwords > 0 &&
"Un-implemented for less than 32 bit regs");
379 NextVgpr = Vgpr + Dwords;
380 }
else if (Vgpr == NextVgpr) {
381 NextVgpr = Vgpr + Dwords;
392 if (VgprBase + NewAddrDwords > 256)
397 int TFEIdx = AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::tfe);
398 int LWEIdx = AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::lwe);
399 unsigned TFEVal = (TFEIdx == -1) ? 0 :
MI.getOperand(TFEIdx).
getImm();
402 if (TFEVal || LWEVal) {
404 for (
unsigned i = LWEIdx + 1, e =
MI.getNumOperands(); i != e; ++i) {
405 if (
MI.getOperand(i).isReg() &&
MI.getOperand(i).isTied() &&
406 MI.getOperand(i).isImplicit()) {
410 "found more than one tied implicit operand when expecting only 1");
412 MI.untieRegOperand(ToUntie);
418 Info->VDataDwords, NewAddrDwords);
419 MI.setDesc(
TII->get(NewOpcode));
421 MI.getOperand(VAddr0Idx).setIsUndef(IsUndef);
422 MI.getOperand(VAddr0Idx).setIsKill(IsKill);
424 for (
unsigned i = 1; i < EndVAddr; ++i)
425 MI.removeOperand(VAddr0Idx + 1);
429 AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::vdata),
430 ToUntie - (EndVAddr - 1));
436bool SIShrinkInstructions::shrinkMadFma(MachineInstr &
MI)
const {
439 if (!ST->hasVOP3Literal())
446 if (
TII->hasAnyModifiersSet(
MI))
449 const unsigned Opcode =
MI.getOpcode();
450 MachineOperand &
Src0 = *
TII->getNamedOperand(
MI, AMDGPU::OpName::src0);
451 MachineOperand &
Src1 = *
TII->getNamedOperand(
MI, AMDGPU::OpName::src1);
452 MachineOperand &
Src2 = *
TII->getNamedOperand(
MI, AMDGPU::OpName::src2);
453 unsigned NewOpcode = AMDGPU::INSTRUCTION_LIST_END;
458 if (
Src2.isImm() && !
TII->isInlineConstant(Src2)) {
469 case AMDGPU::V_MAD_F32_e64:
470 NewOpcode = AMDGPU::V_MADAK_F32;
472 case AMDGPU::V_FMA_F32_e64:
473 NewOpcode = AMDGPU::V_FMAAK_F32;
475 case AMDGPU::V_MAD_F16_e64:
476 NewOpcode = AMDGPU::V_MADAK_F16;
478 case AMDGPU::V_FMA_F16_e64:
479 case AMDGPU::V_FMA_F16_gfx9_e64:
480 NewOpcode = AMDGPU::V_FMAAK_F16;
482 case AMDGPU::V_FMA_F16_gfx9_t16_e64:
483 NewOpcode = AMDGPU::V_FMAAK_F16_t16;
485 case AMDGPU::V_FMA_F16_gfx9_fake16_e64:
486 NewOpcode = AMDGPU::V_FMAAK_F16_fake16;
488 case AMDGPU::V_FMA_F64_e64:
490 NewOpcode = AMDGPU::V_FMAAK_F64;
497 if (
Src1.isImm() && !
TII->isInlineConstant(Src1))
499 else if (
Src0.isImm() && !
TII->isInlineConstant(Src0))
507 case AMDGPU::V_MAD_F32_e64:
508 NewOpcode = AMDGPU::V_MADMK_F32;
510 case AMDGPU::V_FMA_F32_e64:
511 NewOpcode = AMDGPU::V_FMAMK_F32;
513 case AMDGPU::V_MAD_F16_e64:
514 NewOpcode = AMDGPU::V_MADMK_F16;
516 case AMDGPU::V_FMA_F16_e64:
517 case AMDGPU::V_FMA_F16_gfx9_e64:
518 NewOpcode = AMDGPU::V_FMAMK_F16;
520 case AMDGPU::V_FMA_F16_gfx9_t16_e64:
521 NewOpcode = AMDGPU::V_FMAMK_F16_t16;
523 case AMDGPU::V_FMA_F16_gfx9_fake16_e64:
524 NewOpcode = AMDGPU::V_FMAMK_F16_fake16;
526 case AMDGPU::V_FMA_F64_e64:
528 NewOpcode = AMDGPU::V_FMAMK_F64;
533 if (NewOpcode == AMDGPU::INSTRUCTION_LIST_END)
542 MI.getOperand(0).getReg())
547 MI.eraseFromParent();
549 TII->removeModOperands(
MI);
550 MI.setDesc(
TII->get(NewOpcode));
562ChangeKind SIShrinkInstructions::shrinkScalarLogicOp(MachineInstr &
MI)
const {
563 unsigned Opc =
MI.getOpcode();
564 const MachineOperand *Dest = &
MI.getOperand(0);
565 MachineOperand *
Src0 = &
MI.getOperand(1);
566 MachineOperand *
Src1 = &
MI.getOperand(2);
567 MachineOperand *SrcReg =
Src0;
568 MachineOperand *SrcImm =
Src1;
570 if (!SrcImm->
isImm() ||
572 return ChangeKind::None;
574 uint32_t
Imm =
static_cast<uint32_t
>(SrcImm->
getImm());
577 if (
Opc == AMDGPU::S_AND_B32) {
579 MI.findRegisterDefOperand(AMDGPU::SCC,
nullptr)->isDead()) {
581 Opc = AMDGPU::S_BITSET0_B32;
584 Opc = AMDGPU::S_ANDN2_B32;
586 }
else if (
Opc == AMDGPU::S_OR_B32) {
588 MI.findRegisterDefOperand(AMDGPU::SCC,
nullptr)->isDead()) {
590 Opc = AMDGPU::S_BITSET1_B32;
593 Opc = AMDGPU::S_ORN2_B32;
595 }
else if (
Opc == AMDGPU::S_XOR_B32) {
598 Opc = AMDGPU::S_XNOR_B32;
608 return ChangeKind::UpdateHint;
612 const bool IsUndef = SrcReg->
isUndef();
613 const bool IsKill = SrcReg->
isKill();
615 if (
Opc == AMDGPU::S_BITSET0_B32 ||
616 Opc == AMDGPU::S_BITSET1_B32) {
617 Src0->ChangeToImmediate(NewImm);
619 MI.getOperand(2).ChangeToRegister(Dest->
getReg(),
false,
622 MI.tieOperands(0, 2);
626 return ChangeKind::UpdateInst;
630 return ChangeKind::None;
635bool SIShrinkInstructions::instAccessReg(
637 unsigned SubReg)
const {
638 for (
const MachineOperand &MO : R) {
643 LaneBitmask Overlap =
TRI->getSubRegIndexLaneMask(SubReg) &
652bool SIShrinkInstructions::instReadsReg(
const MachineInstr *
MI,
unsigned Reg,
653 unsigned SubReg)
const {
654 return instAccessReg(
MI->all_uses(),
Reg, SubReg);
657bool SIShrinkInstructions::instModifiesReg(
const MachineInstr *
MI,
unsigned Reg,
658 unsigned SubReg)
const {
659 return instAccessReg(
MI->all_defs(),
Reg, SubReg);
662TargetInstrInfo::RegSubRegPair
663SIShrinkInstructions::getSubRegForIndex(
Register Reg,
unsigned Sub,
665 if (
TRI->getRegSizeInBits(
Reg, *
MRI) != 32) {
669 Sub =
TRI->getSubRegFromChannel(
I +
TRI->getChannelFromSubReg(
Sub));
672 return TargetInstrInfo::RegSubRegPair(
Reg,
Sub);
675void SIShrinkInstructions::dropInstructionKeepingImpDefs(
676 MachineInstr &
MI)
const {
677 for (
unsigned i =
MI.getDesc().getNumOperands() +
678 MI.getDesc().implicit_uses().size() +
679 MI.getDesc().implicit_defs().size(),
680 e =
MI.getNumOperands();
682 const MachineOperand &
Op =
MI.getOperand(i);
686 TII->get(AMDGPU::IMPLICIT_DEF),
Op.getReg());
689 MI.eraseFromParent();
711MachineInstr *SIShrinkInstructions::matchSwap(MachineInstr &MovT)
const {
713 MovT.
getOpcode() == AMDGPU::V_MOV_B16_t16_e32 ||
727 unsigned Size =
TII->getOpSize(MovT, 0);
731 if (
Size == 2 &&
X.isVirtual())
737 const unsigned SearchLimit = 16;
740 MachineInstr *MovX =
nullptr;
741 MachineInstr *InsertionPt =
nullptr;
742 MachineInstr *MovY =
nullptr;
746 Iter !=
E &&
Count < SearchLimit; ++Iter) {
747 if (Iter->isDebugInstr())
753 if ((Iter->getOpcode() == AMDGPU::V_MOV_B32_e32 ||
754 Iter->getOpcode() == AMDGPU::V_MOV_B16_t16_e32 ||
755 Iter->getOpcode() == AMDGPU::COPY) &&
756 Iter->getOperand(0).getReg() ==
X &&
757 Iter->getOperand(0).getSubReg() == Xsub &&
758 Iter->getOperand(1).isReg()) {
762 }
else if (instModifiesReg(&*Iter,
X, Xsub)) {
769 if ((Iter->getOpcode() == AMDGPU::V_MOV_B32_e32 ||
770 Iter->getOpcode() == AMDGPU::V_MOV_B16_t16_e32 ||
771 Iter->getOpcode() == AMDGPU::COPY) &&
772 Iter->getOperand(0).getReg() ==
Y &&
773 Iter->getOperand(0).getSubReg() == Ysub &&
774 Iter->getOperand(1).isReg() && Iter->getOperand(1).getReg() ==
T &&
775 Iter->getOperand(1).getSubReg() == Tsub) {
784 if (instModifiesReg(&*Iter,
Y, Ysub))
790 (instReadsReg(&*Iter,
X, Xsub) || instModifiesReg(&*Iter,
X, Xsub))) {
791 InsertionPt = &*Iter;
797 if (instReadsReg(&*Iter,
Y, Ysub))
802 if (instModifiesReg(&*Iter,
T, Tsub))
806 LLVM_DEBUG(
dbgs() <<
"Matched v_swap:\n" << MovT << *MovX << *MovY);
809 SmallVector<MachineInstr *, 4> Swaps;
815 TII->get(AMDGPU::V_SWAP_B16))
824 for (
unsigned I = 0;
I <
Size / 4; ++
I) {
825 TargetInstrInfo::RegSubRegPair X1, Y1;
826 X1 = getSubRegForIndex(
X, Xsub,
I);
827 Y1 = getSubRegForIndex(
Y, Ysub,
I);
829 TII->get(AMDGPU::V_SWAP_B32))
840 for (MachineInstr *
Swap : Swaps) {
841 Swap->removeOperand(
Swap->getNumExplicitOperands());
846 dropInstructionKeepingImpDefs(*MovY);
850 dropInstructionKeepingImpDefs(MovT);
856 if (
Op.isKill() &&
TRI->regsOverlap(
X,
Op.getReg()))
867bool SIShrinkInstructions::tryReplaceDeadSDST(MachineInstr &
MI)
const {
868 if (!ST->hasGFX10_3Insts())
871 MachineOperand *
Op =
TII->getNamedOperand(
MI, AMDGPU::OpName::sdst);
878 Op->setReg(ST->
isWave32() ? AMDGPU::SGPR_NULL : AMDGPU::SGPR_NULL64);
891 unsigned VCCReg = ST->
isWave32() ? AMDGPU::VCC_LO : AMDGPU::VCC;
894 for (MachineBasicBlock &
MBB : MF) {
898 MachineInstr &
MI = *
I;
900 if (
MI.getOpcode() == AMDGPU::V_MOV_B32_e32) {
908 MachineOperand &Src =
MI.getOperand(1);
909 if (Src.isImm() && IsPostRA) {
913 if (ModOpcode != 0) {
914 MI.setDesc(
TII->get(ModOpcode));
915 Src.setImm(
static_cast<int64_t
>(ModImm));
922 if (ST->
hasSwap() && (
MI.getOpcode() == AMDGPU::V_MOV_B32_e32 ||
923 MI.getOpcode() == AMDGPU::V_MOV_B16_t16_e32 ||
924 MI.getOpcode() == AMDGPU::COPY)) {
925 if (
auto *NextMI = matchSwap(
MI)) {
926 Next = NextMI->getIterator();
933 if (
MI.getOpcode() == AMDGPU::S_AND_B32 ||
934 MI.getOpcode() == AMDGPU::S_OR_B32 ||
935 MI.getOpcode() == AMDGPU::S_XOR_B32) {
936 ChangeKind CK = shrinkScalarLogicOp(
MI);
937 if (CK == ChangeKind::UpdateHint)
939 Changed |= (CK == ChangeKind::UpdateInst);
945 if (
MI.getOpcode() == AMDGPU::S_ADD_I32 ||
946 MI.getOpcode() == AMDGPU::S_MUL_I32 ||
947 (
MI.getOpcode() == AMDGPU::S_OR_B32 &&
948 MI.getFlag(MachineInstr::MIFlag::Disjoint) &&
949 MI.allImplicitDefsAreDead())) {
950 const MachineOperand *Dest = &
MI.getOperand(0);
951 MachineOperand *
Src0 = &
MI.getOperand(1);
952 MachineOperand *
Src1 = &
MI.getOperand(2);
954 if (!
Src0->isReg() &&
Src1->isReg()) {
955 if (
TII->commuteInstruction(
MI,
false, 1, 2)) {
971 unsigned Opc = (
MI.getOpcode() == AMDGPU::S_MUL_I32)
973 : AMDGPU::S_ADDK_I32;
976 MI.tieOperands(0, 1);
983 if (
MI.isCompare() &&
TII->isSOPC(
MI)) {
989 if (
MI.getOpcode() == AMDGPU::S_MOV_B32) {
990 const MachineOperand &Dst =
MI.getOperand(0);
991 MachineOperand &Src =
MI.getOperand(1);
993 if (Src.isImm() && Dst.getReg().isPhysical()) {
997 MI.setDesc(
TII->get(AMDGPU::S_MOVK_I32));
1002 MI.setDesc(
TII->get(ModOpc));
1003 Src.setImm(
static_cast<int64_t
>(ModImm));
1011 if (IsPostRA &&
TII->isMIMG(
MI.getOpcode()) &&
1017 if (!
TII->isVOP3(
MI))
1020 if (
MI.getOpcode() == AMDGPU::V_MAD_F32_e64 ||
1021 MI.getOpcode() == AMDGPU::V_FMA_F32_e64 ||
1022 MI.getOpcode() == AMDGPU::V_MAD_F16_e64 ||
1023 MI.getOpcode() == AMDGPU::V_FMA_F16_e64 ||
1024 MI.getOpcode() == AMDGPU::V_FMA_F16_gfx9_e64 ||
1025 MI.getOpcode() == AMDGPU::V_FMA_F16_gfx9_t16_e64 ||
1026 MI.getOpcode() == AMDGPU::V_FMA_F16_gfx9_fake16_e64 ||
1027 (
MI.getOpcode() == AMDGPU::V_FMA_F64_e64 &&
1036 if (!
TII->hasVALU32BitEncoding(
MI.getOpcode()))
1042 if (!
MI.isCommutable() || !
TII->commuteInstruction(
MI) ||
1054 if (Op32 == AMDGPU::V_CNDMASK_B32_e32) {
1057 const MachineOperand *
Src2 =
1058 TII->getNamedOperand(
MI, AMDGPU::OpName::src2);
1062 if (
SReg.isVirtual()) {
1073 const MachineOperand *SDst =
1074 TII->getNamedOperand(
MI, AMDGPU::OpName::sdst);
1079 if (SDst->
getReg() != VCCReg) {
1096 const MachineOperand *
Src2 =
TII->getNamedOperand(
MI,
1097 AMDGPU::OpName::src2);
1098 if (Src2 &&
Src2->getReg() != VCCReg) {
1099 if (
Src2->getReg().isVirtual())
1114 if (ST->hasVOP3Literal() &&
1120 !shouldShrinkTrue16(
MI))
1126 MachineInstr *Inst32 =
TII->buildShrunkInst(
MI, Op32);
1127 ++NumInstructionsShrunk;
1130 copyExtraImplicitOps(*Inst32,
MI);
1132 MI.eraseFromParent();
1133 foldImmediates(*Inst32);
1142bool SIShrinkInstructionsLegacy::runOnMachineFunction(
MachineFunction &MF) {
1146 return SIShrinkInstructions().run(MF);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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)
MachineRegisterInfo & MRI
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.
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 class - Representation of each machine instruction operand.
unsigned getSubReg() const
const GlobalValue * getGlobal() const
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.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
void setIsKill(bool Val=true)
unsigned getTargetFlags() const
static MachineOperand CreateImm(int64_t Val)
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateGA(const GlobalValue *GV, int64_t Offset, unsigned TargetFlags=0)
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 LLVM_READONLY 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 std::optional< unsigned > extractSubregFromGlobalAddressFlags(unsigned TargetFlags, unsigned SubRegIndex)
Return the target flags for a global address operand reading subregister SubRegIndex of a 64-bit glob...
static std::optional< int64_t > extractSubregFromImm(int64_t ImmVal, unsigned SubRegIndex)
Return the extracted immediate value in a subregister use from a constant materialized in a super reg...
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)
bool isKImmOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this a KImm operand?
int getMIMGOpcode(unsigned BaseOpcode, unsigned MIMGEncoding, unsigned VDataDwords, unsigned VAddrDwords, bool IndexedRsrc, bool IndexedSamp)
bool isTrue16Inst(unsigned Opc)
bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi)
LLVM_READONLY int32_t getVOPe32(uint32_t Opcode)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the 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