mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-13 09:33:50 +00:00
Keep track of the last place a live virtreg was used.
This allows us to add accurate kill markers, something the scavenger likes. Add some more tests from ARM that needed this. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103521 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9d7019f586
commit
76b4d5a021
@ -56,9 +56,22 @@ namespace {
|
|||||||
// values are spilled.
|
// values are spilled.
|
||||||
IndexedMap<int, VirtReg2IndexFunctor> StackSlotForVirtReg;
|
IndexedMap<int, VirtReg2IndexFunctor> StackSlotForVirtReg;
|
||||||
|
|
||||||
// Virt2PhysMap - This map contains entries for each virtual register
|
// Everything we know about a live virtual register.
|
||||||
|
struct LiveReg {
|
||||||
|
MachineInstr *LastUse; // Last instr to use reg.
|
||||||
|
unsigned PhysReg; // Currently held here.
|
||||||
|
unsigned LastOpNum; // OpNum on LastUse.
|
||||||
|
|
||||||
|
LiveReg(unsigned p=0) : LastUse(0), PhysReg(p), LastOpNum(0) {
|
||||||
|
assert(p && "Don't create LiveRegs without a PhysReg");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef DenseMap<unsigned, LiveReg> LiveRegMap;
|
||||||
|
|
||||||
|
// LiveVirtRegs - This map contains entries for each virtual register
|
||||||
// that is currently available in a physical register.
|
// that is currently available in a physical register.
|
||||||
DenseMap<unsigned, unsigned> Virt2PhysMap;
|
LiveRegMap LiveVirtRegs;
|
||||||
|
|
||||||
// RegState - Track the state of a physical register.
|
// RegState - Track the state of a physical register.
|
||||||
enum RegState {
|
enum RegState {
|
||||||
@ -77,7 +90,7 @@ namespace {
|
|||||||
|
|
||||||
// A register state may also be a virtual register number, indication that
|
// A register state may also be a virtual register number, indication that
|
||||||
// the physical register is currently allocated to a virtual register. In
|
// the physical register is currently allocated to a virtual register. In
|
||||||
// that case, Virt2PhysMap contains the inverse mapping.
|
// that case, LiveVirtRegs contains the inverse mapping.
|
||||||
};
|
};
|
||||||
|
|
||||||
// PhysRegState - One of the RegState enums, or a virtreg.
|
// PhysRegState - One of the RegState enums, or a virtreg.
|
||||||
@ -112,18 +125,20 @@ namespace {
|
|||||||
void AllocateBasicBlock(MachineBasicBlock &MBB);
|
void AllocateBasicBlock(MachineBasicBlock &MBB);
|
||||||
int getStackSpaceFor(unsigned VirtReg, const TargetRegisterClass *RC);
|
int getStackSpaceFor(unsigned VirtReg, const TargetRegisterClass *RC);
|
||||||
void killVirtReg(unsigned VirtReg);
|
void killVirtReg(unsigned VirtReg);
|
||||||
|
void killVirtReg(LiveRegMap::iterator i);
|
||||||
void spillVirtReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
|
void spillVirtReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
|
||||||
unsigned VirtReg, bool isKill);
|
unsigned VirtReg, bool isKill);
|
||||||
void killPhysReg(unsigned PhysReg);
|
void killPhysReg(unsigned PhysReg);
|
||||||
void spillPhysReg(MachineBasicBlock &MBB, MachineInstr *I,
|
void spillPhysReg(MachineBasicBlock &MBB, MachineInstr *I,
|
||||||
unsigned PhysReg, bool isKill);
|
unsigned PhysReg, bool isKill);
|
||||||
void assignVirtToPhysReg(unsigned VirtReg, unsigned PhysReg);
|
LiveRegMap::iterator assignVirtToPhysReg(unsigned VirtReg,
|
||||||
unsigned allocVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
|
unsigned PhysReg);
|
||||||
unsigned VirtReg);
|
LiveRegMap::iterator allocVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
|
||||||
|
unsigned VirtReg);
|
||||||
unsigned defineVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
|
unsigned defineVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
|
||||||
unsigned VirtReg);
|
unsigned OpNum, unsigned VirtReg);
|
||||||
unsigned reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
|
unsigned reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
|
||||||
unsigned VirtReg);
|
unsigned OpNum, unsigned VirtReg);
|
||||||
void reservePhysReg(MachineBasicBlock &MBB, MachineInstr *MI,
|
void reservePhysReg(MachineBasicBlock &MBB, MachineInstr *MI,
|
||||||
unsigned PhysReg);
|
unsigned PhysReg);
|
||||||
void spillAll(MachineBasicBlock &MBB, MachineInstr *MI);
|
void spillAll(MachineBasicBlock &MBB, MachineInstr *MI);
|
||||||
@ -149,55 +164,79 @@ int RAFast::getStackSpaceFor(unsigned VirtReg, const TargetRegisterClass *RC) {
|
|||||||
return FrameIdx;
|
return FrameIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// killVirtReg - Mark virtreg as no longer available.
|
||||||
|
void RAFast::killVirtReg(LiveRegMap::iterator i) {
|
||||||
|
assert(i != LiveVirtRegs.end() && "Killing unmapped virtual register");
|
||||||
|
unsigned VirtReg = i->first;
|
||||||
|
const LiveReg &LR = i->second;
|
||||||
|
assert(PhysRegState[LR.PhysReg] == VirtReg && "Broken RegState mapping");
|
||||||
|
PhysRegState[LR.PhysReg] = regFree;
|
||||||
|
if (LR.LastUse) {
|
||||||
|
MachineOperand &MO = LR.LastUse->getOperand(LR.LastOpNum);
|
||||||
|
if (MO.isUse()) MO.setIsKill();
|
||||||
|
else MO.setIsDead();
|
||||||
|
DEBUG(dbgs() << " - last seen here: " << *LR.LastUse);
|
||||||
|
}
|
||||||
|
LiveVirtRegs.erase(i);
|
||||||
|
}
|
||||||
|
|
||||||
/// killVirtReg - Mark virtreg as no longer available.
|
/// killVirtReg - Mark virtreg as no longer available.
|
||||||
void RAFast::killVirtReg(unsigned VirtReg) {
|
void RAFast::killVirtReg(unsigned VirtReg) {
|
||||||
assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
|
assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
|
||||||
"killVirtReg needs a virtual register");
|
"killVirtReg needs a virtual register");
|
||||||
DEBUG(dbgs() << " Killing %reg" << VirtReg << "\n");
|
DEBUG(dbgs() << " Killing %reg" << VirtReg << "\n");
|
||||||
DenseMap<unsigned,unsigned>::iterator i = Virt2PhysMap.find(VirtReg);
|
LiveRegMap::iterator i = LiveVirtRegs.find(VirtReg);
|
||||||
if (i == Virt2PhysMap.end()) return;
|
if (i != LiveVirtRegs.end())
|
||||||
unsigned PhysReg = i->second;
|
killVirtReg(i);
|
||||||
assert(PhysRegState[PhysReg] == VirtReg && "Broken RegState mapping");
|
|
||||||
PhysRegState[PhysReg] = regFree;
|
|
||||||
Virt2PhysMap.erase(i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// spillVirtReg - This method spills the value specified by VirtReg into the
|
/// spillVirtReg - This method spills the value specified by VirtReg into the
|
||||||
/// corresponding stack slot if needed. If isKill is set, the register is also
|
/// corresponding stack slot if needed. If isKill is set, the register is also
|
||||||
/// killed.
|
/// killed.
|
||||||
void RAFast::spillVirtReg(MachineBasicBlock &MBB,
|
void RAFast::spillVirtReg(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator I,
|
MachineBasicBlock::iterator MI,
|
||||||
unsigned VirtReg, bool isKill) {
|
unsigned VirtReg, bool isKill) {
|
||||||
assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
|
assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
|
||||||
"Spilling a physical register is illegal!");
|
"Spilling a physical register is illegal!");
|
||||||
DenseMap<unsigned,unsigned>::iterator i = Virt2PhysMap.find(VirtReg);
|
LiveRegMap::iterator i = LiveVirtRegs.find(VirtReg);
|
||||||
assert(i != Virt2PhysMap.end() && "Spilling unmapped virtual register");
|
assert(i != LiveVirtRegs.end() && "Spilling unmapped virtual register");
|
||||||
unsigned PhysReg = i->second;
|
const LiveReg &LR = i->second;
|
||||||
assert(PhysRegState[PhysReg] == VirtReg && "Broken RegState mapping");
|
assert(PhysRegState[LR.PhysReg] == VirtReg && "Broken RegState mapping");
|
||||||
|
|
||||||
if (PhysRegDirty.test(PhysReg)) {
|
// If this physreg is used by the instruction, we want to kill it on the
|
||||||
PhysRegDirty.reset(PhysReg);
|
// instruction, not on the spill.
|
||||||
DEBUG(dbgs() << " Spilling register " << TRI->getName(PhysReg)
|
bool spillKill = isKill && LR.LastUse != MI;
|
||||||
|
|
||||||
|
if (PhysRegDirty.test(LR.PhysReg)) {
|
||||||
|
PhysRegDirty.reset(LR.PhysReg);
|
||||||
|
DEBUG(dbgs() << " Spilling register " << TRI->getName(LR.PhysReg)
|
||||||
<< " containing %reg" << VirtReg);
|
<< " containing %reg" << VirtReg);
|
||||||
const TargetRegisterClass *RC = MF->getRegInfo().getRegClass(VirtReg);
|
const TargetRegisterClass *RC = MF->getRegInfo().getRegClass(VirtReg);
|
||||||
int FrameIndex = getStackSpaceFor(VirtReg, RC);
|
int FrameIndex = getStackSpaceFor(VirtReg, RC);
|
||||||
DEBUG(dbgs() << " to stack slot #" << FrameIndex << "\n");
|
DEBUG(dbgs() << " to stack slot #" << FrameIndex << "\n");
|
||||||
TII->storeRegToStackSlot(MBB, I, PhysReg, isKill, FrameIndex, RC, TRI);
|
TII->storeRegToStackSlot(MBB, MI, LR.PhysReg, spillKill,
|
||||||
|
FrameIndex, RC, TRI);
|
||||||
++NumStores; // Update statistics
|
++NumStores; // Update statistics
|
||||||
|
|
||||||
|
if (spillKill)
|
||||||
|
i->second.LastUse = 0; // Don't kill register again
|
||||||
|
else if (!isKill) {
|
||||||
|
MachineInstr *Spill = llvm::prior(MI);
|
||||||
|
i->second.LastUse = Spill;
|
||||||
|
i->second.LastOpNum = Spill->findRegisterUseOperandIdx(LR.PhysReg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isKill) {
|
if (isKill)
|
||||||
PhysRegState[PhysReg] = regFree;
|
killVirtReg(i);
|
||||||
Virt2PhysMap.erase(i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// spillAll - Spill all dirty virtregs without killing them.
|
/// spillAll - Spill all dirty virtregs without killing them.
|
||||||
void RAFast::spillAll(MachineBasicBlock &MBB, MachineInstr *MI) {
|
void RAFast::spillAll(MachineBasicBlock &MBB, MachineInstr *MI) {
|
||||||
SmallVector<unsigned, 16> Dirty;
|
SmallVector<unsigned, 16> Dirty;
|
||||||
for (DenseMap<unsigned,unsigned>::iterator i = Virt2PhysMap.begin(),
|
for (LiveRegMap::iterator i = LiveVirtRegs.begin(),
|
||||||
e = Virt2PhysMap.end(); i != e; ++i)
|
e = LiveVirtRegs.end(); i != e; ++i)
|
||||||
if (PhysRegDirty.test(i->second))
|
if (PhysRegDirty.test(i->second.PhysReg))
|
||||||
Dirty.push_back(i->first);
|
Dirty.push_back(i->first);
|
||||||
for (unsigned i = 0, e = Dirty.size(); i != e; ++i)
|
for (unsigned i = 0, e = Dirty.size(); i != e; ++i)
|
||||||
spillVirtReg(MBB, MI, Dirty[i], false);
|
spillVirtReg(MBB, MI, Dirty[i], false);
|
||||||
@ -276,16 +315,18 @@ void RAFast::spillPhysReg(MachineBasicBlock &MBB, MachineInstr *MI,
|
|||||||
/// that PhysReg is the proper container for VirtReg now. The physical
|
/// that PhysReg is the proper container for VirtReg now. The physical
|
||||||
/// register must not be used for anything else when this is called.
|
/// register must not be used for anything else when this is called.
|
||||||
///
|
///
|
||||||
void RAFast::assignVirtToPhysReg(unsigned VirtReg, unsigned PhysReg) {
|
RAFast::LiveRegMap::iterator
|
||||||
|
RAFast::assignVirtToPhysReg(unsigned VirtReg, unsigned PhysReg) {
|
||||||
DEBUG(dbgs() << " Assigning %reg" << VirtReg << " to "
|
DEBUG(dbgs() << " Assigning %reg" << VirtReg << " to "
|
||||||
<< TRI->getName(PhysReg) << "\n");
|
<< TRI->getName(PhysReg) << "\n");
|
||||||
Virt2PhysMap.insert(std::make_pair(VirtReg, PhysReg));
|
|
||||||
PhysRegState[PhysReg] = VirtReg;
|
PhysRegState[PhysReg] = VirtReg;
|
||||||
|
return LiveVirtRegs.insert(std::make_pair(VirtReg, PhysReg)).first;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// allocVirtReg - Allocate a physical register for VirtReg.
|
/// allocVirtReg - Allocate a physical register for VirtReg.
|
||||||
unsigned RAFast::allocVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
|
RAFast::LiveRegMap::iterator RAFast::allocVirtReg(MachineBasicBlock &MBB,
|
||||||
unsigned VirtReg) {
|
MachineInstr *MI,
|
||||||
|
unsigned VirtReg) {
|
||||||
const unsigned spillCost = 100;
|
const unsigned spillCost = 100;
|
||||||
assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
|
assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
|
||||||
"Can only allocate virtual registers");
|
"Can only allocate virtual registers");
|
||||||
@ -305,10 +346,8 @@ unsigned RAFast::allocVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
|
|||||||
case regReserved:
|
case regReserved:
|
||||||
continue;
|
continue;
|
||||||
case regFree:
|
case regFree:
|
||||||
if (!UsedInInstr.test(PhysReg)) {
|
if (!UsedInInstr.test(PhysReg))
|
||||||
assignVirtToPhysReg(VirtReg, PhysReg);
|
return assignVirtToPhysReg(VirtReg, PhysReg);
|
||||||
return PhysReg;
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
// Grab the first spillable register we meet.
|
// Grab the first spillable register we meet.
|
||||||
@ -387,8 +426,7 @@ unsigned RAFast::allocVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assignVirtToPhysReg(VirtReg, BestReg);
|
return assignVirtToPhysReg(VirtReg, BestReg);
|
||||||
return BestReg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nothing we can do.
|
// Nothing we can do.
|
||||||
@ -401,40 +439,44 @@ unsigned RAFast::allocVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
|
|||||||
MI->print(Msg, TM);
|
MI->print(Msg, TM);
|
||||||
}
|
}
|
||||||
report_fatal_error(Msg.str());
|
report_fatal_error(Msg.str());
|
||||||
return 0;
|
return LiveVirtRegs.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// defineVirtReg - Allocate a register for VirtReg and mark it as dirty.
|
/// defineVirtReg - Allocate a register for VirtReg and mark it as dirty.
|
||||||
unsigned RAFast::defineVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
|
unsigned RAFast::defineVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
|
||||||
unsigned VirtReg) {
|
unsigned OpNum, unsigned VirtReg) {
|
||||||
assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
|
assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
|
||||||
"Not a virtual register");
|
"Not a virtual register");
|
||||||
unsigned PhysReg = Virt2PhysMap.lookup(VirtReg);
|
LiveRegMap::iterator i = LiveVirtRegs.find(VirtReg);
|
||||||
if (!PhysReg)
|
if (i == LiveVirtRegs.end())
|
||||||
PhysReg = allocVirtReg(MBB, MI, VirtReg);
|
i = allocVirtReg(MBB, MI, VirtReg);
|
||||||
UsedInInstr.set(PhysReg);
|
i->second.LastUse = MI;
|
||||||
PhysRegDirty.set(PhysReg);
|
i->second.LastOpNum = OpNum;
|
||||||
return PhysReg;
|
UsedInInstr.set(i->second.PhysReg);
|
||||||
|
PhysRegDirty.set(i->second.PhysReg);
|
||||||
|
return i->second.PhysReg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// reloadVirtReg - Make sure VirtReg is available in a physreg and return it.
|
/// reloadVirtReg - Make sure VirtReg is available in a physreg and return it.
|
||||||
unsigned RAFast::reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
|
unsigned RAFast::reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
|
||||||
unsigned VirtReg) {
|
unsigned OpNum, unsigned VirtReg) {
|
||||||
assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
|
assert(TargetRegisterInfo::isVirtualRegister(VirtReg) &&
|
||||||
"Not a virtual register");
|
"Not a virtual register");
|
||||||
unsigned PhysReg = Virt2PhysMap.lookup(VirtReg);
|
LiveRegMap::iterator i = LiveVirtRegs.find(VirtReg);
|
||||||
if (!PhysReg) {
|
if (i == LiveVirtRegs.end()) {
|
||||||
PhysReg = allocVirtReg(MBB, MI, VirtReg);
|
i = allocVirtReg(MBB, MI, VirtReg);
|
||||||
PhysRegDirty.reset(PhysReg);
|
PhysRegDirty.reset(i->second.PhysReg);
|
||||||
const TargetRegisterClass *RC = MF->getRegInfo().getRegClass(VirtReg);
|
const TargetRegisterClass *RC = MF->getRegInfo().getRegClass(VirtReg);
|
||||||
int FrameIndex = getStackSpaceFor(VirtReg, RC);
|
int FrameIndex = getStackSpaceFor(VirtReg, RC);
|
||||||
DEBUG(dbgs() << " Reloading %reg" << VirtReg << " into "
|
DEBUG(dbgs() << " Reloading %reg" << VirtReg << " into "
|
||||||
<< TRI->getName(PhysReg) << "\n");
|
<< TRI->getName(i->second.PhysReg) << "\n");
|
||||||
TII->loadRegFromStackSlot(MBB, MI, PhysReg, FrameIndex, RC, TRI);
|
TII->loadRegFromStackSlot(MBB, MI, i->second.PhysReg, FrameIndex, RC, TRI);
|
||||||
++NumLoads;
|
++NumLoads;
|
||||||
}
|
}
|
||||||
UsedInInstr.set(PhysReg);
|
i->second.LastUse = MI;
|
||||||
return PhysReg;
|
i->second.LastOpNum = OpNum;
|
||||||
|
UsedInInstr.set(i->second.PhysReg);
|
||||||
|
return i->second.PhysReg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// reservePhysReg - Mark PhysReg as reserved. This is very similar to
|
/// reservePhysReg - Mark PhysReg as reserved. This is very similar to
|
||||||
@ -491,7 +533,7 @@ void RAFast::AllocateBasicBlock(MachineBasicBlock &MBB) {
|
|||||||
DEBUG(dbgs() << "\nBB#" << MBB.getNumber() << ", "<< MBB.getName() << "\n");
|
DEBUG(dbgs() << "\nBB#" << MBB.getNumber() << ", "<< MBB.getName() << "\n");
|
||||||
|
|
||||||
PhysRegState.assign(TRI->getNumRegs(), regDisabled);
|
PhysRegState.assign(TRI->getNumRegs(), regDisabled);
|
||||||
assert(Virt2PhysMap.empty() && "Mapping not cleared form last block?");
|
assert(LiveVirtRegs.empty() && "Mapping not cleared form last block?");
|
||||||
PhysRegDirty.reset();
|
PhysRegDirty.reset();
|
||||||
|
|
||||||
MachineBasicBlock::iterator MII = MBB.begin();
|
MachineBasicBlock::iterator MII = MBB.begin();
|
||||||
@ -522,20 +564,21 @@ void RAFast::AllocateBasicBlock(MachineBasicBlock &MBB) {
|
|||||||
dbgs() << "=%reg" << PhysRegState[Reg];
|
dbgs() << "=%reg" << PhysRegState[Reg];
|
||||||
if (PhysRegDirty.test(Reg))
|
if (PhysRegDirty.test(Reg))
|
||||||
dbgs() << "*";
|
dbgs() << "*";
|
||||||
assert(Virt2PhysMap.lookup(PhysRegState[Reg]) == Reg &&
|
assert(LiveVirtRegs[PhysRegState[Reg]].PhysReg == Reg &&
|
||||||
"Bad inverse map");
|
"Bad inverse map");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbgs() << '\n';
|
dbgs() << '\n';
|
||||||
// Check that Virt2PhysMap is the inverse.
|
// Check that LiveVirtRegs is the inverse.
|
||||||
for (DenseMap<unsigned,unsigned>::iterator i = Virt2PhysMap.begin(),
|
for (LiveRegMap::iterator i = LiveVirtRegs.begin(),
|
||||||
e = Virt2PhysMap.end(); i != e; ++i) {
|
e = LiveVirtRegs.end(); i != e; ++i) {
|
||||||
assert(TargetRegisterInfo::isVirtualRegister(i->first) &&
|
assert(TargetRegisterInfo::isVirtualRegister(i->first) &&
|
||||||
"Bad map key");
|
"Bad map key");
|
||||||
assert(TargetRegisterInfo::isPhysicalRegister(i->second) &&
|
assert(TargetRegisterInfo::isPhysicalRegister(i->second.PhysReg) &&
|
||||||
"Bad map value");
|
"Bad map value");
|
||||||
assert(PhysRegState[i->second] == i->first && "Bad inverse map");
|
assert(PhysRegState[i->second.PhysReg] == i->first &&
|
||||||
|
"Bad inverse map");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -546,8 +589,11 @@ void RAFast::AllocateBasicBlock(MachineBasicBlock &MBB) {
|
|||||||
if (!MO.isReg()) continue;
|
if (!MO.isReg()) continue;
|
||||||
unsigned Reg = MO.getReg();
|
unsigned Reg = MO.getReg();
|
||||||
if (!Reg || TargetRegisterInfo::isPhysicalRegister(Reg)) continue;
|
if (!Reg || TargetRegisterInfo::isPhysicalRegister(Reg)) continue;
|
||||||
// This may be 0 if the register is currently spilled. Tough.
|
LiveRegMap::iterator i = LiveVirtRegs.find(Reg);
|
||||||
setPhysReg(MO, Virt2PhysMap.lookup(Reg));
|
if (i != LiveVirtRegs.end())
|
||||||
|
setPhysReg(MO, i->second.PhysReg);
|
||||||
|
else
|
||||||
|
MO.setReg(0); // We can't allocate a physreg for a DebugValue, sorry!
|
||||||
}
|
}
|
||||||
// Next instruction.
|
// Next instruction.
|
||||||
continue;
|
continue;
|
||||||
@ -589,11 +635,11 @@ void RAFast::AllocateBasicBlock(MachineBasicBlock &MBB) {
|
|||||||
unsigned Reg = MO.getReg();
|
unsigned Reg = MO.getReg();
|
||||||
if (!Reg || TargetRegisterInfo::isPhysicalRegister(Reg)) continue;
|
if (!Reg || TargetRegisterInfo::isPhysicalRegister(Reg)) continue;
|
||||||
if (MO.isUse()) {
|
if (MO.isUse()) {
|
||||||
setPhysReg(MO, reloadVirtReg(MBB, MI, Reg));
|
setPhysReg(MO, reloadVirtReg(MBB, MI, i, Reg));
|
||||||
if (MO.isKill())
|
if (MO.isKill())
|
||||||
VirtKills.push_back(Reg);
|
VirtKills.push_back(Reg);
|
||||||
} else if (MO.isEarlyClobber()) {
|
} else if (MO.isEarlyClobber()) {
|
||||||
unsigned PhysReg = defineVirtReg(MBB, MI, Reg);
|
unsigned PhysReg = defineVirtReg(MBB, MI, i, Reg);
|
||||||
setPhysReg(MO, PhysReg);
|
setPhysReg(MO, PhysReg);
|
||||||
PhysDefs.push_back(PhysReg);
|
PhysDefs.push_back(PhysReg);
|
||||||
}
|
}
|
||||||
@ -640,7 +686,7 @@ void RAFast::AllocateBasicBlock(MachineBasicBlock &MBB) {
|
|||||||
}
|
}
|
||||||
if (MO.isDead())
|
if (MO.isDead())
|
||||||
VirtKills.push_back(Reg);
|
VirtKills.push_back(Reg);
|
||||||
setPhysReg(MO, defineVirtReg(MBB, MI, Reg));
|
setPhysReg(MO, defineVirtReg(MBB, MI, i, Reg));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spill all dirty virtregs before a call, in case of an exception.
|
// Spill all dirty virtregs before a call, in case of an exception.
|
||||||
@ -665,8 +711,8 @@ void RAFast::AllocateBasicBlock(MachineBasicBlock &MBB) {
|
|||||||
// Spill all physical registers holding virtual registers now.
|
// Spill all physical registers holding virtual registers now.
|
||||||
DEBUG(dbgs() << "Killing live registers at end of block.\n");
|
DEBUG(dbgs() << "Killing live registers at end of block.\n");
|
||||||
MachineBasicBlock::iterator MI = MBB.getFirstTerminator();
|
MachineBasicBlock::iterator MI = MBB.getFirstTerminator();
|
||||||
while (!Virt2PhysMap.empty())
|
while (!LiveVirtRegs.empty())
|
||||||
spillVirtReg(MBB, MI, Virt2PhysMap.begin()->first, true);
|
spillVirtReg(MBB, MI, LiveVirtRegs.begin()->first, true);
|
||||||
|
|
||||||
DEBUG(MBB.dump());
|
DEBUG(MBB.dump());
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
; RUN: llc < %s -mtriple=arm-linux-gnueabi -regalloc=local
|
; RUN: llc < %s -mtriple=arm-linux-gnueabi -regalloc=local
|
||||||
|
; RUN: llc < %s -mtriple=arm-linux-gnueabi -regalloc=fast
|
||||||
; PR1925
|
; PR1925
|
||||||
|
|
||||||
%struct.encode_aux_nearestmatch = type { i32*, i32*, i32*, i32*, i32, i32 }
|
%struct.encode_aux_nearestmatch = type { i32*, i32*, i32*, i32*, i32, i32 }
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
; RUN: llc < %s -mtriple=arm-apple-darwin -regalloc=local
|
; RUN: llc < %s -mtriple=arm-apple-darwin -regalloc=local
|
||||||
|
; RUN: llc < %s -mtriple=arm-apple-darwin -regalloc=fast
|
||||||
; PR1925
|
; PR1925
|
||||||
|
|
||||||
%"struct.kc::impl_Ccode_option" = type { %"struct.kc::impl_abstract_phylum" }
|
%"struct.kc::impl_Ccode_option" = type { %"struct.kc::impl_abstract_phylum" }
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
; RUN: llc < %s -mtriple=armv5-unknown-linux-gnueabi -O0 -regalloc=local
|
; RUN: llc < %s -mtriple=armv5-unknown-linux-gnueabi -O0 -regalloc=local
|
||||||
|
; RUN: llc < %s -mtriple=armv5-unknown-linux-gnueabi -O0 -regalloc=fast
|
||||||
; PR4100
|
; PR4100
|
||||||
@.str = external constant [30 x i8] ; <[30 x i8]*> [#uses=1]
|
@.str = external constant [30 x i8] ; <[30 x i8]*> [#uses=1]
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user