Add <imp-def> and <imp-kill> operands when replacing virtual sub-register defs and kills.
An instruction like this:
%reg1097:1<def> = VMOVSR %R3<kill>, 14, %reg0
Must be replaced with this when substituting physical registers:
%S0<def> = VMOVSR %R3<kill>, 14, %reg0, %D0<imp-def>
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@92812 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp
index 358ea3f..f9c20e6 100644
--- a/lib/CodeGen/MachineInstr.cpp
+++ b/lib/CodeGen/MachineInstr.cpp
@@ -1314,3 +1314,12 @@
true /*IsDead*/));
return true;
}
+
+void MachineInstr::addRegisterDefined(unsigned IncomingReg,
+ const TargetRegisterInfo *RegInfo) {
+ MachineOperand *MO = findRegisterDefOperand(IncomingReg, false, RegInfo);
+ if (!MO || MO->getSubReg())
+ addOperand(MachineOperand::CreateReg(IncomingReg,
+ true /*IsDef*/,
+ true /*IsImp*/));
+}
diff --git a/lib/CodeGen/VirtRegRewriter.cpp b/lib/CodeGen/VirtRegRewriter.cpp
index 81dd1c8..df2b8d2 100644
--- a/lib/CodeGen/VirtRegRewriter.cpp
+++ b/lib/CodeGen/VirtRegRewriter.cpp
@@ -60,6 +60,33 @@
VirtRegRewriter::~VirtRegRewriter() {}
+/// substitutePhysReg - Replace virtual register in MachineOperand with a
+/// physical register. Do the right thing with the sub-register index.
+static void substitutePhysReg(MachineOperand &MO, unsigned Reg,
+ const TargetRegisterInfo &TRI) {
+ if (unsigned SubIdx = MO.getSubReg()) {
+ // Insert the physical subreg and reset the subreg field.
+ MO.setReg(TRI.getSubReg(Reg, SubIdx));
+ MO.setSubReg(0);
+
+ // Any def, dead, and kill flags apply to the full virtual register, so they
+ // also apply to the full physical register. Add imp-def/dead and imp-kill
+ // as needed.
+ MachineInstr &MI = *MO.getParent();
+ if (MO.isDef())
+ if (MO.isDead())
+ MI.addRegisterDead(Reg, &TRI, /*AddIfNotFound=*/ true);
+ else
+ MI.addRegisterDefined(Reg, &TRI);
+ else if (!MO.isUndef() &&
+ (MO.isKill() ||
+ MI.isRegTiedToDefOperand(&MO-&MI.getOperand(0))))
+ MI.addRegisterKilled(Reg, &TRI, /*AddIfNotFound=*/ true);
+ } else {
+ MO.setReg(Reg);
+ }
+}
+
namespace {
/// This class is intended for use with the new spilling framework only. It
@@ -101,10 +128,7 @@
MachineOperand &mop = regItr.getOperand();
assert(mop.isReg() && mop.getReg() == reg && "reg_iterator broken?");
++regItr;
- unsigned subRegIdx = mop.getSubReg();
- unsigned pRegOp = subRegIdx ? tri->getSubReg(pReg, subRegIdx) : pReg;
- mop.setReg(pRegOp);
- mop.setSubReg(0);
+ substitutePhysReg(mop, pReg, *tri);
changed = true;
}
}
@@ -647,12 +671,9 @@
if (TargetRegisterInfo::isPhysicalRegister(VirtReg))
continue;
assert(MO.isUse());
- unsigned SubIdx = MO.getSubReg();
unsigned Phys = VRM.getPhys(VirtReg);
assert(Phys && "Virtual register is not assigned a register?");
- unsigned RReg = SubIdx ? TRI->getSubReg(Phys, SubIdx) : Phys;
- MO.setReg(RReg);
- MO.setSubReg(0);
+ substitutePhysReg(MO, Phys, *TRI);
}
++NumReMats;
}
@@ -1004,11 +1025,12 @@
}
static
-void AssignPhysToVirtReg(MachineInstr *MI, unsigned VirtReg, unsigned PhysReg) {
+void AssignPhysToVirtReg(MachineInstr *MI, unsigned VirtReg, unsigned PhysReg,
+ const TargetRegisterInfo &TRI) {
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
if (MO.isReg() && MO.getReg() == VirtReg)
- MO.setReg(PhysReg);
+ substitutePhysReg(MO, PhysReg, TRI);
}
}
@@ -1175,7 +1197,7 @@
if (!TII->unfoldMemoryOperand(MF, &MI, VirtReg, false, false, NewMIs))
llvm_unreachable("Unable unfold the load / store folding instruction!");
assert(NewMIs.size() == 1);
- AssignPhysToVirtReg(NewMIs[0], VirtReg, PhysReg);
+ AssignPhysToVirtReg(NewMIs[0], VirtReg, PhysReg, *TRI);
VRM.transferRestorePts(&MI, NewMIs[0]);
MII = MBB.insert(MII, NewMIs[0]);
InvalidateKills(MI, TRI, RegKills, KillOps);
@@ -1191,7 +1213,7 @@
if (!TII->unfoldMemoryOperand(MF, &NextMI, VirtReg, false, false, NewMIs))
llvm_unreachable("Unable unfold the load / store folding instruction!");
assert(NewMIs.size() == 1);
- AssignPhysToVirtReg(NewMIs[0], VirtReg, PhysReg);
+ AssignPhysToVirtReg(NewMIs[0], VirtReg, PhysReg, *TRI);
VRM.transferRestorePts(&NextMI, NewMIs[0]);
MBB.insert(NextMII, NewMIs[0]);
InvalidateKills(NextMI, TRI, RegKills, KillOps);
@@ -1840,16 +1862,14 @@
RegInfo->setPhysRegUsed(Phys);
if (MO.isDef())
ReusedOperands.markClobbered(Phys);
- unsigned RReg = SubIdx ? TRI->getSubReg(Phys, SubIdx) : Phys;
- MI.getOperand(i).setReg(RReg);
- MI.getOperand(i).setSubReg(0);
+ substitutePhysReg(MO, Phys, *TRI);
if (VRM.isImplicitlyDefined(VirtReg))
// FIXME: Is this needed?
BuildMI(MBB, &MI, MI.getDebugLoc(),
- TII->get(TargetInstrInfo::IMPLICIT_DEF), RReg);
+ TII->get(TargetInstrInfo::IMPLICIT_DEF), Phys);
continue;
}
-
+
// This virtual register is now known to be a spilled value.
if (!MO.isUse())
continue; // Handle defs in the loop below (handle use&def here though)