@@ -4044,28 +4044,31 @@ static unsigned getNewFMAInst(const GCNSubtarget &ST, unsigned Opc) {
40444044  }
40454045}
40464046
4047+ // / Helper struct for the implementation of 3-address conversion to communicate
4048+ // / updates made to instruction operands.
4049+ struct  SIInstrInfo ::ThreeAddressUpdates {
4050+   // / Other instruction whose def is no longer used by the converted
4051+   // / instruction.
4052+   MachineInstr *RemoveMIUse = nullptr ;
4053+ };
4054+ 
40474055MachineInstr *SIInstrInfo::convertToThreeAddress (MachineInstr &MI,
40484056                                                 LiveVariables *LV,
40494057                                                 LiveIntervals *LIS) const  {
40504058  MachineBasicBlock &MBB = *MI.getParent ();
4051-   unsigned  Opc = MI.getOpcode ();
4059+   ThreeAddressUpdates U;
4060+   MachineInstr *NewMI = convertToThreeAddressImpl (MI, U);
40524061
4053-   //  Handle MFMA.
4054-   int  NewMFMAOpc = AMDGPU::getMFMAEarlyClobberOp (Opc);
4055-   if  (NewMFMAOpc != -1 ) {
4056-     MachineInstrBuilder MIB =
4057-         BuildMI (MBB, MI, MI.getDebugLoc (), get (NewMFMAOpc));
4058-     for  (unsigned  I = 0 , E = MI.getNumOperands (); I != E; ++I)
4059-       MIB.add (MI.getOperand (I));
4060-     updateLiveVariables (LV, MI, *MIB);
4062+   if  (NewMI) {
4063+     updateLiveVariables (LV, MI, *NewMI);
40614064    if  (LIS) {
4062-       LIS->ReplaceMachineInstrInMaps (MI, *MIB );
4065+       LIS->ReplaceMachineInstrInMaps (MI, *NewMI );
40634066      //  SlotIndex of defs needs to be updated when converting to early-clobber
4064-       MachineOperand &Def = MIB ->getOperand (0 );
4067+       MachineOperand &Def = NewMI ->getOperand (0 );
40654068      if  (Def.isEarlyClobber () && Def.isReg () &&
40664069          LIS->hasInterval (Def.getReg ())) {
4067-         SlotIndex OldIndex = LIS->getInstructionIndex (*MIB ).getRegSlot (false );
4068-         SlotIndex NewIndex = LIS->getInstructionIndex (*MIB ).getRegSlot (true );
4070+         SlotIndex OldIndex = LIS->getInstructionIndex (*NewMI ).getRegSlot (false );
4071+         SlotIndex NewIndex = LIS->getInstructionIndex (*NewMI ).getRegSlot (true );
40694072        auto  &LI = LIS->getInterval (Def.getReg ());
40704073        auto  UpdateDefIndex = [&](LiveRange &LR) {
40714074          auto  *S = LR.find (OldIndex);
@@ -4080,6 +4083,58 @@ MachineInstr *SIInstrInfo::convertToThreeAddress(MachineInstr &MI,
40804083          UpdateDefIndex (SR);
40814084      }
40824085    }
4086+   }
4087+ 
4088+   if  (U.RemoveMIUse ) {
4089+     MachineRegisterInfo &MRI = MBB.getParent ()->getRegInfo ();
4090+     //  The only user is the instruction which will be killed.
4091+     Register DefReg = U.RemoveMIUse ->getOperand (0 ).getReg ();
4092+ 
4093+     if  (MRI.hasOneNonDBGUse (DefReg)) {
4094+       //  We cannot just remove the DefMI here, calling pass will crash.
4095+       U.RemoveMIUse ->setDesc (get (AMDGPU::IMPLICIT_DEF));
4096+       U.RemoveMIUse ->getOperand (0 ).setIsDead (true );
4097+       for  (unsigned  I = U.RemoveMIUse ->getNumOperands () - 1 ; I != 0 ; --I)
4098+         U.RemoveMIUse ->removeOperand (I);
4099+       if  (LV)
4100+         LV->getVarInfo (DefReg).AliveBlocks .clear ();
4101+     }
4102+ 
4103+     if  (LIS) {
4104+       LiveInterval &DefLI = LIS->getInterval (DefReg);
4105+ 
4106+       //  We cannot delete the original instruction here, so hack out the use
4107+       //  in the original instruction with a dummy register so we can use
4108+       //  shrinkToUses to deal with any multi-use edge cases. Other targets do
4109+       //  not have the complexity of deleting a use to consider here.
4110+       Register DummyReg = MRI.cloneVirtualRegister (DefReg);
4111+       for  (MachineOperand &MIOp : MI.uses ()) {
4112+         if  (MIOp.isReg () && MIOp.getReg () == DefReg) {
4113+           MIOp.setIsUndef (true );
4114+           MIOp.setReg (DummyReg);
4115+         }
4116+       }
4117+ 
4118+       LIS->shrinkToUses (&DefLI);
4119+     }
4120+   }
4121+ 
4122+   return  NewMI;
4123+ }
4124+ 
4125+ MachineInstr *
4126+ SIInstrInfo::convertToThreeAddressImpl (MachineInstr &MI,
4127+                                        ThreeAddressUpdates &U) const  {
4128+   MachineBasicBlock &MBB = *MI.getParent ();
4129+   unsigned  Opc = MI.getOpcode ();
4130+ 
4131+   //  Handle MFMA.
4132+   int  NewMFMAOpc = AMDGPU::getMFMAEarlyClobberOp (Opc);
4133+   if  (NewMFMAOpc != -1 ) {
4134+     MachineInstrBuilder MIB =
4135+         BuildMI (MBB, MI, MI.getDebugLoc (), get (NewMFMAOpc));
4136+     for  (unsigned  I = 0 , E = MI.getNumOperands (); I != E; ++I)
4137+       MIB.add (MI.getOperand (I));
40834138    return  MIB;
40844139  }
40854140
@@ -4089,11 +4144,6 @@ MachineInstr *SIInstrInfo::convertToThreeAddress(MachineInstr &MI,
40894144                                  .setMIFlags (MI.getFlags ());
40904145    for  (unsigned  I = 0 , E = MI.getNumOperands (); I != E; ++I)
40914146      MIB->addOperand (MI.getOperand (I));
4092- 
4093-     updateLiveVariables (LV, MI, *MIB);
4094-     if  (LIS)
4095-       LIS->ReplaceMachineInstrInMaps (MI, *MIB);
4096- 
40974147    return  MIB;
40984148  }
40994149
@@ -4164,39 +4214,6 @@ MachineInstr *SIInstrInfo::convertToThreeAddress(MachineInstr &MI,
41644214      (ST.getConstantBusLimit (Opc) > 1  || !Src0->isReg () ||
41654215       !RI.isSGPRReg (MBB.getParent ()->getRegInfo (), Src0->getReg ()))) {
41664216    MachineInstr *DefMI;
4167-     const  auto  killDef = [&]() -> void  {
4168-       MachineRegisterInfo &MRI = MBB.getParent ()->getRegInfo ();
4169-       //  The only user is the instruction which will be killed.
4170-       Register DefReg = DefMI->getOperand (0 ).getReg ();
4171- 
4172-       if  (MRI.hasOneNonDBGUse (DefReg)) {
4173-         //  We cannot just remove the DefMI here, calling pass will crash.
4174-         DefMI->setDesc (get (AMDGPU::IMPLICIT_DEF));
4175-         DefMI->getOperand (0 ).setIsDead (true );
4176-         for  (unsigned  I = DefMI->getNumOperands () - 1 ; I != 0 ; --I)
4177-           DefMI->removeOperand (I);
4178-         if  (LV)
4179-           LV->getVarInfo (DefReg).AliveBlocks .clear ();
4180-       }
4181- 
4182-       if  (LIS) {
4183-         LiveInterval &DefLI = LIS->getInterval (DefReg);
4184- 
4185-         //  We cannot delete the original instruction here, so hack out the use
4186-         //  in the original instruction with a dummy register so we can use
4187-         //  shrinkToUses to deal with any multi-use edge cases. Other targets do
4188-         //  not have the complexity of deleting a use to consider here.
4189-         Register DummyReg = MRI.cloneVirtualRegister (DefReg);
4190-         for  (MachineOperand &MIOp : MI.uses ()) {
4191-           if  (MIOp.isReg () && MIOp.getReg () == DefReg) {
4192-             MIOp.setIsUndef (true );
4193-             MIOp.setReg (DummyReg);
4194-           }
4195-         }
4196- 
4197-         LIS->shrinkToUses (&DefLI);
4198-       }
4199-     };
42004217
42014218    int64_t  Imm;
42024219    if  (!Src0Literal && getFoldableImm (Src2, Imm, &DefMI)) {
@@ -4208,10 +4225,7 @@ MachineInstr *SIInstrInfo::convertToThreeAddress(MachineInstr &MI,
42084225                  .add (*Src1)
42094226                  .addImm (Imm)
42104227                  .setMIFlags (MI.getFlags ());
4211-         updateLiveVariables (LV, MI, *MIB);
4212-         if  (LIS)
4213-           LIS->ReplaceMachineInstrInMaps (MI, *MIB);
4214-         killDef ();
4228+         U.RemoveMIUse  = DefMI;
42154229        return  MIB;
42164230      }
42174231    }
@@ -4224,11 +4238,7 @@ MachineInstr *SIInstrInfo::convertToThreeAddress(MachineInstr &MI,
42244238                  .addImm (Imm)
42254239                  .add (*Src2)
42264240                  .setMIFlags (MI.getFlags ());
4227-         updateLiveVariables (LV, MI, *MIB);
4228- 
4229-         if  (LIS)
4230-           LIS->ReplaceMachineInstrInMaps (MI, *MIB);
4231-         killDef ();
4241+         U.RemoveMIUse  = DefMI;
42324242        return  MIB;
42334243      }
42344244    }
@@ -4247,12 +4257,7 @@ MachineInstr *SIInstrInfo::convertToThreeAddress(MachineInstr &MI,
42474257                  .addImm (Imm)
42484258                  .add (*Src2)
42494259                  .setMIFlags (MI.getFlags ());
4250-         updateLiveVariables (LV, MI, *MIB);
4251- 
4252-         if  (LIS)
4253-           LIS->ReplaceMachineInstrInMaps (MI, *MIB);
4254-         if  (DefMI)
4255-           killDef ();
4260+         U.RemoveMIUse  = DefMI;
42564261        return  MIB;
42574262      }
42584263    }
@@ -4281,9 +4286,6 @@ MachineInstr *SIInstrInfo::convertToThreeAddress(MachineInstr &MI,
42814286            .setMIFlags (MI.getFlags ());
42824287  if  (AMDGPU::hasNamedOperand (NewOpc, AMDGPU::OpName::op_sel))
42834288    MIB.addImm (OpSel ? OpSel->getImm () : 0 );
4284-   updateLiveVariables (LV, MI, *MIB);
4285-   if  (LIS)
4286-     LIS->ReplaceMachineInstrInMaps (MI, *MIB);
42874289  return  MIB;
42884290}
42894291
0 commit comments