From 94c5ae08750f314bc3cf1bf882b686244a3927d9 Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Sat, 27 Nov 2010 23:05:25 +0000 Subject: [PATCH] Move more PEI-related hooks to TFI git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120229 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetFrameInfo.h | 17 ++ include/llvm/Target/TargetRegisterInfo.h | 15 -- lib/CodeGen/PrologEpilogInserter.cpp | 6 +- lib/Target/ARM/ARMBaseRegisterInfo.cpp | 322 -------------------------- lib/Target/ARM/ARMBaseRegisterInfo.h | 5 - lib/Target/ARM/ARMFrameInfo.cpp | 325 +++++++++++++++++++++++++++ lib/Target/ARM/ARMFrameInfo.h | 3 + lib/Target/Blackfin/BlackfinFrameInfo.cpp | 17 ++ lib/Target/Blackfin/BlackfinFrameInfo.h | 3 + lib/Target/Blackfin/BlackfinRegisterInfo.cpp | 13 -- lib/Target/Blackfin/BlackfinRegisterInfo.h | 3 - lib/Target/CellSPU/SPUFrameInfo.cpp | 18 ++ lib/Target/CellSPU/SPUFrameInfo.h | 3 + lib/Target/CellSPU/SPURegisterInfo.cpp | 18 -- lib/Target/CellSPU/SPURegisterInfo.h | 3 - lib/Target/PowerPC/PPCFrameInfo.cpp | 259 +++++++++++++++++++++ lib/Target/PowerPC/PPCFrameInfo.h | 4 + lib/Target/PowerPC/PPCRegisterInfo.cpp | 282 +---------------------- lib/Target/PowerPC/PPCRegisterInfo.h | 4 - lib/Target/SystemZ/SystemZFrameInfo.cpp | 35 +++ lib/Target/SystemZ/SystemZFrameInfo.h | 3 + lib/Target/SystemZ/SystemZRegisterInfo.cpp | 35 --- lib/Target/SystemZ/SystemZRegisterInfo.h | 4 - lib/Target/X86/X86FrameInfo.cpp | 41 ++++ lib/Target/X86/X86FrameInfo.h | 11 +- lib/Target/X86/X86RegisterInfo.cpp | 40 ---- lib/Target/X86/X86RegisterInfo.h | 3 - lib/Target/XCore/XCoreFrameInfo.cpp | 44 ++++ lib/Target/XCore/XCoreFrameInfo.h | 5 + lib/Target/XCore/XCoreRegisterInfo.cpp | 43 ---- lib/Target/XCore/XCoreRegisterInfo.h | 5 - 31 files changed, 796 insertions(+), 793 deletions(-) diff --git a/include/llvm/Target/TargetFrameInfo.h b/include/llvm/Target/TargetFrameInfo.h index ebaf221aadd..3e502e7d74b 100644 --- a/include/llvm/Target/TargetFrameInfo.h +++ b/include/llvm/Target/TargetFrameInfo.h @@ -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 diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index 572bbfb7ddf..9caedcb5064 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -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 diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp index c461623192c..5ba7086eef6 100644 --- a/lib/CodeGen/PrologEpilogInserter.cpp +++ b/lib/CodeGen/PrologEpilogInserter.cpp @@ -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); diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp index 42159c9f4fd..3e7c1c3075b 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -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(); - 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 UnspilledCS1GPRs; - SmallVector UnspilledCS2GPRs; - const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo(); - ARMFunctionInfo *AFI = MF.getInfo(); - 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 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; } diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.h b/lib/Target/ARM/ARMBaseRegisterInfo.h index 718f484296f..23a466fad95 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.h +++ b/lib/Target/ARM/ARMBaseRegisterInfo.h @@ -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; diff --git a/lib/Target/ARM/ARMFrameInfo.cpp b/lib/Target/ARM/ARMFrameInfo.cpp index d379bf0e9cb..e2531d04d05 100644 --- a/lib/Target/ARM/ARMFrameInfo.cpp +++ b/lib/Target/ARM/ARMFrameInfo.cpp @@ -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(); + 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 UnspilledCS1GPRs; + SmallVector UnspilledCS2GPRs; + const ARMBaseRegisterInfo *RegInfo = + static_cast(MF.getTarget().getRegisterInfo()); + const ARMBaseInstrInfo &TII = + *static_cast(MF.getTarget().getInstrInfo()); + ARMFunctionInfo *AFI = MF.getInfo(); + 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 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); + } +} diff --git a/lib/Target/ARM/ARMFrameInfo.h b/lib/Target/ARM/ARMFrameInfo.h index 7b34c1569db..886f7492ab5 100644 --- a/lib/Target/ARM/ARMFrameInfo.h +++ b/lib/Target/ARM/ARMFrameInfo.h @@ -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 &CSI, unsigned Opc, diff --git a/lib/Target/Blackfin/BlackfinFrameInfo.cpp b/lib/Target/Blackfin/BlackfinFrameInfo.cpp index 4f9054bf622..c57dc30a3ab 100644 --- a/lib/Target/Blackfin/BlackfinFrameInfo.cpp +++ b/lib/Target/Blackfin/BlackfinFrameInfo.cpp @@ -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(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)); + } +} diff --git a/lib/Target/Blackfin/BlackfinFrameInfo.h b/lib/Target/Blackfin/BlackfinFrameInfo.h index 3b53f349af0..8f46b3e1020 100644 --- a/lib/Target/Blackfin/BlackfinFrameInfo.h +++ b/lib/Target/Blackfin/BlackfinFrameInfo.h @@ -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 diff --git a/lib/Target/Blackfin/BlackfinRegisterInfo.cpp b/lib/Target/Blackfin/BlackfinRegisterInfo.cpp index 23df625a632..9865b3b4019 100644 --- a/lib/Target/Blackfin/BlackfinRegisterInfo.cpp +++ b/lib/Target/Blackfin/BlackfinRegisterInfo.cpp @@ -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; } diff --git a/lib/Target/Blackfin/BlackfinRegisterInfo.h b/lib/Target/Blackfin/BlackfinRegisterInfo.h index 0c47d25a62f..642b8adaf9b 100644 --- a/lib/Target/Blackfin/BlackfinRegisterInfo.h +++ b/lib/Target/Blackfin/BlackfinRegisterInfo.h @@ -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; diff --git a/lib/Target/CellSPU/SPUFrameInfo.cpp b/lib/Target/CellSPU/SPUFrameInfo.cpp index 114d85848bc..1b7d88be67f 100644 --- a/lib/Target/CellSPU/SPUFrameInfo.cpp +++ b/lib/Target/CellSPU/SPUFrameInfo.cpp @@ -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 &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)); +} diff --git a/lib/Target/CellSPU/SPUFrameInfo.h b/lib/Target/CellSPU/SPUFrameInfo.h index f1cb254ed08..aca6fcded5c 100644 --- a/lib/Target/CellSPU/SPUFrameInfo.h +++ b/lib/Target/CellSPU/SPUFrameInfo.h @@ -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 &Moves) const; diff --git a/lib/Target/CellSPU/SPURegisterInfo.cpp b/lib/Target/CellSPU/SPURegisterInfo.cpp index 405994a8f08..d81fc19cbd6 100644 --- a/lib/Target/CellSPU/SPURegisterInfo.cpp +++ b/lib/Target/CellSPU/SPURegisterInfo.cpp @@ -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 { diff --git a/lib/Target/CellSPU/SPURegisterInfo.h b/lib/Target/CellSPU/SPURegisterInfo.h index 9942fe115ab..641da0480a8 100644 --- a/lib/Target/CellSPU/SPURegisterInfo.h +++ b/lib/Target/CellSPU/SPURegisterInfo.h @@ -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) diff --git a/lib/Target/PowerPC/PPCFrameInfo.cpp b/lib/Target/PowerPC/PPCFrameInfo.cpp index 8fa4bdad6e1..817b8f166a0 100644 --- a/lib/Target/PowerPC/PPCFrameInfo.cpp +++ b/lib/Target/PowerPC/PPCFrameInfo.cpp @@ -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 &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(); + 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(); + + // 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(); + 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 &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 GPRegs; + SmallVector G8Regs; + SmallVector FPRegs; + SmallVector 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(); + + 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(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)); + } + } +} diff --git a/lib/Target/PowerPC/PPCFrameInfo.h b/lib/Target/PowerPC/PPCFrameInfo.h index 54448dbdd0d..204aec8a8bb 100644 --- a/lib/Target/PowerPC/PPCFrameInfo.h +++ b/lib/Target/PowerPC/PPCFrameInfo.h @@ -40,6 +40,10 @@ public: bool hasFP(const MachineFunction &MF) const; void getInitialFrameState(std::vector &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). diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp index 182b65a4ba3..daef2773323 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -58,14 +58,11 @@ cl::opt 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(); - 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(); - - // 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(); - 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 &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 GPRegs; - SmallVector G8Regs; - SmallVector FPRegs; - SmallVector 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(); - - 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(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; } diff --git a/lib/Target/PowerPC/PPCRegisterInfo.h b/lib/Target/PowerPC/PPCRegisterInfo.h index 8a9b522b2de..aa29ffef067 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.h +++ b/lib/Target/PowerPC/PPCRegisterInfo.h @@ -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; diff --git a/lib/Target/SystemZ/SystemZFrameInfo.cpp b/lib/Target/SystemZ/SystemZFrameInfo.cpp index 7fde9a0144f..d4539407733 100644 --- a/lib/Target/SystemZ/SystemZFrameInfo.cpp +++ b/lib/Target/SystemZ/SystemZFrameInfo.cpp @@ -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); +} diff --git a/lib/Target/SystemZ/SystemZFrameInfo.h b/lib/Target/SystemZ/SystemZFrameInfo.h index a977502d65b..e7f25c6d4a5 100644 --- a/lib/Target/SystemZ/SystemZFrameInfo.h +++ b/lib/Target/SystemZ/SystemZFrameInfo.h @@ -44,6 +44,9 @@ public: const std::vector &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; diff --git a/lib/Target/SystemZ/SystemZRegisterInfo.cpp b/lib/Target/SystemZ/SystemZRegisterInfo.cpp index 32f81ced5aa..401d88f7455 100644 --- a/lib/Target/SystemZ/SystemZRegisterInfo.cpp +++ b/lib/Target/SystemZ/SystemZRegisterInfo.cpp @@ -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; diff --git a/lib/Target/SystemZ/SystemZRegisterInfo.h b/lib/Target/SystemZ/SystemZRegisterInfo.h index 7d8dcfcf177..b45079889a2 100644 --- a/lib/Target/SystemZ/SystemZRegisterInfo.h +++ b/lib/Target/SystemZ/SystemZRegisterInfo.h @@ -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; diff --git a/lib/Target/X86/X86FrameInfo.cpp b/lib/Target/X86/X86FrameInfo.cpp index 192ed8ebe01..494e9050282 100644 --- a/lib/Target/X86/X86FrameInfo.cpp +++ b/lib/Target/X86/X86FrameInfo.cpp @@ -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(); + 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; + } +} diff --git a/lib/Target/X86/X86FrameInfo.h b/lib/Target/X86/X86FrameInfo.h index d265c610153..fbbde923b97 100644 --- a/lib/Target/X86/X86FrameInfo.h +++ b/lib/Target/X86/X86FrameInfo.h @@ -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 &CSI, const TargetRegisterInfo *TRI) const; -bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - const std::vector &CSI, - const TargetRegisterInfo *TRI) const; + bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + const std::vector &CSI, + const TargetRegisterInfo *TRI) const; bool hasFP(const MachineFunction &MF) const; bool hasReservedCallFrame(const MachineFunction &MF) const; diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp index 3228b141eb6..10266cd5c76 100644 --- a/lib/Target/X86/X86RegisterInfo.cpp +++ b/lib/Target/X86/X86RegisterInfo.cpp @@ -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(); - 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. diff --git a/lib/Target/X86/X86RegisterInfo.h b/lib/Target/X86/X86RegisterInfo.h index e6e235bd1a1..064be64f491 100644 --- a/lib/Target/X86/X86RegisterInfo.h +++ b/lib/Target/X86/X86RegisterInfo.h @@ -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; diff --git a/lib/Target/XCore/XCoreFrameInfo.cpp b/lib/Target/XCore/XCoreFrameInfo.cpp index cf957a7ed45..117dc37a249 100644 --- a/lib/Target/XCore/XCoreFrameInfo.cpp +++ b/lib/Target/XCore/XCoreFrameInfo.cpp @@ -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(); + 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 { + +} diff --git a/lib/Target/XCore/XCoreFrameInfo.h b/lib/Target/XCore/XCoreFrameInfo.h index 57983d179e8..9a98e16721f 100644 --- a/lib/Target/XCore/XCoreFrameInfo.h +++ b/lib/Target/XCore/XCoreFrameInfo.h @@ -44,6 +44,11 @@ namespace llvm { void getInitialFrameState(std::vector &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; diff --git a/lib/Target/XCore/XCoreRegisterInfo.cpp b/lib/Target/XCore/XCoreRegisterInfo.cpp index 1ee3c59c039..106d23bb588 100644 --- a/lib/Target/XCore/XCoreRegisterInfo.cpp +++ b/lib/Target/XCore/XCoreRegisterInfo.cpp @@ -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(); - 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 { diff --git a/lib/Target/XCore/XCoreRegisterInfo.h b/lib/Target/XCore/XCoreRegisterInfo.h index 3d21282a162..218575581d4 100644 --- a/lib/Target/XCore/XCoreRegisterInfo.h +++ b/lib/Target/XCore/XCoreRegisterInfo.h @@ -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; -- 2.11.0