@@ -4032,28 +4032,31 @@ static unsigned getNewFMAInst(const GCNSubtarget &ST, unsigned Opc) {
40324032 }
40334033}
40344034
4035+ // / Helper struct for the implementation of 3-address conversion to communicate
4036+ // / updates made to instruction operands.
4037+ struct SIInstrInfo ::ThreeAddressUpdates {
4038+ // / Other instruction whose def is no longer used by the converted
4039+ // / instruction.
4040+ MachineInstr *RemoveMIUse = nullptr ;
4041+ };
4042+
40354043MachineInstr *SIInstrInfo::convertToThreeAddress (MachineInstr &MI,
40364044 LiveVariables *LV,
40374045 LiveIntervals *LIS) const {
40384046 MachineBasicBlock &MBB = *MI.getParent ();
4039- unsigned Opc = MI.getOpcode ();
4047+ ThreeAddressUpdates U;
4048+ MachineInstr *NewMI = convertToThreeAddressImpl (MI, U);
40404049
4041- // Handle MFMA.
4042- int NewMFMAOpc = AMDGPU::getMFMAEarlyClobberOp (Opc);
4043- if (NewMFMAOpc != -1 ) {
4044- MachineInstrBuilder MIB =
4045- BuildMI (MBB, MI, MI.getDebugLoc (), get (NewMFMAOpc));
4046- for (unsigned I = 0 , E = MI.getNumOperands (); I != E; ++I)
4047- MIB.add (MI.getOperand (I));
4048- updateLiveVariables (LV, MI, *MIB);
4050+ if (NewMI) {
4051+ updateLiveVariables (LV, MI, *NewMI);
40494052 if (LIS) {
4050- LIS->ReplaceMachineInstrInMaps (MI, *MIB );
4053+ LIS->ReplaceMachineInstrInMaps (MI, *NewMI );
40514054 // SlotIndex of defs needs to be updated when converting to early-clobber
4052- MachineOperand &Def = MIB ->getOperand (0 );
4055+ MachineOperand &Def = NewMI ->getOperand (0 );
40534056 if (Def.isEarlyClobber () && Def.isReg () &&
40544057 LIS->hasInterval (Def.getReg ())) {
4055- SlotIndex OldIndex = LIS->getInstructionIndex (*MIB ).getRegSlot (false );
4056- SlotIndex NewIndex = LIS->getInstructionIndex (*MIB ).getRegSlot (true );
4058+ SlotIndex OldIndex = LIS->getInstructionIndex (*NewMI ).getRegSlot (false );
4059+ SlotIndex NewIndex = LIS->getInstructionIndex (*NewMI ).getRegSlot (true );
40574060 auto &LI = LIS->getInterval (Def.getReg ());
40584061 auto UpdateDefIndex = [&](LiveRange &LR) {
40594062 auto *S = LR.find (OldIndex);
@@ -4068,6 +4071,58 @@ MachineInstr *SIInstrInfo::convertToThreeAddress(MachineInstr &MI,
40684071 UpdateDefIndex (SR);
40694072 }
40704073 }
4074+ }
4075+
4076+ if (U.RemoveMIUse ) {
4077+ MachineRegisterInfo &MRI = MBB.getParent ()->getRegInfo ();
4078+ // The only user is the instruction which will be killed.
4079+ Register DefReg = U.RemoveMIUse ->getOperand (0 ).getReg ();
4080+
4081+ if (MRI.hasOneNonDBGUse (DefReg)) {
4082+ // We cannot just remove the DefMI here, calling pass will crash.
4083+ U.RemoveMIUse ->setDesc (get (AMDGPU::IMPLICIT_DEF));
4084+ U.RemoveMIUse ->getOperand (0 ).setIsDead (true );
4085+ for (unsigned I = U.RemoveMIUse ->getNumOperands () - 1 ; I != 0 ; --I)
4086+ U.RemoveMIUse ->removeOperand (I);
4087+ if (LV)
4088+ LV->getVarInfo (DefReg).AliveBlocks .clear ();
4089+ }
4090+
4091+ if (LIS) {
4092+ LiveInterval &DefLI = LIS->getInterval (DefReg);
4093+
4094+ // We cannot delete the original instruction here, so hack out the use
4095+ // in the original instruction with a dummy register so we can use
4096+ // shrinkToUses to deal with any multi-use edge cases. Other targets do
4097+ // not have the complexity of deleting a use to consider here.
4098+ Register DummyReg = MRI.cloneVirtualRegister (DefReg);
4099+ for (MachineOperand &MIOp : MI.uses ()) {
4100+ if (MIOp.isReg () && MIOp.getReg () == DefReg) {
4101+ MIOp.setIsUndef (true );
4102+ MIOp.setReg (DummyReg);
4103+ }
4104+ }
4105+
4106+ LIS->shrinkToUses (&DefLI);
4107+ }
4108+ }
4109+
4110+ return NewMI;
4111+ }
4112+
4113+ MachineInstr *
4114+ SIInstrInfo::convertToThreeAddressImpl (MachineInstr &MI,
4115+ ThreeAddressUpdates &U) const {
4116+ MachineBasicBlock &MBB = *MI.getParent ();
4117+ unsigned Opc = MI.getOpcode ();
4118+
4119+ // Handle MFMA.
4120+ int NewMFMAOpc = AMDGPU::getMFMAEarlyClobberOp (Opc);
4121+ if (NewMFMAOpc != -1 ) {
4122+ MachineInstrBuilder MIB =
4123+ BuildMI (MBB, MI, MI.getDebugLoc (), get (NewMFMAOpc));
4124+ for (unsigned I = 0 , E = MI.getNumOperands (); I != E; ++I)
4125+ MIB.add (MI.getOperand (I));
40714126 return MIB;
40724127 }
40734128
@@ -4077,11 +4132,6 @@ MachineInstr *SIInstrInfo::convertToThreeAddress(MachineInstr &MI,
40774132 .setMIFlags (MI.getFlags ());
40784133 for (unsigned I = 0 , E = MI.getNumOperands (); I != E; ++I)
40794134 MIB->addOperand (MI.getOperand (I));
4080-
4081- updateLiveVariables (LV, MI, *MIB);
4082- if (LIS)
4083- LIS->ReplaceMachineInstrInMaps (MI, *MIB);
4084-
40854135 return MIB;
40864136 }
40874137
@@ -4152,39 +4202,6 @@ MachineInstr *SIInstrInfo::convertToThreeAddress(MachineInstr &MI,
41524202 (ST.getConstantBusLimit (Opc) > 1 || !Src0->isReg () ||
41534203 !RI.isSGPRReg (MBB.getParent ()->getRegInfo (), Src0->getReg ()))) {
41544204 MachineInstr *DefMI;
4155- const auto killDef = [&]() -> void {
4156- MachineRegisterInfo &MRI = MBB.getParent ()->getRegInfo ();
4157- // The only user is the instruction which will be killed.
4158- Register DefReg = DefMI->getOperand (0 ).getReg ();
4159-
4160- if (MRI.hasOneNonDBGUse (DefReg)) {
4161- // We cannot just remove the DefMI here, calling pass will crash.
4162- DefMI->setDesc (get (AMDGPU::IMPLICIT_DEF));
4163- DefMI->getOperand (0 ).setIsDead (true );
4164- for (unsigned I = DefMI->getNumOperands () - 1 ; I != 0 ; --I)
4165- DefMI->removeOperand (I);
4166- if (LV)
4167- LV->getVarInfo (DefReg).AliveBlocks .clear ();
4168- }
4169-
4170- if (LIS) {
4171- LiveInterval &DefLI = LIS->getInterval (DefReg);
4172-
4173- // We cannot delete the original instruction here, so hack out the use
4174- // in the original instruction with a dummy register so we can use
4175- // shrinkToUses to deal with any multi-use edge cases. Other targets do
4176- // not have the complexity of deleting a use to consider here.
4177- Register DummyReg = MRI.cloneVirtualRegister (DefReg);
4178- for (MachineOperand &MIOp : MI.uses ()) {
4179- if (MIOp.isReg () && MIOp.getReg () == DefReg) {
4180- MIOp.setIsUndef (true );
4181- MIOp.setReg (DummyReg);
4182- }
4183- }
4184-
4185- LIS->shrinkToUses (&DefLI);
4186- }
4187- };
41884205
41894206 int64_t Imm;
41904207 if (!Src0Literal && getFoldableImm (Src2, Imm, &DefMI)) {
@@ -4196,10 +4213,7 @@ MachineInstr *SIInstrInfo::convertToThreeAddress(MachineInstr &MI,
41964213 .add (*Src1)
41974214 .addImm (Imm)
41984215 .setMIFlags (MI.getFlags ());
4199- updateLiveVariables (LV, MI, *MIB);
4200- if (LIS)
4201- LIS->ReplaceMachineInstrInMaps (MI, *MIB);
4202- killDef ();
4216+ U.RemoveMIUse = DefMI;
42034217 return MIB;
42044218 }
42054219 }
@@ -4212,11 +4226,7 @@ MachineInstr *SIInstrInfo::convertToThreeAddress(MachineInstr &MI,
42124226 .addImm (Imm)
42134227 .add (*Src2)
42144228 .setMIFlags (MI.getFlags ());
4215- updateLiveVariables (LV, MI, *MIB);
4216-
4217- if (LIS)
4218- LIS->ReplaceMachineInstrInMaps (MI, *MIB);
4219- killDef ();
4229+ U.RemoveMIUse = DefMI;
42204230 return MIB;
42214231 }
42224232 }
@@ -4235,12 +4245,7 @@ MachineInstr *SIInstrInfo::convertToThreeAddress(MachineInstr &MI,
42354245 .addImm (Imm)
42364246 .add (*Src2)
42374247 .setMIFlags (MI.getFlags ());
4238- updateLiveVariables (LV, MI, *MIB);
4239-
4240- if (LIS)
4241- LIS->ReplaceMachineInstrInMaps (MI, *MIB);
4242- if (DefMI)
4243- killDef ();
4248+ U.RemoveMIUse = DefMI;
42444249 return MIB;
42454250 }
42464251 }
@@ -4269,9 +4274,6 @@ MachineInstr *SIInstrInfo::convertToThreeAddress(MachineInstr &MI,
42694274 .setMIFlags (MI.getFlags ());
42704275 if (AMDGPU::hasNamedOperand (NewOpc, AMDGPU::OpName::op_sel))
42714276 MIB.addImm (OpSel ? OpSel->getImm () : 0 );
4272- updateLiveVariables (LV, MI, *MIB);
4273- if (LIS)
4274- LIS->ReplaceMachineInstrInMaps (MI, *MIB);
42754277 return MIB;
42764278}
42774279
0 commit comments