mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-24 12:29:33 +00:00
Fix a bunch of llc-beta failures on x86 yesterday. Don't allow selection
of unallocatable registers, just because an alias is allocatable. We were picking registers like SIL just because ESI was being used. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30197 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cf8cb6d564
commit
45d5788123
@ -66,8 +66,9 @@ namespace {
|
|||||||
// Virt2PhysRegMap). The value mapped to is the virtual register
|
// Virt2PhysRegMap). The value mapped to is the virtual register
|
||||||
// corresponding to the physical register (the inverse of the
|
// corresponding to the physical register (the inverse of the
|
||||||
// Virt2PhysRegMap), or 0. The value is set to 0 if this register is pinned
|
// Virt2PhysRegMap), or 0. The value is set to 0 if this register is pinned
|
||||||
// because it is used by a future instruction. If the entry for a physical
|
// because it is used by a future instruction, and to -2 if it is not
|
||||||
// register is -1, then the physical register is "not in the map".
|
// allocatable. If the entry for a physical register is -1, then the
|
||||||
|
// physical register is "not in the map".
|
||||||
//
|
//
|
||||||
std::vector<int> PhysRegsUsed;
|
std::vector<int> PhysRegsUsed;
|
||||||
|
|
||||||
@ -298,14 +299,16 @@ void RA::spillVirtReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
|||||||
void RA::spillPhysReg(MachineBasicBlock &MBB, MachineInstr *I,
|
void RA::spillPhysReg(MachineBasicBlock &MBB, MachineInstr *I,
|
||||||
unsigned PhysReg, bool OnlyVirtRegs) {
|
unsigned PhysReg, bool OnlyVirtRegs) {
|
||||||
if (PhysRegsUsed[PhysReg] != -1) { // Only spill it if it's used!
|
if (PhysRegsUsed[PhysReg] != -1) { // Only spill it if it's used!
|
||||||
|
assert(PhysRegsUsed[PhysReg] != -2 && "Non allocable reg used!");
|
||||||
if (PhysRegsUsed[PhysReg] || !OnlyVirtRegs)
|
if (PhysRegsUsed[PhysReg] || !OnlyVirtRegs)
|
||||||
spillVirtReg(MBB, I, PhysRegsUsed[PhysReg], PhysReg);
|
spillVirtReg(MBB, I, PhysRegsUsed[PhysReg], PhysReg);
|
||||||
} else {
|
} else {
|
||||||
// If the selected register aliases any other registers, we must make
|
// If the selected register aliases any other registers, we must make
|
||||||
// sure that one of the aliases isn't alive...
|
// sure that one of the aliases isn't alive.
|
||||||
for (const unsigned *AliasSet = RegInfo->getAliasSet(PhysReg);
|
for (const unsigned *AliasSet = RegInfo->getAliasSet(PhysReg);
|
||||||
*AliasSet; ++AliasSet)
|
*AliasSet; ++AliasSet)
|
||||||
if (PhysRegsUsed[*AliasSet] != -1) // Spill aliased register...
|
if (PhysRegsUsed[*AliasSet] != -1 && // Spill aliased register.
|
||||||
|
PhysRegsUsed[*AliasSet] != -2) // If allocatable.
|
||||||
if (PhysRegsUsed[*AliasSet] || !OnlyVirtRegs)
|
if (PhysRegsUsed[*AliasSet] || !OnlyVirtRegs)
|
||||||
spillVirtReg(MBB, I, PhysRegsUsed[*AliasSet], *AliasSet);
|
spillVirtReg(MBB, I, PhysRegsUsed[*AliasSet], *AliasSet);
|
||||||
}
|
}
|
||||||
@ -400,7 +403,7 @@ unsigned RA::getReg(MachineBasicBlock &MBB, MachineInstr *I,
|
|||||||
// physical register!
|
// physical register!
|
||||||
assert(PhysRegsUsed[R] != -1 &&
|
assert(PhysRegsUsed[R] != -1 &&
|
||||||
"PhysReg in PhysRegsUseOrder, but is not allocated?");
|
"PhysReg in PhysRegsUseOrder, but is not allocated?");
|
||||||
if (PhysRegsUsed[R]) {
|
if (PhysRegsUsed[R] && PhysRegsUsed[R] != -2) {
|
||||||
// If the current register is compatible, use it.
|
// If the current register is compatible, use it.
|
||||||
if (RC->contains(R)) {
|
if (RC->contains(R)) {
|
||||||
PhysReg = R;
|
PhysReg = R;
|
||||||
@ -415,7 +418,11 @@ unsigned RA::getReg(MachineBasicBlock &MBB, MachineInstr *I,
|
|||||||
// example, if CL is pinned, and we run across CH, don't use
|
// example, if CL is pinned, and we run across CH, don't use
|
||||||
// CH as justification for using scavenging ECX (which will
|
// CH as justification for using scavenging ECX (which will
|
||||||
// fail).
|
// fail).
|
||||||
PhysRegsUsed[*AliasIt] != 0) {
|
PhysRegsUsed[*AliasIt] != 0 &&
|
||||||
|
|
||||||
|
// Make sure the register is allocatable. Don't allocate SIL on
|
||||||
|
// x86-32.
|
||||||
|
PhysRegsUsed[*AliasIt] != -2) {
|
||||||
PhysReg = *AliasIt; // Take an aliased register
|
PhysReg = *AliasIt; // Take an aliased register
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -516,12 +523,14 @@ void RA::AllocateBasicBlock(MachineBasicBlock &MBB) {
|
|||||||
PhysRegsUseOrder.push_back(Reg);
|
PhysRegsUseOrder.push_back(Reg);
|
||||||
for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg);
|
for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg);
|
||||||
*AliasSet; ++AliasSet) {
|
*AliasSet; ++AliasSet) {
|
||||||
|
if (PhysRegsUsed[*AliasSet] != -2) {
|
||||||
PhysRegsUseOrder.push_back(*AliasSet);
|
PhysRegsUseOrder.push_back(*AliasSet);
|
||||||
PhysRegsUsed[*AliasSet] = 0; // It is free and reserved now
|
PhysRegsUsed[*AliasSet] = 0; // It is free and reserved now
|
||||||
PhysRegsEverUsed[*AliasSet] = true;
|
PhysRegsEverUsed[*AliasSet] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Otherwise, sequentially allocate each instruction in the MBB.
|
// Otherwise, sequentially allocate each instruction in the MBB.
|
||||||
while (MII != MBB.end()) {
|
while (MII != MBB.end()) {
|
||||||
@ -530,7 +539,7 @@ void RA::AllocateBasicBlock(MachineBasicBlock &MBB) {
|
|||||||
DEBUG(std::cerr << "\nStarting RegAlloc of: " << *MI;
|
DEBUG(std::cerr << "\nStarting RegAlloc of: " << *MI;
|
||||||
std::cerr << " Regs have values: ";
|
std::cerr << " Regs have values: ";
|
||||||
for (unsigned i = 0; i != RegInfo->getNumRegs(); ++i)
|
for (unsigned i = 0; i != RegInfo->getNumRegs(); ++i)
|
||||||
if (PhysRegsUsed[i] != -1)
|
if (PhysRegsUsed[i] != -1 && PhysRegsUsed[i] != -2)
|
||||||
std::cerr << "[" << RegInfo->getName(i)
|
std::cerr << "[" << RegInfo->getName(i)
|
||||||
<< ",%reg" << PhysRegsUsed[i] << "] ";
|
<< ",%reg" << PhysRegsUsed[i] << "] ";
|
||||||
std::cerr << "\n");
|
std::cerr << "\n");
|
||||||
@ -593,18 +602,22 @@ void RA::AllocateBasicBlock(MachineBasicBlock &MBB) {
|
|||||||
PhysRegsUseOrder.push_back(Reg);
|
PhysRegsUseOrder.push_back(Reg);
|
||||||
for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg);
|
for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg);
|
||||||
*AliasSet; ++AliasSet) {
|
*AliasSet; ++AliasSet) {
|
||||||
|
if (PhysRegsUsed[*AliasSet] != -2) {
|
||||||
PhysRegsUseOrder.push_back(*AliasSet);
|
PhysRegsUseOrder.push_back(*AliasSet);
|
||||||
PhysRegsUsed[*AliasSet] = 0; // It is free and reserved now
|
PhysRegsUsed[*AliasSet] = 0; // It is free and reserved now
|
||||||
PhysRegsEverUsed[*AliasSet] = true;
|
PhysRegsEverUsed[*AliasSet] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Loop over the implicit defs, spilling them as well.
|
// Loop over the implicit defs, spilling them as well.
|
||||||
if (TID.ImplicitDefs) {
|
if (TID.ImplicitDefs) {
|
||||||
for (const unsigned *ImplicitDefs = TID.ImplicitDefs;
|
for (const unsigned *ImplicitDefs = TID.ImplicitDefs;
|
||||||
*ImplicitDefs; ++ImplicitDefs) {
|
*ImplicitDefs; ++ImplicitDefs) {
|
||||||
unsigned Reg = *ImplicitDefs;
|
unsigned Reg = *ImplicitDefs;
|
||||||
|
if (PhysRegsUsed[Reg] == -2) continue;
|
||||||
|
|
||||||
spillPhysReg(MBB, MI, Reg, true);
|
spillPhysReg(MBB, MI, Reg, true);
|
||||||
PhysRegsUseOrder.push_back(Reg);
|
PhysRegsUseOrder.push_back(Reg);
|
||||||
PhysRegsUsed[Reg] = 0; // It is free and reserved now
|
PhysRegsUsed[Reg] = 0; // It is free and reserved now
|
||||||
@ -612,12 +625,14 @@ void RA::AllocateBasicBlock(MachineBasicBlock &MBB) {
|
|||||||
|
|
||||||
for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg);
|
for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg);
|
||||||
*AliasSet; ++AliasSet) {
|
*AliasSet; ++AliasSet) {
|
||||||
|
if (PhysRegsUsed[*AliasSet] != -2) {
|
||||||
PhysRegsUseOrder.push_back(*AliasSet);
|
PhysRegsUseOrder.push_back(*AliasSet);
|
||||||
PhysRegsUsed[*AliasSet] = 0; // It is free and reserved now
|
PhysRegsUsed[*AliasSet] = 0; // It is free and reserved now
|
||||||
PhysRegsEverUsed[*AliasSet] = true;
|
PhysRegsEverUsed[*AliasSet] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Okay, we have allocated all of the source operands and spilled any values
|
// Okay, we have allocated all of the source operands and spilled any values
|
||||||
// that would be destroyed by defs of this instruction. Loop over the
|
// that would be destroyed by defs of this instruction. Loop over the
|
||||||
@ -675,7 +690,7 @@ void RA::AllocateBasicBlock(MachineBasicBlock &MBB) {
|
|||||||
|
|
||||||
// Spill all physical registers holding virtual registers now.
|
// Spill all physical registers holding virtual registers now.
|
||||||
for (unsigned i = 0, e = RegInfo->getNumRegs(); i != e; ++i)
|
for (unsigned i = 0, e = RegInfo->getNumRegs(); i != e; ++i)
|
||||||
if (PhysRegsUsed[i] != -1)
|
if (PhysRegsUsed[i] != -1 && PhysRegsUsed[i] != -2)
|
||||||
if (unsigned VirtReg = PhysRegsUsed[i])
|
if (unsigned VirtReg = PhysRegsUsed[i])
|
||||||
spillVirtReg(MBB, MI, VirtReg, i);
|
spillVirtReg(MBB, MI, VirtReg, i);
|
||||||
else
|
else
|
||||||
@ -715,6 +730,16 @@ bool RA::runOnMachineFunction(MachineFunction &Fn) {
|
|||||||
|
|
||||||
PhysRegsUsed.assign(RegInfo->getNumRegs(), -1);
|
PhysRegsUsed.assign(RegInfo->getNumRegs(), -1);
|
||||||
|
|
||||||
|
// At various places we want to efficiently check to see whether a register
|
||||||
|
// is allocatable. To handle this, we mark all unallocatable registers as
|
||||||
|
// being pinned down, permanently.
|
||||||
|
{
|
||||||
|
std::vector<bool> Allocable = RegInfo->getAllocatableSet(Fn);
|
||||||
|
for (unsigned i = 0, e = Allocable.size(); i != e; ++i)
|
||||||
|
if (!Allocable[i])
|
||||||
|
PhysRegsUsed[i] = -2; // Mark the reg unallocable.
|
||||||
|
}
|
||||||
|
|
||||||
// initialize the virtual->physical register map to have a 'null'
|
// initialize the virtual->physical register map to have a 'null'
|
||||||
// mapping for all virtual registers
|
// mapping for all virtual registers
|
||||||
Virt2PhysRegMap.grow(MF->getSSARegMap()->getLastVirtReg());
|
Virt2PhysRegMap.grow(MF->getSSARegMap()->getLastVirtReg());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user