X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FPrologEpilogInserter.cpp;h=39f96133bd19783ee1796f504989dfd5952a0c50;hb=f45a82890e34984ad1e1e259f8fb902caddfb0b1;hp=c52da321c1e9a05e922486ff70c1a21f279bc3a7;hpb=a8c63f0fc9feb48f17d702a907f065959c41e337;p=oota-llvm.git diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp index c52da321c1e..39f96133bd1 100644 --- a/lib/CodeGen/PrologEpilogInserter.cpp +++ b/lib/CodeGen/PrologEpilogInserter.cpp @@ -35,12 +35,18 @@ using namespace llvm; namespace { struct VISIBILITY_HIDDEN PEI : public MachineFunctionPass { static char ID; - PEI() : MachineFunctionPass((intptr_t)&ID) {} + PEI() : MachineFunctionPass(&ID) {} const char *getPassName() const { return "Prolog/Epilog Insertion & Frame Finalization"; } + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addPreservedID(MachineLoopInfoID); + AU.addPreservedID(MachineDominatorsID); + MachineFunctionPass::getAnalysisUsage(AU); + } + /// runOnMachineFunction - Insert prolog/epilog code and replace abstract /// frame indexes with appropriate references. /// @@ -50,7 +56,7 @@ namespace { // Get MachineModuleInfo so that we can track the construction of the // frame. - if (MachineModuleInfo *MMI = getAnalysisToUpdate()) + if (MachineModuleInfo *MMI = getAnalysisIfAvailable()) Fn.getFrameInfo()->setMachineModuleInfo(MMI); // Allow the target machine to make some adjustments to the function @@ -300,6 +306,32 @@ void PEI::saveCalleeSavedRegisters(MachineFunction &Fn) { } } +/// AdjustStackOffset - Helper function used to adjust the stack frame offset. +static inline void +AdjustStackOffset(MachineFrameInfo *FFI, int FrameIdx, + bool StackGrowsDown, int64_t &Offset, + unsigned &MaxAlign) { + // If stack grows down, we need to add size of find the lowest address of the + // object. + if (StackGrowsDown) + Offset += FFI->getObjectSize(FrameIdx); + + unsigned Align = FFI->getObjectAlignment(FrameIdx); + + // If the alignment of this object is greater than that of the stack, then + // increase the stack alignment to match. + MaxAlign = std::max(MaxAlign, Align); + + // Adjust to alignment boundary. + Offset = (Offset + Align - 1) / Align * Align; + + if (StackGrowsDown) { + FFI->setObjectOffset(FrameIdx, -Offset); // Set the computed offset + } else { + FFI->setObjectOffset(FrameIdx, Offset); + Offset += FFI->getObjectSize(FrameIdx); + } +} /// calculateFrameObjectOffsets - Calculate actual frame offsets for all of the /// abstract stack objects. @@ -317,7 +349,7 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { // Start at the beginning of the local area. // The Offset is the distance from the stack top in the direction - // of stack growth -- so it's always positive. + // of stack growth -- so it's always nonnegative. int64_t Offset = TFI.getOffsetOfLocalArea(); if (StackGrowsDown) Offset = -Offset; @@ -381,25 +413,16 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); if (RS && RegInfo->hasFP(Fn)) { int SFI = RS->getScavengingFrameIndex(); - if (SFI >= 0) { - // If stack grows down, we need to add size of the lowest - // address of the object. - if (StackGrowsDown) - Offset += FFI->getObjectSize(SFI); - - unsigned Align = FFI->getObjectAlignment(SFI); - // Adjust to alignment boundary - Offset = (Offset+Align-1)/Align*Align; - - if (StackGrowsDown) { - FFI->setObjectOffset(SFI, -Offset); // Set the computed offset - } else { - FFI->setObjectOffset(SFI, Offset); - Offset += FFI->getObjectSize(SFI); - } - } + if (SFI >= 0) + AdjustStackOffset(FFI, SFI, StackGrowsDown, Offset, MaxAlign); } + // Make sure that the stack protector comes before the local variables on the + // stack. + if (FFI->getStackProtectorIndex() >= 0) + AdjustStackOffset(FFI, FFI->getStackProtectorIndex(), StackGrowsDown, + Offset, MaxAlign); + // Then assign frame offsets to stack objects that are not used to spill // callee saved registers. for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) { @@ -409,65 +432,37 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { continue; if (FFI->isDeadObjectIndex(i)) continue; + if (FFI->getStackProtectorIndex() == (int)i) + continue; - // If stack grows down, we need to add size of find the lowest - // address of the object. - if (StackGrowsDown) - Offset += FFI->getObjectSize(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. - MaxAlign = std::max(MaxAlign, Align); - // Adjust to alignment boundary - Offset = (Offset+Align-1)/Align*Align; - - if (StackGrowsDown) { - FFI->setObjectOffset(i, -Offset); // Set the computed offset - } else { - FFI->setObjectOffset(i, Offset); - Offset += FFI->getObjectSize(i); - } + AdjustStackOffset(FFI, i, StackGrowsDown, Offset, MaxAlign); } // Make sure the special register scavenging spill slot is closest to the // stack pointer. 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 - // address of the object. - if (StackGrowsDown) - Offset += FFI->getObjectSize(SFI); - - unsigned Align = FFI->getObjectAlignment(SFI); - // If the alignment of this object is greater than that of the - // stack, then increase the stack alignment to match. - MaxAlign = std::max(MaxAlign, Align); - // Adjust to alignment boundary - Offset = (Offset+Align-1)/Align*Align; - - if (StackGrowsDown) { - FFI->setObjectOffset(SFI, -Offset); // Set the computed offset - } else { - FFI->setObjectOffset(SFI, Offset); - Offset += FFI->getObjectSize(SFI); - } - } + if (SFI >= 0) + AdjustStackOffset(FFI, SFI, StackGrowsDown, Offset, MaxAlign); } // Round up the size to a multiple of the alignment, but only if there are // calls or alloca's in the function. This ensures that any calls to // subroutines have their stack frames suitable aligned. + // Also do this if we need runtime alignment of the stack. In this case + // offsets will be relative to SP not FP; round up the stack size so this + // works. if (!RegInfo->targetHandlesStackFrameRounding() && - (FFI->hasCalls() || FFI->hasVarSizedObjects())) { + (FFI->hasCalls() || FFI->hasVarSizedObjects() || + (RegInfo->needsStackRealignment(Fn) && + FFI->getObjectIndexEnd() != 0))) { // 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; + unsigned AlignMask = std::max(TFI.getStackAlignment(),MaxAlign) - 1; Offset = (Offset + AlignMask) & ~uint64_t(AlignMask); } @@ -549,7 +544,7 @@ void PEI::replaceFrameIndices(MachineFunction &Fn) { bool DoIncr = true; for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) - if (MI->getOperand(i).isFrameIndex()) { + if (MI->getOperand(i).isFI()) { // Some instructions (e.g. inline asm instructions) can have // multiple frame indices and/or cause eliminateFrameIndex // to insert more than one instruction. We need the register