X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FPrologEpilogInserter.cpp;h=6157e3fc99f607248f43d4a306c916f423183ddb;hb=deb9971061cfb9c57930724fcf8d62fb26dc2213;hp=b5715da242f9c3575cddedd3df77bd9603368c54;hpb=78d6db5627bdf41ab3ffd96133821647dbc60d53;p=oota-llvm.git diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp index b5715da242f..6157e3fc99f 100644 --- a/lib/CodeGen/PrologEpilogInserter.cpp +++ b/lib/CodeGen/PrologEpilogInserter.cpp @@ -1,4 +1,11 @@ //===-- PrologEpilogInserter.cpp - Insert Prolog/Epilog code in function --===// +// +// 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 pass is responsible for finalizing the functions frame layout, saving // callee saved registers, and for emitting prolog & epilog code for the @@ -17,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 { @@ -59,10 +67,11 @@ namespace { }; } + /// createPrologEpilogCodeInserter - This function returns a pass that inserts /// prolog and epilog code, and eliminates abstract frame references. /// -Pass *createPrologEpilogCodeInserter() { return new PEI(); } +FunctionPass *llvm::createPrologEpilogCodeInserter() { return new PEI(); } /// saveCallerSavedRegisters - Scan the function for modified caller saved @@ -73,7 +82,7 @@ Pass *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(); @@ -89,28 +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.opIsDef()) + 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; } @@ -126,12 +136,15 @@ void PEI::saveCallerSavedRegisters(MachineFunction &Fn) { unsigned Reg = CSRegs[i]; if (ModifiedRegs[Reg]) { RegsToSave.push_back(Reg); // If modified register... - } else if (const unsigned *AliasSet = RegInfo->getAliasSet(Reg)) - for (unsigned j = 0; AliasSet[j]; ++j) // Check alias registers too... - if (ModifiedRegs[AliasSet[j]]) { + } else { + for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg); + *AliasSet; ++AliasSet) { // Check alias registers too... + if (ModifiedRegs[*AliasSet]) { RegsToSave.push_back(Reg); break; } + } + } } if (RegsToSave.empty()) @@ -157,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 (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]); @@ -177,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 StackAlign = TFI.getStackAlignment(); + 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 < StackAlign && "Cannot align stack object to higher " + 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()); } @@ -218,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 (TII.isReturn(I->back()->getOpcode())) + if (!I->empty() && TII.isReturn(I->back().getOpcode())) Fn.getTarget().getRegisterInfo()->emitEpilogue(Fn, *I); } } @@ -239,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);