Skip to content

Commit 1d91bc6

Browse files
committed
AMDGPU: Refactor three-address conversion (NFC)
Extract the core of the instruction rewriting into an implementation method, and unify the update of live variables / intervals updates in its caller. This is intended to help make future changes to three-address conversion more robust.
1 parent f802acf commit 1d91bc6

File tree

2 files changed

+76
-69
lines changed

2 files changed

+76
-69
lines changed

llvm/lib/Target/AMDGPU/SIInstrInfo.cpp

Lines changed: 71 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
40474055
MachineInstr *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

llvm/lib/Target/AMDGPU/SIInstrInfo.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ struct SIInstrWorklist {
8888
};
8989

9090
class SIInstrInfo final : public AMDGPUGenInstrInfo {
91+
struct ThreeAddressUpdates;
92+
9193
private:
9294
const SIRegisterInfo RI;
9395
const GCNSubtarget &ST;
@@ -190,6 +192,9 @@ class SIInstrInfo final : public AMDGPUGenInstrInfo {
190192

191193
bool resultDependsOnExec(const MachineInstr &MI) const;
192194

195+
MachineInstr *convertToThreeAddressImpl(MachineInstr &MI,
196+
ThreeAddressUpdates &Updates) const;
197+
193198
protected:
194199
/// If the specific machine instruction is a instruction that moves/copies
195200
/// value from one register to another register return destination and source

0 commit comments

Comments
 (0)