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 {
88 "SI Shrink Instructions",
false,
false)
90char SIShrinkInstructionsLegacy::ID = 0;
93 return new SIShrinkInstructionsLegacy();
100 bool TryToCommute)
const {
103 int Src0Idx = AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::src0);
106 MachineOperand &Src0 =
MI.getOperand(Src0Idx);
111 if (Def &&
Def->isMoveImmediate()) {
112 MachineOperand &MovSrc =
Def->getOperand(1);
113 bool ConstantFolded =
false;
115 if (
TII->isOperandLegal(
MI, Src0Idx, &MovSrc)) {
116 if (MovSrc.
isImm()) {
118 ConstantFolded =
true;
119 }
else if (MovSrc.
isFI()) {
121 ConstantFolded =
true;
125 ConstantFolded =
true;
129 if (ConstantFolded) {
131 Def->eraseFromParent();
132 ++NumLiteralConstantsFolded;
140 if (TryToCommute &&
MI.isCommutable()) {
141 if (
TII->commuteInstruction(
MI)) {
142 if (foldImmediates(
MI,
false))
146 TII->commuteInstruction(
MI);
155bool SIShrinkInstructions::shouldShrinkTrue16(MachineInstr &
MI)
const {
156 for (
unsigned I = 0,
E =
MI.getNumExplicitOperands();
I !=
E; ++
I) {
157 const MachineOperand &MO =
MI.getOperand(
I);
161 "True16 Instructions post-RA");
174bool SIShrinkInstructions::isKImmOperand(
const MachineOperand &Src)
const {
176 !
TII->isInlineConstant(*Src.getParent(), Src.getOperandNo());
179bool SIShrinkInstructions::isKUImmOperand(
const MachineOperand &Src)
const {
181 !
TII->isInlineConstant(*Src.getParent(), Src.getOperandNo());
184bool SIShrinkInstructions::isKImmOrKUImmOperand(
const MachineOperand &Src,
185 bool &IsUnsigned)
const {
188 return !
TII->isInlineConstant(Src);
193 return !
TII->isInlineConstant(Src);
210 int32_t &ModifiedImm,
bool Scalar) {
211 if (
TII->isInlineConstant(Src))
213 int32_t SrcImm =
static_cast<int32_t
>(Src.getImm());
219 ModifiedImm = ~SrcImm;
220 if (
TII->isInlineConstant(
APInt(32, ModifiedImm,
true)))
221 return AMDGPU::V_NOT_B32_e32;
225 if (
TII->isInlineConstant(
APInt(32, ModifiedImm,
true)))
226 return Scalar ? AMDGPU::S_BREV_B32 : AMDGPU::V_BFREV_B32_e32;
233void SIShrinkInstructions::copyExtraImplicitOps(MachineInstr &NewMI,
234 MachineInstr &
MI)
const {
235 MachineFunction &MF = *
MI.getMF();
236 for (
unsigned i =
MI.getDesc().getNumOperands() +
237 MI.getDesc().implicit_uses().size() +
238 MI.getDesc().implicit_defs().size(),
239 e =
MI.getNumOperands();
241 const MachineOperand &MO =
MI.getOperand(i);
247bool SIShrinkInstructions::shrinkScalarCompare(MachineInstr &
MI)
const {
254 if (!
MI.getOperand(0).isReg()) {
255 if (
TII->commuteInstruction(
MI,
false, 0, 1))
260 const MachineOperand &Src0 =
MI.getOperand(0);
264 MachineOperand &Src1 =
MI.getOperand(1);
274 if (SOPKOpc == AMDGPU::S_CMPK_EQ_U32 || SOPKOpc == AMDGPU::S_CMPK_LG_U32) {
276 if (isKImmOrKUImmOperand(Src1, HasUImm)) {
278 SOPKOpc = (SOPKOpc == AMDGPU::S_CMPK_EQ_U32) ?
279 AMDGPU::S_CMPK_EQ_I32 : AMDGPU::S_CMPK_LG_I32;
283 MI.setDesc(
TII->get(SOPKOpc));
290 const MCInstrDesc &NewDesc =
TII->get(SOPKOpc);
303bool SIShrinkInstructions::shrinkMIMG(MachineInstr &
MI)
const {
309 switch (
Info->MIMGEncoding) {
310 case AMDGPU::MIMGEncGfx10NSA:
311 NewEncoding = AMDGPU::MIMGEncGfx10Default;
313 case AMDGPU::MIMGEncGfx11NSA:
314 NewEncoding = AMDGPU::MIMGEncGfx11Default;
321 AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::vaddr0);
322 unsigned NewAddrDwords =
Info->VAddrDwords;
325 if (
Info->VAddrDwords == 2) {
326 RC = &AMDGPU::VReg_64RegClass;
327 }
else if (
Info->VAddrDwords == 3) {
328 RC = &AMDGPU::VReg_96RegClass;
329 }
else if (
Info->VAddrDwords == 4) {
330 RC = &AMDGPU::VReg_128RegClass;
331 }
else if (
Info->VAddrDwords == 5) {
332 RC = &AMDGPU::VReg_160RegClass;
333 }
else if (
Info->VAddrDwords == 6) {
334 RC = &AMDGPU::VReg_192RegClass;
335 }
else if (
Info->VAddrDwords == 7) {
336 RC = &AMDGPU::VReg_224RegClass;
337 }
else if (
Info->VAddrDwords == 8) {
338 RC = &AMDGPU::VReg_256RegClass;
339 }
else if (
Info->VAddrDwords == 9) {
340 RC = &AMDGPU::VReg_288RegClass;
341 }
else if (
Info->VAddrDwords == 10) {
342 RC = &AMDGPU::VReg_320RegClass;
343 }
else if (
Info->VAddrDwords == 11) {
344 RC = &AMDGPU::VReg_352RegClass;
345 }
else if (
Info->VAddrDwords == 12) {
346 RC = &AMDGPU::VReg_384RegClass;
348 RC = &AMDGPU::VReg_512RegClass;
352 unsigned VgprBase = 0;
353 unsigned NextVgpr = 0;
355 bool IsKill = NewAddrDwords ==
Info->VAddrDwords;
357 const bool IsPartialNSA = NewAddrDwords > NSAMaxSize;
358 const unsigned EndVAddr = IsPartialNSA ? NSAMaxSize :
Info->VAddrOperands;
359 for (
unsigned Idx = 0; Idx < EndVAddr; ++Idx) {
360 const MachineOperand &
Op =
MI.getOperand(VAddr0Idx + Idx);
361 unsigned Vgpr =
TRI->getHWRegIndex(
Op.getReg());
362 unsigned Dwords =
TRI->getRegSizeInBits(
Op.getReg(), *MRI) / 32;
363 assert(Dwords > 0 &&
"Un-implemented for less than 32 bit regs");
367 NextVgpr = Vgpr + Dwords;
368 }
else if (Vgpr == NextVgpr) {
369 NextVgpr = Vgpr + Dwords;
380 if (VgprBase + NewAddrDwords > 256)
385 int TFEIdx = AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::tfe);
386 int LWEIdx = AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::lwe);
387 unsigned TFEVal = (TFEIdx == -1) ? 0 :
MI.getOperand(TFEIdx).
getImm();
388 unsigned LWEVal = (LWEIdx == -1) ? 0 :
MI.getOperand(LWEIdx).
getImm();
390 if (TFEVal || LWEVal) {
392 for (
unsigned i = LWEIdx + 1, e =
MI.getNumOperands(); i != e; ++i) {
393 if (
MI.getOperand(i).isReg() &&
MI.getOperand(i).isTied() &&
394 MI.getOperand(i).isImplicit()) {
398 "found more than one tied implicit operand when expecting only 1");
400 MI.untieRegOperand(ToUntie);
406 Info->VDataDwords, NewAddrDwords);
407 MI.setDesc(
TII->get(NewOpcode));
409 MI.getOperand(VAddr0Idx).setIsUndef(IsUndef);
410 MI.getOperand(VAddr0Idx).setIsKill(IsKill);
412 for (
unsigned i = 1; i < EndVAddr; ++i)
413 MI.removeOperand(VAddr0Idx + 1);
417 AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::vdata),
418 ToUntie - (EndVAddr - 1));
424bool SIShrinkInstructions::shrinkMadFma(MachineInstr &
MI)
const {
427 if (!ST->hasVOP3Literal())
434 if (
TII->hasAnyModifiersSet(
MI))
437 const unsigned Opcode =
MI.getOpcode();
438 MachineOperand &Src0 = *
TII->getNamedOperand(
MI, AMDGPU::OpName::src0);
439 MachineOperand &Src1 = *
TII->getNamedOperand(
MI, AMDGPU::OpName::src1);
440 MachineOperand &Src2 = *
TII->getNamedOperand(
MI, AMDGPU::OpName::src2);
441 unsigned NewOpcode = AMDGPU::INSTRUCTION_LIST_END;
446 if (Src2.
isImm() && !
TII->isInlineConstant(Src2)) {
457 case AMDGPU::V_MAD_F32_e64:
458 NewOpcode = AMDGPU::V_MADAK_F32;
460 case AMDGPU::V_FMA_F32_e64:
461 NewOpcode = AMDGPU::V_FMAAK_F32;
463 case AMDGPU::V_MAD_F16_e64:
464 NewOpcode = AMDGPU::V_MADAK_F16;
466 case AMDGPU::V_FMA_F16_e64:
467 case AMDGPU::V_FMA_F16_gfx9_e64:
468 NewOpcode = AMDGPU::V_FMAAK_F16;
470 case AMDGPU::V_FMA_F16_gfx9_t16_e64:
471 NewOpcode = AMDGPU::V_FMAAK_F16_t16;
473 case AMDGPU::V_FMA_F16_gfx9_fake16_e64:
474 NewOpcode = AMDGPU::V_FMAAK_F16_fake16;
476 case AMDGPU::V_FMA_F64_e64:
478 NewOpcode = AMDGPU::V_FMAAK_F64;
485 if (Src1.
isImm() && !
TII->isInlineConstant(Src1))
487 else if (Src0.
isImm() && !
TII->isInlineConstant(Src0))
495 case AMDGPU::V_MAD_F32_e64:
496 NewOpcode = AMDGPU::V_MADMK_F32;
498 case AMDGPU::V_FMA_F32_e64:
499 NewOpcode = AMDGPU::V_FMAMK_F32;
501 case AMDGPU::V_MAD_F16_e64:
502 NewOpcode = AMDGPU::V_MADMK_F16;
504 case AMDGPU::V_FMA_F16_e64:
505 case AMDGPU::V_FMA_F16_gfx9_e64:
506 NewOpcode = AMDGPU::V_FMAMK_F16;
508 case AMDGPU::V_FMA_F16_gfx9_t16_e64:
509 NewOpcode = AMDGPU::V_FMAMK_F16_t16;
511 case AMDGPU::V_FMA_F16_gfx9_fake16_e64:
512 NewOpcode = AMDGPU::V_FMAMK_F16_fake16;
514 case AMDGPU::V_FMA_F64_e64:
516 NewOpcode = AMDGPU::V_FMAMK_F64;
521 if (NewOpcode == AMDGPU::INSTRUCTION_LIST_END)
530 MI.getOperand(0).getReg())
535 MI.eraseFromParent();
537 TII->removeModOperands(
MI);
538 MI.setDesc(
TII->get(NewOpcode));
550ChangeKind SIShrinkInstructions::shrinkScalarLogicOp(MachineInstr &
MI)
const {
551 unsigned Opc =
MI.getOpcode();
552 const MachineOperand *Dest = &
MI.getOperand(0);
553 MachineOperand *Src0 = &
MI.getOperand(1);
554 MachineOperand *Src1 = &
MI.getOperand(2);
555 MachineOperand *SrcReg = Src0;
556 MachineOperand *SrcImm = Src1;
558 if (!SrcImm->
isImm() ||
560 return ChangeKind::None;
562 uint32_t
Imm =
static_cast<uint32_t
>(SrcImm->
getImm());
565 if (
Opc == AMDGPU::S_AND_B32) {
567 MI.findRegisterDefOperand(AMDGPU::SCC,
nullptr)->isDead()) {
569 Opc = AMDGPU::S_BITSET0_B32;
572 Opc = AMDGPU::S_ANDN2_B32;
574 }
else if (
Opc == AMDGPU::S_OR_B32) {
576 MI.findRegisterDefOperand(AMDGPU::SCC,
nullptr)->isDead()) {
578 Opc = AMDGPU::S_BITSET1_B32;
581 Opc = AMDGPU::S_ORN2_B32;
583 }
else if (
Opc == AMDGPU::S_XOR_B32) {
586 Opc = AMDGPU::S_XNOR_B32;
596 return ChangeKind::UpdateHint;
600 const bool IsUndef = SrcReg->
isUndef();
601 const bool IsKill = SrcReg->
isKill();
603 if (
Opc == AMDGPU::S_BITSET0_B32 ||
604 Opc == AMDGPU::S_BITSET1_B32) {
607 MI.getOperand(2).ChangeToRegister(Dest->
getReg(),
false,
610 MI.tieOperands(0, 2);
614 return ChangeKind::UpdateInst;
618 return ChangeKind::None;
623bool SIShrinkInstructions::instAccessReg(
625 unsigned SubReg)
const {
626 for (
const MachineOperand &MO : R) {
631 LaneBitmask Overlap =
TRI->getSubRegIndexLaneMask(SubReg) &
640bool SIShrinkInstructions::instReadsReg(
const MachineInstr *
MI,
unsigned Reg,
641 unsigned SubReg)
const {
642 return instAccessReg(
MI->all_uses(),
Reg, SubReg);
645bool SIShrinkInstructions::instModifiesReg(
const MachineInstr *
MI,
unsigned Reg,
646 unsigned SubReg)
const {
647 return instAccessReg(
MI->all_defs(),
Reg, SubReg);
650TargetInstrInfo::RegSubRegPair
651SIShrinkInstructions::getSubRegForIndex(
Register Reg,
unsigned Sub,
653 if (
TRI->getRegSizeInBits(
Reg, *MRI) != 32) {
657 Sub =
TRI->getSubRegFromChannel(
I +
TRI->getChannelFromSubReg(
Sub));
660 return TargetInstrInfo::RegSubRegPair(
Reg,
Sub);
663void SIShrinkInstructions::dropInstructionKeepingImpDefs(
664 MachineInstr &
MI)
const {
665 for (
unsigned i =
MI.getDesc().getNumOperands() +
666 MI.getDesc().implicit_uses().size() +
667 MI.getDesc().implicit_defs().size(),
668 e =
MI.getNumOperands();
670 const MachineOperand &
Op =
MI.getOperand(i);
674 TII->get(AMDGPU::IMPLICIT_DEF),
Op.getReg());
677 MI.eraseFromParent();
699MachineInstr *SIShrinkInstructions::matchSwap(MachineInstr &MovT)
const {
701 MovT.
getOpcode() == AMDGPU::V_MOV_B16_t16_e32 ||
715 unsigned Size =
TII->getOpSize(MovT, 0);
719 if (
Size == 2 &&
X.isVirtual())
722 if (!
TRI->isVGPR(*MRI,
X))
725 const unsigned SearchLimit = 16;
728 MachineInstr *MovX =
nullptr;
729 MachineInstr *InsertionPt =
nullptr;
730 MachineInstr *MovY =
nullptr;
734 Iter !=
E &&
Count < SearchLimit; ++Iter) {
735 if (Iter->isDebugInstr())
741 if ((Iter->getOpcode() == AMDGPU::V_MOV_B32_e32 ||
742 Iter->getOpcode() == AMDGPU::V_MOV_B16_t16_e32 ||
743 Iter->getOpcode() == AMDGPU::COPY) &&
744 Iter->getOperand(0).getReg() ==
X &&
745 Iter->getOperand(0).getSubReg() == Xsub &&
746 Iter->getOperand(1).isReg()) {
750 }
else if (instModifiesReg(&*Iter,
X, Xsub)) {
757 if ((Iter->getOpcode() == AMDGPU::V_MOV_B32_e32 ||
758 Iter->getOpcode() == AMDGPU::V_MOV_B16_t16_e32 ||
759 Iter->getOpcode() == AMDGPU::COPY) &&
760 Iter->getOperand(0).getReg() ==
Y &&
761 Iter->getOperand(0).getSubReg() == Ysub &&
762 Iter->getOperand(1).isReg() && Iter->getOperand(1).getReg() ==
T &&
763 Iter->getOperand(1).getSubReg() == Tsub) {
772 if (instModifiesReg(&*Iter,
Y, Ysub))
778 (instReadsReg(&*Iter,
X, Xsub) || instModifiesReg(&*Iter,
X, Xsub))) {
779 InsertionPt = &*Iter;
785 if (instReadsReg(&*Iter,
Y, Ysub))
790 if (instModifiesReg(&*Iter,
T, Tsub))
794 LLVM_DEBUG(
dbgs() <<
"Matched v_swap:\n" << MovT << *MovX << *MovY);
797 SmallVector<MachineInstr *, 4> Swaps;
803 TII->get(AMDGPU::V_SWAP_B16))
812 for (
unsigned I = 0;
I <
Size / 4; ++
I) {
813 TargetInstrInfo::RegSubRegPair X1, Y1;
814 X1 = getSubRegForIndex(
X, Xsub,
I);
815 Y1 = getSubRegForIndex(
Y, Ysub,
I);
817 TII->get(AMDGPU::V_SWAP_B32))
828 for (MachineInstr *Swap : Swaps) {
829 Swap->removeOperand(Swap->getNumExplicitOperands());
834 dropInstructionKeepingImpDefs(*MovY);
838 dropInstructionKeepingImpDefs(MovT);
844 if (
Op.isKill() &&
TRI->regsOverlap(
X,
Op.getReg()))
855bool SIShrinkInstructions::tryReplaceDeadSDST(MachineInstr &
MI)
const {
856 if (!ST->hasGFX10_3Insts())
859 MachineOperand *
Op =
TII->getNamedOperand(
MI, AMDGPU::OpName::sdst);
866 Op->setReg(ST->
isWave32() ? AMDGPU::SGPR_NULL : AMDGPU::SGPR_NULL64);
870bool SIShrinkInstructions::run(MachineFunction &MF) {
879 unsigned VCCReg = ST->
isWave32() ? AMDGPU::VCC_LO : AMDGPU::VCC;
882 for (MachineBasicBlock &
MBB : MF) {
886 MachineInstr &
MI = *
I;
888 if (
MI.getOpcode() == AMDGPU::V_MOV_B32_e32) {
896 MachineOperand &Src =
MI.getOperand(1);
897 if (Src.isImm() && IsPostRA) {
901 if (ModOpcode != 0) {
902 MI.setDesc(
TII->get(ModOpcode));
903 Src.setImm(
static_cast<int64_t
>(ModImm));
910 if (ST->
hasSwap() && (
MI.getOpcode() == AMDGPU::V_MOV_B32_e32 ||
911 MI.getOpcode() == AMDGPU::V_MOV_B16_t16_e32 ||
912 MI.getOpcode() == AMDGPU::COPY)) {
913 if (
auto *NextMI = matchSwap(
MI)) {
914 Next = NextMI->getIterator();
921 if (
MI.getOpcode() == AMDGPU::S_AND_B32 ||
922 MI.getOpcode() == AMDGPU::S_OR_B32 ||
923 MI.getOpcode() == AMDGPU::S_XOR_B32) {
924 ChangeKind CK = shrinkScalarLogicOp(
MI);
925 if (CK == ChangeKind::UpdateHint)
927 Changed |= (CK == ChangeKind::UpdateInst);
931 if (
MI.getOpcode() == AMDGPU::S_ADD_I32 ||
932 MI.getOpcode() == AMDGPU::S_MUL_I32 ||
933 (
MI.getOpcode() == AMDGPU::S_OR_B32 &&
934 MI.getFlag(MachineInstr::MIFlag::Disjoint))) {
935 const MachineOperand *Dest = &
MI.getOperand(0);
936 MachineOperand *Src0 = &
MI.getOperand(1);
937 MachineOperand *Src1 = &
MI.getOperand(2);
940 if (
TII->commuteInstruction(
MI,
false, 1, 2)) {
956 unsigned Opc = (
MI.getOpcode() == AMDGPU::S_MUL_I32)
958 : AMDGPU::S_ADDK_I32;
961 MI.tieOperands(0, 1);
968 if (
MI.isCompare() &&
TII->isSOPC(
MI)) {
974 if (
MI.getOpcode() == AMDGPU::S_MOV_B32) {
975 const MachineOperand &Dst =
MI.getOperand(0);
976 MachineOperand &Src =
MI.getOperand(1);
978 if (Src.isImm() && Dst.getReg().isPhysical()) {
982 MI.setDesc(
TII->get(AMDGPU::S_MOVK_I32));
987 MI.setDesc(
TII->get(ModOpc));
988 Src.setImm(
static_cast<int64_t
>(ModImm));
996 if (IsPostRA &&
TII->isMIMG(
MI.getOpcode()) &&
1002 if (!
TII->isVOP3(
MI))
1005 if (
MI.getOpcode() == AMDGPU::V_MAD_F32_e64 ||
1006 MI.getOpcode() == AMDGPU::V_FMA_F32_e64 ||
1007 MI.getOpcode() == AMDGPU::V_MAD_F16_e64 ||
1008 MI.getOpcode() == AMDGPU::V_FMA_F16_e64 ||
1009 MI.getOpcode() == AMDGPU::V_FMA_F16_gfx9_e64 ||
1010 MI.getOpcode() == AMDGPU::V_FMA_F16_gfx9_t16_e64 ||
1011 MI.getOpcode() == AMDGPU::V_FMA_F16_gfx9_fake16_e64 ||
1012 (
MI.getOpcode() == AMDGPU::V_FMA_F64_e64 &&
1020 if (
TII->isVOP3(
MI.getOpcode())) {
1022 if (!
TII->hasVALU32BitEncoding(
MI.getOpcode())) {
1027 if (!
TII->canShrink(
MI, *MRI)) {
1030 if (!
MI.isCommutable() || !
TII->commuteInstruction(
MI) ||
1031 !
TII->canShrink(
MI, *MRI)) {
1042 if (Op32 == AMDGPU::V_CNDMASK_B32_e32) {
1045 const MachineOperand *Src2 =
1046 TII->getNamedOperand(
MI, AMDGPU::OpName::src2);
1050 if (
SReg.isVirtual()) {
1061 const MachineOperand *SDst =
1062 TII->getNamedOperand(
MI, AMDGPU::OpName::sdst);
1067 if (SDst->
getReg() != VCCReg) {
1084 const MachineOperand *Src2 =
TII->getNamedOperand(
MI,
1085 AMDGPU::OpName::src2);
1086 if (Src2 && Src2->
getReg() != VCCReg) {
1102 if (ST->hasVOP3Literal() &&
1108 !shouldShrinkTrue16(
MI))
1114 MachineInstr *Inst32 =
TII->buildShrunkInst(
MI, Op32);
1115 ++NumInstructionsShrunk;
1118 copyExtraImplicitOps(*Inst32,
MI);
1121 if (SDst && SDst->
isDead())
1124 MI.eraseFromParent();
1125 foldImmediates(*Inst32);
1134bool SIShrinkInstructionsLegacy::runOnMachineFunction(MachineFunction &MF) {
1138 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.
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)
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