LocalStackSlotAllocation.cpp revision 74d803a58c7935c067397bb19afc05ec464d8159
13d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach//===- LocalStackSlotAllocation.cpp - Pre-allocate locals to stack slots --===// 23d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach// 33d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach// The LLVM Compiler Infrastructure 43d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach// 53d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach// This file is distributed under the University of Illinois Open Source 63d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach// License. See LICENSE.TXT for details. 73d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach// 83d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach//===----------------------------------------------------------------------===// 93d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach// 103d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach// This pass assigns local frame indices to stack slots relative to one another 113d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach// and allocates additional base registers to access them when the target 123d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach// estimates the are likely to be out of range of stack pointer and frame 133d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach// pointer relative addressing. 143d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach// 153d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach//===----------------------------------------------------------------------===// 163d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 173d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#define DEBUG_TYPE "localstackalloc" 183d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#include "llvm/Constants.h" 193d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#include "llvm/DerivedTypes.h" 203d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#include "llvm/Instructions.h" 213d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#include "llvm/Intrinsics.h" 223d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#include "llvm/LLVMContext.h" 233d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#include "llvm/Module.h" 243d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#include "llvm/Pass.h" 253d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#include "llvm/ADT/SmallSet.h" 268708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach#include "llvm/ADT/Statistic.h" 273d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#include "llvm/CodeGen/MachineFrameInfo.h" 283d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#include "llvm/CodeGen/MachineFunction.h" 293d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#include "llvm/CodeGen/MachineFunctionPass.h" 30dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach#include "llvm/CodeGen/MachineRegisterInfo.h" 313d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#include "llvm/CodeGen/Passes.h" 323d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#include "llvm/Support/Debug.h" 333d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#include "llvm/Support/ErrorHandling.h" 343d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#include "llvm/Support/raw_ostream.h" 353d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#include "llvm/Target/TargetRegisterInfo.h" 363d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#include "llvm/Target/TargetFrameInfo.h" 373d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 383d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbachusing namespace llvm; 393d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 408708ead5a46f4ec8f2d5f832be23381924d72b8dJim GrosbachSTATISTIC(NumAllocations, "Number of frame indices allocated into local block"); 418708ead5a46f4ec8f2d5f832be23381924d72b8dJim GrosbachSTATISTIC(NumBaseRegisters, "Number of virtual frame base registers allocated"); 428708ead5a46f4ec8f2d5f832be23381924d72b8dJim GrosbachSTATISTIC(NumReplacements, "Number of frame indices references replaced"); 433d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 443d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbachnamespace { 453d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach class LocalStackSlotPass: public MachineFunctionPass { 463d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach void calculateFrameObjectOffsets(MachineFunction &Fn); 478708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach 488708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach void insertFrameReferenceRegisters(MachineFunction &Fn); 493d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach public: 503d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach static char ID; // Pass identification, replacement for typeid 513d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach explicit LocalStackSlotPass() : MachineFunctionPass(ID) { } 523d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach bool runOnMachineFunction(MachineFunction &MF); 533d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 543d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach virtual void getAnalysisUsage(AnalysisUsage &AU) const { 553d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach AU.setPreservesCFG(); 563d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach MachineFunctionPass::getAnalysisUsage(AU); 573d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach } 583d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach const char *getPassName() const { 593d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach return "Local Stack Slot Allocation"; 603d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach } 613d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 623d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach private: 633d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach }; 643d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach} // end anonymous namespace 653d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 663d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbachchar LocalStackSlotPass::ID = 0; 673d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 683d72367d30c9ce6f387764a028763f7a366cc443Jim GrosbachFunctionPass *llvm::createLocalStackSlotAllocationPass() { 693d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach return new LocalStackSlotPass(); 703d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach} 713d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 723d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbachbool LocalStackSlotPass::runOnMachineFunction(MachineFunction &MF) { 738708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // Lay out the local blob. 743d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach calculateFrameObjectOffsets(MF); 758708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach 768708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // Insert virtual base registers to resolve frame index references. 778708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach insertFrameReferenceRegisters(MF); 783d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach return true; 793d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach} 803d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 813d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach/// AdjustStackOffset - Helper function used to adjust the stack frame offset. 823d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbachstatic inline void 833d72367d30c9ce6f387764a028763f7a366cc443Jim GrosbachAdjustStackOffset(MachineFrameInfo *MFI, int FrameIdx, int64_t &Offset, 843d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach unsigned &MaxAlign) { 853d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach unsigned Align = MFI->getObjectAlignment(FrameIdx); 863d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 873d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // If the alignment of this object is greater than that of the stack, then 883d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // increase the stack alignment to match. 893d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach MaxAlign = std::max(MaxAlign, Align); 903d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 913d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // Adjust to alignment boundary. 923d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach Offset = (Offset + Align - 1) / Align * Align; 933d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 943d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach DEBUG(dbgs() << "Allocate FI(" << FrameIdx << ") to local offset " 953d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach << Offset << "\n"); 963d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach MFI->mapLocalFrameObject(FrameIdx, Offset); 973d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach Offset += MFI->getObjectSize(FrameIdx); 983d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 993d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach ++NumAllocations; 1003d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach} 1013d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 1023d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach/// calculateFrameObjectOffsets - Calculate actual frame offsets for all of the 1033d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach/// abstract stack objects. 1043d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach/// 1053d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbachvoid LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) { 1063d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // Loop over all of the stack objects, assigning sequential addresses... 1073d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach MachineFrameInfo *MFI = Fn.getFrameInfo(); 1083d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach int64_t Offset = 0; 1094861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach unsigned MaxAlign = 0; 1103d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 1113d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // Make sure that the stack protector comes before the local variables on the 1123d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // stack. 1133d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach SmallSet<int, 16> LargeStackObjs; 1143d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach if (MFI->getStackProtectorIndex() >= 0) { 1153d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach AdjustStackOffset(MFI, MFI->getStackProtectorIndex(), Offset, MaxAlign); 1163d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 1173d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // Assign large stack objects first. 1183d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) { 1193d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach if (MFI->isDeadObjectIndex(i)) 1203d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach continue; 1213d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach if (MFI->getStackProtectorIndex() == (int)i) 1223d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach continue; 1233d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach if (!MFI->MayNeedStackProtector(i)) 1243d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach continue; 1253d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 1263d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach AdjustStackOffset(MFI, i, Offset, MaxAlign); 1273d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach LargeStackObjs.insert(i); 1283d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach } 1293d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach } 1303d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 1313d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // Then assign frame offsets to stack objects that are not used to spill 1323d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // callee saved registers. 1333d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) { 1343d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach if (MFI->isDeadObjectIndex(i)) 1353d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach continue; 1363d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach if (MFI->getStackProtectorIndex() == (int)i) 1373d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach continue; 1383d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach if (LargeStackObjs.count(i)) 1393d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach continue; 1403d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 1413d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach AdjustStackOffset(MFI, i, Offset, MaxAlign); 1423d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach } 1433d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 1443d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // Remember how big this blob of stack space is 14563249347c2700fe2481e0bc36caa63f6e2cf6eabJim Grosbach MFI->setLocalFrameSize(Offset); 1464861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach MFI->setLocalFrameMaxAlign(MaxAlign); 1473d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach} 1488708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach 14974d803a58c7935c067397bb19afc05ec464d8159Jim Grosbachstatic inline bool 15074d803a58c7935c067397bb19afc05ec464d8159Jim GrosbachlookupCandidateBaseReg(const SmallVector<std::pair<unsigned, int64_t>, 8> &Regs, 15174d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach std::pair<unsigned, int64_t> &RegOffset, 15274d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach const MachineInstr *MI, 15374d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach const TargetRegisterInfo *TRI) { 15474d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach unsigned e = Regs.size(); 15574d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach for (unsigned i = 0; i < e; ++i) { 15674d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach RegOffset = Regs[i]; 15774d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach if (TRI->isBaseRegInRange(MI, RegOffset.first, RegOffset.second)) 15874d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach return true; 15974d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach } 16074d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach return false; 16174d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach} 16274d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach 1638708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbachvoid LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) { 1648708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // Scan the function's instructions looking for frame index references. 1658708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // For each, ask the target if it wants a virtual base register for it 1668708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // based on what we can tell it about where the local will end up in the 1678708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // stack frame. If it wants one, re-use a suitable one we've previously 1688708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // allocated, or if there isn't one that fits the bill, allocate a new one 1698708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // and ask the target to create a defining instruction for it. 1708708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach 1718708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach MachineFrameInfo *MFI = Fn.getFrameInfo(); 1728708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo(); 1738708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach 1748708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach for (MachineFunction::iterator BB = Fn.begin(), 1758708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach E = Fn.end(); BB != E; ++BB) { 1768708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) { 1778708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach MachineInstr *MI = I; 178dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach // Debug value instructions can't be out of range, so they don't need 179dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach // any updates. 180dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach // FIXME: When we extend this stuff to handle functions with both 181dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach // VLAs and dynamic realignment, we should update the debug values 182dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach // to reference the new base pointer when possible. 183dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach if (MI->isDebugValue()) 184dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach continue; 185dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach 18674d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach // A base register definition is a register+offset pair. 18774d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach SmallVector<std::pair<unsigned, int64_t>, 8> BaseRegisters; 18874d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach 1898708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // For now, allocate the base register(s) within the basic block 1908708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // where they're used, and don't try to keep them around outside 1918708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // of that. It may be beneficial to try sharing them more broadly 1928708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // than that, but the increased register pressure makes that a 1938708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // tricky thing to balance. Investigate if re-materializing these 1948708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // becomes an issue. 1958708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 1968708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // Consider replacing all frame index operands that reference 1978708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // an object allocated in the local block. 198dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach if (MI->getOperand(i).isFI()) { 199dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach int FrameIdx = MI->getOperand(i).getIndex(); 200dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach // Don't try this with values not in the local block. 201dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach if (!MFI->isObjectPreAllocated(FrameIdx)) 202dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach continue; 203dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach 2048708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach DEBUG(dbgs() << "Considering: " << *MI); 2058708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach if (TRI->needsFrameBaseReg(MI, i)) { 20674d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach unsigned BaseReg = 0; 20774d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach unsigned Offset = 0; 20874d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach 2098708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach DEBUG(dbgs() << " Replacing FI in: " << *MI); 2108708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach 2118ae231a06ce1f999f07841150635e190ddcba196Jim Grosbach // If we have a suitable base register available, use it; otherwise 2128ae231a06ce1f999f07841150635e190ddcba196Jim Grosbach // create a new one. 213dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach 21474d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach std::pair<unsigned, int64_t> RegOffset; 21574d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach if (lookupCandidateBaseReg(BaseRegisters, RegOffset, MI, TRI)) { 21674d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach // We found a register to reuse. 21774d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach BaseReg = RegOffset.first; 21874d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach Offset = RegOffset.second; 21974d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach } else { 22074d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach // No previously defined register was in range, so create a 22174d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach // new one. 22274d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach const TargetRegisterClass *RC = TRI->getPointerRegClass(); 22374d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach BaseReg = Fn.getRegInfo().createVirtualRegister(RC); 22474d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach 22574d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach // Tell the target to insert the instruction to initialize 22674d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach // the base register. 22774d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach TRI->materializeFrameBaseRegister(I, BaseReg, FrameIdx); 22874d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach 22974d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach BaseRegisters.push_back(std::pair<unsigned, int64_t>(BaseReg, 23074d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach Offset)); 23174d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach ++NumBaseRegisters; 23274d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach } 23374d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach assert(BaseReg != 0 && "Unable to allocate virtual base register!"); 234dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach 235dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach // Modify the instruction to use the new base register rather 236dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach // than the frame index operand. 23774d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach TRI->resolveFrameIndex(I, BaseReg, Offset); 238dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach 2398708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach ++NumReplacements; 2408708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach } 2418708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach 2428708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach } 2438708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach } 2448708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach } 2458708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach } 2468708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach} 247