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;
122 }
else if (!
Src0.getSubReg() &&
123 TII->isOperandLegal(
MI, Src0Idx, &MovSrc)) {
126 ConstantFolded =
true;
130 ConstantFolded =
true;
134 if (ConstantFolded) {
136 Def->eraseFromParent();
137 ++NumLiteralConstantsFolded;
145 if (TryToCommute &&
MI.isCommutable()) {
146 if (
TII->commuteInstruction(
MI)) {
147 if (foldImmediates(
MI,
false))
151 TII->commuteInstruction(
MI);
160bool SIShrinkInstructions::shouldShrinkTrue16(MachineInstr &
MI)
const {
161 for (
unsigned I = 0,
E =
MI.getNumExplicitOperands();
I !=
E; ++
I) {
162 const MachineOperand &MO =
MI.getOperand(
I);
166 "True16 Instructions post-RA");
179bool SIShrinkInstructions::isKImmOperand(
const MachineInstr &
MI,
180 const MachineOperand &Src)
const {
182 !
TII->isInlineConstant(
MI,
MI.getOperandNo(&Src));
185bool SIShrinkInstructions::isKUImmOperand(
const MachineInstr &
MI,
186 const MachineOperand &Src)
const {
188 !
TII->isInlineConstant(
MI,
MI.getOperandNo(&Src));
191bool SIShrinkInstructions::isKImmOrKUImmOperand(
const MachineOperand &Src,
192 bool &IsUnsigned)
const {
195 return !
TII->isInlineConstant(Src);
200 return !
TII->isInlineConstant(Src);
217 int32_t &ModifiedImm,
bool Scalar) {
218 if (
TII->isInlineConstant(Src))
220 int32_t SrcImm =
static_cast<int32_t
>(Src.getImm());
226 ModifiedImm = ~SrcImm;
227 if (
TII->isInlineConstant(
APInt(32, ModifiedImm,
true)))
228 return AMDGPU::V_NOT_B32_e32;
232 if (
TII->isInlineConstant(
APInt(32, ModifiedImm,
true)))
233 return Scalar ? AMDGPU::S_BREV_B32 : AMDGPU::V_BFREV_B32_e32;
240void SIShrinkInstructions::copyExtraImplicitOps(MachineInstr &NewMI,
241 MachineInstr &
MI)
const {
243 for (
unsigned i =
MI.getDesc().getNumOperands() +
244 MI.getDesc().implicit_uses().size() +
245 MI.getDesc().implicit_defs().size(),
246 e =
MI.getNumOperands();
248 const MachineOperand &MO =
MI.getOperand(i);
254bool SIShrinkInstructions::shrinkScalarCompare(MachineInstr &
MI)
const {
261 if (!
MI.getOperand(0).isReg()) {
262 if (
TII->commuteInstruction(
MI,
false, 0, 1))
267 const MachineOperand &
Src0 =
MI.getOperand(0);
271 MachineOperand &
Src1 =
MI.getOperand(1);
281 if (SOPKOpc == AMDGPU::S_CMPK_EQ_U32 || SOPKOpc == AMDGPU::S_CMPK_LG_U32) {
283 if (isKImmOrKUImmOperand(Src1, HasUImm)) {
285 SOPKOpc = (SOPKOpc == AMDGPU::S_CMPK_EQ_U32) ?
286 AMDGPU::S_CMPK_EQ_I32 : AMDGPU::S_CMPK_LG_I32;
290 MI.setDesc(
TII->get(SOPKOpc));
297 const MCInstrDesc &NewDesc =
TII->get(SOPKOpc);
310bool SIShrinkInstructions::shrinkMIMG(MachineInstr &
MI)
const {
316 switch (
Info->MIMGEncoding) {
317 case AMDGPU::MIMGEncGfx10NSA:
318 NewEncoding = AMDGPU::MIMGEncGfx10Default;
320 case AMDGPU::MIMGEncGfx11NSA:
321 NewEncoding = AMDGPU::MIMGEncGfx11Default;
328 AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::vaddr0);
329 unsigned NewAddrDwords =
Info->VAddrDwords;
332 if (
Info->VAddrDwords == 2) {
333 RC = &AMDGPU::VReg_64RegClass;
334 }
else if (
Info->VAddrDwords == 3) {
335 RC = &AMDGPU::VReg_96RegClass;
336 }
else if (
Info->VAddrDwords == 4) {
337 RC = &AMDGPU::VReg_128RegClass;
338 }
else if (
Info->VAddrDwords == 5) {
339 RC = &AMDGPU::VReg_160RegClass;
340 }
else if (
Info->VAddrDwords == 6) {
341 RC = &AMDGPU::VReg_192RegClass;
342 }
else if (
Info->VAddrDwords == 7) {
343 RC = &AMDGPU::VReg_224RegClass;
344 }
else if (
Info->VAddrDwords == 8) {
345 RC = &AMDGPU::VReg_256RegClass;
346 }
else if (
Info->VAddrDwords == 9) {
347 RC = &AMDGPU::VReg_288RegClass;
348 }
else if (
Info->VAddrDwords == 10) {
349 RC = &AMDGPU::VReg_320RegClass;
350 }
else if (
Info->VAddrDwords == 11) {
351 RC = &AMDGPU::VReg_352RegClass;
352 }
else if (
Info->VAddrDwords == 12) {
353 RC = &AMDGPU::VReg_384RegClass;
355 RC = &AMDGPU::VReg_512RegClass;
359 unsigned VgprBase = 0;
360 unsigned NextVgpr = 0;
362 bool IsKill = NewAddrDwords ==
Info->VAddrDwords;
364 const bool IsPartialNSA = NewAddrDwords > NSAMaxSize;
365 const unsigned EndVAddr = IsPartialNSA ? NSAMaxSize :
Info->VAddrOperands;
366 for (
unsigned Idx = 0;
Idx < EndVAddr; ++
Idx) {
367 const MachineOperand &
Op =
MI.getOperand(VAddr0Idx + Idx);
368 unsigned Vgpr =
TRI->getHWRegIndex(
Op.getReg());
369 unsigned Dwords =
TRI->getRegSizeInBits(
Op.getReg(), *
MRI) / 32;
370 assert(Dwords > 0 &&
"Un-implemented for less than 32 bit regs");
374 NextVgpr = Vgpr + Dwords;
375 }
else if (Vgpr == NextVgpr) {
376 NextVgpr = Vgpr + Dwords;
387 if (VgprBase + NewAddrDwords > 256)
392 int TFEIdx = AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::tfe);
393 int LWEIdx = AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::lwe);
394 unsigned TFEVal = (TFEIdx == -1) ? 0 :
MI.getOperand(TFEIdx).
getImm();
397 if (TFEVal || LWEVal) {
399 for (
unsigned i = LWEIdx + 1, e =
MI.getNumOperands(); i != e; ++i) {
400 if (
MI.getOperand(i).isReg() &&
MI.getOperand(i).isTied() &&
401 MI.getOperand(i).isImplicit()) {
405 "found more than one tied implicit operand when expecting only 1");
407 MI.untieRegOperand(ToUntie);
413 Info->VDataDwords, NewAddrDwords);
414 MI.setDesc(
TII->get(NewOpcode));
416 MI.getOperand(VAddr0Idx).setIsUndef(IsUndef);
417 MI.getOperand(VAddr0Idx).setIsKill(IsKill);
419 for (
unsigned i = 1; i < EndVAddr; ++i)
420 MI.removeOperand(VAddr0Idx + 1);
424 AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::vdata),
425 ToUntie - (EndVAddr - 1));
431bool SIShrinkInstructions::shrinkMadFma(MachineInstr &
MI)
const {
434 if (!ST->hasVOP3Literal())
441 if (
TII->hasAnyModifiersSet(
MI))
444 const unsigned Opcode =
MI.getOpcode();
445 MachineOperand &
Src0 = *
TII->getNamedOperand(
MI, AMDGPU::OpName::src0);
446 MachineOperand &
Src1 = *
TII->getNamedOperand(
MI, AMDGPU::OpName::src1);
447 MachineOperand &
Src2 = *
TII->getNamedOperand(
MI, AMDGPU::OpName::src2);
448 unsigned NewOpcode = AMDGPU::INSTRUCTION_LIST_END;
453 if (
Src2.isImm() && !
TII->isInlineConstant(Src2)) {
464 case AMDGPU::V_MAD_F32_e64:
465 NewOpcode = AMDGPU::V_MADAK_F32;
467 case AMDGPU::V_FMA_F32_e64:
468 NewOpcode = AMDGPU::V_FMAAK_F32;
470 case AMDGPU::V_MAD_F16_e64:
471 NewOpcode = AMDGPU::V_MADAK_F16;
473 case AMDGPU::V_FMA_F16_e64:
474 case AMDGPU::V_FMA_F16_gfx9_e64:
475 NewOpcode = AMDGPU::V_FMAAK_F16;
477 case AMDGPU::V_FMA_F16_gfx9_t16_e64:
478 NewOpcode = AMDGPU::V_FMAAK_F16_t16;
480 case AMDGPU::V_FMA_F16_gfx9_fake16_e64:
481 NewOpcode = AMDGPU::V_FMAAK_F16_fake16;
483 case AMDGPU::V_FMA_F64_e64:
485 NewOpcode = AMDGPU::V_FMAAK_F64;
492 if (
Src1.isImm() && !
TII->isInlineConstant(Src1))
494 else if (
Src0.isImm() && !
TII->isInlineConstant(Src0))
502 case AMDGPU::V_MAD_F32_e64:
503 NewOpcode = AMDGPU::V_MADMK_F32;
505 case AMDGPU::V_FMA_F32_e64:
506 NewOpcode = AMDGPU::V_FMAMK_F32;
508 case AMDGPU::V_MAD_F16_e64:
509 NewOpcode = AMDGPU::V_MADMK_F16;
511 case AMDGPU::V_FMA_F16_e64:
512 case AMDGPU::V_FMA_F16_gfx9_e64:
513 NewOpcode = AMDGPU::V_FMAMK_F16;
515 case AMDGPU::V_FMA_F16_gfx9_t16_e64:
516 NewOpcode = AMDGPU::V_FMAMK_F16_t16;
518 case AMDGPU::V_FMA_F16_gfx9_fake16_e64:
519 NewOpcode = AMDGPU::V_FMAMK_F16_fake16;
521 case AMDGPU::V_FMA_F64_e64:
523 NewOpcode = AMDGPU::V_FMAMK_F64;
528 if (NewOpcode == AMDGPU::INSTRUCTION_LIST_END)
537 MI.getOperand(0).getReg())
542 MI.eraseFromParent();
544 TII->removeModOperands(
MI);
545 MI.setDesc(
TII->get(NewOpcode));
557ChangeKind SIShrinkInstructions::shrinkScalarLogicOp(MachineInstr &
MI)
const {
558 unsigned Opc =
MI.getOpcode();
559 const MachineOperand *Dest = &
MI.getOperand(0);
560 MachineOperand *
Src0 = &
MI.getOperand(1);
561 MachineOperand *
Src1 = &
MI.getOperand(2);
562 MachineOperand *SrcReg =
Src0;
563 MachineOperand *SrcImm =
Src1;
565 if (!SrcImm->
isImm() ||
567 return ChangeKind::None;
569 uint32_t
Imm =
static_cast<uint32_t
>(SrcImm->
getImm());
572 if (
Opc == AMDGPU::S_AND_B32) {
574 MI.findRegisterDefOperand(AMDGPU::SCC,
nullptr)->isDead()) {
576 Opc = AMDGPU::S_BITSET0_B32;
579 Opc = AMDGPU::S_ANDN2_B32;
581 }
else if (
Opc == AMDGPU::S_OR_B32) {
583 MI.findRegisterDefOperand(AMDGPU::SCC,
nullptr)->isDead()) {
585 Opc = AMDGPU::S_BITSET1_B32;
588 Opc = AMDGPU::S_ORN2_B32;
590 }
else if (
Opc == AMDGPU::S_XOR_B32) {
593 Opc = AMDGPU::S_XNOR_B32;
603 return ChangeKind::UpdateHint;
607 const bool IsUndef = SrcReg->
isUndef();
608 const bool IsKill = SrcReg->
isKill();
610 if (
Opc == AMDGPU::S_BITSET0_B32 ||
611 Opc == AMDGPU::S_BITSET1_B32) {
612 Src0->ChangeToImmediate(NewImm);
614 MI.getOperand(2).ChangeToRegister(Dest->
getReg(),
false,
617 MI.tieOperands(0, 2);
621 return ChangeKind::UpdateInst;
625 return ChangeKind::None;
630bool SIShrinkInstructions::instAccessReg(
632 unsigned SubReg)
const {
633 for (
const MachineOperand &MO : R) {
638 LaneBitmask Overlap =
TRI->getSubRegIndexLaneMask(SubReg) &
647bool SIShrinkInstructions::instReadsReg(
const MachineInstr *
MI,
unsigned Reg,
648 unsigned SubReg)
const {
649 return instAccessReg(
MI->all_uses(),
Reg, SubReg);
652bool SIShrinkInstructions::instModifiesReg(
const MachineInstr *
MI,
unsigned Reg,
653 unsigned SubReg)
const {
654 return instAccessReg(
MI->all_defs(),
Reg, SubReg);
657TargetInstrInfo::RegSubRegPair
658SIShrinkInstructions::getSubRegForIndex(
Register Reg,
unsigned Sub,
660 if (
TRI->getRegSizeInBits(
Reg, *
MRI) != 32) {
664 Sub =
TRI->getSubRegFromChannel(
I +
TRI->getChannelFromSubReg(
Sub));
667 return TargetInstrInfo::RegSubRegPair(
Reg,
Sub);
670void SIShrinkInstructions::dropInstructionKeepingImpDefs(
671 MachineInstr &
MI)
const {
672 for (
unsigned i =
MI.getDesc().getNumOperands() +
673 MI.getDesc().implicit_uses().size() +
674 MI.getDesc().implicit_defs().size(),
675 e =
MI.getNumOperands();
677 const MachineOperand &
Op =
MI.getOperand(i);
681 TII->get(AMDGPU::IMPLICIT_DEF),
Op.getReg());
684 MI.eraseFromParent();
706MachineInstr *SIShrinkInstructions::matchSwap(MachineInstr &MovT)
const {
708 MovT.
getOpcode() == AMDGPU::V_MOV_B16_t16_e32 ||
722 unsigned Size =
TII->getOpSize(MovT, 0);
726 if (
Size == 2 &&
X.isVirtual())
732 const unsigned SearchLimit = 16;
735 MachineInstr *MovX =
nullptr;
736 MachineInstr *InsertionPt =
nullptr;
737 MachineInstr *MovY =
nullptr;
741 Iter !=
E &&
Count < SearchLimit; ++Iter) {
742 if (Iter->isDebugInstr())
748 if ((Iter->getOpcode() == AMDGPU::V_MOV_B32_e32 ||
749 Iter->getOpcode() == AMDGPU::V_MOV_B16_t16_e32 ||
750 Iter->getOpcode() == AMDGPU::COPY) &&
751 Iter->getOperand(0).getReg() ==
X &&
752 Iter->getOperand(0).getSubReg() == Xsub &&
753 Iter->getOperand(1).isReg()) {
757 }
else if (instModifiesReg(&*Iter,
X, Xsub)) {
764 if ((Iter->getOpcode() == AMDGPU::V_MOV_B32_e32 ||
765 Iter->getOpcode() == AMDGPU::V_MOV_B16_t16_e32 ||
766 Iter->getOpcode() == AMDGPU::COPY) &&
767 Iter->getOperand(0).getReg() ==
Y &&
768 Iter->getOperand(0).getSubReg() == Ysub &&
769 Iter->getOperand(1).isReg() && Iter->getOperand(1).getReg() ==
T &&
770 Iter->getOperand(1).getSubReg() == Tsub) {
779 if (instModifiesReg(&*Iter,
Y, Ysub))
785 (instReadsReg(&*Iter,
X, Xsub) || instModifiesReg(&*Iter,
X, Xsub))) {
786 InsertionPt = &*Iter;
792 if (instReadsReg(&*Iter,
Y, Ysub))
797 if (instModifiesReg(&*Iter,
T, Tsub))
801 LLVM_DEBUG(
dbgs() <<
"Matched v_swap:\n" << MovT << *MovX << *MovY);
804 SmallVector<MachineInstr *, 4> Swaps;
810 TII->get(AMDGPU::V_SWAP_B16))
819 for (
unsigned I = 0;
I <
Size / 4; ++
I) {
820 TargetInstrInfo::RegSubRegPair X1, Y1;
821 X1 = getSubRegForIndex(
X, Xsub,
I);
822 Y1 = getSubRegForIndex(
Y, Ysub,
I);
824 TII->get(AMDGPU::V_SWAP_B32))
835 for (MachineInstr *
Swap : Swaps) {
836 Swap->removeOperand(
Swap->getNumExplicitOperands());
841 dropInstructionKeepingImpDefs(*MovY);
845 dropInstructionKeepingImpDefs(MovT);
851 if (
Op.isKill() &&
TRI->regsOverlap(
X,
Op.getReg()))
862bool SIShrinkInstructions::tryReplaceDeadSDST(MachineInstr &
MI)
const {
863 if (!ST->hasGFX10_3Insts())
866 MachineOperand *
Op =
TII->getNamedOperand(
MI, AMDGPU::OpName::sdst);
873 Op->setReg(ST->
isWave32() ? AMDGPU::SGPR_NULL : AMDGPU::SGPR_NULL64);
886 unsigned VCCReg = ST->
isWave32() ? AMDGPU::VCC_LO : AMDGPU::VCC;
889 for (MachineBasicBlock &
MBB : MF) {
893 MachineInstr &
MI = *
I;
895 if (
MI.getOpcode() == AMDGPU::V_MOV_B32_e32) {
903 MachineOperand &Src =
MI.getOperand(1);
904 if (Src.isImm() && IsPostRA) {
908 if (ModOpcode != 0) {
909 MI.setDesc(
TII->get(ModOpcode));
910 Src.setImm(
static_cast<int64_t
>(ModImm));
917 if (ST->
hasSwap() && (
MI.getOpcode() == AMDGPU::V_MOV_B32_e32 ||
918 MI.getOpcode() == AMDGPU::V_MOV_B16_t16_e32 ||
919 MI.getOpcode() == AMDGPU::COPY)) {
920 if (
auto *NextMI = matchSwap(
MI)) {
921 Next = NextMI->getIterator();
928 if (
MI.getOpcode() == AMDGPU::S_AND_B32 ||
929 MI.getOpcode() == AMDGPU::S_OR_B32 ||
930 MI.getOpcode() == AMDGPU::S_XOR_B32) {
931 ChangeKind CK = shrinkScalarLogicOp(
MI);
932 if (CK == ChangeKind::UpdateHint)
934 Changed |= (CK == ChangeKind::UpdateInst);
940 if (
MI.getOpcode() == AMDGPU::S_ADD_I32 ||
941 MI.getOpcode() == AMDGPU::S_MUL_I32 ||
942 (
MI.getOpcode() == AMDGPU::S_OR_B32 &&
943 MI.getFlag(MachineInstr::MIFlag::Disjoint) &&
944 MI.allImplicitDefsAreDead())) {
945 const MachineOperand *Dest = &
MI.getOperand(0);
946 MachineOperand *
Src0 = &
MI.getOperand(1);
947 MachineOperand *
Src1 = &
MI.getOperand(2);
949 if (!
Src0->isReg() &&
Src1->isReg()) {
950 if (
TII->commuteInstruction(
MI,
false, 1, 2)) {
966 unsigned Opc = (
MI.getOpcode() == AMDGPU::S_MUL_I32)
968 : AMDGPU::S_ADDK_I32;
971 MI.tieOperands(0, 1);
978 if (
MI.isCompare() &&
TII->isSOPC(
MI)) {
984 if (
MI.getOpcode() == AMDGPU::S_MOV_B32) {
985 const MachineOperand &Dst =
MI.getOperand(0);
986 MachineOperand &Src =
MI.getOperand(1);
988 if (Src.isImm() && Dst.getReg().isPhysical()) {
992 MI.setDesc(
TII->get(AMDGPU::S_MOVK_I32));
997 MI.setDesc(
TII->get(ModOpc));
998 Src.setImm(
static_cast<int64_t
>(ModImm));
1006 if (IsPostRA &&
TII->isMIMG(
MI.getOpcode()) &&
1012 if (!
TII->isVOP3(
MI))
1015 if (
MI.getOpcode() == AMDGPU::V_MAD_F32_e64 ||
1016 MI.getOpcode() == AMDGPU::V_FMA_F32_e64 ||
1017 MI.getOpcode() == AMDGPU::V_MAD_F16_e64 ||
1018 MI.getOpcode() == AMDGPU::V_FMA_F16_e64 ||
1019 MI.getOpcode() == AMDGPU::V_FMA_F16_gfx9_e64 ||
1020 MI.getOpcode() == AMDGPU::V_FMA_F16_gfx9_t16_e64 ||
1021 MI.getOpcode() == AMDGPU::V_FMA_F16_gfx9_fake16_e64 ||
1022 (
MI.getOpcode() == AMDGPU::V_FMA_F64_e64 &&
1031 if (!
TII->hasVALU32BitEncoding(
MI.getOpcode()))
1037 if (!
MI.isCommutable() || !
TII->commuteInstruction(
MI) ||
1049 if (Op32 == AMDGPU::V_CNDMASK_B32_e32) {
1052 const MachineOperand *
Src2 =
1053 TII->getNamedOperand(
MI, AMDGPU::OpName::src2);
1057 if (
SReg.isVirtual()) {
1068 const MachineOperand *SDst =
1069 TII->getNamedOperand(
MI, AMDGPU::OpName::sdst);
1074 if (SDst->
getReg() != VCCReg) {
1091 const MachineOperand *
Src2 =
TII->getNamedOperand(
MI,
1092 AMDGPU::OpName::src2);
1093 if (Src2 &&
Src2->getReg() != VCCReg) {
1094 if (
Src2->getReg().isVirtual())
1109 if (ST->hasVOP3Literal() &&
1115 !shouldShrinkTrue16(
MI))
1121 MachineInstr *Inst32 =
TII->buildShrunkInst(
MI, Op32);
1122 ++NumInstructionsShrunk;
1125 copyExtraImplicitOps(*Inst32,
MI);
1127 MI.eraseFromParent();
1128 foldImmediates(*Inst32);
1137bool SIShrinkInstructionsLegacy::runOnMachineFunction(
MachineFunction &MF) {
1141 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.
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< 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