mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-26 13:36:28 +00:00
In Thumb1, the register scavenger is not always able to use an emergency
spill slot. When frame references are via the frame pointer, they will be negative, but Thumb1 load/store instructions only allow positive immediate offsets. Instead, Thumb1 will spill to R12. llvm-svn: 83336
This commit is contained in:
parent
72c458d8a6
commit
d6da133b85
@ -635,6 +635,24 @@ public:
|
||||
virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
|
||||
}
|
||||
|
||||
/// saveScavengerRegister - Save the register so it can be used by the
|
||||
/// register scavenger. Return true if the register was saved, false
|
||||
/// otherwise. If this function does not save the register, the scavenger
|
||||
/// will instead spill it to the emergency spill slot.
|
||||
///
|
||||
virtual bool saveScavengerRegister(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I,
|
||||
const TargetRegisterClass *RC,
|
||||
unsigned Reg) const {return false;}
|
||||
|
||||
/// restoreScavengerRegister - Restore a register saved by
|
||||
/// saveScavengerRegister().
|
||||
///
|
||||
virtual void restoreScavengerRegister(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I,
|
||||
const TargetRegisterClass *RC,
|
||||
unsigned Reg) const {}
|
||||
|
||||
/// eliminateFrameIndex - This method must be overriden to eliminate abstract
|
||||
/// frame indices from instructions which may use them. The instruction
|
||||
/// referenced by the iterator contains an MO_FrameIndex operand which must be
|
||||
|
@ -268,9 +268,6 @@ unsigned RegScavenger::findSurvivorReg(MachineBasicBlock::iterator MI,
|
||||
unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC,
|
||||
MachineBasicBlock::iterator I,
|
||||
int SPAdj) {
|
||||
assert(ScavengingFrameIndex >= 0 &&
|
||||
"Cannot scavenge a register without an emergency spill slot!");
|
||||
|
||||
// Mask off the registers which are not in the TargetRegisterClass.
|
||||
BitVector Candidates(NumPhysRegs, false);
|
||||
CreateRegClassMask(RC, Candidates);
|
||||
@ -301,14 +298,23 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC,
|
||||
// Avoid infinite regress
|
||||
ScavengedReg = SReg;
|
||||
|
||||
// Spill the scavenged register before I.
|
||||
TII->storeRegToStackSlot(*MBB, I, SReg, true, ScavengingFrameIndex, RC);
|
||||
MachineBasicBlock::iterator II = prior(I);
|
||||
TRI->eliminateFrameIndex(II, SPAdj, this);
|
||||
// If the target knows how to save/restore the register, let it do so;
|
||||
// otherwise, use the emergency stack spill slot.
|
||||
if (!TRI->saveScavengerRegister(*MBB, I, RC, SReg)) {
|
||||
// Spill the scavenged register before I.
|
||||
assert(ScavengingFrameIndex >= 0 &&
|
||||
"Cannot scavenging register without an emergency spill slot!");
|
||||
TII->storeRegToStackSlot(*MBB, I, SReg, true, ScavengingFrameIndex, RC);
|
||||
MachineBasicBlock::iterator II = prior(I);
|
||||
TRI->eliminateFrameIndex(II, SPAdj, this);
|
||||
|
||||
// Restore the scavenged register before its use (or first terminator).
|
||||
TII->loadRegFromStackSlot(*MBB, UseMI, SReg, ScavengingFrameIndex, RC);
|
||||
} else
|
||||
TRI->restoreScavengerRegister(*MBB, UseMI, RC, SReg);
|
||||
|
||||
// Restore the scavenged register before its use (or first terminator).
|
||||
TII->loadRegFromStackSlot(*MBB, UseMI, SReg, ScavengingFrameIndex, RC);
|
||||
ScavengeRestore = prior(UseMI);
|
||||
|
||||
// Doing this here leads to infinite regress.
|
||||
// ScavengedReg = SReg;
|
||||
ScavengedRC = RC;
|
||||
|
@ -660,8 +660,7 @@ ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
||||
// off the frame pointer, the effective stack size is 4 bytes larger
|
||||
// since the FP points to the stack slot of the previous FP.
|
||||
if (estimateStackSize(MF, MFI) + (hasFP(MF) ? 4 : 0)
|
||||
>= estimateRSStackSizeLimit(MF)
|
||||
|| AFI->isThumb1OnlyFunction()) {
|
||||
>= estimateRSStackSizeLimit(MF)) {
|
||||
// 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;
|
||||
@ -690,7 +689,8 @@ ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
||||
MF.getRegInfo().setPhysRegUsed(Extras[i]);
|
||||
AFI->setCSRegisterIsSpilled(Extras[i]);
|
||||
}
|
||||
} else {
|
||||
} else if (!AFI->isThumb1OnlyFunction()) {
|
||||
// note: Thumb1 functions spill to R12, not the stack.
|
||||
// Reserve a slot closest to SP or frame pointer.
|
||||
const TargetRegisterClass *RC = ARM::GPRRegisterClass;
|
||||
RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
|
||||
|
@ -402,6 +402,31 @@ rewriteFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// saveScavengerRegister - Save the register so it can be used by the
|
||||
/// register scavenger. Return true.
|
||||
bool Thumb1RegisterInfo::saveScavengerRegister(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I,
|
||||
const TargetRegisterClass *RC,
|
||||
unsigned Reg) const {
|
||||
// Thumb1 can't use the emergency spill slot on the stack because
|
||||
// ldr/str immediate offsets must be positive, and if we're referencing
|
||||
// off the frame pointer (if, for example, there are alloca() calls in
|
||||
// the function, the offset will be negative. Use R12 instead since that's
|
||||
// a call clobbered register that we know won't be used in Thumb1 mode.
|
||||
|
||||
TII.copyRegToReg(MBB, I, ARM::R12, Reg, ARM::GPRRegisterClass, RC);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// restoreScavengerRegister - restore a registers saved by
|
||||
// saveScavengerRegister().
|
||||
void Thumb1RegisterInfo::restoreScavengerRegister(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I,
|
||||
const TargetRegisterClass *RC,
|
||||
unsigned Reg) const {
|
||||
TII.copyRegToReg(MBB, I, Reg, ARM::R12, RC, ARM::GPRRegisterClass);
|
||||
}
|
||||
|
||||
void Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
||||
int SPAdj, RegScavenger *RS) const{
|
||||
unsigned i = 0;
|
||||
|
@ -54,6 +54,14 @@ public:
|
||||
unsigned FrameReg, int Offset,
|
||||
unsigned MOVOpc, unsigned ADDriOpc, unsigned SUBriOpc) const;
|
||||
|
||||
bool saveScavengerRegister(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I,
|
||||
const TargetRegisterClass *RC,
|
||||
unsigned Reg) const;
|
||||
void restoreScavengerRegister(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I,
|
||||
const TargetRegisterClass *RC,
|
||||
unsigned Reg) const;
|
||||
void eliminateFrameIndex(MachineBasicBlock::iterator II,
|
||||
int SPAdj, RegScavenger *RS = NULL) const;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user