X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FPrologEpilogInserter.cpp;h=d3b0b11c705957eb2a720b6de1fd0d5e3727a186;hb=f9410141f703f4e8a6aba717617ef958249f6d13;hp=3106455850931defc66aa541e9a1c24491b15ff4;hpb=be680dcea6858c438c6615326ae1c098ff448ae1;p=oota-llvm.git diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp index 31064558509..d3b0b11c705 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. /// @@ -68,7 +74,7 @@ namespace { // Allow the target machine to make final modifications to the function // before the frame layout is finalized. - Fn.getTarget().getRegisterInfo()->processFunctionBeforeFrameFinalized(Fn); + TRI->processFunctionBeforeFrameFinalized(Fn); // Calculate actual frame offsets for all of the abstract stack objects... calculateFrameObjectOffsets(Fn); @@ -313,11 +319,11 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { // Loop over all of the stack objects, assigning sequential addresses... MachineFrameInfo *FFI = Fn.getFrameInfo(); - unsigned MaxAlign = 0; + unsigned MaxAlign = FFI->getMaxAlignment(); // 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; @@ -362,7 +368,8 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { FFI->setObjectOffset(i, -Offset); // Set the computed offset } } else { - for (unsigned i = MaxCSFrameIndex; i >= MinCSFrameIndex; --i) { + int MaxCSFI = MaxCSFrameIndex, MinCSFI = MinCSFrameIndex; + for (int i = MaxCSFI; i >= MinCSFI ; --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. @@ -458,15 +465,20 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { // 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); } @@ -484,14 +496,16 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { /// prolog and epilog code to the function. /// void PEI::insertPrologEpilogCode(MachineFunction &Fn) { + const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo(); + // Add prologue to the function... - Fn.getTarget().getRegisterInfo()->emitPrologue(Fn); + TRI->emitPrologue(Fn); // Add epilogue to restore the callee-save registers in each exiting block for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) { // If last instruction is a return instruction, add an epilogue if (!I->empty() && I->back().getDesc().isReturn()) - Fn.getTarget().getRegisterInfo()->emitEpilogue(Fn, *I); + TRI->emitEpilogue(Fn, *I); } } @@ -517,40 +531,67 @@ void PEI::replaceFrameIndices(MachineFunction &Fn) { for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) { MachineInstr *MI = I; + if (I->getOpcode() == TargetInstrInfo::DECLARE) { + // Ignore it. + ++I; + continue; + } + if (I->getOpcode() == FrameSetupOpcode || I->getOpcode() == FrameDestroyOpcode) { - // Remember how much SP has been adjustment to create the call frame. + // Remember how much SP has been adjusted to create the call + // frame. int Size = I->getOperand(0).getImm(); + if ((!StackGrowsDown && I->getOpcode() == FrameSetupOpcode) || (StackGrowsDown && I->getOpcode() == FrameDestroyOpcode)) Size = -Size; + SPAdj += Size; + MachineBasicBlock::iterator PrevI = prior(I); TRI.eliminateCallFramePseudoInstr(Fn, *BB, I); + // Visit the instructions created by eliminateCallFramePseudoInstr(). I = next(PrevI); - MI = NULL; - } else if (I->getOpcode() == TargetInstrInfo::DECLARE) - // Ignore it. - I++; - 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. - TRI.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; - } + continue; } + + bool DoIncr = true; + + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) + 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 + // scavenger to go through all of these instructions so that + // it can update its register information. We keep the + // iterator at the point before insertion so that we can + // revisit them in full. + bool AtBeginning = (I == BB->begin()); + if (!AtBeginning) --I; + + // If this instruction has a FrameIndex operand, we need to + // use that target machine register info object to eliminate + // it. + TRI.eliminateFrameIndex(MI, SPAdj, RS); + + // Reset the iterator if we were at the beginning of the BB. + if (AtBeginning) { + I = BB->begin(); + DoIncr = false; + } + + MI = 0; + break; + } + + if (DoIncr) ++I; + // Update register states. if (RS && MI) RS->forward(MI); } + assert(SPAdj == 0 && "Unbalanced call frame setup / destroy pairs?"); } }