Move more PEI-related hooks to TFI

llvm-svn: 120229
This commit is contained in:
Anton Korobeynikov 2010-11-27 23:05:25 +00:00
parent d08fbd19f5
commit 7283b8d18c
31 changed files with 796 additions and 793 deletions

View File

@ -24,6 +24,7 @@ namespace llvm {
class MachineFunction;
class MachineBasicBlock;
class MachineMove;
class RegScavenger;
/// Information about stack frame layout on the target. It holds the direction
/// of stack growth, the known stack alignment on entry to each function, and
@ -172,6 +173,22 @@ public:
/// returned directly, and the base register is returned via FrameReg.
virtual int getFrameIndexReference(const MachineFunction &MF, int FI,
unsigned &FrameReg) const;
/// processFunctionBeforeCalleeSavedScan - This method is called immediately
/// before PrologEpilogInserter scans the physical registers used to determine
/// what callee saved registers should be spilled. This method is optional.
virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS = NULL) const {
}
/// processFunctionBeforeFrameFinalized - This method is called immediately
/// before the specified function's frame layout (MF.getFrameInfo()) is
/// finalized. Once the frame is finalized, MO_FrameIndex operands are
/// replaced with direct constants. This method is optional.
///
virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
}
};
} // End llvm namespace

View File

@ -678,21 +678,6 @@ public:
assert(0 && "Call Frame Pseudo Instructions do not exist on this target!");
}
/// processFunctionBeforeCalleeSavedScan - This method is called immediately
/// before PrologEpilogInserter scans the physical registers used to determine
/// what callee saved registers should be spilled. This method is optional.
virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS = NULL) const {
}
/// processFunctionBeforeFrameFinalized - This method is called immediately
/// before the specified function's frame layout (MF.getFrameInfo()) is
/// finalized. Once the frame is finalized, MO_FrameIndex operands are
/// replaced with direct constants. This method is optional.
///
virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
}
/// saveScavengerRegister - Spill the register so it can be used by the
/// register scavenger. Return true if the register was spilled, false

View File

@ -65,6 +65,8 @@ FunctionPass *llvm::createPrologEpilogCodeInserter() { return new PEI(); }
bool PEI::runOnMachineFunction(MachineFunction &Fn) {
const Function* F = Fn.getFunction();
const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo();
const TargetFrameInfo *TFI = Fn.getTarget().getFrameInfo();
RS = TRI->requiresRegisterScavenging(Fn) ? new RegScavenger() : NULL;
FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(Fn);
@ -75,7 +77,7 @@ bool PEI::runOnMachineFunction(MachineFunction &Fn) {
// Allow the target machine to make some adjustments to the function
// e.g. UsedPhysRegs before calculateCalleeSavedRegisters.
TRI->processFunctionBeforeCalleeSavedScan(Fn, RS);
TFI->processFunctionBeforeCalleeSavedScan(Fn, RS);
// Scan the function for modified callee saved registers and insert spill code
// for any callee saved registers that are modified.
@ -95,7 +97,7 @@ bool PEI::runOnMachineFunction(MachineFunction &Fn) {
// Allow the target machine to make final modifications to the function
// before the frame layout is finalized.
TRI->processFunctionBeforeFrameFinalized(Fn);
TFI->processFunctionBeforeFrameFinalized(Fn);
// Calculate actual frame offsets for all abstract stack objects...
calculateFrameObjectOffsets(Fn);

View File

@ -591,328 +591,6 @@ cannotEliminateFrame(const MachineFunction &MF) const {
|| needsStackRealignment(MF);
}
/// estimateStackSize - Estimate and return the size of the frame.
static unsigned estimateStackSize(MachineFunction &MF) {
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) {
if (FFI->isDeadObjectIndex(i))
continue;
Offset += FFI->getObjectSize(i);
unsigned Align = FFI->getObjectAlignment(i);
// Adjust to alignment boundary
Offset = (Offset+Align-1)/Align*Align;
}
return (unsigned)Offset;
}
/// estimateRSStackSizeLimit - Look at each instruction that references stack
/// frames and return the stack size limit beyond which some of these
/// instructions will require a scratch register during their expansion later.
unsigned
ARMBaseRegisterInfo::estimateRSStackSizeLimit(MachineFunction &MF) const {
const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo();
const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
unsigned Limit = (1 << 12) - 1;
for (MachineFunction::iterator BB = MF.begin(),E = MF.end(); BB != E; ++BB) {
for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end();
I != E; ++I) {
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
if (!I->getOperand(i).isFI()) continue;
// When using ADDri to get the address of a stack object, 255 is the
// largest offset guaranteed to fit in the immediate offset.
if (I->getOpcode() == ARM::ADDri) {
Limit = std::min(Limit, (1U << 8) - 1);
break;
}
// Otherwise check the addressing mode.
switch (I->getDesc().TSFlags & ARMII::AddrModeMask) {
case ARMII::AddrMode3:
case ARMII::AddrModeT2_i8:
Limit = std::min(Limit, (1U << 8) - 1);
break;
case ARMII::AddrMode5:
case ARMII::AddrModeT2_i8s4:
Limit = std::min(Limit, ((1U << 8) - 1) * 4);
break;
case ARMII::AddrModeT2_i12:
// i12 supports only positive offset so these will be converted to
// i8 opcodes. See llvm::rewriteT2FrameIndex.
if (TFI->hasFP(MF) && AFI->hasStackFrame())
Limit = std::min(Limit, (1U << 8) - 1);
break;
case ARMII::AddrMode4:
case ARMII::AddrMode6:
// Addressing modes 4 & 6 (load/store) instructions can't encode an
// immediate offset for stack references.
return 0;
default:
break;
}
break; // At most one FI per instruction
}
}
}
return Limit;
}
static unsigned GetFunctionSizeInBytes(const MachineFunction &MF,
const ARMBaseInstrInfo &TII) {
unsigned FnSize = 0;
for (MachineFunction::const_iterator MBBI = MF.begin(), E = MF.end();
MBBI != E; ++MBBI) {
const MachineBasicBlock &MBB = *MBBI;
for (MachineBasicBlock::const_iterator I = MBB.begin(),E = MBB.end();
I != E; ++I)
FnSize += TII.GetInstSizeInBytes(I);
}
return FnSize;
}
void
ARMBaseRegisterInfo::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
// to combine multiple loads / stores.
bool CanEliminateFrame = true;
bool CS1Spilled = false;
bool LRSpilled = false;
unsigned NumGPRSpills = 0;
SmallVector<unsigned, 4> UnspilledCS1GPRs;
SmallVector<unsigned, 4> UnspilledCS2GPRs;
const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo();
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
MachineFrameInfo *MFI = MF.getFrameInfo();
// Spill R4 if Thumb2 function requires stack realignment - it will be used as
// scratch register. Also spill R4 if Thumb2 function has varsized objects,
// since it's always posible to restore sp from fp in a single instruction.
// FIXME: It will be better just to find spare register here.
if (AFI->isThumb2Function() &&
(MFI->hasVarSizedObjects() || needsStackRealignment(MF)))
MF.getRegInfo().setPhysRegUsed(ARM::R4);
// Spill LR if Thumb1 function uses variable length argument lists.
if (AFI->isThumb1OnlyFunction() && AFI->getVarArgsRegSaveSize() > 0)
MF.getRegInfo().setPhysRegUsed(ARM::LR);
// Spill the BasePtr if it's used.
if (hasBasePointer(MF))
MF.getRegInfo().setPhysRegUsed(BasePtr);
// Don't spill FP if the frame can be eliminated. This is determined
// by scanning the callee-save registers to see if any is used.
const unsigned *CSRegs = getCalleeSavedRegs();
for (unsigned i = 0; CSRegs[i]; ++i) {
unsigned Reg = CSRegs[i];
bool Spilled = false;
if (MF.getRegInfo().isPhysRegUsed(Reg)) {
AFI->setCSRegisterIsSpilled(Reg);
Spilled = true;
CanEliminateFrame = false;
} else {
// Check alias registers too.
for (const unsigned *Aliases = getAliasSet(Reg); *Aliases; ++Aliases) {
if (MF.getRegInfo().isPhysRegUsed(*Aliases)) {
Spilled = true;
CanEliminateFrame = false;
}
}
}
if (!ARM::GPRRegisterClass->contains(Reg))
continue;
if (Spilled) {
NumGPRSpills++;
if (!STI.isTargetDarwin()) {
if (Reg == ARM::LR)
LRSpilled = true;
CS1Spilled = true;
continue;
}
// Keep track if LR and any of R4, R5, R6, and R7 is spilled.
switch (Reg) {
case ARM::LR:
LRSpilled = true;
// Fallthrough
case ARM::R4:
case ARM::R5:
case ARM::R6:
case ARM::R7:
CS1Spilled = true;
break;
default:
break;
}
} else {
if (!STI.isTargetDarwin()) {
UnspilledCS1GPRs.push_back(Reg);
continue;
}
switch (Reg) {
case ARM::R4:
case ARM::R5:
case ARM::R6:
case ARM::R7:
case ARM::LR:
UnspilledCS1GPRs.push_back(Reg);
break;
default:
UnspilledCS2GPRs.push_back(Reg);
break;
}
}
}
bool ForceLRSpill = false;
if (!LRSpilled && AFI->isThumb1OnlyFunction()) {
unsigned FnSize = GetFunctionSizeInBytes(MF, TII);
// Force LR to be spilled if the Thumb function size is > 2048. This enables
// use of BL to implement far jump. If it turns out that it's not needed
// then the branch fix up path will undo it.
if (FnSize >= (1 << 11)) {
CanEliminateFrame = false;
ForceLRSpill = true;
}
}
// If any of the stack slot references may be out of range of an immediate
// offset, make sure a register (or a spill slot) is available for the
// register scavenger. Note that if we're indexing off the frame pointer, the
// effective stack size is 4 bytes larger since the FP points to the stack
// slot of the previous FP. Also, if we have variable sized objects in the
// function, stack slot references will often be negative, and some of
// our instructions are positive-offset only, so conservatively consider
// that case to want a spill slot (or register) as well. Similarly, if
// the function adjusts the stack pointer during execution and the
// adjustments aren't already part of our stack size estimate, our offset
// calculations may be off, so be conservative.
// FIXME: We could add logic to be more precise about negative offsets
// and which instructions will need a scratch register for them. Is it
// worth the effort and added fragility?
bool BigStack =
(RS &&
(estimateStackSize(MF) + ((TFI->hasFP(MF) && AFI->hasStackFrame()) ? 4:0) >=
estimateRSStackSizeLimit(MF)))
|| MFI->hasVarSizedObjects()
|| (MFI->adjustsStack() && !TFI->canSimplifyCallFramePseudos(MF));
bool ExtraCSSpill = false;
if (BigStack || !CanEliminateFrame || cannotEliminateFrame(MF)) {
AFI->setHasStackFrame(true);
// If LR is not spilled, but at least one of R4, R5, R6, and R7 is spilled.
// Spill LR as well so we can fold BX_RET to the registers restore (LDM).
if (!LRSpilled && CS1Spilled) {
MF.getRegInfo().setPhysRegUsed(ARM::LR);
AFI->setCSRegisterIsSpilled(ARM::LR);
NumGPRSpills++;
UnspilledCS1GPRs.erase(std::find(UnspilledCS1GPRs.begin(),
UnspilledCS1GPRs.end(), (unsigned)ARM::LR));
ForceLRSpill = false;
ExtraCSSpill = true;
}
if (TFI->hasFP(MF)) {
MF.getRegInfo().setPhysRegUsed(FramePtr);
NumGPRSpills++;
}
// If stack and double are 8-byte aligned and we are spilling an odd number
// of GPRs, spill one extra callee save GPR so we won't have to pad between
// the integer and double callee save areas.
unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
if (TargetAlign == 8 && (NumGPRSpills & 1)) {
if (CS1Spilled && !UnspilledCS1GPRs.empty()) {
for (unsigned i = 0, e = UnspilledCS1GPRs.size(); i != e; ++i) {
unsigned Reg = UnspilledCS1GPRs[i];
// Don't spill high register if the function is thumb1
if (!AFI->isThumb1OnlyFunction() ||
isARMLowRegister(Reg) || Reg == ARM::LR) {
MF.getRegInfo().setPhysRegUsed(Reg);
AFI->setCSRegisterIsSpilled(Reg);
if (!isReservedReg(MF, Reg))
ExtraCSSpill = true;
break;
}
}
} else if (!UnspilledCS2GPRs.empty() &&
!AFI->isThumb1OnlyFunction()) {
unsigned Reg = UnspilledCS2GPRs.front();
MF.getRegInfo().setPhysRegUsed(Reg);
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 additional
// callee-saved register or reserve a special spill slot to facilitate
// register scavenging. Thumb1 needs a spill slot for stack pointer
// adjustments also, even when the frame itself is small.
if (BigStack && !ExtraCSSpill) {
// 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) &&
(!AFI->isThumb1OnlyFunction() || isARMLowRegister(Reg) ||
Reg == ARM::LR)) {
Extras.push_back(Reg);
NumExtras--;
}
}
// For non-Thumb1 functions, also check for hi-reg CS registers
if (!AFI->isThumb1OnlyFunction()) {
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.getRegInfo().setPhysRegUsed(Extras[i]);
AFI->setCSRegisterIsSpilled(Extras[i]);
}
} 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(),
RC->getAlignment(),
false));
}
}
}
if (ForceLRSpill) {
MF.getRegInfo().setPhysRegUsed(ARM::LR);
AFI->setCSRegisterIsSpilled(ARM::LR);
AFI->setLRIsSpilledForFarJump(true);
}
}
unsigned ARMBaseRegisterInfo::getRARegister() const {
return ARM::LR;
}

View File

@ -154,9 +154,6 @@ public:
bool cannotEliminateFrame(const MachineFunction &MF) const;
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS = NULL) const;
// Debug information queries.
unsigned getRARegister() const;
unsigned getFrameRegister(const MachineFunction &MF) const;
@ -198,8 +195,6 @@ public:
int SPAdj, RegScavenger *RS = NULL) const;
private:
unsigned estimateRSStackSizeLimit(MachineFunction &MF) const;
unsigned getRegisterPairEven(unsigned Reg, const MachineFunction &MF) const;
unsigned getRegisterPairOdd(unsigned Reg, const MachineFunction &MF) const;

View File

@ -18,6 +18,7 @@
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/Target/TargetOptions.h"
using namespace llvm;
@ -614,3 +615,327 @@ bool ARMFrameInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
return true;
}
// FIXME: Make generic?
static unsigned GetFunctionSizeInBytes(const MachineFunction &MF,
const ARMBaseInstrInfo &TII) {
unsigned FnSize = 0;
for (MachineFunction::const_iterator MBBI = MF.begin(), E = MF.end();
MBBI != E; ++MBBI) {
const MachineBasicBlock &MBB = *MBBI;
for (MachineBasicBlock::const_iterator I = MBB.begin(),E = MBB.end();
I != E; ++I)
FnSize += TII.GetInstSizeInBytes(I);
}
return FnSize;
}
/// estimateStackSize - Estimate and return the size of the frame.
/// FIXME: Make generic?
static unsigned estimateStackSize(MachineFunction &MF) {
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) {
if (FFI->isDeadObjectIndex(i))
continue;
Offset += FFI->getObjectSize(i);
unsigned Align = FFI->getObjectAlignment(i);
// Adjust to alignment boundary
Offset = (Offset+Align-1)/Align*Align;
}
return (unsigned)Offset;
}
/// estimateRSStackSizeLimit - Look at each instruction that references stack
/// frames and return the stack size limit beyond which some of these
/// instructions will require a scratch register during their expansion later.
// FIXME: Move to TII?
static unsigned estimateRSStackSizeLimit(MachineFunction &MF,
const TargetFrameInfo *TFI) {
const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
unsigned Limit = (1 << 12) - 1;
for (MachineFunction::iterator BB = MF.begin(),E = MF.end(); BB != E; ++BB) {
for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end();
I != E; ++I) {
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
if (!I->getOperand(i).isFI()) continue;
// When using ADDri to get the address of a stack object, 255 is the
// largest offset guaranteed to fit in the immediate offset.
if (I->getOpcode() == ARM::ADDri) {
Limit = std::min(Limit, (1U << 8) - 1);
break;
}
// Otherwise check the addressing mode.
switch (I->getDesc().TSFlags & ARMII::AddrModeMask) {
case ARMII::AddrMode3:
case ARMII::AddrModeT2_i8:
Limit = std::min(Limit, (1U << 8) - 1);
break;
case ARMII::AddrMode5:
case ARMII::AddrModeT2_i8s4:
Limit = std::min(Limit, ((1U << 8) - 1) * 4);
break;
case ARMII::AddrModeT2_i12:
// i12 supports only positive offset so these will be converted to
// i8 opcodes. See llvm::rewriteT2FrameIndex.
if (TFI->hasFP(MF) && AFI->hasStackFrame())
Limit = std::min(Limit, (1U << 8) - 1);
break;
case ARMII::AddrMode4:
case ARMII::AddrMode6:
// Addressing modes 4 & 6 (load/store) instructions can't encode an
// immediate offset for stack references.
return 0;
default:
break;
}
break; // At most one FI per instruction
}
}
}
return Limit;
}
void
ARMFrameInfo::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
// to combine multiple loads / stores.
bool CanEliminateFrame = true;
bool CS1Spilled = false;
bool LRSpilled = false;
unsigned NumGPRSpills = 0;
SmallVector<unsigned, 4> UnspilledCS1GPRs;
SmallVector<unsigned, 4> UnspilledCS2GPRs;
const ARMBaseRegisterInfo *RegInfo =
static_cast<const ARMBaseRegisterInfo*>(MF.getTarget().getRegisterInfo());
const ARMBaseInstrInfo &TII =
*static_cast<const ARMBaseInstrInfo*>(MF.getTarget().getInstrInfo());
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
MachineFrameInfo *MFI = MF.getFrameInfo();
unsigned FramePtr = RegInfo->getFrameRegister(MF);
// Spill R4 if Thumb2 function requires stack realignment - it will be used as
// scratch register. Also spill R4 if Thumb2 function has varsized objects,
// since it's always posible to restore sp from fp in a single instruction.
// FIXME: It will be better just to find spare register here.
if (AFI->isThumb2Function() &&
(MFI->hasVarSizedObjects() || RegInfo->needsStackRealignment(MF)))
MF.getRegInfo().setPhysRegUsed(ARM::R4);
// Spill LR if Thumb1 function uses variable length argument lists.
if (AFI->isThumb1OnlyFunction() && AFI->getVarArgsRegSaveSize() > 0)
MF.getRegInfo().setPhysRegUsed(ARM::LR);
// Spill the BasePtr if it's used.
if (RegInfo->hasBasePointer(MF))
MF.getRegInfo().setPhysRegUsed(RegInfo->getBaseRegister());
// Don't spill FP if the frame can be eliminated. This is determined
// by scanning the callee-save registers to see if any is used.
const unsigned *CSRegs = RegInfo->getCalleeSavedRegs();
for (unsigned i = 0; CSRegs[i]; ++i) {
unsigned Reg = CSRegs[i];
bool Spilled = false;
if (MF.getRegInfo().isPhysRegUsed(Reg)) {
AFI->setCSRegisterIsSpilled(Reg);
Spilled = true;
CanEliminateFrame = false;
} else {
// Check alias registers too.
for (const unsigned *Aliases =
RegInfo->getAliasSet(Reg); *Aliases; ++Aliases) {
if (MF.getRegInfo().isPhysRegUsed(*Aliases)) {
Spilled = true;
CanEliminateFrame = false;
}
}
}
if (!ARM::GPRRegisterClass->contains(Reg))
continue;
if (Spilled) {
NumGPRSpills++;
if (!STI.isTargetDarwin()) {
if (Reg == ARM::LR)
LRSpilled = true;
CS1Spilled = true;
continue;
}
// Keep track if LR and any of R4, R5, R6, and R7 is spilled.
switch (Reg) {
case ARM::LR:
LRSpilled = true;
// Fallthrough
case ARM::R4: case ARM::R5:
case ARM::R6: case ARM::R7:
CS1Spilled = true;
break;
default:
break;
}
} else {
if (!STI.isTargetDarwin()) {
UnspilledCS1GPRs.push_back(Reg);
continue;
}
switch (Reg) {
case ARM::R4: case ARM::R5:
case ARM::R6: case ARM::R7:
case ARM::LR:
UnspilledCS1GPRs.push_back(Reg);
break;
default:
UnspilledCS2GPRs.push_back(Reg);
break;
}
}
}
bool ForceLRSpill = false;
if (!LRSpilled && AFI->isThumb1OnlyFunction()) {
unsigned FnSize = GetFunctionSizeInBytes(MF, TII);
// Force LR to be spilled if the Thumb function size is > 2048. This enables
// use of BL to implement far jump. If it turns out that it's not needed
// then the branch fix up path will undo it.
if (FnSize >= (1 << 11)) {
CanEliminateFrame = false;
ForceLRSpill = true;
}
}
// If any of the stack slot references may be out of range of an immediate
// offset, make sure a register (or a spill slot) is available for the
// register scavenger. Note that if we're indexing off the frame pointer, the
// effective stack size is 4 bytes larger since the FP points to the stack
// slot of the previous FP. Also, if we have variable sized objects in the
// function, stack slot references will often be negative, and some of
// our instructions are positive-offset only, so conservatively consider
// that case to want a spill slot (or register) as well. Similarly, if
// the function adjusts the stack pointer during execution and the
// adjustments aren't already part of our stack size estimate, our offset
// calculations may be off, so be conservative.
// FIXME: We could add logic to be more precise about negative offsets
// and which instructions will need a scratch register for them. Is it
// worth the effort and added fragility?
bool BigStack =
(RS &&
(estimateStackSize(MF) + ((hasFP(MF) && AFI->hasStackFrame()) ? 4:0) >=
estimateRSStackSizeLimit(MF, this)))
|| MFI->hasVarSizedObjects()
|| (MFI->adjustsStack() && !canSimplifyCallFramePseudos(MF));
bool ExtraCSSpill = false;
if (BigStack || !CanEliminateFrame || RegInfo->cannotEliminateFrame(MF)) {
AFI->setHasStackFrame(true);
// If LR is not spilled, but at least one of R4, R5, R6, and R7 is spilled.
// Spill LR as well so we can fold BX_RET to the registers restore (LDM).
if (!LRSpilled && CS1Spilled) {
MF.getRegInfo().setPhysRegUsed(ARM::LR);
AFI->setCSRegisterIsSpilled(ARM::LR);
NumGPRSpills++;
UnspilledCS1GPRs.erase(std::find(UnspilledCS1GPRs.begin(),
UnspilledCS1GPRs.end(), (unsigned)ARM::LR));
ForceLRSpill = false;
ExtraCSSpill = true;
}
if (hasFP(MF)) {
MF.getRegInfo().setPhysRegUsed(FramePtr);
NumGPRSpills++;
}
// If stack and double are 8-byte aligned and we are spilling an odd number
// of GPRs, spill one extra callee save GPR so we won't have to pad between
// the integer and double callee save areas.
unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
if (TargetAlign == 8 && (NumGPRSpills & 1)) {
if (CS1Spilled && !UnspilledCS1GPRs.empty()) {
for (unsigned i = 0, e = UnspilledCS1GPRs.size(); i != e; ++i) {
unsigned Reg = UnspilledCS1GPRs[i];
// Don't spill high register if the function is thumb1
if (!AFI->isThumb1OnlyFunction() ||
isARMLowRegister(Reg) || Reg == ARM::LR) {
MF.getRegInfo().setPhysRegUsed(Reg);
AFI->setCSRegisterIsSpilled(Reg);
if (!RegInfo->isReservedReg(MF, Reg))
ExtraCSSpill = true;
break;
}
}
} else if (!UnspilledCS2GPRs.empty() && !AFI->isThumb1OnlyFunction()) {
unsigned Reg = UnspilledCS2GPRs.front();
MF.getRegInfo().setPhysRegUsed(Reg);
AFI->setCSRegisterIsSpilled(Reg);
if (!RegInfo->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 additional
// callee-saved register or reserve a special spill slot to facilitate
// register scavenging. Thumb1 needs a spill slot for stack pointer
// adjustments also, even when the frame itself is small.
if (BigStack && !ExtraCSSpill) {
// 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 (!RegInfo->isReservedReg(MF, Reg) &&
(!AFI->isThumb1OnlyFunction() || isARMLowRegister(Reg) ||
Reg == ARM::LR)) {
Extras.push_back(Reg);
NumExtras--;
}
}
// For non-Thumb1 functions, also check for hi-reg CS registers
if (!AFI->isThumb1OnlyFunction()) {
while (NumExtras && !UnspilledCS2GPRs.empty()) {
unsigned Reg = UnspilledCS2GPRs.back();
UnspilledCS2GPRs.pop_back();
if (!RegInfo->isReservedReg(MF, Reg)) {
Extras.push_back(Reg);
NumExtras--;
}
}
}
if (Extras.size() && NumExtras == 0) {
for (unsigned i = 0, e = Extras.size(); i != e; ++i) {
MF.getRegInfo().setPhysRegUsed(Extras[i]);
AFI->setCSRegisterIsSpilled(Extras[i]);
}
} 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(),
RC->getAlignment(),
false));
}
}
}
if (ForceLRSpill) {
MF.getRegInfo().setPhysRegUsed(ARM::LR);
AFI->setCSRegisterIsSpilled(ARM::LR);
AFI->setLRIsSpilledForFarJump(true);
}
}

View File

@ -54,6 +54,9 @@ public:
unsigned &FrameReg, int SPAdj) const;
int getFrameIndexOffset(const MachineFunction &MF, int FI) const;
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS) const;
private:
void emitPopInst(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
const std::vector<CalleeSavedInfo> &CSI, unsigned Opc,

View File

@ -16,6 +16,7 @@
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/Target/TargetOptions.h"
using namespace llvm;
@ -105,3 +106,19 @@ void BlackfinFrameInfo::emitEpilogue(MachineFunction &MF,
// emit an UNLINK instruction
BuildMI(MBB, MBBI, dl, TII.get(BF::UNLINK));
}
void BlackfinFrameInfo::
processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS) const {
MachineFrameInfo *MFI = MF.getFrameInfo();
const BlackfinRegisterInfo *RegInfo =
static_cast<const BlackfinRegisterInfo*>(MF.getTarget().getRegisterInfo());
const TargetRegisterClass *RC = BF::DPRegisterClass;
if (RegInfo->requiresRegisterScavenging(MF)) {
// Reserve a slot close to SP or frame pointer.
RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
RC->getAlignment(),
false));
}
}

View File

@ -36,6 +36,9 @@ public:
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
bool hasFP(const MachineFunction &MF) const;
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS) const;
};
} // End llvm namespace

View File

@ -325,19 +325,6 @@ BlackfinRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
}
}
void BlackfinRegisterInfo::
processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS) const {
MachineFrameInfo *MFI = MF.getFrameInfo();
const TargetRegisterClass *RC = BF::DPRegisterClass;
if (requiresRegisterScavenging(MF)) {
// Reserve a slot close to SP or frame pointer.
RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
RC->getAlignment(),
false));
}
}
unsigned BlackfinRegisterInfo::getRARegister() const {
return BF::RETS;
}

View File

@ -52,9 +52,6 @@ namespace llvm {
void eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, RegScavenger *RS = NULL) const;
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS) const;
unsigned getFrameRegister(const MachineFunction &MF) const;
unsigned getRARegister() const;

View File

@ -22,6 +22,7 @@
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/CommandLine.h"
@ -255,3 +256,20 @@ void SPUFrameInfo::getInitialFrameState(std::vector<MachineMove> &Moves) const {
MachineLocation Src(SPU::R1, 0);
Moves.push_back(MachineMove(0, Dst, Src));
}
void SPUFrameInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS) const{
// Mark LR and SP unused, since the prolog spills them to stack and
// we don't want anyone else to spill them for us.
//
// Also, unless R2 is really used someday, don't spill it automatically.
MF.getRegInfo().setPhysRegUnused(SPU::R0);
MF.getRegInfo().setPhysRegUnused(SPU::R1);
MF.getRegInfo().setPhysRegUnused(SPU::R2);
MachineFrameInfo *MFI = MF.getFrameInfo();
const TargetRegisterClass *RC = &SPU::R32CRegClass;
RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
RC->getAlignment(),
false));
}

View File

@ -40,6 +40,9 @@ namespace llvm {
//! Prediate: Target has dedicated frame pointer
bool hasFP(const MachineFunction &MF) const;
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS = NULL) const;
//! Perform target-specific stack frame setup.
void getInitialFrameState(std::vector<MachineMove> &Moves) const;

View File

@ -310,24 +310,6 @@ SPURegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
}
}
void SPURegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS)
const {
// Mark LR and SP unused, since the prolog spills them to stack and
// we don't want anyone else to spill them for us.
//
// Also, unless R2 is really used someday, don't spill it automatically.
MF.getRegInfo().setPhysRegUnused(SPU::R0);
MF.getRegInfo().setPhysRegUnused(SPU::R1);
MF.getRegInfo().setPhysRegUnused(SPU::R2);
MachineFrameInfo *MFI = MF.getFrameInfo();
const TargetRegisterClass *RC = &SPU::R32CRegClass;
RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
RC->getAlignment(),
false));
}
unsigned
SPURegisterInfo::getRARegister() const
{

View File

@ -64,9 +64,6 @@ namespace llvm {
void eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
RegScavenger *RS = NULL) const;
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS = NULL) const;
//! Get return address register (LR, aka R0)
unsigned getRARegister() const;
//! Get the stack frame register (SP, aka R1)

View File

@ -20,6 +20,7 @@
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/Target/TargetOptions.h"
using namespace llvm;
@ -696,3 +697,261 @@ void PPCFrameInfo::getInitialFrameState(std::vector<MachineMove> &Moves) const {
MachineLocation Src(PPC::R1, 0);
Moves.push_back(MachineMove(0, Dst, Src));
}
static bool spillsCR(const MachineFunction &MF) {
const PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
return FuncInfo->isCRSpilled();
}
/// MustSaveLR - Return true if this function requires that we save the LR
/// register onto the stack in the prolog and restore it in the epilog of the
/// function.
static bool MustSaveLR(const MachineFunction &MF, unsigned LR) {
const PPCFunctionInfo *MFI = MF.getInfo<PPCFunctionInfo>();
// We need a save/restore of LR if there is any def of LR (which is
// defined by calls, including the PIC setup sequence), or if there is
// some use of the LR stack slot (e.g. for builtin_return_address).
// (LR comes in 32 and 64 bit versions.)
MachineRegisterInfo::def_iterator RI = MF.getRegInfo().def_begin(LR);
return RI !=MF.getRegInfo().def_end() || MFI->isLRStoreRequired();
}
void
PPCFrameInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS) const {
const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo();
// Save and clear the LR state.
PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
unsigned LR = RegInfo->getRARegister();
FI->setMustSaveLR(MustSaveLR(MF, LR));
MF.getRegInfo().setPhysRegUnused(LR);
// Save R31 if necessary
int FPSI = FI->getFramePointerSaveIndex();
bool isPPC64 = Subtarget.isPPC64();
bool isDarwinABI = Subtarget.isDarwinABI();
MachineFrameInfo *MFI = MF.getFrameInfo();
// If the frame pointer save index hasn't been defined yet.
if (!FPSI && hasFP(MF)) {
// Find out what the fix offset of the frame pointer save area.
int FPOffset = getFramePointerSaveOffset(isPPC64, isDarwinABI);
// Allocate the frame index for frame pointer save area.
FPSI = MF.getFrameInfo()->CreateFixedObject(isPPC64? 8 : 4, FPOffset, true);
// Save the result.
FI->setFramePointerSaveIndex(FPSI);
}
// Reserve stack space to move the linkage area to in case of a tail call.
int TCSPDelta = 0;
if (GuaranteedTailCallOpt && (TCSPDelta = FI->getTailCallSPDelta()) < 0) {
MF.getFrameInfo()->CreateFixedObject(-1 * TCSPDelta, TCSPDelta, true);
}
// Reserve a slot closest to SP or frame pointer if we have a dynalloc or
// a large stack, which will require scavenging a register to materialize a
// large offset.
// FIXME: this doesn't actually check stack size, so is a bit pessimistic
// FIXME: doesn't detect whether or not we need to spill vXX, which requires
// r0 for now.
if (RegInfo->requiresRegisterScavenging(MF)) // FIXME (64-bit): Enable.
if (hasFP(MF) || spillsCR(MF)) {
const TargetRegisterClass *GPRC = &PPC::GPRCRegClass;
const TargetRegisterClass *G8RC = &PPC::G8RCRegClass;
const TargetRegisterClass *RC = isPPC64 ? G8RC : GPRC;
RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
RC->getAlignment(),
false));
}
}
void PPCFrameInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF)
const {
// Early exit if not using the SVR4 ABI.
if (!Subtarget.isSVR4ABI())
return;
// Get callee saved register information.
MachineFrameInfo *FFI = MF.getFrameInfo();
const std::vector<CalleeSavedInfo> &CSI = FFI->getCalleeSavedInfo();
// Early exit if no callee saved registers are modified!
if (CSI.empty() && !hasFP(MF)) {
return;
}
unsigned MinGPR = PPC::R31;
unsigned MinG8R = PPC::X31;
unsigned MinFPR = PPC::F31;
unsigned MinVR = PPC::V31;
bool HasGPSaveArea = false;
bool HasG8SaveArea = false;
bool HasFPSaveArea = false;
bool HasCRSaveArea = false;
bool HasVRSAVESaveArea = false;
bool HasVRSaveArea = false;
SmallVector<CalleeSavedInfo, 18> GPRegs;
SmallVector<CalleeSavedInfo, 18> G8Regs;
SmallVector<CalleeSavedInfo, 18> FPRegs;
SmallVector<CalleeSavedInfo, 18> VRegs;
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
unsigned Reg = CSI[i].getReg();
if (PPC::GPRCRegisterClass->contains(Reg)) {
HasGPSaveArea = true;
GPRegs.push_back(CSI[i]);
if (Reg < MinGPR) {
MinGPR = Reg;
}
} else if (PPC::G8RCRegisterClass->contains(Reg)) {
HasG8SaveArea = true;
G8Regs.push_back(CSI[i]);
if (Reg < MinG8R) {
MinG8R = Reg;
}
} else if (PPC::F8RCRegisterClass->contains(Reg)) {
HasFPSaveArea = true;
FPRegs.push_back(CSI[i]);
if (Reg < MinFPR) {
MinFPR = Reg;
}
// FIXME SVR4: Disable CR save area for now.
} else if (PPC::CRBITRCRegisterClass->contains(Reg)
|| PPC::CRRCRegisterClass->contains(Reg)) {
// HasCRSaveArea = true;
} else if (PPC::VRSAVERCRegisterClass->contains(Reg)) {
HasVRSAVESaveArea = true;
} else if (PPC::VRRCRegisterClass->contains(Reg)) {
HasVRSaveArea = true;
VRegs.push_back(CSI[i]);
if (Reg < MinVR) {
MinVR = Reg;
}
} else {
llvm_unreachable("Unknown RegisterClass!");
}
}
PPCFunctionInfo *PFI = MF.getInfo<PPCFunctionInfo>();
int64_t LowerBound = 0;
// Take into account stack space reserved for tail calls.
int TCSPDelta = 0;
if (GuaranteedTailCallOpt && (TCSPDelta = PFI->getTailCallSPDelta()) < 0) {
LowerBound = TCSPDelta;
}
// The Floating-point register save area is right below the back chain word
// of the previous stack frame.
if (HasFPSaveArea) {
for (unsigned i = 0, e = FPRegs.size(); i != e; ++i) {
int FI = FPRegs[i].getFrameIdx();
FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
}
LowerBound -= (31 - PPCRegisterInfo::getRegisterNumbering(MinFPR) + 1) * 8;
}
// Check whether the frame pointer register is allocated. If so, make sure it
// is spilled to the correct offset.
if (hasFP(MF)) {
HasGPSaveArea = true;
int FI = PFI->getFramePointerSaveIndex();
assert(FI && "No Frame Pointer Save Slot!");
FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
}
// General register save area starts right below the Floating-point
// register save area.
if (HasGPSaveArea || HasG8SaveArea) {
// Move general register save area spill slots down, taking into account
// the size of the Floating-point register save area.
for (unsigned i = 0, e = GPRegs.size(); i != e; ++i) {
int FI = GPRegs[i].getFrameIdx();
FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
}
// Move general register save area spill slots down, taking into account
// the size of the Floating-point register save area.
for (unsigned i = 0, e = G8Regs.size(); i != e; ++i) {
int FI = G8Regs[i].getFrameIdx();
FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
}
unsigned MinReg =
std::min<unsigned>(PPCRegisterInfo::getRegisterNumbering(MinGPR),
PPCRegisterInfo::getRegisterNumbering(MinG8R));
if (Subtarget.isPPC64()) {
LowerBound -= (31 - MinReg + 1) * 8;
} else {
LowerBound -= (31 - MinReg + 1) * 4;
}
}
// The CR save area is below the general register save area.
if (HasCRSaveArea) {
// FIXME SVR4: Is it actually possible to have multiple elements in CSI
// which have the CR/CRBIT register class?
// Adjust the frame index of the CR spill slot.
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
unsigned Reg = CSI[i].getReg();
if (PPC::CRBITRCRegisterClass->contains(Reg) ||
PPC::CRRCRegisterClass->contains(Reg)) {
int FI = CSI[i].getFrameIdx();
FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
}
}
LowerBound -= 4; // The CR save area is always 4 bytes long.
}
if (HasVRSAVESaveArea) {
// FIXME SVR4: Is it actually possible to have multiple elements in CSI
// which have the VRSAVE register class?
// Adjust the frame index of the VRSAVE spill slot.
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
unsigned Reg = CSI[i].getReg();
if (PPC::VRSAVERCRegisterClass->contains(Reg)) {
int FI = CSI[i].getFrameIdx();
FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
}
}
LowerBound -= 4; // The VRSAVE save area is always 4 bytes long.
}
if (HasVRSaveArea) {
// Insert alignment padding, we need 16-byte alignment.
LowerBound = (LowerBound - 15) & ~(15);
for (unsigned i = 0, e = VRegs.size(); i != e; ++i) {
int FI = VRegs[i].getFrameIdx();
FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
}
}
}

View File

@ -40,6 +40,10 @@ public:
bool hasFP(const MachineFunction &MF) const;
void getInitialFrameState(std::vector<MachineMove> &Moves) const;
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS = NULL) const;
void processFunctionBeforeFrameFinalized(MachineFunction &MF) const;
/// targetHandlesStackFrameRounding - Returns true if the target is
/// responsible for rounding up the stack frame (probably at emitPrologue
/// time).

View File

@ -58,14 +58,11 @@ cl::opt<bool> EnablePPC64RS("enable-ppc64-regscavenger",
using namespace llvm;
#define EnableRegisterScavenging \
((EnablePPC32RS && !Subtarget.isPPC64()) || \
(EnablePPC64RS && Subtarget.isPPC64()))
// FIXME (64-bit): Should be inlined.
bool
PPCRegisterInfo::requiresRegisterScavenging(const MachineFunction &) const {
return EnableRegisterScavenging;
return ((EnablePPC32RS && !Subtarget.isPPC64()) ||
(EnablePPC64RS && Subtarget.isPPC64()));
}
/// getRegisterNumbering - Given the enum value for some register, e.g.
@ -259,11 +256,6 @@ PPCRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
return Subtarget.isPPC64() ? SVR4_64_CalleeSavedRegs : SVR4_CalleeSavedRegs;
}
static bool spillsCR(const MachineFunction &MF) {
const PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
return FuncInfo->isCRSpilled();
}
BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
BitVector Reserved(getNumRegs());
const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo();
@ -293,7 +285,7 @@ BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
Reserved.set(PPC::R13);
Reserved.set(PPC::R31);
if (!EnableRegisterScavenging)
if (!requiresRegisterScavenging(MF))
Reserved.set(PPC::R0); // FIXME (64-bit): Remove
Reserved.set(PPC::X0);
@ -323,22 +315,6 @@ BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
// Stack Frame Processing methods
//===----------------------------------------------------------------------===//
/// MustSaveLR - Return true if this function requires that we save the LR
/// register onto the stack in the prolog and restore it in the epilog of the
/// function.
static bool MustSaveLR(const MachineFunction &MF, unsigned LR) {
const PPCFunctionInfo *MFI = MF.getInfo<PPCFunctionInfo>();
// We need a save/restore of LR if there is any def of LR (which is
// defined by calls, including the PIC setup sequence), or if there is
// some use of the LR stack slot (e.g. for builtin_return_address).
// (LR comes in 32 and 64 bit versions.)
MachineRegisterInfo::def_iterator RI = MF.getRegInfo().def_begin(LR);
return RI !=MF.getRegInfo().def_end() || MFI->isLRStoreRequired();
}
void PPCRegisterInfo::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
@ -435,7 +411,7 @@ void PPCRegisterInfo::lowerDynamicAlloc(MachineBasicBlock::iterator II,
// FIXME (64-bit): Use "findScratchRegister"
unsigned Reg;
if (EnableRegisterScavenging)
if (requiresRegisterScavenging(MF))
Reg = findScratchRegister(II, RS, RC, SPAdj);
else
Reg = PPC::R0;
@ -445,7 +421,7 @@ void PPCRegisterInfo::lowerDynamicAlloc(MachineBasicBlock::iterator II,
.addReg(PPC::R31)
.addImm(FrameSize);
} else if (LP64) {
if (EnableRegisterScavenging) // FIXME (64-bit): Use "true" part.
if (requiresRegisterScavenging(MF)) // FIXME (64-bit): Use "true" part.
BuildMI(MBB, II, dl, TII.get(PPC::LD), Reg)
.addImm(0)
.addReg(PPC::X1);
@ -462,7 +438,7 @@ void PPCRegisterInfo::lowerDynamicAlloc(MachineBasicBlock::iterator II,
// Grow the stack and update the stack pointer link, then determine the
// address of new allocated space.
if (LP64) {
if (EnableRegisterScavenging) // FIXME (64-bit): Use "true" part.
if (requiresRegisterScavenging(MF)) // FIXME (64-bit): Use "true" part.
BuildMI(MBB, II, dl, TII.get(PPC::STDUX))
.addReg(Reg, RegState::Kill)
.addReg(PPC::X1)
@ -597,7 +573,7 @@ PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
}
// Special case for pseudo-op SPILL_CR.
if (EnableRegisterScavenging) // FIXME (64-bit): Enable by default.
if (requiresRegisterScavenging(MF)) // FIXME (64-bit): Enable by default.
if (OpC == PPC::SPILL_CR) {
lowerCRSpilling(II, FrameIndex, SPAdj, RS);
return;
@ -655,7 +631,7 @@ PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
// FIXME (64-bit): Use "findScratchRegister".
unsigned SReg;
if (EnableRegisterScavenging)
if (requiresRegisterScavenging(MF))
SReg = findScratchRegister(II, RS, &PPC::GPRCRegClass, SPAdj);
else
SReg = PPC::R0;
@ -688,248 +664,6 @@ PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
MI.getOperand(OperandBase + 1).ChangeToRegister(SReg, false);
}
void
PPCRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS) const {
const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo();
// Save and clear the LR state.
PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
unsigned LR = getRARegister();
FI->setMustSaveLR(MustSaveLR(MF, LR));
MF.getRegInfo().setPhysRegUnused(LR);
// Save R31 if necessary
int FPSI = FI->getFramePointerSaveIndex();
bool isPPC64 = Subtarget.isPPC64();
bool isDarwinABI = Subtarget.isDarwinABI();
MachineFrameInfo *MFI = MF.getFrameInfo();
// If the frame pointer save index hasn't been defined yet.
if (!FPSI && TFI->hasFP(MF)) {
// Find out what the fix offset of the frame pointer save area.
int FPOffset = PPCFrameInfo::getFramePointerSaveOffset(isPPC64,
isDarwinABI);
// Allocate the frame index for frame pointer save area.
FPSI = MF.getFrameInfo()->CreateFixedObject(isPPC64? 8 : 4, FPOffset, true);
// Save the result.
FI->setFramePointerSaveIndex(FPSI);
}
// Reserve stack space to move the linkage area to in case of a tail call.
int TCSPDelta = 0;
if (GuaranteedTailCallOpt && (TCSPDelta = FI->getTailCallSPDelta()) < 0) {
MF.getFrameInfo()->CreateFixedObject(-1 * TCSPDelta, TCSPDelta, true);
}
// Reserve a slot closest to SP or frame pointer if we have a dynalloc or
// a large stack, which will require scavenging a register to materialize a
// large offset.
// FIXME: this doesn't actually check stack size, so is a bit pessimistic
// FIXME: doesn't detect whether or not we need to spill vXX, which requires
// r0 for now.
if (EnableRegisterScavenging) // FIXME (64-bit): Enable.
if (TFI->hasFP(MF) || spillsCR(MF)) {
const TargetRegisterClass *GPRC = &PPC::GPRCRegClass;
const TargetRegisterClass *G8RC = &PPC::G8RCRegClass;
const TargetRegisterClass *RC = isPPC64 ? G8RC : GPRC;
RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
RC->getAlignment(),
false));
}
}
void
PPCRegisterInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF)
const {
// Early exit if not using the SVR4 ABI.
if (!Subtarget.isSVR4ABI()) {
return;
}
// Get callee saved register information.
MachineFrameInfo *FFI = MF.getFrameInfo();
const std::vector<CalleeSavedInfo> &CSI = FFI->getCalleeSavedInfo();
const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo();
// Early exit if no callee saved registers are modified!
if (CSI.empty() && !TFI->hasFP(MF)) {
return;
}
unsigned MinGPR = PPC::R31;
unsigned MinG8R = PPC::X31;
unsigned MinFPR = PPC::F31;
unsigned MinVR = PPC::V31;
bool HasGPSaveArea = false;
bool HasG8SaveArea = false;
bool HasFPSaveArea = false;
bool HasCRSaveArea = false;
bool HasVRSAVESaveArea = false;
bool HasVRSaveArea = false;
SmallVector<CalleeSavedInfo, 18> GPRegs;
SmallVector<CalleeSavedInfo, 18> G8Regs;
SmallVector<CalleeSavedInfo, 18> FPRegs;
SmallVector<CalleeSavedInfo, 18> VRegs;
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
unsigned Reg = CSI[i].getReg();
if (PPC::GPRCRegisterClass->contains(Reg)) {
HasGPSaveArea = true;
GPRegs.push_back(CSI[i]);
if (Reg < MinGPR) {
MinGPR = Reg;
}
} else if (PPC::G8RCRegisterClass->contains(Reg)) {
HasG8SaveArea = true;
G8Regs.push_back(CSI[i]);
if (Reg < MinG8R) {
MinG8R = Reg;
}
} else if (PPC::F8RCRegisterClass->contains(Reg)) {
HasFPSaveArea = true;
FPRegs.push_back(CSI[i]);
if (Reg < MinFPR) {
MinFPR = Reg;
}
// FIXME SVR4: Disable CR save area for now.
} else if (PPC::CRBITRCRegisterClass->contains(Reg)
|| PPC::CRRCRegisterClass->contains(Reg)) {
// HasCRSaveArea = true;
} else if (PPC::VRSAVERCRegisterClass->contains(Reg)) {
HasVRSAVESaveArea = true;
} else if (PPC::VRRCRegisterClass->contains(Reg)) {
HasVRSaveArea = true;
VRegs.push_back(CSI[i]);
if (Reg < MinVR) {
MinVR = Reg;
}
} else {
llvm_unreachable("Unknown RegisterClass!");
}
}
PPCFunctionInfo *PFI = MF.getInfo<PPCFunctionInfo>();
int64_t LowerBound = 0;
// Take into account stack space reserved for tail calls.
int TCSPDelta = 0;
if (GuaranteedTailCallOpt && (TCSPDelta = PFI->getTailCallSPDelta()) < 0) {
LowerBound = TCSPDelta;
}
// The Floating-point register save area is right below the back chain word
// of the previous stack frame.
if (HasFPSaveArea) {
for (unsigned i = 0, e = FPRegs.size(); i != e; ++i) {
int FI = FPRegs[i].getFrameIdx();
FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
}
LowerBound -= (31 - getRegisterNumbering(MinFPR) + 1) * 8;
}
// Check whether the frame pointer register is allocated. If so, make sure it
// is spilled to the correct offset.
if (TFI->hasFP(MF)) {
HasGPSaveArea = true;
int FI = PFI->getFramePointerSaveIndex();
assert(FI && "No Frame Pointer Save Slot!");
FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
}
// General register save area starts right below the Floating-point
// register save area.
if (HasGPSaveArea || HasG8SaveArea) {
// Move general register save area spill slots down, taking into account
// the size of the Floating-point register save area.
for (unsigned i = 0, e = GPRegs.size(); i != e; ++i) {
int FI = GPRegs[i].getFrameIdx();
FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
}
// Move general register save area spill slots down, taking into account
// the size of the Floating-point register save area.
for (unsigned i = 0, e = G8Regs.size(); i != e; ++i) {
int FI = G8Regs[i].getFrameIdx();
FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
}
unsigned MinReg = std::min<unsigned>(getRegisterNumbering(MinGPR),
getRegisterNumbering(MinG8R));
if (Subtarget.isPPC64()) {
LowerBound -= (31 - MinReg + 1) * 8;
} else {
LowerBound -= (31 - MinReg + 1) * 4;
}
}
// The CR save area is below the general register save area.
if (HasCRSaveArea) {
// FIXME SVR4: Is it actually possible to have multiple elements in CSI
// which have the CR/CRBIT register class?
// Adjust the frame index of the CR spill slot.
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
unsigned Reg = CSI[i].getReg();
if (PPC::CRBITRCRegisterClass->contains(Reg) ||
PPC::CRRCRegisterClass->contains(Reg)) {
int FI = CSI[i].getFrameIdx();
FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
}
}
LowerBound -= 4; // The CR save area is always 4 bytes long.
}
if (HasVRSAVESaveArea) {
// FIXME SVR4: Is it actually possible to have multiple elements in CSI
// which have the VRSAVE register class?
// Adjust the frame index of the VRSAVE spill slot.
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
unsigned Reg = CSI[i].getReg();
if (PPC::VRSAVERCRegisterClass->contains(Reg)) {
int FI = CSI[i].getFrameIdx();
FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
}
}
LowerBound -= 4; // The VRSAVE save area is always 4 bytes long.
}
if (HasVRSaveArea) {
// Insert alignment padding, we need 16-byte alignment.
LowerBound = (LowerBound - 15) & ~(15);
for (unsigned i = 0, e = VRegs.size(); i != e; ++i) {
int FI = VRegs[i].getFrameIdx();
FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
}
}
}
unsigned PPCRegisterInfo::getRARegister() const {
return !Subtarget.isPPC64() ? PPC::LR : PPC::LR8;
}

View File

@ -59,10 +59,6 @@ public:
void eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, RegScavenger *RS = NULL) const;
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS = NULL) const;
void processFunctionBeforeFrameFinalized(MachineFunction &MF) const;
// Debug information queries.
unsigned getRARegister() const;
unsigned getFrameRegister(const MachineFunction &MF) const;

View File

@ -351,3 +351,38 @@ SystemZFrameInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
return true;
}
void
SystemZFrameInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS) const {
// Determine whether R15/R14 will ever be clobbered inside the function. And
// if yes - mark it as 'callee' saved.
MachineFrameInfo *FFI = MF.getFrameInfo();
MachineRegisterInfo &MRI = MF.getRegInfo();
// Check whether high FPRs are ever used, if yes - we need to save R15 as
// well.
static const unsigned HighFPRs[] = {
SystemZ::F8L, SystemZ::F9L, SystemZ::F10L, SystemZ::F11L,
SystemZ::F12L, SystemZ::F13L, SystemZ::F14L, SystemZ::F15L,
SystemZ::F8S, SystemZ::F9S, SystemZ::F10S, SystemZ::F11S,
SystemZ::F12S, SystemZ::F13S, SystemZ::F14S, SystemZ::F15S,
};
bool HighFPRsUsed = false;
for (unsigned i = 0, e = array_lengthof(HighFPRs); i != e; ++i)
HighFPRsUsed |= MRI.isPhysRegUsed(HighFPRs[i]);
if (FFI->hasCalls())
/* FIXME: function is varargs */
/* FIXME: function grabs RA */
/* FIXME: function calls eh_return */
MRI.setPhysRegUsed(SystemZ::R14D);
if (HighFPRsUsed ||
FFI->hasCalls() ||
FFI->getObjectIndexEnd() != 0 || // Contains automatic variables
FFI->hasVarSizedObjects() // Function calls dynamic alloca's
/* FIXME: function is varargs */)
MRI.setPhysRegUsed(SystemZ::R15D);
}

View File

@ -44,6 +44,9 @@ public:
const std::vector<CalleeSavedInfo> &CSI,
const TargetRegisterInfo *TRI) const;
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS) const;
bool hasReservedCallFrame(const MachineFunction &MF) const { return true; }
bool hasFP(const MachineFunction &MF) const;
int getFrameIndexOffset(const MachineFunction &MF, int FI) const;

View File

@ -99,41 +99,6 @@ SystemZRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
MI.getOperand(i+1).ChangeToImmediate(Offset);
}
void
SystemZRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS) const {
// Determine whether R15/R14 will ever be clobbered inside the function. And
// if yes - mark it as 'callee' saved.
MachineFrameInfo *FFI = MF.getFrameInfo();
MachineRegisterInfo &MRI = MF.getRegInfo();
// Check whether high FPRs are ever used, if yes - we need to save R15 as
// well.
static const unsigned HighFPRs[] = {
SystemZ::F8L, SystemZ::F9L, SystemZ::F10L, SystemZ::F11L,
SystemZ::F12L, SystemZ::F13L, SystemZ::F14L, SystemZ::F15L,
SystemZ::F8S, SystemZ::F9S, SystemZ::F10S, SystemZ::F11S,
SystemZ::F12S, SystemZ::F13S, SystemZ::F14S, SystemZ::F15S,
};
bool HighFPRsUsed = false;
for (unsigned i = 0, e = array_lengthof(HighFPRs); i != e; ++i)
HighFPRsUsed |= MRI.isPhysRegUsed(HighFPRs[i]);
if (FFI->hasCalls())
/* FIXME: function is varargs */
/* FIXME: function grabs RA */
/* FIXME: function calls eh_return */
MRI.setPhysRegUsed(SystemZ::R14D);
if (HighFPRsUsed ||
FFI->hasCalls() ||
FFI->getObjectIndexEnd() != 0 || // Contains automatic variables
FFI->hasVarSizedObjects() // Function calls dynamic alloca's
/* FIXME: function is varargs */)
MRI.setPhysRegUsed(SystemZ::R15D);
}
unsigned SystemZRegisterInfo::getRARegister() const {
assert(0 && "What is the return address register");
return 0;

View File

@ -41,10 +41,6 @@ struct SystemZRegisterInfo : public SystemZGenRegisterInfo {
void eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, RegScavenger *RS = NULL) const;
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS) const;
// Debug information queries.
unsigned getRARegister() const;
unsigned getFrameRegister(const MachineFunction &MF) const;

View File

@ -870,3 +870,44 @@ bool X86FrameInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
}
return true;
}
void
X86FrameInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS) const {
MachineFrameInfo *MFI = MF.getFrameInfo();
const X86RegisterInfo *RegInfo = TM.getRegisterInfo();
unsigned SlotSize = RegInfo->getSlotSize();
X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
int32_t TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta();
if (TailCallReturnAddrDelta < 0) {
// create RETURNADDR area
// arg
// arg
// RETADDR
// { ...
// RETADDR area
// ...
// }
// [EBP]
MFI->CreateFixedObject(-TailCallReturnAddrDelta,
(-1U*SlotSize)+TailCallReturnAddrDelta, true);
}
if (hasFP(MF)) {
assert((TailCallReturnAddrDelta <= 0) &&
"The Delta should always be zero or negative");
const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo();
// Create a frame entry for the EBP register that must be saved.
int FrameIdx = MFI->CreateFixedObject(SlotSize,
-(int)SlotSize +
TFI.getOffsetOfLocalArea() +
TailCallReturnAddrDelta,
true);
assert(FrameIdx == MFI->getObjectIndexBegin() &&
"Slot for EBP register must be last in order to be found!");
FrameIdx = 0;
}
}

View File

@ -40,15 +40,18 @@ public:
void emitPrologue(MachineFunction &MF) const;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS = NULL) const;
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
const std::vector<CalleeSavedInfo> &CSI,
const TargetRegisterInfo *TRI) const;
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
const std::vector<CalleeSavedInfo> &CSI,
const TargetRegisterInfo *TRI) const;
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
const std::vector<CalleeSavedInfo> &CSI,
const TargetRegisterInfo *TRI) const;
bool hasFP(const MachineFunction &MF) const;
bool hasReservedCallFrame(const MachineFunction &MF) const;

View File

@ -609,46 +609,6 @@ X86RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
}
}
void
X86RegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS) const {
MachineFrameInfo *MFI = MF.getFrameInfo();
const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo();
X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
int32_t TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta();
if (TailCallReturnAddrDelta < 0) {
// create RETURNADDR area
// arg
// arg
// RETADDR
// { ...
// RETADDR area
// ...
// }
// [EBP]
MFI->CreateFixedObject(-TailCallReturnAddrDelta,
(-1U*SlotSize)+TailCallReturnAddrDelta, true);
}
if (TFI->hasFP(MF)) {
assert((TailCallReturnAddrDelta <= 0) &&
"The Delta should always be zero or negative");
const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo();
// Create a frame entry for the EBP register that must be saved.
int FrameIdx = MFI->CreateFixedObject(SlotSize,
-(int)SlotSize +
TFI.getOffsetOfLocalArea() +
TailCallReturnAddrDelta,
true);
assert(FrameIdx == MFI->getObjectIndexBegin() &&
"Slot for EBP register must be last in order to be found!");
FrameIdx = 0;
}
}
unsigned X86RegisterInfo::getRARegister() const {
return Is64Bit ? X86::RIP // Should have dwarf #16.
: X86::EIP; // Should have dwarf #8.

View File

@ -125,9 +125,6 @@ public:
void eliminateFrameIndex(MachineBasicBlock::iterator MI,
int SPAdj, RegScavenger *RS = NULL) const;
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS = NULL) const;
// Debug information queries.
unsigned getRARegister() const;
unsigned getFrameRegister(const MachineFunction &MF) const;

View File

@ -22,6 +22,7 @@
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/ErrorHandling.h"
@ -336,3 +337,46 @@ bool XCoreFrameInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
}
return true;
}
void
XCoreFrameInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS) const {
MachineFrameInfo *MFI = MF.getFrameInfo();
const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo();
bool LRUsed = MF.getRegInfo().isPhysRegUsed(XCore::LR);
const TargetRegisterClass *RC = XCore::GRRegsRegisterClass;
XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
if (LRUsed) {
MF.getRegInfo().setPhysRegUnused(XCore::LR);
bool isVarArg = MF.getFunction()->isVarArg();
int FrameIdx;
if (! isVarArg) {
// A fixed offset of 0 allows us to save / restore LR using entsp / retsp.
FrameIdx = MFI->CreateFixedObject(RC->getSize(), 0, true);
} else {
FrameIdx = MFI->CreateStackObject(RC->getSize(), RC->getAlignment(),
false);
}
XFI->setUsesLR(FrameIdx);
XFI->setLRSpillSlot(FrameIdx);
}
if (RegInfo->requiresRegisterScavenging(MF)) {
// Reserve a slot close to SP or frame pointer.
RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
RC->getAlignment(),
false));
}
if (hasFP(MF)) {
// A callee save register is used to hold the FP.
// This needs saving / restoring in the epilogue / prologue.
XFI->setFPSpillSlot(MFI->CreateStackObject(RC->getSize(),
RC->getAlignment(),
false));
}
}
void XCoreFrameInfo::
processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
}

View File

@ -44,6 +44,11 @@ namespace llvm {
void getInitialFrameState(std::vector<MachineMove> &Moves) const;
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS = NULL) const;
void processFunctionBeforeFrameFinalized(MachineFunction &MF) const;
//! Stack slot size (4 bytes)
static int stackSlotSize() {
return 4;

View File

@ -295,49 +295,6 @@ XCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
MBB.erase(II);
}
void
XCoreRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS) const {
MachineFrameInfo *MFI = MF.getFrameInfo();
const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo();
bool LRUsed = MF.getRegInfo().isPhysRegUsed(XCore::LR);
const TargetRegisterClass *RC = XCore::GRRegsRegisterClass;
XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>();
if (LRUsed) {
MF.getRegInfo().setPhysRegUnused(XCore::LR);
bool isVarArg = MF.getFunction()->isVarArg();
int FrameIdx;
if (! isVarArg) {
// A fixed offset of 0 allows us to save / restore LR using entsp / retsp.
FrameIdx = MFI->CreateFixedObject(RC->getSize(), 0, true);
} else {
FrameIdx = MFI->CreateStackObject(RC->getSize(), RC->getAlignment(),
false);
}
XFI->setUsesLR(FrameIdx);
XFI->setLRSpillSlot(FrameIdx);
}
if (requiresRegisterScavenging(MF)) {
// Reserve a slot close to SP or frame pointer.
RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
RC->getAlignment(),
false));
}
if (TFI->hasFP(MF)) {
// A callee save register is used to hold the FP.
// This needs saving / restoring in the epilogue / prologue.
XFI->setFPSpillSlot(MFI->CreateStackObject(RC->getSize(),
RC->getAlignment(),
false));
}
}
void XCoreRegisterInfo::
processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
}
void XCoreRegisterInfo::
loadConstant(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned DstReg, int64_t Value, DebugLoc dl) const {

View File

@ -55,11 +55,6 @@ public:
void eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, RegScavenger *RS = NULL) const;
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS = NULL) const;
void processFunctionBeforeFrameFinalized(MachineFunction &MF) const;
// Debug information queries.
unsigned getRARegister() const;
unsigned getFrameRegister(const MachineFunction &MF) const;