Enable re-materialization of instructions which have virtual register operands if
the definition of the operand also reaches its uses.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47475 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp
index e93bac4..0f2b9bb 100644
--- a/lib/CodeGen/VirtRegMap.cpp
+++ b/lib/CodeGen/VirtRegMap.cpp
@@ -574,6 +574,32 @@
}
}
+/// ReMaterialize - Re-materialize definition for Reg targetting DestReg.
+///
+static void ReMaterialize(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator &MII,
+ unsigned DestReg, unsigned Reg,
+ const TargetRegisterInfo *TRI,
+ VirtRegMap &VRM) {
+ TRI->reMaterialize(MBB, MII, DestReg, VRM.getReMaterializedMI(Reg));
+ MachineInstr *NewMI = prior(MII);
+ for (unsigned i = 0, e = NewMI->getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = NewMI->getOperand(i);
+ if (!MO.isRegister() || MO.getReg() == 0)
+ continue;
+ unsigned VirtReg = MO.getReg();
+ if (TargetRegisterInfo::isPhysicalRegister(VirtReg))
+ continue;
+ assert(MO.isUse());
+ unsigned SubIdx = MO.getSubReg();
+ unsigned Phys = VRM.getPhys(VirtReg);
+ assert(Phys);
+ unsigned RReg = SubIdx ? TRI->getSubReg(Phys, SubIdx) : Phys;
+ MO.setReg(RReg);
+ }
+ ++NumReMats;
+}
+
// ReusedOp - For each reused operand, we keep track of a bit of information, in
// case we need to rollback upon processing a new operand. See comments below.
@@ -693,12 +719,11 @@
MI, Spills, MaybeDeadStores,
Rejected, RegKills, KillOps, VRM);
+ MachineBasicBlock::iterator MII = MI;
if (NewOp.StackSlotOrReMat > VirtRegMap::MAX_STACK_SLOT) {
- TRI->reMaterialize(*MBB, MI, NewPhysReg,
- VRM.getReMaterializedMI(NewOp.VirtReg));
- ++NumReMats;
+ ReMaterialize(*MBB, MII, NewPhysReg, NewOp.VirtReg, TRI, VRM);
} else {
- TII->loadRegFromStackSlot(*MBB, MI, NewPhysReg,
+ TII->loadRegFromStackSlot(*MBB, MII, NewPhysReg,
NewOp.StackSlotOrReMat, AliasRC);
// Any stores to this stack slot are not dead anymore.
MaybeDeadStores[NewOp.StackSlotOrReMat] = NULL;
@@ -710,7 +735,6 @@
MI->getOperand(NewOp.Operand).setReg(NewPhysReg);
Spills.addAvailable(NewOp.StackSlotOrReMat, MI, NewPhysReg);
- MachineBasicBlock::iterator MII = MI;
--MII;
UpdateKills(*MII, RegKills, KillOps);
DOUT << '\t' << *MII;
@@ -973,15 +997,13 @@
if (VRM.isRestorePt(&MI)) {
std::vector<unsigned> &RestoreRegs = VRM.getRestorePtRestores(&MI);
for (unsigned i = 0, e = RestoreRegs.size(); i != e; ++i) {
- unsigned VirtReg = RestoreRegs[i];
+ unsigned VirtReg = RestoreRegs[e-i-1]; // Reverse order.
if (!VRM.getPreSplitReg(VirtReg))
continue; // Split interval spilled again.
unsigned Phys = VRM.getPhys(VirtReg);
RegInfo->setPhysRegUsed(Phys);
if (VRM.isReMaterialized(VirtReg)) {
- TRI->reMaterialize(MBB, &MI, Phys,
- VRM.getReMaterializedMI(VirtReg));
- ++NumReMats;
+ ReMaterialize(MBB, MII, Phys, VirtReg, TRI, VRM);
} else {
const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
TII->loadRegFromStackSlot(MBB, &MI, Phys, VRM.getStackSlot(VirtReg),
@@ -1219,8 +1241,7 @@
RegInfo->setPhysRegUsed(PhysReg);
ReusedOperands.markClobbered(PhysReg);
if (DoReMat) {
- TRI->reMaterialize(MBB, &MI, PhysReg, VRM.getReMaterializedMI(VirtReg));
- ++NumReMats;
+ ReMaterialize(MBB, MII, PhysReg, VirtReg, TRI, VRM);
} else {
const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
TII->loadRegFromStackSlot(MBB, &MI, PhysReg, SSorRMId, RC);