X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FPrologEpilogInserter.cpp;h=9e7ad6752a73d188388834e6f06c182bc76ef163;hb=74d3f50a803347432b3dc26f67e23297c2a1f232;hp=8efef1beb577058ed79cc794af7344b6cd8cdb25;hpb=bbeeb2a61ea19fbb5449260165b56c40fdc4860b;p=oota-llvm.git diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp index 8efef1beb57..9e7ad6752a7 100644 --- a/lib/CodeGen/PrologEpilogInserter.cpp +++ b/lib/CodeGen/PrologEpilogInserter.cpp @@ -14,10 +14,14 @@ // This pass must be run after register allocation. After this pass is // executed, it is illegal to construct MO_FrameIndex operands. // +// This pass provides an optional shrink wrapping variant of prolog/epilog +// insertion, enabled via --shrink-wrap. See ShrinkWrapping.cpp. +// //===----------------------------------------------------------------------===// -#include "llvm/CodeGen/Passes.h" -#include "llvm/CodeGen/MachineFunctionPass.h" +#include "PrologEpilogInserter.h" +#include "llvm/CodeGen/MachineDominators.h" +#include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineModuleInfo.h" @@ -30,92 +34,88 @@ #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.setPreservesAll(); - MachineFunctionPass::getAnalysisUsage(AU); - } - - /// runOnMachineFunction - Insert prolog/epilog code and replace abstract - /// frame indexes with appropriate references. - /// - bool runOnMachineFunction(MachineFunction &Fn) { - 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()) - Fn.getFrameInfo()->setMachineModuleInfo(MMI); - - // Allow the target machine to make some adjustments to the function - // e.g. UsedPhysRegs before calculateCalleeSavedRegisters. - 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 - // the MaxCallFrameSize and HasCalls variables for the function's frame - // information and eliminates call frame pseudo instructions. - calculateCalleeSavedRegisters(Fn); - - // Add the code to save and restore the callee saved registers - saveCalleeSavedRegisters(Fn); - - // Allow the target machine to make final modifications to the function - // before the frame layout is finalized. - TRI->processFunctionBeforeFrameFinalized(Fn); - - // Calculate actual frame offsets for all of the abstract stack objects... - calculateFrameObjectOffsets(Fn); - - // Add prolog and epilog code to the function. This function is required - // to align the stack frame as necessary for any stack variables or - // called functions. Because of this, calculateCalleeSavedRegisters - // must be called before this function in order to set the HasCalls - // and MaxCallFrameSize variables. - insertPrologEpilogCode(Fn); - - // Replace all MO_FrameIndex operands with physical register references - // and actual offsets. - // - replaceFrameIndices(Fn); - - delete RS; - return true; - } - - private: - RegScavenger *RS; - - // MinCSFrameIndex, MaxCSFrameIndex - Keeps the range of callee saved - // stack frame indexes. - unsigned MinCSFrameIndex, MaxCSFrameIndex; - - void calculateCalleeSavedRegisters(MachineFunction &Fn); - void saveCalleeSavedRegisters(MachineFunction &Fn); - void calculateFrameObjectOffsets(MachineFunction &Fn); - void replaceFrameIndices(MachineFunction &Fn); - void insertPrologEpilogCode(MachineFunction &Fn); - }; - char PEI::ID = 0; -} +char PEI::ID = 0; +static RegisterPass +X("prologepilog", "Prologue/Epilogue Insertion"); /// createPrologEpilogCodeInserter - This function returns a pass that inserts /// prolog and epilog code, and eliminates abstract frame references. /// FunctionPass *llvm::createPrologEpilogCodeInserter() { return new PEI(); } +/// runOnMachineFunction - Insert prolog/epilog code and replace abstract +/// frame indexes with appropriate references. +/// +bool PEI::runOnMachineFunction(MachineFunction &Fn) { + 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 = getAnalysisIfAvailable()) + Fn.getFrameInfo()->setMachineModuleInfo(MMI); + + // Allow the target machine to make some adjustments to the function + // e.g. UsedPhysRegs before calculateCalleeSavedRegisters. + 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 + // the MaxCallFrameSize and HasCalls variables for the function's frame + // information and eliminates call frame pseudo instructions. + calculateCalleeSavedRegisters(Fn); + + // Determine placement of CSR spill/restore code: + // - with shrink wrapping, place spills and restores to tightly + // enclose regions in the Machine CFG of the function where + // they are used. Without shrink wrapping + // - default (no shrink wrapping), place all spills in the + // entry block, all restores in return blocks. + placeCSRSpillsAndRestores(Fn); + + // Add the code to save and restore the callee saved registers + insertCSRSpillsAndRestores(Fn); + + // Allow the target machine to make final modifications to the function + // before the frame layout is finalized. + TRI->processFunctionBeforeFrameFinalized(Fn); + + // Calculate actual frame offsets for all abstract stack objects... + calculateFrameObjectOffsets(Fn); + + // Add prolog and epilog code to the function. This function is required + // to align the stack frame as necessary for any stack variables or + // called functions. Because of this, calculateCalleeSavedRegisters + // must be called before this function in order to set the HasCalls + // and MaxCallFrameSize variables. + insertPrologEpilogCode(Fn); + + // Replace all MO_FrameIndex operands with physical register references + // and actual offsets. + // + replaceFrameIndices(Fn); + + delete RS; + clearAllSets(); + return true; +} + +#if 0 +void PEI::getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesCFG(); + if (ShrinkWrapping || ShrinkWrapFunc != "") { + AU.addRequired(); + AU.addRequired(); + } + AU.addPreserved(); + AU.addPreserved(); + MachineFunctionPass::getAnalysisUsage(AU); +} +#endif /// calculateCalleeSavedRegisters - Scan the function for modified callee saved /// registers. Also calculate the MaxCallFrameSize and HasCalls variables for @@ -220,7 +220,8 @@ void PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) { unsigned Align = RC->getAlignment(); unsigned StackAlign = TFI->getStackAlignment(); // We may not be able to sastify the desired alignment specification of - // the TargetRegisterClass if the stack alignment is smaller. Use the min. + // the TargetRegisterClass if the stack alignment is smaller. + // Use the min. Align = std::min(Align, StackAlign); FrameIdx = FFI->CreateStackObject(RC->getSize(), Align); if ((unsigned)FrameIdx < MinCSFrameIndex) MinCSFrameIndex = FrameIdx; @@ -235,41 +236,39 @@ void PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) { FFI->setCalleeSavedInfo(CSI); } -/// saveCalleeSavedRegisters - Insert spill code for any callee saved registers -/// that are modified in the function. +/// insertCSRSpillsAndRestores - Insert spill and restore code for +/// callee saved registers used in the function, handling shrink wrapping. /// -void PEI::saveCalleeSavedRegisters(MachineFunction &Fn) { +void PEI::insertCSRSpillsAndRestores(MachineFunction &Fn) { // Get callee saved register information. MachineFrameInfo *FFI = Fn.getFrameInfo(); const std::vector &CSI = FFI->getCalleeSavedInfo(); - + // Early exit if no callee saved registers are modified! if (CSI.empty()) return; 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 (!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. - TII.storeRegToStackSlot(*MBB, I, CSI[i].getReg(), true, - CSI[i].getFrameIdx(), CSI[i].getRegClass()); + MachineBasicBlock::iterator I; + + if (! ShrinkWrapThisFunction) { + // Spill using target interface. + I = EntryBlock->begin(); + if (!TII.spillCalleeSavedRegisters(*EntryBlock, 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. + EntryBlock->addLiveIn(CSI[i].getReg()); + + // Insert the spill to the stack frame. + TII.storeRegToStackSlot(*EntryBlock, I, CSI[i].getReg(), true, + CSI[i].getFrameIdx(), CSI[i].getRegClass()); + } } - } - // Add code to restore the callee-save registers in each exiting block. - 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() && FI->back().getDesc().isReturn()) { - MBB = FI; + // Restore using target interface. + for (unsigned ri = 0, re = ReturnBlocks.size(); ri != re; ++ri) { + MachineBasicBlock* MBB = ReturnBlocks[ri]; I = MBB->end(); --I; // Skip over all terminator instructions, which are part of the return @@ -282,18 +281,18 @@ void PEI::saveCalleeSavedRegisters(MachineFunction &Fn) { MachineBasicBlock::iterator BeforeI = I; if (!AtStart) --BeforeI; - - // Restore all registers immediately before the return and any terminators - // that preceed it. + + // Restore all registers immediately before the return and any + // terminators that preceed it. if (!TII.restoreCalleeSavedRegisters(*MBB, I, CSI)) { for (unsigned i = 0, e = CSI.size(); i != e; ++i) { TII.loadRegFromStackSlot(*MBB, I, CSI[i].getReg(), - CSI[i].getFrameIdx(), - CSI[i].getRegClass()); + CSI[i].getFrameIdx(), + CSI[i].getRegClass()); assert(I != MBB->begin() && "loadRegFromStackSlot didn't insert any code!"); - // Insert in reverse order. loadRegFromStackSlot can insert multiple - // instructions. + // Insert in reverse order. loadRegFromStackSlot can insert + // multiple instructions. if (AtStart) I = MBB->begin(); else { @@ -303,8 +302,128 @@ void PEI::saveCalleeSavedRegisters(MachineFunction &Fn) { } } } + return; + } + + // Insert spills. + std::vector blockCSI; + for (CSRegBlockMap::iterator BI = CSRSave.begin(), + BE = CSRSave.end(); BI != BE; ++BI) { + MachineBasicBlock* MBB = BI->first; + CSRegSet save = BI->second; + + if (save.empty()) + continue; + + blockCSI.clear(); + for (CSRegSet::iterator RI = save.begin(), + RE = save.end(); RI != RE; ++RI) { + blockCSI.push_back(CSI[*RI]); + } + assert(blockCSI.size() > 0 && + "Could not collect callee saved register info"); + + I = MBB->begin(); + + // When shrink wrapping, use stack slot stores/loads. + for (unsigned i = 0, e = blockCSI.size(); i != e; ++i) { + // Add the callee-saved register as live-in. + // It's killed at the spill. + MBB->addLiveIn(blockCSI[i].getReg()); + + // Insert the spill to the stack frame. + TII.storeRegToStackSlot(*MBB, I, blockCSI[i].getReg(), + true, + blockCSI[i].getFrameIdx(), + blockCSI[i].getRegClass()); + } + } + + for (CSRegBlockMap::iterator BI = CSRRestore.begin(), + BE = CSRRestore.end(); BI != BE; ++BI) { + MachineBasicBlock* MBB = BI->first; + CSRegSet restore = BI->second; + + if (restore.empty()) + continue; + + blockCSI.clear(); + for (CSRegSet::iterator RI = restore.begin(), + RE = restore.end(); RI != RE; ++RI) { + blockCSI.push_back(CSI[*RI]); + } + assert(blockCSI.size() > 0 && + "Could not find callee saved register info"); + + // If MBB is empty and needs restores, insert at the _beginning_. + if (MBB->empty()) { + I = MBB->begin(); + } else { + I = MBB->end(); + --I; + + // Skip over all terminator instructions, which are part of the + // return sequence. + if (! I->getDesc().isTerminator()) { + ++I; + } else { + MachineBasicBlock::iterator I2 = I; + while (I2 != MBB->begin() && (--I2)->getDesc().isTerminator()) + I = I2; + } + } + + bool AtStart = I == MBB->begin(); + MachineBasicBlock::iterator BeforeI = I; + if (!AtStart) + --BeforeI; + + // Restore all registers immediately before the return and any + // terminators that preceed it. + for (unsigned i = 0, e = blockCSI.size(); i != e; ++i) { + TII.loadRegFromStackSlot(*MBB, I, blockCSI[i].getReg(), + blockCSI[i].getFrameIdx(), + blockCSI[i].getRegClass()); + assert(I != MBB->begin() && + "loadRegFromStackSlot didn't insert any code!"); + // Insert in reverse order. loadRegFromStackSlot can insert + // multiple instructions. + if (AtStart) + I = MBB->begin(); + else { + I = BeforeI; + ++I; + } + } + } } +/// 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. @@ -331,8 +450,8 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { // If there are fixed sized objects that are preallocated in the local area, // non-fixed objects can't be allocated right at the start of local area. - // We currently don't support filling in holes in between fixed sized objects, - // so we adjust 'Offset' to point to the end of last fixed sized + // We currently don't support filling in holes in between fixed sized + // objects, so we adjust 'Offset' to point to the end of last fixed sized // preallocated object. for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) { int64_t FixedOff; @@ -358,8 +477,8 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { 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. + // 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; @@ -370,8 +489,8 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { 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. + // 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; @@ -386,25 +505,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) { @@ -414,51 +524,18 @@ 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 @@ -468,7 +545,7 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { // 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 @@ -524,12 +601,12 @@ void PEI::replaceFrameIndices(MachineFunction &Fn) { int FrameSetupOpcode = TRI.getCallFrameSetupOpcode(); int FrameDestroyOpcode = TRI.getCallFrameDestroyOpcode(); - for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) { + 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 (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) { if (I->getOpcode() == TargetInstrInfo::DECLARE) { // Ignore it. ++I; @@ -548,18 +625,22 @@ void PEI::replaceFrameIndices(MachineFunction &Fn) { SPAdj += Size; - MachineBasicBlock::iterator PrevI = prior(I); + MachineBasicBlock::iterator PrevI = BB->end(); + if (I != BB->begin()) PrevI = prior(I); TRI.eliminateCallFramePseudoInstr(Fn, *BB, I); // Visit the instructions created by eliminateCallFramePseudoInstr(). - I = next(PrevI); + if (PrevI == BB->end()) + I = BB->begin(); // The replaced instr was the first in the block. + else + I = next(PrevI); continue; } + MachineInstr *MI = I; 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 @@ -573,6 +654,7 @@ void PEI::replaceFrameIndices(MachineFunction &Fn) { // 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. @@ -585,7 +667,7 @@ void PEI::replaceFrameIndices(MachineFunction &Fn) { break; } - if (DoIncr) ++I; + if (DoIncr && I != BB->end()) ++I; // Update register states. if (RS && MI) RS->forward(MI); @@ -594,3 +676,4 @@ void PEI::replaceFrameIndices(MachineFunction &Fn) { assert(SPAdj == 0 && "Unbalanced call frame setup / destroy pairs?"); } } +