If an available register falls through to a succ block, unset the last kill. Sorry, it's impossible to reduce a sensible test case. It basically requires the moon and stars to align in order to cause a failure.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@65497 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2009-02-26 02:30:42 +00:00
parent 7b048b391f
commit f792352c25

View File

@ -408,7 +408,12 @@ public:
/// value for this slot lives in (as the previous value is dead now).
void ModifyStackSlotOrReMat(int SlotOrReMat);
void AddAvailableRegsToLiveIn(MachineBasicBlock &MBB);
/// AddAvailableRegsToLiveIn - Availability information is being kept coming
/// into the specified MBB. Add available physical registers as potential
/// live-in's. If they are reused in the MBB, they will be added to the
/// live-in set to make register scavenger and post-allocation scheduler.
void AddAvailableRegsToLiveIn(MachineBasicBlock &MBB, BitVector &RegKills,
std::vector<MachineOperand*> &KillOps);
};
}
@ -488,22 +493,62 @@ void AvailableSpills::ModifyStackSlotOrReMat(int SlotOrReMat) {
PhysRegsAvailable.erase(I);
}
/// InvalidateKill - A MI that defines the specified register is being deleted,
/// invalidate the register kill information.
static void InvalidateKill(unsigned Reg, BitVector &RegKills,
std::vector<MachineOperand*> &KillOps) {
if (RegKills[Reg]) {
KillOps[Reg]->setIsKill(false);
KillOps[Reg] = NULL;
RegKills.reset(Reg);
}
}
/// AddAvailableRegsToLiveIn - Availability information is being kept coming
/// into the specified MBB. Add available physical registers as live-in's
/// so register scavenger and post-allocation scheduler are happy.
void AvailableSpills::AddAvailableRegsToLiveIn(MachineBasicBlock &MBB) {
/// into the specified MBB. Add available physical registers as potential
/// live-in's. If they are reused in the MBB, they will be added to the
/// live-in set to make register scavenger and post-allocation scheduler.
void AvailableSpills::AddAvailableRegsToLiveIn(MachineBasicBlock &MBB,
BitVector &RegKills,
std::vector<MachineOperand*> &KillOps) {
std::set<unsigned> NotAvailable;
for (std::multimap<unsigned, int>::iterator
I = PhysRegsAvailable.begin(), E = PhysRegsAvailable.end();
I != E; ++I) {
unsigned Reg = (*I).first;
unsigned Reg = I->first;
bool MakeAvail = true;
const TargetRegisterClass* RC = TRI->getPhysicalRegisterRegClass(Reg);
// FIXME: A temporary workaround. We can't reuse available value if it's
// not safe to move the def of the virtual register's class. e.g.
// X86::RFP* register classes. Do not add it as a live-in.
if (!TII->isSafeToMoveRegClassDefs(RC))
continue;
if (!MBB.isLiveIn(Reg))
MakeAvail = false;
if (MBB.isLiveIn(Reg))
// It's already livein somehow. Be conservative, do not make it available.
MakeAvail = false;
if (!MakeAvail)
// This is no longer available.
NotAvailable.insert(Reg);
else {
MBB.addLiveIn(Reg);
InvalidateKill(Reg, RegKills, KillOps);
}
// Skip over the same register.
std::multimap<unsigned, int>::iterator NI = next(I);
while (NI != E && NI->first == Reg) {
++I;
++NI;
}
}
for (std::set<unsigned>::iterator I = NotAvailable.begin(),
E = NotAvailable.end(); I != E; ++I) {
ClobberPhysReg(*I);
for (const unsigned *SubRegs = TRI->getSubRegisters(*I);
*SubRegs; ++SubRegs)
ClobberPhysReg(*SubRegs);
}
}
@ -546,6 +591,11 @@ namespace {
// reloads. This is usually refreshed per basic block.
AvailableSpills Spills(TRI, TII);
// Keep track of kill information.
BitVector RegKills(TRI->getNumRegs());
std::vector<MachineOperand*> KillOps;
KillOps.resize(TRI->getNumRegs(), NULL);
// SingleEntrySuccs - Successor blocks which have a single predecessor.
SmallVector<MachineBasicBlock*, 4> SinglePredSuccs;
SmallPtrSet<MachineBasicBlock*,16> EarlyVisited;
@ -559,7 +609,7 @@ namespace {
DFI != E; ++DFI) {
MachineBasicBlock *MBB = *DFI;
if (!EarlyVisited.count(MBB))
RewriteMBB(*MBB, VRM, Spills);
RewriteMBB(*MBB, VRM, Spills, RegKills, KillOps);
// If this MBB is the only predecessor of a successor. Keep the
// availability information and visit it next.
@ -574,8 +624,8 @@ namespace {
// the only predecessor.
MBB = SinglePredSuccs[0];
if (!Visited.count(MBB) && EarlyVisited.insert(MBB)) {
Spills.AddAvailableRegsToLiveIn(*MBB);
RewriteMBB(*MBB, VRM, Spills);
Spills.AddAvailableRegsToLiveIn(*MBB, RegKills, KillOps);
RewriteMBB(*MBB, VRM, Spills, RegKills, KillOps);
}
}
} while (MBB);
@ -612,6 +662,7 @@ namespace {
bool CommuteToFoldReload(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MII,
unsigned VirtReg, unsigned SrcReg, int SS,
AvailableSpills &Spills,
BitVector &RegKills,
std::vector<MachineOperand*> &KillOps,
const TargetRegisterInfo *TRI,
@ -627,7 +678,8 @@ namespace {
std::vector<MachineOperand*> &KillOps,
VirtRegMap &VRM);
void RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
AvailableSpills &Spills);
AvailableSpills &Spills,
BitVector &RegKills, std::vector<MachineOperand*> &KillOps);
};
}
@ -653,17 +705,6 @@ static void InvalidateKills(MachineInstr &MI, BitVector &RegKills,
}
}
/// InvalidateKill - A MI that defines the specified register is being deleted,
/// invalidate the register kill information.
static void InvalidateKill(unsigned Reg, BitVector &RegKills,
std::vector<MachineOperand*> &KillOps) {
if (RegKills[Reg]) {
KillOps[Reg]->setIsKill(false);
KillOps[Reg] = NULL;
RegKills.reset(Reg);
}
}
/// InvalidateRegDef - If the def operand of the specified def MI is now dead
/// (since it's spill instruction is removed), mark it isDead. Also checks if
/// the def MI has other definition operands that are not dead. Returns it by
@ -1086,6 +1127,7 @@ bool LocalSpiller::PrepForUnfoldOpti(MachineBasicBlock &MBB,
bool LocalSpiller::CommuteToFoldReload(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MII,
unsigned VirtReg, unsigned SrcReg, int SS,
AvailableSpills &Spills,
BitVector &RegKills,
std::vector<MachineOperand*> &KillOps,
const TargetRegisterInfo *TRI,
@ -1154,6 +1196,11 @@ bool LocalSpiller::CommuteToFoldReload(MachineBasicBlock &MBB,
VRM.RemoveMachineInstrFromMaps(&MI);
MBB.erase(&MI);
// If NewReg was previously holding value of some SS, it's now clobbered.
// This has to be done now because it's a physical register. When this
// instruction is re-visited, it's ignored.
Spills.ClobberPhysReg(NewReg);
++NumCommutes;
return true;
}
@ -1280,7 +1327,8 @@ void LocalSpiller::TransferDeadness(MachineBasicBlock *MBB, unsigned CurDist,
/// rewriteMBB - Keep track of which spills are available even after the
/// register allocator is done with them. If possible, avid reloading vregs.
void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
AvailableSpills &Spills) {
AvailableSpills &Spills, BitVector &RegKills,
std::vector<MachineOperand*> &KillOps) {
DOUT << "\n**** Local spiller rewriting MBB '"
<< MBB.getBasicBlock()->getName() << ":\n";
@ -1298,9 +1346,9 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
// ReMatDefs - These are rematerializable def MIs which are not deleted.
SmallSet<MachineInstr*, 4> ReMatDefs;
// Keep track of kill information.
BitVector RegKills(TRI->getNumRegs());
std::vector<MachineOperand*> KillOps;
// Clear kill info.
RegKills.reset();
KillOps.clear();
KillOps.resize(TRI->getNumRegs(), NULL);
unsigned Dist = 0;
@ -1368,11 +1416,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
int SSorRMId = DoReMat
? VRM.getReMatId(VirtReg) : VRM.getStackSlot(VirtReg);
const TargetRegisterClass* RC = RegInfo->getRegClass(VirtReg);
// FIXME: A temporary workaround. Don't reuse available value if it's
// not safe to move the def of the virtual register's class. e.g.
// X86::RFP* register classes.
unsigned InReg = TII->isSafeToMoveRegClassDefs(RC) ?
Spills.getSpillSlotOrReMatPhysReg(SSorRMId) : 0;
unsigned InReg = Spills.getSpillSlotOrReMatPhysReg(SSorRMId);
if (InReg == Phys) {
// If the value is already available in the expected register, save
// a reload / remat.
@ -1600,11 +1644,6 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
PotentialDeadStoreSlots.push_back(ReuseSlot);
}
// Assumes this is the last use. IsKill will be unset if reg is reused
// unless it's a two-address operand.
if (ti == -1)
MI.getOperand(i).setIsKill();
continue;
} // CanReuse
@ -1877,7 +1916,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM,
"Src hasn't been allocated yet?");
if (CommuteToFoldReload(MBB, MII, VirtReg, SrcReg, StackSlot,
RegKills, KillOps, TRI, VRM)) {
Spills, RegKills, KillOps, TRI, VRM)) {
NextMII = next(MII);
BackTracked = true;
goto ProcessNextInst;