mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-21 11:38:28 +00:00
Scavenge a register using the register scavenger when needed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34966 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
87f8bf65dd
commit
140e33cfd1
@ -85,11 +85,6 @@ ARMRegisterInfo::ARMRegisterInfo(const TargetInstrInfo &tii,
|
||||
: ARMGenRegisterInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP),
|
||||
TII(tii), STI(sti),
|
||||
FramePtr(STI.useThumbBacktraces() ? ARM::R7 : ARM::R11) {
|
||||
RS = (EnableScavenging) ? new RegScavenger() : NULL;
|
||||
}
|
||||
|
||||
ARMRegisterInfo::~ARMRegisterInfo() {
|
||||
delete RS;
|
||||
}
|
||||
|
||||
bool ARMRegisterInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||
@ -328,6 +323,25 @@ BitVector ARMRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
|
||||
return Reserved;
|
||||
}
|
||||
|
||||
bool
|
||||
ARMRegisterInfo::isReservedReg(const MachineFunction &MF, unsigned Reg) const {
|
||||
switch (Reg) {
|
||||
default: break;
|
||||
case ARM::SP:
|
||||
case ARM::PC:
|
||||
return true;
|
||||
case ARM::R7:
|
||||
case ARM::R11:
|
||||
if (FramePtr == Reg && (STI.isTargetDarwin() || hasFP(MF)))
|
||||
return true;
|
||||
break;
|
||||
case ARM::R9:
|
||||
return STI.isR9Reserved();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ARMRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const {
|
||||
const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
|
||||
@ -918,15 +932,34 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
||||
// to form it with a series of ADDri's. Do this by taking 8-bit chunks
|
||||
// out of 'Offset'.
|
||||
unsigned ScratchReg = findScratchRegister(RS, &ARM::GPRRegClass, AFI);
|
||||
assert(ScratchReg && "Unable to find a free register!");
|
||||
if (ScratchReg == 0)
|
||||
// No register is "free". Scavenge a register.
|
||||
ScratchReg = RS->scavengeRegister(&ARM::GPRRegClass, II);
|
||||
emitARMRegPlusImmediate(MBB, II, ScratchReg, FrameReg,
|
||||
isSub ? -Offset : Offset, TII);
|
||||
MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
void ARMRegisterInfo::
|
||||
processFunctionBeforeCalleeSavedScan(MachineFunction &MF) const {
|
||||
static unsigned estimateStackSize(MachineFunction &MF, MachineFrameInfo *MFI) {
|
||||
const MachineFrameInfo *FFI = MF.getFrameInfo();
|
||||
int Offset = 0;
|
||||
for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) {
|
||||
int FixedOff = -FFI->getObjectOffset(i);
|
||||
if (FixedOff > Offset) Offset = FixedOff;
|
||||
}
|
||||
for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) {
|
||||
Offset += FFI->getObjectSize(i);
|
||||
unsigned Align = FFI->getObjectAlignment(i);
|
||||
// Adjust to alignment boundary
|
||||
Offset = (Offset+Align-1)/Align*Align;
|
||||
}
|
||||
return (unsigned)Offset;
|
||||
}
|
||||
|
||||
void
|
||||
ARMRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
||||
RegScavenger *RS) const {
|
||||
// This tells PEI to spill the FP as if it is any other callee-save register
|
||||
// to take advantage the eliminateFrameIndex machinery. This also ensures it
|
||||
// is spilled in the order specified by getCalleeSavedRegs() to make it easier
|
||||
@ -1020,6 +1053,7 @@ processFunctionBeforeCalleeSavedScan(MachineFunction &MF) const {
|
||||
}
|
||||
}
|
||||
|
||||
bool ExtraCSSpill = false;
|
||||
if (!CanEliminateFrame || hasFP(MF)) {
|
||||
AFI->setHasStackFrame(true);
|
||||
|
||||
@ -1032,6 +1066,7 @@ processFunctionBeforeCalleeSavedScan(MachineFunction &MF) const {
|
||||
UnspilledCS1GPRs.erase(std::find(UnspilledCS1GPRs.begin(),
|
||||
UnspilledCS1GPRs.end(), (unsigned)ARM::LR));
|
||||
ForceLRSpill = false;
|
||||
ExtraCSSpill = true;
|
||||
}
|
||||
|
||||
// Darwin ABI requires FP to point to the stack slot that contains the
|
||||
@ -1050,10 +1085,74 @@ processFunctionBeforeCalleeSavedScan(MachineFunction &MF) const {
|
||||
unsigned Reg = UnspilledCS1GPRs.front();
|
||||
MF.changePhyRegUsed(Reg, true);
|
||||
AFI->setCSRegisterIsSpilled(Reg);
|
||||
if (!isReservedReg(MF, Reg))
|
||||
ExtraCSSpill = true;
|
||||
} else if (!UnspilledCS2GPRs.empty()) {
|
||||
unsigned Reg = UnspilledCS2GPRs.front();
|
||||
MF.changePhyRegUsed(Reg, true);
|
||||
AFI->setCSRegisterIsSpilled(Reg);
|
||||
if (!isReservedReg(MF, Reg))
|
||||
ExtraCSSpill = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Estimate if we might need to scavenge a register at some point in order
|
||||
// to materialize a stack offset. If so, either spill one additiona
|
||||
// callee-saved register or reserve a special spill slot to facilitate
|
||||
// register scavenging.
|
||||
if (RS && !ExtraCSSpill && !AFI->isThumbFunction()) {
|
||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
unsigned Size = estimateStackSize(MF, MFI);
|
||||
unsigned Limit = (1 << 12) - 1;
|
||||
for (MachineFunction::iterator BB = MF.begin(),E = MF.end();BB != E; ++BB)
|
||||
for (MachineBasicBlock::iterator I= BB->begin(); I != BB->end(); ++I) {
|
||||
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
|
||||
if (I->getOperand(i).isFrameIndex()) {
|
||||
unsigned Opcode = I->getOpcode();
|
||||
const TargetInstrDescriptor &Desc = TII.get(Opcode);
|
||||
unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
|
||||
if (AddrMode == ARMII::AddrMode3) {
|
||||
Limit = (1 << 8) - 1;
|
||||
goto DoneEstimating;
|
||||
} else if (AddrMode == ARMII::AddrMode5) {
|
||||
Limit = ((1 << 8) - 1) * 4;
|
||||
goto DoneEstimating;
|
||||
}
|
||||
}
|
||||
}
|
||||
DoneEstimating:
|
||||
if (Size >= Limit) {
|
||||
// If any non-reserved CS register isn't spilled, just spill one or two
|
||||
// extra. That should take care of it!
|
||||
unsigned NumExtras = TargetAlign / 4;
|
||||
SmallVector<unsigned, 2> Extras;
|
||||
while (NumExtras && !UnspilledCS1GPRs.empty()) {
|
||||
unsigned Reg = UnspilledCS1GPRs.back();
|
||||
UnspilledCS1GPRs.pop_back();
|
||||
if (!isReservedReg(MF, Reg)) {
|
||||
Extras.push_back(Reg);
|
||||
NumExtras--;
|
||||
}
|
||||
}
|
||||
while (NumExtras && !UnspilledCS2GPRs.empty()) {
|
||||
unsigned Reg = UnspilledCS2GPRs.back();
|
||||
UnspilledCS2GPRs.pop_back();
|
||||
if (!isReservedReg(MF, Reg)) {
|
||||
Extras.push_back(Reg);
|
||||
NumExtras--;
|
||||
}
|
||||
}
|
||||
if (Extras.size() && NumExtras == 0) {
|
||||
for (unsigned i = 0, e = Extras.size(); i != e; ++i) {
|
||||
MF.changePhyRegUsed(Extras[i], true);
|
||||
AFI->setCSRegisterIsSpilled(Extras[i]);
|
||||
}
|
||||
} else {
|
||||
// Reserve a slot closest to SP or frame pointer.
|
||||
const TargetRegisterClass *RC = &ARM::GPRRegClass;
|
||||
RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
|
||||
RC->getAlignment()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,17 +27,12 @@ struct ARMRegisterInfo : public ARMGenRegisterInfo {
|
||||
const TargetInstrInfo &TII;
|
||||
const ARMSubtarget &STI;
|
||||
private:
|
||||
/// RS - An instance of the register scavenger.
|
||||
RegScavenger *RS;
|
||||
|
||||
/// FramePtr - ARM physical register used as frame ptr.
|
||||
unsigned FramePtr;
|
||||
|
||||
public:
|
||||
ARMRegisterInfo(const TargetInstrInfo &tii, const ARMSubtarget &STI);
|
||||
|
||||
~ARMRegisterInfo();
|
||||
|
||||
/// getRegisterNumbering - Given the enum value for some register, e.g.
|
||||
/// ARM::LR, return the number that it corresponds to (e.g. 14).
|
||||
static unsigned getRegisterNumbering(unsigned RegEnum);
|
||||
@ -74,6 +69,8 @@ public:
|
||||
|
||||
BitVector getReservedRegs(const MachineFunction &MF) const;
|
||||
|
||||
bool isReservedReg(const MachineFunction &MF, unsigned Reg) const;
|
||||
|
||||
bool requiresRegisterScavenging(const MachineFunction &MF) const;
|
||||
|
||||
bool hasFP(const MachineFunction &MF) const;
|
||||
@ -85,7 +82,8 @@ public:
|
||||
void eliminateFrameIndex(MachineBasicBlock::iterator II,
|
||||
RegScavenger *RS = NULL) const;
|
||||
|
||||
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF) const;
|
||||
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
||||
RegScavenger *RS = NULL) const;
|
||||
|
||||
void emitPrologue(MachineFunction &MF) const;
|
||||
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
|
||||
|
Loading…
Reference in New Issue
Block a user