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