LocalStackSlotAllocation.cpp revision f0b7b5f0d6afdcac071356692a80ab17488ae2ff
1//===- LocalStackSlotAllocation.cpp - Pre-allocate locals to stack slots --===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This pass assigns local frame indices to stack slots relative to one another 11// and allocates additional base registers to access them when the target 12// estimates the are likely to be out of range of stack pointer and frame 13// pointer relative addressing. 14// 15//===----------------------------------------------------------------------===// 16 17#define DEBUG_TYPE "localstackalloc" 18#include "llvm/Constants.h" 19#include "llvm/DerivedTypes.h" 20#include "llvm/Instructions.h" 21#include "llvm/Intrinsics.h" 22#include "llvm/ADT/Statistic.h" 23#include "llvm/LLVMContext.h" 24#include "llvm/Module.h" 25#include "llvm/Pass.h" 26#include "llvm/ADT/SmallSet.h" 27#include "llvm/CodeGen/MachineFrameInfo.h" 28#include "llvm/CodeGen/MachineFunction.h" 29#include "llvm/CodeGen/MachineFunctionPass.h" 30#include "llvm/CodeGen/Passes.h" 31#include "llvm/Support/Debug.h" 32#include "llvm/Support/ErrorHandling.h" 33#include "llvm/Support/raw_ostream.h" 34#include "llvm/Target/TargetRegisterInfo.h" 35#include "llvm/Target/TargetFrameInfo.h" 36 37using namespace llvm; 38 39STATISTIC(NumAllocations, "Number of frame indices processed"); 40 41namespace { 42 class LocalStackSlotPass: public MachineFunctionPass { 43 int64_t LocalStackSize; 44 45 void calculateFrameObjectOffsets(MachineFunction &Fn); 46 public: 47 static char ID; // Pass identification, replacement for typeid 48 explicit LocalStackSlotPass() : MachineFunctionPass(ID) { } 49 bool runOnMachineFunction(MachineFunction &MF); 50 51 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 52 AU.setPreservesCFG(); 53 MachineFunctionPass::getAnalysisUsage(AU); 54 } 55 const char *getPassName() const { 56 return "Local Stack Slot Allocation"; 57 } 58 59 private: 60 }; 61} // end anonymous namespace 62 63char LocalStackSlotPass::ID = 0; 64 65FunctionPass *llvm::createLocalStackSlotAllocationPass() { 66 return new LocalStackSlotPass(); 67} 68 69bool LocalStackSlotPass::runOnMachineFunction(MachineFunction &MF) { 70 calculateFrameObjectOffsets(MF); 71 DEBUG(dbgs() << LocalStackSize << " bytes of local storage pre-allocated\n"); 72 return true; 73} 74 75/// AdjustStackOffset - Helper function used to adjust the stack frame offset. 76static inline void 77AdjustStackOffset(MachineFrameInfo *MFI, int FrameIdx, int64_t &Offset, 78 unsigned &MaxAlign) { 79 unsigned Align = MFI->getObjectAlignment(FrameIdx); 80 81 // If the alignment of this object is greater than that of the stack, then 82 // increase the stack alignment to match. 83 MaxAlign = std::max(MaxAlign, Align); 84 85 // Adjust to alignment boundary. 86 Offset = (Offset + Align - 1) / Align * Align; 87 88 DEBUG(dbgs() << "Allocate FI(" << FrameIdx << ") to local offset " 89 << Offset << "\n"); 90 MFI->mapLocalFrameObject(FrameIdx, Offset); 91 Offset += MFI->getObjectSize(FrameIdx); 92 93 ++NumAllocations; 94} 95 96/// calculateFrameObjectOffsets - Calculate actual frame offsets for all of the 97/// abstract stack objects. 98/// 99void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) { 100 const TargetFrameInfo &TFI = *Fn.getTarget().getFrameInfo(); 101 102 // Loop over all of the stack objects, assigning sequential addresses... 103 MachineFrameInfo *MFI = Fn.getFrameInfo(); 104 int64_t Offset = 0; 105 unsigned MaxAlign = MFI->getMaxAlignment(); 106 107 // Make sure that the stack protector comes before the local variables on the 108 // stack. 109 SmallSet<int, 16> LargeStackObjs; 110 if (MFI->getStackProtectorIndex() >= 0) { 111 AdjustStackOffset(MFI, MFI->getStackProtectorIndex(), Offset, MaxAlign); 112 113 // Assign large stack objects first. 114 for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) { 115 if (MFI->isDeadObjectIndex(i)) 116 continue; 117 if (MFI->getStackProtectorIndex() == (int)i) 118 continue; 119 if (!MFI->MayNeedStackProtector(i)) 120 continue; 121 122 AdjustStackOffset(MFI, i, Offset, MaxAlign); 123 LargeStackObjs.insert(i); 124 } 125 } 126 127 // Then assign frame offsets to stack objects that are not used to spill 128 // callee saved registers. 129 for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) { 130 if (MFI->isDeadObjectIndex(i)) 131 continue; 132 if (MFI->getStackProtectorIndex() == (int)i) 133 continue; 134 if (LargeStackObjs.count(i)) 135 continue; 136 137 AdjustStackOffset(MFI, i, Offset, MaxAlign); 138 } 139 140 const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo(); 141 if (!RegInfo->targetHandlesStackFrameRounding()) { 142 // If we have reserved argument space for call sites in the function 143 // immediately on entry to the current function, count it as part of the 144 // overall stack size. 145 if (MFI->adjustsStack() && RegInfo->hasReservedCallFrame(Fn)) 146 Offset += MFI->getMaxCallFrameSize(); 147 148 // Round up the size to a multiple of the alignment. If the function has 149 // any calls or alloca's, align to the target's StackAlignment value to 150 // ensure that the callee's frame or the alloca data is suitably aligned; 151 // otherwise, for leaf functions, align to the TransientStackAlignment 152 // value. 153 unsigned StackAlign; 154 if (MFI->adjustsStack() || MFI->hasVarSizedObjects() || 155 (RegInfo->needsStackRealignment(Fn) && MFI->getObjectIndexEnd() != 0)) 156 StackAlign = TFI.getStackAlignment(); 157 else 158 StackAlign = TFI.getTransientStackAlignment(); 159 160 // If the frame pointer is eliminated, all frame offsets will be relative to 161 // SP not FP. Align to MaxAlign so this works. 162 StackAlign = std::max(StackAlign, MaxAlign); 163 unsigned AlignMask = StackAlign - 1; 164 Offset = (Offset + AlignMask) & ~uint64_t(AlignMask); 165 } 166 167 // Remember how big this blob of stack space is 168 LocalStackSize = Offset; 169} 170