1e580952dSDimitry Andric //===- LocalStackSlotAllocation.cpp - Pre-allocate locals to stack slots --===// 2e580952dSDimitry Andric // 3e580952dSDimitry Andric // The LLVM Compiler Infrastructure 4e580952dSDimitry Andric // 5e580952dSDimitry Andric // This file is distributed under the University of Illinois Open Source 6e580952dSDimitry Andric // License. See LICENSE.TXT for details. 7e580952dSDimitry Andric // 8e580952dSDimitry Andric //===----------------------------------------------------------------------===// 9e580952dSDimitry Andric // 10e580952dSDimitry Andric // This pass assigns local frame indices to stack slots relative to one another 11e580952dSDimitry Andric // and allocates additional base registers to access them when the target 122754fe60SDimitry Andric // estimates they are likely to be out of range of stack pointer and frame 13e580952dSDimitry Andric // pointer relative addressing. 14e580952dSDimitry Andric // 15e580952dSDimitry Andric //===----------------------------------------------------------------------===// 16e580952dSDimitry Andric 17e580952dSDimitry Andric #define DEBUG_TYPE "localstackalloc" 18139f7f9bSDimitry Andric #include "llvm/CodeGen/Passes.h" 19139f7f9bSDimitry Andric #include "llvm/ADT/STLExtras.h" 20e580952dSDimitry Andric #include "llvm/ADT/SmallSet.h" 21e580952dSDimitry Andric #include "llvm/ADT/Statistic.h" 22e580952dSDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 23e580952dSDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 24e580952dSDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 25e580952dSDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 26139f7f9bSDimitry Andric #include "llvm/IR/Constants.h" 27139f7f9bSDimitry Andric #include "llvm/IR/DerivedTypes.h" 28139f7f9bSDimitry Andric #include "llvm/IR/Instructions.h" 29139f7f9bSDimitry Andric #include "llvm/IR/Intrinsics.h" 30139f7f9bSDimitry Andric #include "llvm/IR/LLVMContext.h" 31139f7f9bSDimitry Andric #include "llvm/IR/Module.h" 32139f7f9bSDimitry Andric #include "llvm/Pass.h" 33e580952dSDimitry Andric #include "llvm/Support/Debug.h" 34e580952dSDimitry Andric #include "llvm/Support/ErrorHandling.h" 35e580952dSDimitry Andric #include "llvm/Support/raw_ostream.h" 362754fe60SDimitry Andric #include "llvm/Target/TargetFrameLowering.h" 37139f7f9bSDimitry Andric #include "llvm/Target/TargetRegisterInfo.h" 38e580952dSDimitry Andric 39e580952dSDimitry Andric using namespace llvm; 40e580952dSDimitry Andric 41e580952dSDimitry Andric STATISTIC(NumAllocations, "Number of frame indices allocated into local block"); 42e580952dSDimitry Andric STATISTIC(NumBaseRegisters, "Number of virtual frame base registers allocated"); 43e580952dSDimitry Andric STATISTIC(NumReplacements, "Number of frame indices references replaced"); 44e580952dSDimitry Andric 45e580952dSDimitry Andric namespace { 46e580952dSDimitry Andric class FrameRef { 47e580952dSDimitry Andric MachineBasicBlock::iterator MI; // Instr referencing the frame 48e580952dSDimitry Andric int64_t LocalOffset; // Local offset of the frame idx referenced 49284c1978SDimitry Andric int FrameIdx; // The frame index 50e580952dSDimitry Andric public: 51284c1978SDimitry Andric FrameRef(MachineBasicBlock::iterator I, int64_t Offset, int Idx) : 52284c1978SDimitry Andric MI(I), LocalOffset(Offset), FrameIdx(Idx) {} 53e580952dSDimitry Andric bool operator<(const FrameRef &RHS) const { 54e580952dSDimitry Andric return LocalOffset < RHS.LocalOffset; 55e580952dSDimitry Andric } 56284c1978SDimitry Andric MachineBasicBlock::iterator getMachineInstr() const { return MI; } 57284c1978SDimitry Andric int64_t getLocalOffset() const { return LocalOffset; } 58284c1978SDimitry Andric int getFrameIndex() const { return FrameIdx; } 59e580952dSDimitry Andric }; 60e580952dSDimitry Andric 61e580952dSDimitry Andric class LocalStackSlotPass: public MachineFunctionPass { 62e580952dSDimitry Andric SmallVector<int64_t,16> LocalOffsets; 63e580952dSDimitry Andric 64e580952dSDimitry Andric void AdjustStackOffset(MachineFrameInfo *MFI, int FrameIdx, int64_t &Offset, 65e580952dSDimitry Andric bool StackGrowsDown, unsigned &MaxAlign); 66e580952dSDimitry Andric void calculateFrameObjectOffsets(MachineFunction &Fn); 67e580952dSDimitry Andric bool insertFrameReferenceRegisters(MachineFunction &Fn); 68e580952dSDimitry Andric public: 69e580952dSDimitry Andric static char ID; // Pass identification, replacement for typeid 70e580952dSDimitry Andric explicit LocalStackSlotPass() : MachineFunctionPass(ID) { } 71e580952dSDimitry Andric bool runOnMachineFunction(MachineFunction &MF); 72e580952dSDimitry Andric 73e580952dSDimitry Andric virtual void getAnalysisUsage(AnalysisUsage &AU) const { 74e580952dSDimitry Andric AU.setPreservesCFG(); 75e580952dSDimitry Andric MachineFunctionPass::getAnalysisUsage(AU); 76e580952dSDimitry Andric } 77e580952dSDimitry Andric 78e580952dSDimitry Andric private: 79e580952dSDimitry Andric }; 80e580952dSDimitry Andric } // end anonymous namespace 81e580952dSDimitry Andric 82e580952dSDimitry Andric char LocalStackSlotPass::ID = 0; 83dff0c46cSDimitry Andric char &llvm::LocalStackSlotAllocationID = LocalStackSlotPass::ID; 84dff0c46cSDimitry Andric INITIALIZE_PASS(LocalStackSlotPass, "localstackalloc", 85dff0c46cSDimitry Andric "Local Stack Slot Allocation", false, false) 86e580952dSDimitry Andric 87e580952dSDimitry Andric bool LocalStackSlotPass::runOnMachineFunction(MachineFunction &MF) { 88e580952dSDimitry Andric MachineFrameInfo *MFI = MF.getFrameInfo(); 89e580952dSDimitry Andric const TargetRegisterInfo *TRI = MF.getTarget().getRegisterInfo(); 90e580952dSDimitry Andric unsigned LocalObjectCount = MFI->getObjectIndexEnd(); 91e580952dSDimitry Andric 92e580952dSDimitry Andric // If the target doesn't want/need this pass, or if there are no locals 93e580952dSDimitry Andric // to consider, early exit. 94e580952dSDimitry Andric if (!TRI->requiresVirtualBaseRegisters(MF) || LocalObjectCount == 0) 95e580952dSDimitry Andric return true; 96e580952dSDimitry Andric 97e580952dSDimitry Andric // Make sure we have enough space to store the local offsets. 98e580952dSDimitry Andric LocalOffsets.resize(MFI->getObjectIndexEnd()); 99e580952dSDimitry Andric 100e580952dSDimitry Andric // Lay out the local blob. 101e580952dSDimitry Andric calculateFrameObjectOffsets(MF); 102e580952dSDimitry Andric 103e580952dSDimitry Andric // Insert virtual base registers to resolve frame index references. 104e580952dSDimitry Andric bool UsedBaseRegs = insertFrameReferenceRegisters(MF); 105e580952dSDimitry Andric 106e580952dSDimitry Andric // Tell MFI whether any base registers were allocated. PEI will only 107e580952dSDimitry Andric // want to use the local block allocations from this pass if there were any. 108e580952dSDimitry Andric // Otherwise, PEI can do a bit better job of getting the alignment right 109e580952dSDimitry Andric // without a hole at the start since it knows the alignment of the stack 110e580952dSDimitry Andric // at the start of local allocation, and this pass doesn't. 111e580952dSDimitry Andric MFI->setUseLocalStackAllocationBlock(UsedBaseRegs); 112e580952dSDimitry Andric 113e580952dSDimitry Andric return true; 114e580952dSDimitry Andric } 115e580952dSDimitry Andric 116e580952dSDimitry Andric /// AdjustStackOffset - Helper function used to adjust the stack frame offset. 117e580952dSDimitry Andric void LocalStackSlotPass::AdjustStackOffset(MachineFrameInfo *MFI, 118e580952dSDimitry Andric int FrameIdx, int64_t &Offset, 119e580952dSDimitry Andric bool StackGrowsDown, 120e580952dSDimitry Andric unsigned &MaxAlign) { 121e580952dSDimitry Andric // If the stack grows down, add the object size to find the lowest address. 122e580952dSDimitry Andric if (StackGrowsDown) 123e580952dSDimitry Andric Offset += MFI->getObjectSize(FrameIdx); 124e580952dSDimitry Andric 125e580952dSDimitry Andric unsigned Align = MFI->getObjectAlignment(FrameIdx); 126e580952dSDimitry Andric 127e580952dSDimitry Andric // If the alignment of this object is greater than that of the stack, then 128e580952dSDimitry Andric // increase the stack alignment to match. 129e580952dSDimitry Andric MaxAlign = std::max(MaxAlign, Align); 130e580952dSDimitry Andric 131e580952dSDimitry Andric // Adjust to alignment boundary. 132e580952dSDimitry Andric Offset = (Offset + Align - 1) / Align * Align; 133e580952dSDimitry Andric 134e580952dSDimitry Andric int64_t LocalOffset = StackGrowsDown ? -Offset : Offset; 135e580952dSDimitry Andric DEBUG(dbgs() << "Allocate FI(" << FrameIdx << ") to local offset " 136e580952dSDimitry Andric << LocalOffset << "\n"); 137e580952dSDimitry Andric // Keep the offset available for base register allocation 138e580952dSDimitry Andric LocalOffsets[FrameIdx] = LocalOffset; 139e580952dSDimitry Andric // And tell MFI about it for PEI to use later 140e580952dSDimitry Andric MFI->mapLocalFrameObject(FrameIdx, LocalOffset); 141e580952dSDimitry Andric 142e580952dSDimitry Andric if (!StackGrowsDown) 143e580952dSDimitry Andric Offset += MFI->getObjectSize(FrameIdx); 144e580952dSDimitry Andric 145e580952dSDimitry Andric ++NumAllocations; 146e580952dSDimitry Andric } 147e580952dSDimitry Andric 148e580952dSDimitry Andric /// calculateFrameObjectOffsets - Calculate actual frame offsets for all of the 149e580952dSDimitry Andric /// abstract stack objects. 150e580952dSDimitry Andric /// 151e580952dSDimitry Andric void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) { 152e580952dSDimitry Andric // Loop over all of the stack objects, assigning sequential addresses... 153e580952dSDimitry Andric MachineFrameInfo *MFI = Fn.getFrameInfo(); 1542754fe60SDimitry Andric const TargetFrameLowering &TFI = *Fn.getTarget().getFrameLowering(); 155e580952dSDimitry Andric bool StackGrowsDown = 1562754fe60SDimitry Andric TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown; 157e580952dSDimitry Andric int64_t Offset = 0; 158e580952dSDimitry Andric unsigned MaxAlign = 0; 159e580952dSDimitry Andric 160e580952dSDimitry Andric // Make sure that the stack protector comes before the local variables on the 161e580952dSDimitry Andric // stack. 162e580952dSDimitry Andric SmallSet<int, 16> LargeStackObjs; 163e580952dSDimitry Andric if (MFI->getStackProtectorIndex() >= 0) { 164e580952dSDimitry Andric AdjustStackOffset(MFI, MFI->getStackProtectorIndex(), Offset, 165e580952dSDimitry Andric StackGrowsDown, MaxAlign); 166e580952dSDimitry Andric 167e580952dSDimitry Andric // Assign large stack objects first. 168e580952dSDimitry Andric for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) { 169e580952dSDimitry Andric if (MFI->isDeadObjectIndex(i)) 170e580952dSDimitry Andric continue; 171e580952dSDimitry Andric if (MFI->getStackProtectorIndex() == (int)i) 172e580952dSDimitry Andric continue; 173e580952dSDimitry Andric if (!MFI->MayNeedStackProtector(i)) 174e580952dSDimitry Andric continue; 175e580952dSDimitry Andric 176e580952dSDimitry Andric AdjustStackOffset(MFI, i, Offset, StackGrowsDown, MaxAlign); 177e580952dSDimitry Andric LargeStackObjs.insert(i); 178e580952dSDimitry Andric } 179e580952dSDimitry Andric } 180e580952dSDimitry Andric 181e580952dSDimitry Andric // Then assign frame offsets to stack objects that are not used to spill 182e580952dSDimitry Andric // callee saved registers. 183e580952dSDimitry Andric for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) { 184e580952dSDimitry Andric if (MFI->isDeadObjectIndex(i)) 185e580952dSDimitry Andric continue; 186e580952dSDimitry Andric if (MFI->getStackProtectorIndex() == (int)i) 187e580952dSDimitry Andric continue; 188e580952dSDimitry Andric if (LargeStackObjs.count(i)) 189e580952dSDimitry Andric continue; 190e580952dSDimitry Andric 191e580952dSDimitry Andric AdjustStackOffset(MFI, i, Offset, StackGrowsDown, MaxAlign); 192e580952dSDimitry Andric } 193e580952dSDimitry Andric 194e580952dSDimitry Andric // Remember how big this blob of stack space is 195e580952dSDimitry Andric MFI->setLocalFrameSize(Offset); 196e580952dSDimitry Andric MFI->setLocalFrameMaxAlign(MaxAlign); 197e580952dSDimitry Andric } 198e580952dSDimitry Andric 199e580952dSDimitry Andric static inline bool 200284c1978SDimitry Andric lookupCandidateBaseReg(int64_t BaseOffset, 201e580952dSDimitry Andric int64_t FrameSizeAdjust, 202e580952dSDimitry Andric int64_t LocalFrameOffset, 203e580952dSDimitry Andric const MachineInstr *MI, 204e580952dSDimitry Andric const TargetRegisterInfo *TRI) { 205e580952dSDimitry Andric // Check if the relative offset from the where the base register references 206e580952dSDimitry Andric // to the target address is in range for the instruction. 207284c1978SDimitry Andric int64_t Offset = FrameSizeAdjust + LocalFrameOffset - BaseOffset; 208284c1978SDimitry Andric return TRI->isFrameOffsetLegal(MI, Offset); 209e580952dSDimitry Andric } 210e580952dSDimitry Andric 211e580952dSDimitry Andric bool LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) { 212e580952dSDimitry Andric // Scan the function's instructions looking for frame index references. 213e580952dSDimitry Andric // For each, ask the target if it wants a virtual base register for it 214e580952dSDimitry Andric // based on what we can tell it about where the local will end up in the 215e580952dSDimitry Andric // stack frame. If it wants one, re-use a suitable one we've previously 216e580952dSDimitry Andric // allocated, or if there isn't one that fits the bill, allocate a new one 217e580952dSDimitry Andric // and ask the target to create a defining instruction for it. 218e580952dSDimitry Andric bool UsedBaseReg = false; 219e580952dSDimitry Andric 220e580952dSDimitry Andric MachineFrameInfo *MFI = Fn.getFrameInfo(); 221e580952dSDimitry Andric const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo(); 2222754fe60SDimitry Andric const TargetFrameLowering &TFI = *Fn.getTarget().getFrameLowering(); 223e580952dSDimitry Andric bool StackGrowsDown = 2242754fe60SDimitry Andric TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown; 225e580952dSDimitry Andric 226e580952dSDimitry Andric // Collect all of the instructions in the block that reference 227e580952dSDimitry Andric // a frame index. Also store the frame index referenced to ease later 228e580952dSDimitry Andric // lookup. (For any insn that has more than one FI reference, we arbitrarily 229e580952dSDimitry Andric // choose the first one). 230e580952dSDimitry Andric SmallVector<FrameRef, 64> FrameReferenceInsns; 2312754fe60SDimitry Andric 232e580952dSDimitry Andric for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) { 233e580952dSDimitry Andric for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) { 234e580952dSDimitry Andric MachineInstr *MI = I; 2352754fe60SDimitry Andric 236e580952dSDimitry Andric // Debug value instructions can't be out of range, so they don't need 237e580952dSDimitry Andric // any updates. 238e580952dSDimitry Andric if (MI->isDebugValue()) 239e580952dSDimitry Andric continue; 2402754fe60SDimitry Andric 241e580952dSDimitry Andric // For now, allocate the base register(s) within the basic block 242e580952dSDimitry Andric // where they're used, and don't try to keep them around outside 243e580952dSDimitry Andric // of that. It may be beneficial to try sharing them more broadly 244e580952dSDimitry Andric // than that, but the increased register pressure makes that a 245e580952dSDimitry Andric // tricky thing to balance. Investigate if re-materializing these 246e580952dSDimitry Andric // becomes an issue. 247e580952dSDimitry Andric for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 248e580952dSDimitry Andric // Consider replacing all frame index operands that reference 249e580952dSDimitry Andric // an object allocated in the local block. 250e580952dSDimitry Andric if (MI->getOperand(i).isFI()) { 251e580952dSDimitry Andric // Don't try this with values not in the local block. 252e580952dSDimitry Andric if (!MFI->isObjectPreAllocated(MI->getOperand(i).getIndex())) 253e580952dSDimitry Andric break; 254284c1978SDimitry Andric int Idx = MI->getOperand(i).getIndex(); 255284c1978SDimitry Andric int64_t LocalOffset = LocalOffsets[Idx]; 256284c1978SDimitry Andric if (!TRI->needsFrameBaseReg(MI, LocalOffset)) 257284c1978SDimitry Andric break; 258e580952dSDimitry Andric FrameReferenceInsns. 259284c1978SDimitry Andric push_back(FrameRef(MI, LocalOffset, Idx)); 260e580952dSDimitry Andric break; 261e580952dSDimitry Andric } 262e580952dSDimitry Andric } 263e580952dSDimitry Andric } 264e580952dSDimitry Andric } 2652754fe60SDimitry Andric 266e580952dSDimitry Andric // Sort the frame references by local offset 267e580952dSDimitry Andric array_pod_sort(FrameReferenceInsns.begin(), FrameReferenceInsns.end()); 268e580952dSDimitry Andric 2692754fe60SDimitry Andric MachineBasicBlock *Entry = Fn.begin(); 270e580952dSDimitry Andric 271284c1978SDimitry Andric unsigned BaseReg = 0; 272284c1978SDimitry Andric int64_t BaseOffset = 0; 273284c1978SDimitry Andric 2742754fe60SDimitry Andric // Loop through the frame references and allocate for them as necessary. 275e580952dSDimitry Andric for (int ref = 0, e = FrameReferenceInsns.size(); ref < e ; ++ref) { 276284c1978SDimitry Andric FrameRef &FR = FrameReferenceInsns[ref]; 277284c1978SDimitry Andric MachineBasicBlock::iterator I = FR.getMachineInstr(); 278e580952dSDimitry Andric MachineInstr *MI = I; 279284c1978SDimitry Andric int64_t LocalOffset = FR.getLocalOffset(); 280284c1978SDimitry Andric int FrameIdx = FR.getFrameIndex(); 281e580952dSDimitry Andric assert(MFI->isObjectPreAllocated(FrameIdx) && 282e580952dSDimitry Andric "Only pre-allocated locals expected!"); 283e580952dSDimitry Andric 284e580952dSDimitry Andric DEBUG(dbgs() << "Considering: " << *MI); 285284c1978SDimitry Andric 286284c1978SDimitry Andric unsigned idx = 0; 287284c1978SDimitry Andric for (unsigned f = MI->getNumOperands(); idx != f; ++idx) { 288284c1978SDimitry Andric if (!MI->getOperand(idx).isFI()) 289284c1978SDimitry Andric continue; 290284c1978SDimitry Andric 291284c1978SDimitry Andric if (FrameIdx == I->getOperand(idx).getIndex()) 292284c1978SDimitry Andric break; 293284c1978SDimitry Andric } 294284c1978SDimitry Andric 295284c1978SDimitry Andric assert(idx < MI->getNumOperands() && "Cannot find FI operand"); 296284c1978SDimitry Andric 297e580952dSDimitry Andric int64_t Offset = 0; 298284c1978SDimitry Andric int64_t FrameSizeAdjust = StackGrowsDown ? MFI->getLocalFrameSize() : 0; 299e580952dSDimitry Andric 300e580952dSDimitry Andric DEBUG(dbgs() << " Replacing FI in: " << *MI); 301e580952dSDimitry Andric 302e580952dSDimitry Andric // If we have a suitable base register available, use it; otherwise 303e580952dSDimitry Andric // create a new one. Note that any offset encoded in the 304e580952dSDimitry Andric // instruction itself will be taken into account by the target, 305e580952dSDimitry Andric // so we don't have to adjust for it here when reusing a base 306e580952dSDimitry Andric // register. 307284c1978SDimitry Andric if (UsedBaseReg && lookupCandidateBaseReg(BaseOffset, FrameSizeAdjust, 308284c1978SDimitry Andric LocalOffset, MI, TRI)) { 309284c1978SDimitry Andric DEBUG(dbgs() << " Reusing base register " << BaseReg << "\n"); 310e580952dSDimitry Andric // We found a register to reuse. 311284c1978SDimitry Andric Offset = FrameSizeAdjust + LocalOffset - BaseOffset; 312e580952dSDimitry Andric } else { 313284c1978SDimitry Andric // No previously defined register was in range, so create a // new one. 314284c1978SDimitry Andric 315e580952dSDimitry Andric int64_t InstrOffset = TRI->getFrameIndexInstrOffset(MI, idx); 316284c1978SDimitry Andric 317284c1978SDimitry Andric int64_t PrevBaseOffset = BaseOffset; 318284c1978SDimitry Andric BaseOffset = FrameSizeAdjust + LocalOffset + InstrOffset; 319284c1978SDimitry Andric 320284c1978SDimitry Andric // We'd like to avoid creating single-use virtual base registers. 321284c1978SDimitry Andric // Because the FrameRefs are in sorted order, and we've already 322284c1978SDimitry Andric // processed all FrameRefs before this one, just check whether or not 323284c1978SDimitry Andric // the next FrameRef will be able to reuse this new register. If not, 324284c1978SDimitry Andric // then don't bother creating it. 325284c1978SDimitry Andric bool CanReuse = false; 326284c1978SDimitry Andric for (int refn = ref + 1; refn < e; ++refn) { 327284c1978SDimitry Andric FrameRef &FRN = FrameReferenceInsns[refn]; 328284c1978SDimitry Andric MachineBasicBlock::iterator J = FRN.getMachineInstr(); 329284c1978SDimitry Andric MachineInstr *MIN = J; 330284c1978SDimitry Andric 331284c1978SDimitry Andric CanReuse = lookupCandidateBaseReg(BaseOffset, FrameSizeAdjust, 332284c1978SDimitry Andric FRN.getLocalOffset(), MIN, TRI); 333284c1978SDimitry Andric break; 334284c1978SDimitry Andric } 335284c1978SDimitry Andric 336284c1978SDimitry Andric if (!CanReuse) { 337284c1978SDimitry Andric BaseOffset = PrevBaseOffset; 338284c1978SDimitry Andric continue; 339284c1978SDimitry Andric } 340284c1978SDimitry Andric 3417ae0e2c9SDimitry Andric const MachineFunction *MF = MI->getParent()->getParent(); 3427ae0e2c9SDimitry Andric const TargetRegisterClass *RC = TRI->getPointerRegClass(*MF); 343e580952dSDimitry Andric BaseReg = Fn.getRegInfo().createVirtualRegister(RC); 344e580952dSDimitry Andric 345e580952dSDimitry Andric DEBUG(dbgs() << " Materializing base register " << BaseReg << 346284c1978SDimitry Andric " at frame local offset " << LocalOffset + InstrOffset << "\n"); 3472754fe60SDimitry Andric 348e580952dSDimitry Andric // Tell the target to insert the instruction to initialize 349e580952dSDimitry Andric // the base register. 3502754fe60SDimitry Andric // MachineBasicBlock::iterator InsertionPt = Entry->begin(); 3512754fe60SDimitry Andric TRI->materializeFrameBaseRegister(Entry, BaseReg, FrameIdx, 3522754fe60SDimitry Andric InstrOffset); 353e580952dSDimitry Andric 354e580952dSDimitry Andric // The base register already includes any offset specified 355e580952dSDimitry Andric // by the instruction, so account for that so it doesn't get 356e580952dSDimitry Andric // applied twice. 357e580952dSDimitry Andric Offset = -InstrOffset; 358e580952dSDimitry Andric 359e580952dSDimitry Andric ++NumBaseRegisters; 360e580952dSDimitry Andric UsedBaseReg = true; 361e580952dSDimitry Andric } 362e580952dSDimitry Andric assert(BaseReg != 0 && "Unable to allocate virtual base register!"); 363e580952dSDimitry Andric 364e580952dSDimitry Andric // Modify the instruction to use the new base register rather 365e580952dSDimitry Andric // than the frame index operand. 366e580952dSDimitry Andric TRI->resolveFrameIndex(I, BaseReg, Offset); 367e580952dSDimitry Andric DEBUG(dbgs() << "Resolved: " << *MI); 368e580952dSDimitry Andric 369e580952dSDimitry Andric ++NumReplacements; 370e580952dSDimitry Andric } 371284c1978SDimitry Andric 372e580952dSDimitry Andric return UsedBaseReg; 373e580952dSDimitry Andric } 374