#include "llvm/Target/TargetFrameInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/ADT/STLExtras.h"
#include <climits>
using namespace llvm;
namespace {
struct VISIBILITY_HIDDEN PEI : public MachineFunctionPass {
+ static char ID;
+ PEI() : MachineFunctionPass((intptr_t)&ID) {}
+
const char *getPassName() const {
return "Prolog/Epilog Insertion & Frame Finalization";
}
void replaceFrameIndices(MachineFunction &Fn);
void insertPrologEpilogCode(MachineFunction &Fn);
};
+ char PEI::ID = 0;
}
const TargetFrameInfo *TFI = Fn.getTarget().getFrameInfo();
// Get the callee saved register list...
- const unsigned *CSRegs = RegInfo->getCalleeSavedRegs();
+ const unsigned *CSRegs = RegInfo->getCalleeSavedRegs(&Fn);
// Get the function call frame set-up and tear-down instruction opcode
int FrameSetupOpcode = RegInfo->getCallFrameSetupOpcode();
unsigned MaxCallFrameSize = 0;
bool HasCalls = false;
+ std::vector<MachineBasicBlock::iterator> FrameSDOps;
for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB)
- for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); )
+ for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I)
if (I->getOpcode() == FrameSetupOpcode ||
I->getOpcode() == FrameDestroyOpcode) {
assert(I->getNumOperands() >= 1 && "Call Frame Setup/Destroy Pseudo"
unsigned Size = I->getOperand(0).getImmedValue();
if (Size > MaxCallFrameSize) MaxCallFrameSize = Size;
HasCalls = true;
- RegInfo->eliminateCallFramePseudoInstr(Fn, *BB, I++);
- } else {
- ++I;
+ FrameSDOps.push_back(I);
}
MachineFrameInfo *FFI = Fn.getFrameInfo();
FFI->setHasCalls(HasCalls);
FFI->setMaxCallFrameSize(MaxCallFrameSize);
+ for (unsigned i = 0, e = FrameSDOps.size(); i != e; ++i) {
+ MachineBasicBlock::iterator I = FrameSDOps[i];
+ // If call frames are not being included as part of the stack frame,
+ // and there is no dynamic allocation (therefore referencing frame slots
+ // off sp), leave the pseudo ops alone. We'll eliminate them later.
+ if (RegInfo->hasReservedCallFrame(Fn) || RegInfo->hasFP(Fn))
+ RegInfo->eliminateCallFramePseudoInstr(Fn, *I->getParent(), I);
+ }
+
// Now figure out which *callee saved* registers are modified by the current
// function, thus needing to be saved and restored in the prolog/epilog.
//
const TargetRegisterClass* const *CSRegClasses =
- RegInfo->getCalleeSavedRegClasses();
+ RegInfo->getCalleeSavedRegClasses(&Fn);
std::vector<CalleeSavedInfo> CSI;
for (unsigned i = 0; CSRegs[i]; ++i) {
unsigned Reg = CSRegs[i];
// First assign frame offsets to stack objects that are used to spill
// callee saved registers.
if (StackGrowsDown) {
- for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) {
- if (i < MinCSFrameIndex || i > MaxCSFrameIndex)
- continue;
-
+ for (unsigned i = MinCSFrameIndex; i <= MaxCSFrameIndex; ++i) {
// If stack grows down, we need to add size of find the lowest
// address of the object.
Offset += FFI->getObjectSize(i);
FFI->setObjectOffset(i, -Offset); // Set the computed offset
}
} else {
- for (int i = FFI->getObjectIndexEnd()-1; i >= 0; --i) {
- if ((unsigned)i < MinCSFrameIndex || (unsigned)i > MaxCSFrameIndex)
- continue;
-
+ for (unsigned i = MaxCSFrameIndex; i >= MinCSFrameIndex; --i) {
unsigned Align = FFI->getObjectAlignment(i);
// If the alignment of this object is greater than that of the stack, then
// increase the stack alignment to match.
if (RS && RegInfo->hasFP(Fn)) {
int SFI = RS->getScavengingFrameIndex();
if (SFI >= 0) {
- // If stack grows down, we need to add size of find the lowest
+ // If stack grows down, we need to add size of the lowest
// address of the object.
if (StackGrowsDown)
Offset += FFI->getObjectSize(SFI);
// Make sure the special register scavenging spill slot is closest to the
// stack pointer.
- if (RS) {
+ if (RS && !RegInfo->hasFP(Fn)) {
int SFI = RS->getScavengingFrameIndex();
if (SFI >= 0) {
// If stack grows down, we need to add size of find the lowest
// subroutines have their stack frames suitable aligned.
if (!RegInfo->targetHandlesStackFrameRounding() &&
(FFI->hasCalls() || FFI->hasVarSizedObjects())) {
- // When we have no frame pointer, we reserve argument space for call sites
- // in the function immediately on entry to the current function. This
- // eliminates the need for add/sub sp brackets around call sites.
- if (!RegInfo->hasFP(Fn))
+ // If we have reserved argument space for call sites in the function
+ // immediately on entry to the current function, count it as part of the
+ // overall stack size.
+ if (RegInfo->hasReservedCallFrame(Fn))
Offset += FFI->getMaxCallFrameSize();
unsigned AlignMask = TFI.getStackAlignment() - 1;
const TargetMachine &TM = Fn.getTarget();
assert(TM.getRegisterInfo() && "TM::getRegisterInfo() must be implemented!");
const MRegisterInfo &MRI = *TM.getRegisterInfo();
+ const TargetFrameInfo *TFI = TM.getFrameInfo();
+ bool StackGrowsDown =
+ TFI->getStackGrowthDirection() == TargetFrameInfo::StackGrowsDown;
+ int FrameSetupOpcode = MRI.getCallFrameSetupOpcode();
+ int FrameDestroyOpcode = MRI.getCallFrameDestroyOpcode();
for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) {
+ int SPAdj = 0; // SP offset due to call frame setup / destroy.
if (RS) RS->enterBasicBlock(BB);
for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) {
- MachineInstr *MI = I++;
- for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i)
- if (MI->getOperand(i).isFrameIndex()) {
- // If this instruction has a FrameIndex operand, we need to use that
- // target machine register info object to eliminate it.
- MRI.eliminateFrameIndex(MI, RS);
-
- // Revisit the instruction in full. Some instructions (e.g. inline
- // asm instructions) can have multiple frame indices.
- --I;
- MI = 0;
- break;
- }
+ MachineInstr *MI = I;
+
+ // Remember how much SP has been adjustment to create the call frame.
+ if (I->getOpcode() == FrameSetupOpcode ||
+ I->getOpcode() == FrameDestroyOpcode) {
+ int Size = I->getOperand(0).getImmedValue();
+ if ((!StackGrowsDown && I->getOpcode() == FrameSetupOpcode) ||
+ (StackGrowsDown && I->getOpcode() == FrameDestroyOpcode))
+ Size = -Size;
+ SPAdj += Size;
+ MachineBasicBlock::iterator PrevI = prior(I);
+ MRI.eliminateCallFramePseudoInstr(Fn, *BB, I);
+ // Visit the instructions created by eliminateCallFramePseudoInstr().
+ I = next(PrevI);
+ MI = NULL;
+ } else {
+ I++;
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i)
+ if (MI->getOperand(i).isFrameIndex()) {
+ // If this instruction has a FrameIndex operand, we need to use that
+ // target machine register info object to eliminate it.
+ MRI.eliminateFrameIndex(MI, SPAdj, RS);
+
+ // Revisit the instruction in full. Some instructions (e.g. inline
+ // asm instructions) can have multiple frame indices.
+ --I;
+ MI = 0;
+ break;
+ }
+ }
// Update register states.
if (RS && MI) RS->forward(MI);
}
+ assert(SPAdj == 0 && "Unbalanced call frame setup / destroy pairs?");
}
}