X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FPrologEpilogInserter.cpp;h=6157e3fc99f607248f43d4a306c916f423183ddb;hb=deb9971061cfb9c57930724fcf8d62fb26dc2213;hp=a60b8b127bf8ddf9efa516a735a08dc573677769;hpb=b576c94c15af9a440f69d9d03c2afead7971118c;p=oota-llvm.git diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp index a60b8b127bf..6157e3fc99f 100644 --- a/lib/CodeGen/PrologEpilogInserter.cpp +++ b/lib/CodeGen/PrologEpilogInserter.cpp @@ -24,6 +24,7 @@ #include "llvm/Target/MRegisterInfo.h" #include "llvm/Target/TargetFrameInfo.h" #include "llvm/Target/TargetInstrInfo.h" +using namespace llvm; namespace { struct PEI : public MachineFunctionPass { @@ -66,10 +67,11 @@ namespace { }; } + /// createPrologEpilogCodeInserter - This function returns a pass that inserts /// prolog and epilog code, and eliminates abstract frame references. /// -FunctionPass *createPrologEpilogCodeInserter() { return new PEI(); } +FunctionPass *llvm::createPrologEpilogCodeInserter() { return new PEI(); } /// saveCallerSavedRegisters - Scan the function for modified caller saved @@ -80,7 +82,7 @@ FunctionPass *createPrologEpilogCodeInserter() { return new PEI(); } /// void PEI::saveCallerSavedRegisters(MachineFunction &Fn) { const MRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); - const TargetFrameInfo &FrameInfo = Fn.getTarget().getFrameInfo(); + const TargetFrameInfo &FrameInfo = *Fn.getTarget().getFrameInfo(); // Get the callee saved register list... const unsigned *CSRegs = RegInfo->getCalleeSaveRegs(); @@ -96,29 +98,29 @@ void PEI::saveCallerSavedRegisters(MachineFunction &Fn) { return; // This bitset contains an entry for each physical register for the target... - std::vector ModifiedRegs(MRegisterInfo::FirstVirtualRegister); + std::vector ModifiedRegs(RegInfo->getNumRegs()); unsigned MaxCallFrameSize = 0; bool HasCalls = false; for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) - if ((*I)->getOpcode() == FrameSetupOpcode || - (*I)->getOpcode() == FrameDestroyOpcode) { - assert((*I)->getNumOperands() == 1 && "Call Frame Setup/Destroy Pseudo" + 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).getImmedValue(); if (Size > MaxCallFrameSize) MaxCallFrameSize = Size; HasCalls = true; - RegInfo->eliminateCallFramePseudoInstr(Fn, *BB, I); + RegInfo->eliminateCallFramePseudoInstr(Fn, *BB, I++); } else { - for (unsigned i = 0, e = (*I)->getNumOperands(); i != e; ++i) { - MachineOperand &MO = (*I)->getOperand(i); - assert(!MO.isVirtualRegister() && - "Register allocation must be performed!"); - if (MO.isPhysicalRegister() && - (MO.opIsDefOnly() || MO.opIsDefAndUse())) + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { + MachineOperand &MO = I->getOperand(i); + if (MO.isRegister() && MO.isDef()) { + assert(MRegisterInfo::isPhysicalRegister(MO.getReg()) && + "Register allocation must be performed!"); ModifiedRegs[MO.getReg()] = true; // Register is modified - } + } + } ++I; } @@ -168,11 +170,12 @@ void PEI::saveCallerSavedRegisters(MachineFunction &Fn) { } // Add code to restore the callee-save registers in each exiting block. - const TargetInstrInfo &TII = Fn.getTarget().getInstrInfo(); + 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())) { - MBB = FI; I = MBB->end()-1; + if (!FI->empty() && TII.isReturn(FI->back().getOpcode())) { + MBB = FI; + I = MBB->end(); --I; for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) { const TargetRegisterClass *RC = RegInfo->getRegClass(RegsToSave[i]); @@ -188,35 +191,72 @@ void PEI::saveCallerSavedRegisters(MachineFunction &Fn) { /// abstract stack objects... /// void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { - const TargetFrameInfo &TFI = Fn.getTarget().getFrameInfo(); + const TargetFrameInfo &TFI = *Fn.getTarget().getFrameInfo(); bool StackGrowsDown = TFI.getStackGrowthDirection() == TargetFrameInfo::StackGrowsDown; - assert(StackGrowsDown && "Only tested on stack down growing targets!"); // Loop over all of the stack objects, assigning sequential addresses... MachineFrameInfo *FFI = Fn.getFrameInfo(); unsigned StackAlignment = TFI.getStackAlignment(); - // Start at the beginning of the local area... + // 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(); + if (StackGrowsDown) + Offset = -Offset; + assert(Offset >= 0 + && "Local area offset should be in direction of stack growth"); + + // 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 + // preallocated object. + for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) { + int 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 + // the offset is negative, so we negate the offset to get the distance. + FixedOff = -FFI->getObjectOffset(i); + } else { + // The maximum distance from the start pointer is at the upper + // address of the object. + FixedOff = FFI->getObjectOffset(i) + FFI->getObjectSize(i); + } + if (FixedOff > Offset) Offset = FixedOff; + } + for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) { - Offset += FFI->getObjectSize(i); // Allocate Size bytes... + // 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); assert(Align <= StackAlignment && "Cannot align stack object to higher " "alignment boundary than the stack itself!"); Offset = (Offset+Align-1)/Align*Align; // Adjust to Alignment boundary... - FFI->setObjectOffset(i, -Offset); // Set the computed offset + if (StackGrowsDown) { + FFI->setObjectOffset(i, -Offset); // Set the computed offset + } else { + FFI->setObjectOffset(i, Offset); + Offset += FFI->getObjectSize(i); + } } - // Align the final stack pointer offset... - Offset = (Offset+StackAlignment-1)/StackAlignment*StackAlignment; + // Align the final stack pointer offset, but only if there are calls in the + // function. This ensures that any calls to subroutines have their stack + // frames suitable aligned. + if (FFI->hasCalls()) + Offset = (Offset+StackAlignment-1)/StackAlignment*StackAlignment; // Set the final value of the stack pointer... - FFI->setStackSize(Offset-TFI.getOffsetOfLocalArea()); + FFI->setStackSize(Offset+TFI.getOffsetOfLocalArea()); } @@ -229,10 +269,10 @@ void PEI::insertPrologEpilogCode(MachineFunction &Fn) { Fn.getTarget().getRegisterInfo()->emitPrologue(Fn); // Add epilogue to restore the callee-save registers in each exiting block - const TargetInstrInfo &TII = Fn.getTarget().getInstrInfo(); + 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())) + if (!I->empty() && TII.isReturn(I->back().getOpcode())) Fn.getTarget().getRegisterInfo()->emitEpilogue(Fn, *I); } } @@ -250,8 +290,8 @@ void PEI::replaceFrameIndices(MachineFunction &Fn) { for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++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()) { + 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(Fn, I);