X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FPrologEpilogInserter.cpp;h=7b6747363663249a39644c410f3e33468ea05533;hb=fecdea0bf77599038eb368db3bc6a38a14900308;hp=d1112d3c14aaaf50184087ab3ec62445c81c9106;hpb=d9642faf7c66273eb3a8d99e5fa6b542da5374dd;p=oota-llvm.git diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp index d1112d3c14a..7b674736366 100644 --- a/lib/CodeGen/PrologEpilogInserter.cpp +++ b/lib/CodeGen/PrologEpilogInserter.cpp @@ -19,6 +19,7 @@ // //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "pei" #include "PrologEpilogInserter.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineLoopInfo.h" @@ -32,16 +33,22 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/Debug.h" #include "llvm/ADT/IndexedMap.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/STLExtras.h" #include using namespace llvm; +// FIXME: For testing purposes only. Remove once the pre-allocation pass +// is done. +extern cl::opt EnableLocalStackAlloc; + char PEI::ID = 0; -static RegisterPass -X("prologepilog", "Prologue/Epilogue Insertion"); +INITIALIZE_PASS(PEI, "prologepilog", + "Prologue/Epilogue Insertion", false, false); /// createPrologEpilogCodeInserter - This function returns a pass that inserts /// prolog and epilog code, and eliminates abstract frame references. @@ -72,10 +79,10 @@ bool PEI::runOnMachineFunction(MachineFunction &Fn) { calculateCalleeSavedRegisters(Fn); // Determine placement of CSR spill/restore code: - // - with shrink wrapping, place spills and restores to tightly + // - 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 + // they are used. + // - Without shink wrapping (default), place all spills in the // entry block, all restores in return blocks. placeCSRSpillsAndRestores(Fn); @@ -461,8 +468,10 @@ AdjustStackOffset(MachineFrameInfo *MFI, int FrameIdx, Offset = (Offset + Align - 1) / Align * Align; if (StackGrowsDown) { + DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << -Offset << "]\n"); MFI->setObjectOffset(FrameIdx, -Offset); // Set the computed offset } else { + DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << Offset << "]\n"); MFI->setObjectOffset(FrameIdx, Offset); Offset += MFI->getObjectSize(FrameIdx); } @@ -547,15 +556,66 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { AdjustStackOffset(MFI, SFI, StackGrowsDown, Offset, MaxAlign); } + // FIXME: Once this is working, then enable flag will change to a target + // check for whether the frame is large enough to want to use virtual + // frame index registers. Functions which don't want/need this optimization + // will continue to use the existing code path. + if (EnableLocalStackAlloc) { + unsigned Align = MFI->getLocalFrameMaxAlign(); + + // Adjust to alignment boundary. + Offset = (Offset + Align - 1) / Align * Align; + + // Store the offset of the start of the local allocation block. This + // will be used later when resolving frame base virtual register pseudos. + MFI->setLocalFrameBaseOffset(Offset); + + DEBUG(dbgs() << "Local frame base offset: " << Offset << "\n"); + + // Allocate the local block + Offset += MFI->getLocalFrameSize(); + + // Resolve offsets for objects in the local block. + for (unsigned i = 0, e = MFI->getLocalFrameObjectCount(); i != e; ++i) { + std::pair Entry = MFI->getLocalFrameObjectMap(i); + int64_t FIOffset = MFI->getLocalFrameBaseOffset() + Entry.second; + + AdjustStackOffset(MFI, Entry.first, StackGrowsDown, FIOffset, MaxAlign); + } + } + // Make sure that the stack protector comes before the local variables on the // stack. - if (MFI->getStackProtectorIndex() >= 0) + SmallSet LargeStackObjs; + if (MFI->getStackProtectorIndex() >= 0) { AdjustStackOffset(MFI, MFI->getStackProtectorIndex(), StackGrowsDown, Offset, MaxAlign); + // Assign large stack objects first. + for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) { + if (MFI->isObjectPreAllocated(i)) + continue; + if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex) + continue; + if (RS && (int)i == RS->getScavengingFrameIndex()) + continue; + if (MFI->isDeadObjectIndex(i)) + continue; + if (MFI->getStackProtectorIndex() == (int)i) + continue; + if (!MFI->MayNeedStackProtector(i)) + continue; + + AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign); + LargeStackObjs.insert(i); + } + } + // Then assign frame offsets to stack objects that are not used to spill // callee saved registers. for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) { + if (MFI->isObjectPreAllocated(i)) + continue; if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex) continue; if (RS && (int)i == RS->getScavengingFrameIndex()) @@ -564,6 +624,8 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { continue; if (MFI->getStackProtectorIndex() == (int)i) continue; + if (LargeStackObjs.count(i)) + continue; AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign); } @@ -885,21 +947,7 @@ void PEI::scavengeFrameVirtualRegs(MachineFunction &Fn) { // Scavenge a new scratch register CurrentVirtReg = Reg; const TargetRegisterClass *RC = Fn.getRegInfo().getRegClass(Reg); - const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo(); - BitVector Candidates(TRI->getNumRegs()); - RS->getRegsAvailable(RC, Candidates); - - // If there are any registers available, use the one that's - // unused for the longest after this instruction. That increases - // the ability to reuse the value. - if (Candidates.any()) { - MachineBasicBlock::iterator UMI; - CurrentScratchReg = RS->findSurvivorReg(I, Candidates, 25, UMI); - } else { - // No register is "free". Scavenge a register. - CurrentScratchReg = RS->scavengeRegister(RC, I, SPAdj); - } - + CurrentScratchReg = RS->scavengeRegister(RC, I, SPAdj); PrevValue = Value; } // replace this reference to the virtual register with the