mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
Add ARM heuristic for when to allocate a virtual base register for stack
access. rdar://8277890&7352504 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@111968 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6d8f1a9a18
commit
3197380143
@ -653,7 +653,7 @@ public:
|
||||
/// reference would be better served by a base register other than FP
|
||||
/// or SP. Used by LocalStackFrameAllocation to determine which frame index
|
||||
/// references it should create new base registers for.
|
||||
virtual bool needsFrameBaseReg(MachineInstr *MI, unsigned operand) const {
|
||||
virtual bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -250,7 +250,7 @@ bool LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) {
|
||||
continue;
|
||||
|
||||
DEBUG(dbgs() << "Considering: " << *MI);
|
||||
if (TRI->needsFrameBaseReg(MI, i)) {
|
||||
if (TRI->needsFrameBaseReg(MI, LocalOffsets[FrameIdx])) {
|
||||
unsigned BaseReg = 0;
|
||||
int64_t Offset = 0;
|
||||
int64_t FrameSizeAdjust = StackGrowsDown ? MFI->getLocalFrameSize()
|
||||
|
@ -44,7 +44,7 @@ cl::opt<bool>
|
||||
ReuseFrameIndexVals("arm-reuse-frame-index-vals", cl::Hidden, cl::init(true),
|
||||
cl::desc("Reuse repeated frame index values"));
|
||||
static cl::opt<bool>
|
||||
ForceAllBaseRegAlloc("arm-force-base-reg-alloc", cl::Hidden, cl::init(true),
|
||||
ForceAllBaseRegAlloc("arm-force-base-reg-alloc", cl::Hidden, cl::init(false),
|
||||
cl::desc("Force use of virtual base registers for stack load/store"));
|
||||
static cl::opt<bool>
|
||||
EnableLocalStackAlloc("enable-local-stack-alloc", cl::init(false), cl::Hidden,
|
||||
@ -1436,9 +1436,10 @@ getFrameIndexInstrOffset(MachineInstr *MI, int Idx) const {
|
||||
/// or SP. Used by LocalStackFrameAllocation to determine which frame index
|
||||
/// references it should create new base registers for.
|
||||
bool ARMBaseRegisterInfo::
|
||||
needsFrameBaseReg(MachineInstr *MI, unsigned operand) const {
|
||||
assert (MI->getOperand(operand).isFI() &&
|
||||
"needsFrameBaseReg() called on non Frame Index operand!");
|
||||
needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const {
|
||||
for (unsigned i = 0; !MI->getOperand(i).isFI(); ++i) {
|
||||
assert(i < MI->getNumOperands() &&"Instr doesn't have FrameIndex operand!");
|
||||
}
|
||||
|
||||
// It's the load/store FI references that cause issues, as it can be difficult
|
||||
// to materialize the offset if it won't fit in the literal field. Estimate
|
||||
@ -1465,12 +1466,49 @@ needsFrameBaseReg(MachineInstr *MI, unsigned operand) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
// FIXME: TODO
|
||||
// Without a virtual base register, if the function has variable sized
|
||||
// objects, all fixed-size local references will be via the frame pointer,
|
||||
// otherwise via the stack pointer. Approximate the offset and see if it's
|
||||
// legal for the instruction.
|
||||
// Approximate the offset and see if it's legal for the instruction.
|
||||
// Note that the incoming offset is based on the SP value at function entry,
|
||||
// so it'll be negative.
|
||||
MachineFunction &MF = *MI->getParent()->getParent();
|
||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
|
||||
|
||||
// Estimate an offset from the frame pointer.
|
||||
// Conservatively assume all callee-saved registers get pushed. R4-R6
|
||||
// will be earlier than the FP, so we ignore those.
|
||||
// R7, LR
|
||||
int64_t FPOffset = Offset - 8;
|
||||
// ARM and Thumb2 functions also need to consider R8-R11 and D8-D15
|
||||
if (!AFI->isThumbFunction() || !AFI->isThumb1OnlyFunction())
|
||||
FPOffset -= 80;
|
||||
// Estimate an offset from the stack pointer.
|
||||
Offset = -Offset;
|
||||
// Assume that we'll have at least some spill slots allocated.
|
||||
// FIXME: This is a total SWAG number. We should run some statistics
|
||||
// and pick a real one.
|
||||
Offset += 128; // 128 bytes of spill slots
|
||||
|
||||
// If there is a frame pointer, try using it.
|
||||
// The FP is only available if there is no dynamic realignment. We
|
||||
// don't know for sure yet whether we'll need that, so we guess based
|
||||
// on whether there are any local variables that would trigger it.
|
||||
unsigned StackAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
|
||||
if (hasFP(MF) &&
|
||||
!((MFI->getLocalFrameMaxAlign() > StackAlign) && canRealignStack(MF))) {
|
||||
if (isFrameOffsetLegal(MI, FPOffset))
|
||||
return false;
|
||||
}
|
||||
// If we can reference via the stack pointer, try that.
|
||||
// FIXME: This (and the code that resolves the references) can be improved
|
||||
// to only disallow SP relative references in the live range of
|
||||
// the VLA(s). In practice, it's unclear how much difference that
|
||||
// would make, but it may be worth doing.
|
||||
if (!MFI->hasVarSizedObjects() && isFrameOffsetLegal(MI, Offset))
|
||||
return false;
|
||||
|
||||
// The offset likely isn't legal, we want to allocate a virtual base register.
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ public:
|
||||
bool canRealignStack(const MachineFunction &MF) const;
|
||||
bool needsStackRealignment(const MachineFunction &MF) const;
|
||||
int64_t getFrameIndexInstrOffset(MachineInstr *MI, int Idx) const;
|
||||
bool needsFrameBaseReg(MachineInstr *MI, unsigned operand) const;
|
||||
bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const;
|
||||
void materializeFrameBaseRegister(MachineBasicBlock::iterator I,
|
||||
unsigned BaseReg, int FrameIdx,
|
||||
int64_t Offset) const;
|
||||
|
Loading…
Reference in New Issue
Block a user