X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FPrologEpilogInserter.cpp;h=322c28bd4ddbfc0dc20a3f918d5e4374440eece6;hb=b169426272b85ce28a9a56d13154e61b158fc47a;hp=b76fa3f4eb4b2d6d630da9ed1e6097e4804eb81a;hpb=d2eae62e93fc6e398263a952609b6ea60a204802;p=oota-llvm.git diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp index b76fa3f4eb4..322c28bd4dd 100644 --- a/lib/CodeGen/PrologEpilogInserter.cpp +++ b/lib/CodeGen/PrologEpilogInserter.cpp @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -20,37 +20,48 @@ #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/RegisterScavenging.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Target/MRegisterInfo.h" +#include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetFrameInfo.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Support/Compiler.h" +#include "llvm/ADT/STLExtras.h" #include using namespace llvm; namespace { struct VISIBILITY_HIDDEN PEI : public MachineFunctionPass { + static char 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. /// bool runOnMachineFunction(MachineFunction &Fn) { - const MRegisterInfo *MRI = Fn.getTarget().getRegisterInfo(); - RS = MRI->requiresRegisterScavenging(Fn) ? new RegScavenger() : NULL; + const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo(); + RS = TRI->requiresRegisterScavenging(Fn) ? new RegScavenger() : NULL; // 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 // e.g. UsedPhysRegs before calculateCalleeSavedRegisters. - MRI->processFunctionBeforeCalleeSavedScan(Fn, RS); + TRI->processFunctionBeforeCalleeSavedScan(Fn, RS); // Scan the function for modified callee saved registers and insert spill // code for any callee saved registers that are modified. Also calculate @@ -63,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); @@ -97,6 +108,7 @@ namespace { void replaceFrameIndices(MachineFunction &Fn); void insertPrologEpilogCode(MachineFunction &Fn); }; + char PEI::ID = 0; } @@ -112,11 +124,11 @@ FunctionPass *llvm::createPrologEpilogCodeInserter() { return new PEI(); } /// instructions. /// void PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) { - const MRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); + const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); 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(); @@ -135,40 +147,47 @@ void PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) { unsigned MaxCallFrameSize = 0; bool HasCalls = false; + std::vector 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" " instructions should have a single immediate argument!"); - unsigned Size = I->getOperand(0).getImmedValue(); + unsigned Size = I->getOperand(0).getImm(); 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 bool *PhysRegsUsed = Fn.getUsedPhysregs(); const TargetRegisterClass* const *CSRegClasses = - RegInfo->getCalleeSavedRegClasses(); + RegInfo->getCalleeSavedRegClasses(&Fn); std::vector CSI; for (unsigned i = 0; CSRegs[i]; ++i) { unsigned Reg = CSRegs[i]; - if (PhysRegsUsed[Reg]) { + if (Fn.getRegInfo().isPhysRegUsed(Reg)) { // If the reg is modified, save it! CSI.push_back(CalleeSavedInfo(Reg, CSRegClasses[i])); } else { for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg); *AliasSet; ++AliasSet) { // Check alias registers too. - if (PhysRegsUsed[*AliasSet]) { + if (Fn.getRegInfo().isPhysRegUsed(*AliasSet)) { CSI.push_back(CalleeSavedInfo(Reg, CSRegClasses[i])); break; } @@ -229,35 +248,35 @@ void PEI::saveCalleeSavedRegisters(MachineFunction &Fn) { if (CSI.empty()) return; - const MRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); + const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); // Now that we have a stack slot for each register to be saved, insert spill // code into the entry block. MachineBasicBlock *MBB = Fn.begin(); MachineBasicBlock::iterator I = MBB->begin(); - if (!RegInfo->spillCalleeSavedRegisters(*MBB, I, CSI)) { + + if (!TII.spillCalleeSavedRegisters(*MBB, I, CSI)) { for (unsigned i = 0, e = CSI.size(); i != e; ++i) { // Add the callee-saved register as live-in. It's killed at the spill. MBB->addLiveIn(CSI[i].getReg()); // Insert the spill to the stack frame. - RegInfo->storeRegToStackSlot(*MBB, I, CSI[i].getReg(), + TII.storeRegToStackSlot(*MBB, I, CSI[i].getReg(), true, CSI[i].getFrameIdx(), CSI[i].getRegClass()); } } // Add code to restore the callee-save registers in each exiting block. - const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); for (MachineFunction::iterator FI = Fn.begin(), E = Fn.end(); FI != E; ++FI) // If last instruction is a return instruction, add an epilogue. - if (!FI->empty() && TII.isReturn(FI->back().getOpcode())) { + if (!FI->empty() && FI->back().getDesc().isReturn()) { MBB = FI; I = MBB->end(); --I; // Skip over all terminator instructions, which are part of the return // sequence. MachineBasicBlock::iterator I2 = I; - while (I2 != MBB->begin() && TII.isTerminatorInstr((--I2)->getOpcode())) + while (I2 != MBB->begin() && (--I2)->getDesc().isTerminator()) I = I2; bool AtStart = I == MBB->begin(); @@ -267,9 +286,9 @@ void PEI::saveCalleeSavedRegisters(MachineFunction &Fn) { // Restore all registers immediately before the return and any terminators // that preceed it. - if (!RegInfo->restoreCalleeSavedRegisters(*MBB, I, CSI)) { + if (!TII.restoreCalleeSavedRegisters(*MBB, I, CSI)) { for (unsigned i = 0, e = CSI.size(); i != e; ++i) { - RegInfo->loadRegFromStackSlot(*MBB, I, CSI[i].getReg(), + TII.loadRegFromStackSlot(*MBB, I, CSI[i].getReg(), CSI[i].getFrameIdx(), CSI[i].getRegClass()); assert(I != MBB->begin() && @@ -287,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. @@ -300,12 +345,12 @@ 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. - int Offset = TFI.getOffsetOfLocalArea(); + // of stack growth -- so it's always nonnegative. + int64_t Offset = TFI.getOffsetOfLocalArea(); if (StackGrowsDown) Offset = -Offset; assert(Offset >= 0 @@ -317,7 +362,7 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { // so we adjust 'Offset' to point to the end of last fixed sized // preallocated object. for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) { - int FixedOff; + int64_t FixedOff; if (StackGrowsDown) { // The maximum distance from the stack pointer is at lower address of // the object -- which is given by offset. For down growing stack @@ -334,10 +379,7 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { // 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); @@ -352,10 +394,8 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { 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; - + 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. @@ -370,28 +410,19 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { // Make sure the special register scavenging spill slot is closest to the // frame pointer if a frame pointer is required. - const MRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); + 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 find 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) { @@ -399,63 +430,40 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { continue; if (RS && (int)i == RS->getScavengingFrameIndex()) 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) { + 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); - // 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())) { - // 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)) + (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; - Offset = (Offset + AlignMask) & ~AlignMask; + unsigned AlignMask = std::max(TFI.getStackAlignment(),MaxAlign) - 1; + Offset = (Offset + AlignMask) & ~uint64_t(AlignMask); } // Update frame info to pretend that this is part of the stack... @@ -463,8 +471,7 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { // Remember the required stack alignment in case targets need it to perform // dynamic stack alignment. - assert(FFI->getMaxAlignment() == MaxAlign && - "Stack alignment calculation broken!"); + FFI->setMaxAlignment(MaxAlign); } @@ -473,15 +480,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 - const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo(); 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() && TII.isReturn(I->back().getOpcode())) - Fn.getTarget().getRegisterInfo()->emitEpilogue(Fn, *I); + if (!I->empty() && I->back().getDesc().isReturn()) + TRI->emitEpilogue(Fn, *I); } } @@ -494,24 +502,84 @@ void PEI::replaceFrameIndices(MachineFunction &Fn) { const TargetMachine &TM = Fn.getTarget(); assert(TM.getRegisterInfo() && "TM::getRegisterInfo() must be implemented!"); - const MRegisterInfo &MRI = *TM.getRegisterInfo(); + const TargetRegisterInfo &TRI = *TM.getRegisterInfo(); + const TargetFrameInfo *TFI = TM.getFrameInfo(); + bool StackGrowsDown = + TFI->getStackGrowthDirection() == TargetFrameInfo::StackGrowsDown; + int FrameSetupOpcode = TRI.getCallFrameSetupOpcode(); + int FrameDestroyOpcode = TRI.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(); ++I) { - for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) - if (I->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(I, RS); - - // Revisit the instruction in full. Some instructions (e.g. inline - // asm instructions) can have multiple frame indices. - e = I->getNumOperands(); - i = -1U; + 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 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 = BB->end(); + if (I != BB->begin()) PrevI = prior(I); + TRI.eliminateCallFramePseudoInstr(Fn, *BB, I); + + // Visit the instructions created by eliminateCallFramePseudoInstr(). + if (PrevI == BB->end()) + I = BB->begin(); // The replaced instr was the first in the block. + else + I = next(PrevI); + 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 != BB->end()) ++I; + // Update register states. - if (RS) RS->forward(I); + if (RS && MI) RS->forward(MI); } + + assert(SPAdj == 0 && "Unbalanced call frame setup / destroy pairs?"); } }