mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-25 17:20:48 +00:00
Revert "Use a simpler data structure to calculate the least recently used register in RegAllocLocal."
This reverts commit 101392. It broke a buildbot. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@101595 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -76,16 +76,15 @@ namespace {
|
|||||||
//
|
//
|
||||||
std::vector<int> PhysRegsUsed;
|
std::vector<int> PhysRegsUsed;
|
||||||
|
|
||||||
// InstrNum - Number of the current instruction. This is used for the
|
// PhysRegsUseOrder - This contains a list of the physical registers that
|
||||||
// PhysLastUse map.
|
// currently have a virtual register value in them. This list provides an
|
||||||
|
// ordering of registers, imposing a reallocation order. This list is only
|
||||||
|
// used if all registers are allocated and we have to spill one, in which
|
||||||
|
// case we spill the least recently used register. Entries at the front of
|
||||||
|
// the list are the least recently used registers, entries at the back are
|
||||||
|
// the most recently used.
|
||||||
//
|
//
|
||||||
unsigned InstrNum;
|
std::vector<unsigned> PhysRegsUseOrder;
|
||||||
|
|
||||||
// PhysLastUse - Store the instruction number of the last use of each physical
|
|
||||||
// register. This is used to find the least recently used register. when
|
|
||||||
// spilling.
|
|
||||||
//
|
|
||||||
std::vector<unsigned> PhysLastUse;
|
|
||||||
|
|
||||||
// Virt2LastUseMap - This maps each virtual register to its last use
|
// Virt2LastUseMap - This maps each virtual register to its last use
|
||||||
// (MachineInstr*, operand index pair).
|
// (MachineInstr*, operand index pair).
|
||||||
@@ -124,8 +123,28 @@ namespace {
|
|||||||
return VirtRegModified[Reg - TargetRegisterInfo::FirstVirtualRegister];
|
return VirtRegModified[Reg - TargetRegisterInfo::FirstVirtualRegister];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddToPhysRegsUseOrder(unsigned Reg) {
|
||||||
|
std::vector<unsigned>::iterator It =
|
||||||
|
std::find(PhysRegsUseOrder.begin(), PhysRegsUseOrder.end(), Reg);
|
||||||
|
if (It != PhysRegsUseOrder.end())
|
||||||
|
PhysRegsUseOrder.erase(It);
|
||||||
|
PhysRegsUseOrder.push_back(Reg);
|
||||||
|
}
|
||||||
|
|
||||||
void MarkPhysRegRecentlyUsed(unsigned Reg) {
|
void MarkPhysRegRecentlyUsed(unsigned Reg) {
|
||||||
PhysLastUse[Reg] = InstrNum;
|
if (PhysRegsUseOrder.empty() ||
|
||||||
|
PhysRegsUseOrder.back() == Reg) return; // Already most recently used
|
||||||
|
|
||||||
|
for (unsigned i = PhysRegsUseOrder.size(); i != 0; --i) {
|
||||||
|
unsigned RegMatch = PhysRegsUseOrder[i-1]; // remove from middle
|
||||||
|
if (!areRegsEqual(Reg, RegMatch)) continue;
|
||||||
|
|
||||||
|
PhysRegsUseOrder.erase(PhysRegsUseOrder.begin()+i-1);
|
||||||
|
// Add it to the end of the list
|
||||||
|
PhysRegsUseOrder.push_back(RegMatch);
|
||||||
|
if (RegMatch == Reg)
|
||||||
|
return; // Found an exact match, exit early
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -260,6 +279,11 @@ int RALocal::getStackSpaceFor(unsigned VirtReg, const TargetRegisterClass *RC) {
|
|||||||
///
|
///
|
||||||
void RALocal::removePhysReg(unsigned PhysReg) {
|
void RALocal::removePhysReg(unsigned PhysReg) {
|
||||||
PhysRegsUsed[PhysReg] = -1; // PhyReg no longer used
|
PhysRegsUsed[PhysReg] = -1; // PhyReg no longer used
|
||||||
|
|
||||||
|
std::vector<unsigned>::iterator It =
|
||||||
|
std::find(PhysRegsUseOrder.begin(), PhysRegsUseOrder.end(), PhysReg);
|
||||||
|
if (It != PhysRegsUseOrder.end())
|
||||||
|
PhysRegsUseOrder.erase(It);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -341,7 +365,7 @@ void RALocal::assignVirtToPhysReg(unsigned VirtReg, unsigned PhysReg) {
|
|||||||
// it holds VirtReg.
|
// it holds VirtReg.
|
||||||
PhysRegsUsed[PhysReg] = VirtReg;
|
PhysRegsUsed[PhysReg] = VirtReg;
|
||||||
getVirt2PhysRegMapSlot(VirtReg) = PhysReg;
|
getVirt2PhysRegMapSlot(VirtReg) = PhysReg;
|
||||||
MarkPhysRegRecentlyUsed(PhysReg); // New use of PhysReg
|
AddToPhysRegsUseOrder(PhysReg); // New use of PhysReg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -397,20 +421,56 @@ unsigned RALocal::getReg(MachineBasicBlock &MBB, MachineInstr *I,
|
|||||||
return PhysReg;
|
return PhysReg;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the least recently used register in the allocation order.
|
// If we didn't find an unused register, scavenge one now!
|
||||||
unsigned Oldest = 0;
|
assert(!PhysRegsUseOrder.empty() && "No allocated registers??");
|
||||||
TargetRegisterClass::iterator RI = RC->allocation_order_begin(*MF);
|
|
||||||
TargetRegisterClass::iterator RE = RC->allocation_order_end(*MF);
|
// Loop over all of the preallocated registers from the least recently used
|
||||||
for (; RI != RE; ++RI) {
|
// to the most recently used. When we find one that is capable of holding
|
||||||
unsigned Age = InstrNum-PhysLastUse[*RI];
|
// our register, use it.
|
||||||
if (Age <= Oldest && PhysReg) continue;
|
for (unsigned i = 0; PhysReg == 0; ++i) {
|
||||||
PhysReg = *RI;
|
assert(i != PhysRegsUseOrder.size() &&
|
||||||
Oldest = Age;
|
"Couldn't find a register of the appropriate class!");
|
||||||
|
|
||||||
|
unsigned R = PhysRegsUseOrder[i];
|
||||||
|
|
||||||
|
// We can only use this register if it holds a virtual register (ie, it
|
||||||
|
// can be spilled). Do not use it if it is an explicitly allocated
|
||||||
|
// physical register!
|
||||||
|
assert(PhysRegsUsed[R] != -1 &&
|
||||||
|
"PhysReg in PhysRegsUseOrder, but is not allocated?");
|
||||||
|
if (PhysRegsUsed[R] && PhysRegsUsed[R] != -2) {
|
||||||
|
// If the current register is compatible, use it.
|
||||||
|
if (RC->contains(R)) {
|
||||||
|
PhysReg = R;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If one of the registers aliased to the current register is
|
||||||
|
// compatible, use it.
|
||||||
|
for (const unsigned *AliasIt = TRI->getAliasSet(R);
|
||||||
|
*AliasIt; ++AliasIt) {
|
||||||
|
if (!RC->contains(*AliasIt)) continue;
|
||||||
|
|
||||||
|
// If this is pinned down for some reason, don't use it. For
|
||||||
|
// example, if CL is pinned, and we run across CH, don't use
|
||||||
|
// CH as justification for using scavenging ECX (which will
|
||||||
|
// fail).
|
||||||
|
if (PhysRegsUsed[*AliasIt] == 0) continue;
|
||||||
|
|
||||||
|
// Make sure the register is allocatable. Don't allocate SIL on
|
||||||
|
// x86-32.
|
||||||
|
if (PhysRegsUsed[*AliasIt] == -2) continue;
|
||||||
|
|
||||||
|
PhysReg = *AliasIt; // Take an aliased register
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(PhysReg && "Physical register not assigned!?!?");
|
assert(PhysReg && "Physical register not assigned!?!?");
|
||||||
|
|
||||||
// Spill it to memory and reap its remains.
|
// At this point PhysRegsUseOrder[i] is the least recently used register of
|
||||||
|
// compatible register class. Spill it to memory and reap its remains.
|
||||||
spillPhysReg(MBB, I, PhysReg);
|
spillPhysReg(MBB, I, PhysReg);
|
||||||
|
|
||||||
// Now that we know which register we need to assign this to, do it now!
|
// Now that we know which register we need to assign this to, do it now!
|
||||||
@@ -578,10 +638,18 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {
|
|||||||
|
|
||||||
if (TargetRegisterInfo::isVirtualRegister(MO.getReg())) continue;
|
if (TargetRegisterInfo::isVirtualRegister(MO.getReg())) continue;
|
||||||
|
|
||||||
for (const unsigned *A = TRI->getAliasSet(MO.getReg()); *A; ++A) {
|
const unsigned *Aliases = TRI->getAliasSet(MO.getReg());
|
||||||
std::pair<MachineInstr*, unsigned> &LUD = LastUseDef[*A];
|
if (Aliases == 0)
|
||||||
if (LUD.first != I)
|
continue;
|
||||||
LUD = std::make_pair(I, i);
|
|
||||||
|
while (*Aliases) {
|
||||||
|
DenseMap<unsigned, std::pair<MachineInstr*, unsigned> >::iterator
|
||||||
|
alias = LastUseDef.find(*Aliases);
|
||||||
|
|
||||||
|
if (alias != LastUseDef.end() && alias->second.first != I)
|
||||||
|
LastUseDef[*Aliases] = std::make_pair(I, i);
|
||||||
|
|
||||||
|
++Aliases;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -712,11 +780,12 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
|
|||||||
unsigned Reg = *I;
|
unsigned Reg = *I;
|
||||||
MF->getRegInfo().setPhysRegUsed(Reg);
|
MF->getRegInfo().setPhysRegUsed(Reg);
|
||||||
PhysRegsUsed[Reg] = 0; // It is free and reserved now
|
PhysRegsUsed[Reg] = 0; // It is free and reserved now
|
||||||
MarkPhysRegRecentlyUsed(Reg);
|
AddToPhysRegsUseOrder(Reg);
|
||||||
for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
|
for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
|
||||||
*SubRegs; ++SubRegs) {
|
*SubRegs; ++SubRegs) {
|
||||||
if (PhysRegsUsed[*SubRegs] == -2) continue;
|
if (PhysRegsUsed[*SubRegs] == -2) continue;
|
||||||
MarkPhysRegRecentlyUsed(*SubRegs);
|
|
||||||
|
AddToPhysRegsUseOrder(*SubRegs);
|
||||||
PhysRegsUsed[*SubRegs] = 0; // It is free and reserved now
|
PhysRegsUsed[*SubRegs] = 0; // It is free and reserved now
|
||||||
MF->getRegInfo().setPhysRegUsed(*SubRegs);
|
MF->getRegInfo().setPhysRegUsed(*SubRegs);
|
||||||
}
|
}
|
||||||
@@ -727,7 +796,6 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
|
|||||||
// Otherwise, sequentially allocate each instruction in the MBB.
|
// Otherwise, sequentially allocate each instruction in the MBB.
|
||||||
while (MII != MBB.end()) {
|
while (MII != MBB.end()) {
|
||||||
MachineInstr *MI = MII++;
|
MachineInstr *MI = MII++;
|
||||||
++InstrNum;
|
|
||||||
const TargetInstrDesc &TID = MI->getDesc();
|
const TargetInstrDesc &TID = MI->getDesc();
|
||||||
DEBUG({
|
DEBUG({
|
||||||
dbgs() << "\nStarting RegAlloc of: " << *MI;
|
dbgs() << "\nStarting RegAlloc of: " << *MI;
|
||||||
@@ -806,14 +874,14 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
|
|||||||
MF->getRegInfo().setPhysRegUsed(Reg);
|
MF->getRegInfo().setPhysRegUsed(Reg);
|
||||||
spillPhysReg(MBB, MI, Reg, true); // Spill any existing value in reg
|
spillPhysReg(MBB, MI, Reg, true); // Spill any existing value in reg
|
||||||
PhysRegsUsed[Reg] = 0; // It is free and reserved now
|
PhysRegsUsed[Reg] = 0; // It is free and reserved now
|
||||||
MarkPhysRegRecentlyUsed(Reg);
|
AddToPhysRegsUseOrder(Reg);
|
||||||
|
|
||||||
for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
|
for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
|
||||||
*SubRegs; ++SubRegs) {
|
*SubRegs; ++SubRegs) {
|
||||||
if (PhysRegsUsed[*SubRegs] == -2) continue;
|
if (PhysRegsUsed[*SubRegs] == -2) continue;
|
||||||
MF->getRegInfo().setPhysRegUsed(*SubRegs);
|
MF->getRegInfo().setPhysRegUsed(*SubRegs);
|
||||||
PhysRegsUsed[*SubRegs] = 0; // It is free and reserved now
|
PhysRegsUsed[*SubRegs] = 0; // It is free and reserved now
|
||||||
MarkPhysRegRecentlyUsed(*SubRegs);
|
AddToPhysRegsUseOrder(*SubRegs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -903,7 +971,7 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
|
|||||||
MF->getRegInfo().setPhysRegUsed(Reg);
|
MF->getRegInfo().setPhysRegUsed(Reg);
|
||||||
spillPhysReg(MBB, MI, Reg, true); // Spill any existing value in reg
|
spillPhysReg(MBB, MI, Reg, true); // Spill any existing value in reg
|
||||||
PhysRegsUsed[Reg] = 0; // It is free and reserved now
|
PhysRegsUsed[Reg] = 0; // It is free and reserved now
|
||||||
MarkPhysRegRecentlyUsed(Reg);
|
AddToPhysRegsUseOrder(Reg);
|
||||||
|
|
||||||
for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
|
for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
|
||||||
*SubRegs; ++SubRegs) {
|
*SubRegs; ++SubRegs) {
|
||||||
@@ -911,7 +979,7 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
|
|||||||
|
|
||||||
MF->getRegInfo().setPhysRegUsed(*SubRegs);
|
MF->getRegInfo().setPhysRegUsed(*SubRegs);
|
||||||
PhysRegsUsed[*SubRegs] = 0; // It is free and reserved now
|
PhysRegsUsed[*SubRegs] = 0; // It is free and reserved now
|
||||||
MarkPhysRegRecentlyUsed(*SubRegs);
|
AddToPhysRegsUseOrder(*SubRegs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -922,7 +990,7 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
|
|||||||
unsigned Reg = *ImplicitDefs;
|
unsigned Reg = *ImplicitDefs;
|
||||||
if (PhysRegsUsed[Reg] != -2) {
|
if (PhysRegsUsed[Reg] != -2) {
|
||||||
spillPhysReg(MBB, MI, Reg, true);
|
spillPhysReg(MBB, MI, Reg, true);
|
||||||
MarkPhysRegRecentlyUsed(Reg);
|
AddToPhysRegsUseOrder(Reg);
|
||||||
PhysRegsUsed[Reg] = 0; // It is free and reserved now
|
PhysRegsUsed[Reg] = 0; // It is free and reserved now
|
||||||
}
|
}
|
||||||
MF->getRegInfo().setPhysRegUsed(Reg);
|
MF->getRegInfo().setPhysRegUsed(Reg);
|
||||||
@@ -930,7 +998,7 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
|
|||||||
*SubRegs; ++SubRegs) {
|
*SubRegs; ++SubRegs) {
|
||||||
if (PhysRegsUsed[*SubRegs] == -2) continue;
|
if (PhysRegsUsed[*SubRegs] == -2) continue;
|
||||||
|
|
||||||
MarkPhysRegRecentlyUsed(*SubRegs);
|
AddToPhysRegsUseOrder(*SubRegs);
|
||||||
PhysRegsUsed[*SubRegs] = 0; // It is free and reserved now
|
PhysRegsUsed[*SubRegs] = 0; // It is free and reserved now
|
||||||
MF->getRegInfo().setPhysRegUsed(*SubRegs);
|
MF->getRegInfo().setPhysRegUsed(*SubRegs);
|
||||||
}
|
}
|
||||||
@@ -1055,6 +1123,11 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
|
|||||||
}
|
}
|
||||||
assert(AllOk && "Virtual registers still in phys regs?");
|
assert(AllOk && "Virtual registers still in phys regs?");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Clear any physical register which appear live at the end of the basic
|
||||||
|
// block, but which do not hold any virtual registers. e.g., the stack
|
||||||
|
// pointer.
|
||||||
|
PhysRegsUseOrder.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// runOnMachineFunction - Register allocate the whole function
|
/// runOnMachineFunction - Register allocate the whole function
|
||||||
@@ -1067,8 +1140,6 @@ bool RALocal::runOnMachineFunction(MachineFunction &Fn) {
|
|||||||
TII = TM->getInstrInfo();
|
TII = TM->getInstrInfo();
|
||||||
|
|
||||||
PhysRegsUsed.assign(TRI->getNumRegs(), -1);
|
PhysRegsUsed.assign(TRI->getNumRegs(), -1);
|
||||||
InstrNum = 0;
|
|
||||||
PhysLastUse.assign(TRI->getNumRegs(), 0);
|
|
||||||
|
|
||||||
// At various places we want to efficiently check to see whether a register
|
// At various places we want to efficiently check to see whether a register
|
||||||
// is allocatable. To handle this, we mark all unallocatable registers as
|
// is allocatable. To handle this, we mark all unallocatable registers as
|
||||||
|
Reference in New Issue
Block a user