summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/VirtRegRewriter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/VirtRegRewriter.cpp')
-rw-r--r--lib/CodeGen/VirtRegRewriter.cpp144
1 files changed, 82 insertions, 62 deletions
diff --git a/lib/CodeGen/VirtRegRewriter.cpp b/lib/CodeGen/VirtRegRewriter.cpp
index 054c3b6..df2b8d2 100644
--- a/lib/CodeGen/VirtRegRewriter.cpp
+++ b/lib/CodeGen/VirtRegRewriter.cpp
@@ -60,6 +60,33 @@ ScheduleSpills("schedule-spills",
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
@@ -69,10 +96,10 @@ struct TrivialRewriter : public VirtRegRewriter {
bool runOnMachineFunction(MachineFunction &MF, VirtRegMap &VRM,
LiveIntervals* LIs) {
- DEBUG(errs() << "********** REWRITE MACHINE CODE **********\n");
- DEBUG(errs() << "********** Function: "
+ DEBUG(dbgs() << "********** REWRITE MACHINE CODE **********\n");
+ DEBUG(dbgs() << "********** Function: "
<< MF.getFunction()->getName() << '\n');
- DEBUG(errs() << "**** Machine Instrs"
+ DEBUG(dbgs() << "**** Machine Instrs"
<< "(NOTE! Does not include spills and reloads!) ****\n");
DEBUG(MF.dump());
@@ -101,16 +128,13 @@ struct TrivialRewriter : public VirtRegRewriter {
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;
}
}
}
- DEBUG(errs() << "**** Post Machine Instrs ****\n");
+ DEBUG(dbgs() << "**** Post Machine Instrs ****\n");
DEBUG(MF.dump());
return changed;
@@ -191,11 +215,11 @@ public:
(unsigned)CanClobber;
if (SlotOrReMat > VirtRegMap::MAX_STACK_SLOT)
- DEBUG(errs() << "Remembering RM#"
+ DEBUG(dbgs() << "Remembering RM#"
<< SlotOrReMat-VirtRegMap::MAX_STACK_SLOT-1);
else
- DEBUG(errs() << "Remembering SS#" << SlotOrReMat);
- DEBUG(errs() << " in physreg " << TRI->getName(Reg) << "\n");
+ DEBUG(dbgs() << "Remembering SS#" << SlotOrReMat);
+ DEBUG(dbgs() << " in physreg " << TRI->getName(Reg) << "\n");
}
/// canClobberPhysRegForSS - Return true if the spiller is allowed to change
@@ -647,12 +671,9 @@ static void ReMaterialize(MachineBasicBlock &MBB,
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;
}
@@ -686,7 +707,7 @@ void AvailableSpills::disallowClobberPhysRegOnly(unsigned PhysReg) {
assert((SpillSlotsOrReMatsAvailable[SlotOrReMat] >> 1) == PhysReg &&
"Bidirectional map mismatch!");
SpillSlotsOrReMatsAvailable[SlotOrReMat] &= ~1;
- DEBUG(errs() << "PhysReg " << TRI->getName(PhysReg)
+ DEBUG(dbgs() << "PhysReg " << TRI->getName(PhysReg)
<< " copied, it is available for use but can no longer be modified\n");
}
}
@@ -711,12 +732,12 @@ void AvailableSpills::ClobberPhysRegOnly(unsigned PhysReg) {
assert((SpillSlotsOrReMatsAvailable[SlotOrReMat] >> 1) == PhysReg &&
"Bidirectional map mismatch!");
SpillSlotsOrReMatsAvailable.erase(SlotOrReMat);
- DEBUG(errs() << "PhysReg " << TRI->getName(PhysReg)
+ DEBUG(dbgs() << "PhysReg " << TRI->getName(PhysReg)
<< " clobbered, invalidating ");
if (SlotOrReMat > VirtRegMap::MAX_STACK_SLOT)
- DEBUG(errs() << "RM#" << SlotOrReMat-VirtRegMap::MAX_STACK_SLOT-1 <<"\n");
+ DEBUG(dbgs() << "RM#" << SlotOrReMat-VirtRegMap::MAX_STACK_SLOT-1 <<"\n");
else
- DEBUG(errs() << "SS#" << SlotOrReMat << "\n");
+ DEBUG(dbgs() << "SS#" << SlotOrReMat << "\n");
}
}
@@ -895,9 +916,9 @@ unsigned ReuseInfo::GetRegForReload(const TargetRegisterClass *RC,
Spills.addAvailable(NewOp.StackSlotOrReMat, NewPhysReg);
UpdateKills(*prior(InsertLoc), TRI, RegKills, KillOps);
- DEBUG(errs() << '\t' << *prior(InsertLoc));
+ DEBUG(dbgs() << '\t' << *prior(InsertLoc));
- DEBUG(errs() << "Reuse undone!\n");
+ DEBUG(dbgs() << "Reuse undone!\n");
--NumReused;
// Finally, PhysReg is now available, go ahead and use it.
@@ -1004,11 +1025,12 @@ static unsigned FindFreeRegister(MachineBasicBlock::iterator MII,
}
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);
}
}
@@ -1041,9 +1063,9 @@ public:
TRI = MF.getTarget().getRegisterInfo();
TII = MF.getTarget().getInstrInfo();
AllocatableRegs = TRI->getAllocatableSet(MF);
- DEBUG(errs() << "\n**** Local spiller rewriting function '"
+ DEBUG(dbgs() << "\n**** Local spiller rewriting function '"
<< MF.getFunction()->getName() << "':\n");
- DEBUG(errs() << "**** Machine Instrs (NOTE! Does not include spills and"
+ DEBUG(dbgs() << "**** Machine Instrs (NOTE! Does not include spills and"
" reloads!) ****\n");
DEBUG(MF.dump());
@@ -1095,7 +1117,7 @@ public:
Spills.clear();
}
- DEBUG(errs() << "**** Post Machine Instrs ****\n");
+ DEBUG(dbgs() << "**** Post Machine Instrs ****\n");
DEBUG(MF.dump());
// Mark unused spill slots.
@@ -1175,7 +1197,7 @@ private:
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 @@ private:
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);
@@ -1467,11 +1489,11 @@ private:
TII->storeRegToStackSlot(MBB, llvm::next(MII), PhysReg, true, StackSlot, RC);
MachineInstr *StoreMI = prior(oldNextMII);
VRM.addSpillSlotUse(StackSlot, StoreMI);
- DEBUG(errs() << "Store:\t" << *StoreMI);
+ DEBUG(dbgs() << "Store:\t" << *StoreMI);
// If there is a dead store to this stack slot, nuke it now.
if (LastStore) {
- DEBUG(errs() << "Removed dead store:\t" << *LastStore);
+ DEBUG(dbgs() << "Removed dead store:\t" << *LastStore);
++NumDSE;
SmallVector<unsigned, 2> KillRegs;
InvalidateKills(*LastStore, TRI, RegKills, KillOps, &KillRegs);
@@ -1599,7 +1621,7 @@ private:
AvailableSpills &Spills, BitVector &RegKills,
std::vector<MachineOperand*> &KillOps) {
- DEBUG(errs() << "\n**** Local spiller rewriting MBB '"
+ DEBUG(dbgs() << "\n**** Local spiller rewriting MBB '"
<< MBB.getName() << "':\n");
MachineFunction &MF = *MBB.getParent();
@@ -1699,11 +1721,11 @@ private:
// If the value is already available in the expected register, save
// a reload / remat.
if (SSorRMId)
- DEBUG(errs() << "Reusing RM#"
+ DEBUG(dbgs() << "Reusing RM#"
<< SSorRMId-VirtRegMap::MAX_STACK_SLOT-1);
else
- DEBUG(errs() << "Reusing SS#" << SSorRMId);
- DEBUG(errs() << " from physreg "
+ DEBUG(dbgs() << "Reusing SS#" << SSorRMId);
+ DEBUG(dbgs() << " from physreg "
<< TRI->getName(InReg) << " for vreg"
<< VirtReg <<" instead of reloading into physreg "
<< TRI->getName(Phys) << '\n');
@@ -1711,11 +1733,11 @@ private:
continue;
} else if (InReg && InReg != Phys) {
if (SSorRMId)
- DEBUG(errs() << "Reusing RM#"
+ DEBUG(dbgs() << "Reusing RM#"
<< SSorRMId-VirtRegMap::MAX_STACK_SLOT-1);
else
- DEBUG(errs() << "Reusing SS#" << SSorRMId);
- DEBUG(errs() << " from physreg "
+ DEBUG(dbgs() << "Reusing SS#" << SSorRMId);
+ DEBUG(dbgs() << " from physreg "
<< TRI->getName(InReg) << " for vreg"
<< VirtReg <<" by copying it into physreg "
<< TRI->getName(Phys) << '\n');
@@ -1742,7 +1764,7 @@ private:
KillOpnd->setIsKill();
UpdateKills(*CopyMI, TRI, RegKills, KillOps);
- DEBUG(errs() << '\t' << *CopyMI);
+ DEBUG(dbgs() << '\t' << *CopyMI);
++NumCopified;
continue;
}
@@ -1769,7 +1791,7 @@ private:
Spills.addAvailable(SSorRMId, Phys);
UpdateKills(*prior(InsertLoc), TRI, RegKills, KillOps);
- DEBUG(errs() << '\t' << *prior(MII));
+ DEBUG(dbgs() << '\t' << *prior(MII));
}
}
@@ -1789,7 +1811,7 @@ private:
TII->storeRegToStackSlot(MBB, llvm::next(MII), Phys, isKill, StackSlot, RC);
MachineInstr *StoreMI = prior(oldNextMII);
VRM.addSpillSlotUse(StackSlot, StoreMI);
- DEBUG(errs() << "Store:\t" << *StoreMI);
+ DEBUG(dbgs() << "Store:\t" << *StoreMI);
VRM.virtFolded(VirtReg, StoreMI, VirtRegMap::isMod);
}
NextMII = llvm::next(MII);
@@ -1840,16 +1862,14 @@ private:
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)
@@ -1908,11 +1928,11 @@ private:
if (CanReuse) {
// If this stack slot value is already available, reuse it!
if (ReuseSlot > VirtRegMap::MAX_STACK_SLOT)
- DEBUG(errs() << "Reusing RM#"
+ DEBUG(dbgs() << "Reusing RM#"
<< ReuseSlot-VirtRegMap::MAX_STACK_SLOT-1);
else
- DEBUG(errs() << "Reusing SS#" << ReuseSlot);
- DEBUG(errs() << " from physreg "
+ DEBUG(dbgs() << "Reusing SS#" << ReuseSlot);
+ DEBUG(dbgs() << " from physreg "
<< TRI->getName(PhysReg) << " for vreg"
<< VirtReg <<" instead of reloading into physreg "
<< TRI->getName(VRM.getPhys(VirtReg)) << '\n');
@@ -1991,11 +2011,11 @@ private:
if (DesignatedReg == PhysReg) {
// If this stack slot value is already available, reuse it!
if (ReuseSlot > VirtRegMap::MAX_STACK_SLOT)
- DEBUG(errs() << "Reusing RM#"
+ DEBUG(dbgs() << "Reusing RM#"
<< ReuseSlot-VirtRegMap::MAX_STACK_SLOT-1);
else
- DEBUG(errs() << "Reusing SS#" << ReuseSlot);
- DEBUG(errs() << " from physreg " << TRI->getName(PhysReg)
+ DEBUG(dbgs() << "Reusing SS#" << ReuseSlot);
+ DEBUG(dbgs() << " from physreg " << TRI->getName(PhysReg)
<< " for vreg" << VirtReg
<< " instead of reloading into same physreg.\n");
unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg;
@@ -2029,7 +2049,7 @@ private:
SubIdx ? TRI->getSubReg(DesignatedReg, SubIdx) : DesignatedReg;
MI.getOperand(i).setReg(RReg);
MI.getOperand(i).setSubReg(0);
- DEBUG(errs() << '\t' << *prior(MII));
+ DEBUG(dbgs() << '\t' << *prior(MII));
++NumReused;
continue;
} // if (PhysReg)
@@ -2082,7 +2102,7 @@ private:
}
UpdateKills(*prior(InsertLoc), TRI, RegKills, KillOps);
- DEBUG(errs() << '\t' << *prior(InsertLoc));
+ DEBUG(dbgs() << '\t' << *prior(InsertLoc));
}
unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg;
MI.getOperand(i).setReg(RReg);
@@ -2096,7 +2116,7 @@ private:
int PDSSlot = PotentialDeadStoreSlots[j];
MachineInstr* DeadStore = MaybeDeadStores[PDSSlot];
if (DeadStore) {
- DEBUG(errs() << "Removed dead store:\t" << *DeadStore);
+ DEBUG(dbgs() << "Removed dead store:\t" << *DeadStore);
InvalidateKills(*DeadStore, TRI, RegKills, KillOps);
VRM.RemoveMachineInstrFromMaps(DeadStore);
MBB.erase(DeadStore);
@@ -2106,7 +2126,7 @@ private:
}
- DEBUG(errs() << '\t' << MI);
+ DEBUG(dbgs() << '\t' << MI);
// If we have folded references to memory operands, make sure we clear all
@@ -2116,7 +2136,7 @@ private:
for (tie(I, End) = VRM.getFoldedVirts(&MI); I != End; ) {
unsigned VirtReg = I->second.first;
VirtRegMap::ModRef MR = I->second.second;
- DEBUG(errs() << "Folded vreg: " << VirtReg << " MR: " << MR);
+ DEBUG(dbgs() << "Folded vreg: " << VirtReg << " MR: " << MR);
// MI2VirtMap be can updated which invalidate the iterator.
// Increment the iterator first.
@@ -2125,7 +2145,7 @@ private:
if (SS == VirtRegMap::NO_STACK_SLOT)
continue;
FoldedSS.insert(SS);
- DEBUG(errs() << " - StackSlot: " << SS << "\n");
+ DEBUG(dbgs() << " - StackSlot: " << SS << "\n");
// If this folded instruction is just a use, check to see if it's a
// straight load from the virt reg slot.
@@ -2136,7 +2156,7 @@ private:
// If this spill slot is available, turn it into a copy (or nothing)
// instead of leaving it as a load!
if (unsigned InReg = Spills.getSpillSlotOrReMatPhysReg(SS)) {
- DEBUG(errs() << "Promoted Load To Copy: " << MI);
+ DEBUG(dbgs() << "Promoted Load To Copy: " << MI);
if (DestReg != InReg) {
const TargetRegisterClass *RC = RegInfo->getRegClass(VirtReg);
TII->copyRegToReg(MBB, &MI, DestReg, InReg, RC, RC);
@@ -2160,7 +2180,7 @@ private:
BackTracked = true;
} else {
- DEBUG(errs() << "Removing now-noop copy: " << MI);
+ DEBUG(dbgs() << "Removing now-noop copy: " << MI);
// Unset last kill since it's being reused.
InvalidateKill(InReg, TRI, RegKills, KillOps);
Spills.disallowClobberPhysReg(InReg);
@@ -2230,7 +2250,7 @@ private:
if (isDead) { // Previous store is dead.
// If we get here, the store is dead, nuke it now.
- DEBUG(errs() << "Removed dead store:\t" << *DeadStore);
+ DEBUG(dbgs() << "Removed dead store:\t" << *DeadStore);
InvalidateKills(*DeadStore, TRI, RegKills, KillOps);
VRM.RemoveMachineInstrFromMaps(DeadStore);
MBB.erase(DeadStore);
@@ -2301,7 +2321,7 @@ private:
if (TII->isMoveInstr(MI, Src, Dst, SrcSR, DstSR) && Src == Dst &&
!MI.findRegisterUseOperand(Src)->isUndef()) {
++NumDCE;
- DEBUG(errs() << "Removing now-noop copy: " << MI);
+ DEBUG(dbgs() << "Removing now-noop copy: " << MI);
SmallVector<unsigned, 2> KillRegs;
InvalidateKills(MI, TRI, RegKills, KillOps, &KillRegs);
if (MO.isDead() && !KillRegs.empty()) {
@@ -2389,7 +2409,7 @@ private:
unsigned Src, Dst, SrcSR, DstSR;
if (TII->isMoveInstr(MI, Src, Dst, SrcSR, DstSR) && Src == Dst) {
++NumDCE;
- DEBUG(errs() << "Removing now-noop copy: " << MI);
+ DEBUG(dbgs() << "Removing now-noop copy: " << MI);
InvalidateKills(MI, TRI, RegKills, KillOps);
VRM.RemoveMachineInstrFromMaps(&MI);
MBB.erase(&MI);
OpenPOWER on IntegriCloud