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 1267b067d2f91ede565a3cde857442a44314d72537Bob Wilson// estimates they are likely to be out of range of stack pointer and frame 133d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach// pointer relative addressing. 143d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach// 153d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach//===----------------------------------------------------------------------===// 163d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 17d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/Passes.h" 18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/STLExtras.h" 1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/SetVector.h" 20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/SmallSet.h" 21d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/Statistic.h" 22d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/MachineFrameInfo.h" 23d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/MachineFunction.h" 24d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/MachineFunctionPass.h" 25d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/MachineRegisterInfo.h" 2636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/StackProtector.h" 270b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Constants.h" 280b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h" 290b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Instructions.h" 300b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Intrinsics.h" 310b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/LLVMContext.h" 320b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h" 333d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#include "llvm/Pass.h" 343d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#include "llvm/Support/Debug.h" 353d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#include "llvm/Support/ErrorHandling.h" 363d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach#include "llvm/Support/raw_ostream.h" 3716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov#include "llvm/Target/TargetFrameLowering.h" 38d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetRegisterInfo.h" 393d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 403d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbachusing namespace llvm; 413d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 42dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "localstackalloc" 43dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 448708ead5a46f4ec8f2d5f832be23381924d72b8dJim GrosbachSTATISTIC(NumAllocations, "Number of frame indices allocated into local block"); 458708ead5a46f4ec8f2d5f832be23381924d72b8dJim GrosbachSTATISTIC(NumBaseRegisters, "Number of virtual frame base registers allocated"); 468708ead5a46f4ec8f2d5f832be23381924d72b8dJim GrosbachSTATISTIC(NumReplacements, "Number of frame indices references replaced"); 473d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 483d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbachnamespace { 49864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach class FrameRef { 50864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach MachineBasicBlock::iterator MI; // Instr referencing the frame 51864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach int64_t LocalOffset; // Local offset of the frame idx referenced 52db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel int FrameIdx; // The frame index 53864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach public: 54db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel FrameRef(MachineBasicBlock::iterator I, int64_t Offset, int Idx) : 55db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel MI(I), LocalOffset(Offset), FrameIdx(Idx) {} 56864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach bool operator<(const FrameRef &RHS) const { 57864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach return LocalOffset < RHS.LocalOffset; 58864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach } 59db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel MachineBasicBlock::iterator getMachineInstr() const { return MI; } 60db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel int64_t getLocalOffset() const { return LocalOffset; } 61db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel int getFrameIndex() const { return FrameIdx; } 62864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach }; 63864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach 643d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach class LocalStackSlotPass: public MachineFunctionPass { 652b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach SmallVector<int64_t,16> LocalOffsets; 6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// StackObjSet - A set of stack object indexes 6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines typedef SmallSetVector<int, 8> StackObjSet; 688708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach 692b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach void AdjustStackOffset(MachineFrameInfo *MFI, int FrameIdx, int64_t &Offset, 7067ff81a08319f916571cea90ed92e17015c8584fJim Grosbach bool StackGrowsDown, unsigned &MaxAlign); 7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void AssignProtectedObjSet(const StackObjSet &UnassignedObjs, 7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallSet<int, 16> &ProtectedObjs, 7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachineFrameInfo *MFI, bool StackGrowsDown, 7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines int64_t &Offset, unsigned &MaxAlign); 752b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach void calculateFrameObjectOffsets(MachineFunction &Fn); 762d16f5b0cb5ae03c4b4ff6711d543552d97243a0Jim Grosbach bool insertFrameReferenceRegisters(MachineFunction &Fn); 773d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach public: 783d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach static char ID; // Pass identification, replacement for typeid 7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines explicit LocalStackSlotPass() : MachineFunctionPass(ID) { 8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines initializeLocalStackSlotPassPass(*PassRegistry::getPassRegistry()); 8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool runOnMachineFunction(MachineFunction &MF) override; 833d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override { 853d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach AU.setPreservesCFG(); 8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AU.addRequired<StackProtector>(); 873d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach MachineFunctionPass::getAnalysisUsage(AU); 883d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach } 893d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 903d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach private: 913d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach }; 923d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach} // end anonymous namespace 933d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 943d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbachchar LocalStackSlotPass::ID = 0; 951dd8c8560d45d36a8e507cd014352f1d313f9f9eAndrew Trickchar &llvm::LocalStackSlotAllocationID = LocalStackSlotPass::ID; 9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesINITIALIZE_PASS_BEGIN(LocalStackSlotPass, "localstackalloc", 9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "Local Stack Slot Allocation", false, false) 9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesINITIALIZE_PASS_DEPENDENCY(StackProtector) 9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesINITIALIZE_PASS_END(LocalStackSlotPass, "localstackalloc", 10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "Local Stack Slot Allocation", false, false) 10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1023d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 1033d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbachbool LocalStackSlotPass::runOnMachineFunction(MachineFunction &MF) { 1042b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach MachineFrameInfo *MFI = MF.getFrameInfo(); 105a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbach const TargetRegisterInfo *TRI = MF.getTarget().getRegisterInfo(); 1062b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach unsigned LocalObjectCount = MFI->getObjectIndexEnd(); 1072b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach 108a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbach // If the target doesn't want/need this pass, or if there are no locals 109a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbach // to consider, early exit. 110a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbach if (!TRI->requiresVirtualBaseRegisters(MF) || LocalObjectCount == 0) 1112b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach return true; 1122b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach 1132b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach // Make sure we have enough space to store the local offsets. 1142b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach LocalOffsets.resize(MFI->getObjectIndexEnd()); 1152b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach 1168708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // Lay out the local blob. 1173d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach calculateFrameObjectOffsets(MF); 1188708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach 1198708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // Insert virtual base registers to resolve frame index references. 1202d16f5b0cb5ae03c4b4ff6711d543552d97243a0Jim Grosbach bool UsedBaseRegs = insertFrameReferenceRegisters(MF); 1212b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach 122a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach // Tell MFI whether any base registers were allocated. PEI will only 123a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach // want to use the local block allocations from this pass if there were any. 124a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach // Otherwise, PEI can do a bit better job of getting the alignment right 125a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach // without a hole at the start since it knows the alignment of the stack 126a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach // at the start of local allocation, and this pass doesn't. 1272d16f5b0cb5ae03c4b4ff6711d543552d97243a0Jim Grosbach MFI->setUseLocalStackAllocationBlock(UsedBaseRegs); 128a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach 1293d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach return true; 1303d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach} 1313d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 1323d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach/// AdjustStackOffset - Helper function used to adjust the stack frame offset. 1332b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbachvoid LocalStackSlotPass::AdjustStackOffset(MachineFrameInfo *MFI, 1342b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach int FrameIdx, int64_t &Offset, 13567ff81a08319f916571cea90ed92e17015c8584fJim Grosbach bool StackGrowsDown, 1362b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach unsigned &MaxAlign) { 13767ff81a08319f916571cea90ed92e17015c8584fJim Grosbach // If the stack grows down, add the object size to find the lowest address. 13867ff81a08319f916571cea90ed92e17015c8584fJim Grosbach if (StackGrowsDown) 13967ff81a08319f916571cea90ed92e17015c8584fJim Grosbach Offset += MFI->getObjectSize(FrameIdx); 14067ff81a08319f916571cea90ed92e17015c8584fJim Grosbach 1413d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach unsigned Align = MFI->getObjectAlignment(FrameIdx); 1423d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 1433d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // If the alignment of this object is greater than that of the stack, then 1443d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // increase the stack alignment to match. 1453d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach MaxAlign = std::max(MaxAlign, Align); 1463d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 1473d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // Adjust to alignment boundary. 1483d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach Offset = (Offset + Align - 1) / Align * Align; 1493d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 15067ff81a08319f916571cea90ed92e17015c8584fJim Grosbach int64_t LocalOffset = StackGrowsDown ? -Offset : Offset; 1513d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach DEBUG(dbgs() << "Allocate FI(" << FrameIdx << ") to local offset " 15267ff81a08319f916571cea90ed92e17015c8584fJim Grosbach << LocalOffset << "\n"); 1532b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach // Keep the offset available for base register allocation 15467ff81a08319f916571cea90ed92e17015c8584fJim Grosbach LocalOffsets[FrameIdx] = LocalOffset; 1552b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach // And tell MFI about it for PEI to use later 15667ff81a08319f916571cea90ed92e17015c8584fJim Grosbach MFI->mapLocalFrameObject(FrameIdx, LocalOffset); 15767ff81a08319f916571cea90ed92e17015c8584fJim Grosbach 15867ff81a08319f916571cea90ed92e17015c8584fJim Grosbach if (!StackGrowsDown) 15967ff81a08319f916571cea90ed92e17015c8584fJim Grosbach Offset += MFI->getObjectSize(FrameIdx); 1603d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 1613d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach ++NumAllocations; 1623d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach} 1633d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 16436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// AssignProtectedObjSet - Helper function to assign large stack objects (i.e., 16536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// those required to be close to the Stack Protector) to stack offsets. 16636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid LocalStackSlotPass::AssignProtectedObjSet(const StackObjSet &UnassignedObjs, 16736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallSet<int, 16> &ProtectedObjs, 16836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachineFrameInfo *MFI, 16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool StackGrowsDown, int64_t &Offset, 17036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned &MaxAlign) { 17136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 17236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (StackObjSet::const_iterator I = UnassignedObjs.begin(), 17336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines E = UnassignedObjs.end(); I != E; ++I) { 17436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines int i = *I; 17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AdjustStackOffset(MFI, i, Offset, StackGrowsDown, MaxAlign); 17636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ProtectedObjs.insert(i); 17736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 17836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 17936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1803d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach/// calculateFrameObjectOffsets - Calculate actual frame offsets for all of the 1813d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach/// abstract stack objects. 1823d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach/// 1833d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbachvoid LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) { 1843d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // Loop over all of the stack objects, assigning sequential addresses... 1853d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach MachineFrameInfo *MFI = Fn.getFrameInfo(); 18616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering &TFI = *Fn.getTarget().getFrameLowering(); 18767ff81a08319f916571cea90ed92e17015c8584fJim Grosbach bool StackGrowsDown = 18816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown; 1893d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach int64_t Offset = 0; 1904861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach unsigned MaxAlign = 0; 19136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StackProtector *SP = &getAnalysis<StackProtector>(); 1923d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 1933d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // Make sure that the stack protector comes before the local variables on the 1943d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // stack. 19536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallSet<int, 16> ProtectedObjs; 1963d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach if (MFI->getStackProtectorIndex() >= 0) { 19736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StackObjSet LargeArrayObjs; 19836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StackObjSet SmallArrayObjs; 19936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StackObjSet AddrOfObjs; 20036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 20167ff81a08319f916571cea90ed92e17015c8584fJim Grosbach AdjustStackOffset(MFI, MFI->getStackProtectorIndex(), Offset, 20267ff81a08319f916571cea90ed92e17015c8584fJim Grosbach StackGrowsDown, MaxAlign); 2033d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 2043d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // Assign large stack objects first. 2053d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) { 2063d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach if (MFI->isDeadObjectIndex(i)) 2073d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach continue; 2083d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach if (MFI->getStackProtectorIndex() == (int)i) 2093d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach continue; 2103d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 21136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (SP->getSSPLayout(MFI->getObjectAllocation(i))) { 21236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case StackProtector::SSPLK_None: 21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case StackProtector::SSPLK_SmallArray: 21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallArrayObjs.insert(i); 21636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 21736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case StackProtector::SSPLK_AddrOf: 21836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AddrOfObjs.insert(i); 21936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 22036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case StackProtector::SSPLK_LargeArray: 22136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LargeArrayObjs.insert(i); 22236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 22336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 22436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines llvm_unreachable("Unexpected SSPLayoutKind."); 2253d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach } 22636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 22736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AssignProtectedObjSet(LargeArrayObjs, ProtectedObjs, MFI, StackGrowsDown, 22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Offset, MaxAlign); 22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AssignProtectedObjSet(SmallArrayObjs, ProtectedObjs, MFI, StackGrowsDown, 23036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Offset, MaxAlign); 23136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AssignProtectedObjSet(AddrOfObjs, ProtectedObjs, MFI, StackGrowsDown, 23236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Offset, MaxAlign); 2333d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach } 2343d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 2353d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // Then assign frame offsets to stack objects that are not used to spill 2363d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // callee saved registers. 2373d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) { 2383d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach if (MFI->isDeadObjectIndex(i)) 2393d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach continue; 2403d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach if (MFI->getStackProtectorIndex() == (int)i) 2413d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach continue; 24236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ProtectedObjs.count(i)) 2433d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach continue; 2443d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 24567ff81a08319f916571cea90ed92e17015c8584fJim Grosbach AdjustStackOffset(MFI, i, Offset, StackGrowsDown, MaxAlign); 2463d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach } 2473d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 2483d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // Remember how big this blob of stack space is 24963249347c2700fe2481e0bc36caa63f6e2cf6eabJim Grosbach MFI->setLocalFrameSize(Offset); 2504861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach MFI->setLocalFrameMaxAlign(MaxAlign); 2513d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach} 2528708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach 25374d803a58c7935c067397bb19afc05ec464d8159Jim Grosbachstatic inline bool 254db31bd31d62b5b85dddd5fbecae1a04a02201adcHal FinkellookupCandidateBaseReg(int64_t BaseOffset, 25567ff81a08319f916571cea90ed92e17015c8584fJim Grosbach int64_t FrameSizeAdjust, 2562b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach int64_t LocalFrameOffset, 25774d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach const MachineInstr *MI, 25874d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach const TargetRegisterInfo *TRI) { 259db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // Check if the relative offset from the where the base register references 260db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // to the target address is in range for the instruction. 261db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel int64_t Offset = FrameSizeAdjust + LocalFrameOffset - BaseOffset; 262db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel return TRI->isFrameOffsetLegal(MI, Offset); 26374d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach} 26474d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach 2652d16f5b0cb5ae03c4b4ff6711d543552d97243a0Jim Grosbachbool LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) { 2668708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // Scan the function's instructions looking for frame index references. 2678708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // For each, ask the target if it wants a virtual base register for it 2688708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // based on what we can tell it about where the local will end up in the 2698708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // stack frame. If it wants one, re-use a suitable one we've previously 2708708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // allocated, or if there isn't one that fits the bill, allocate a new one 2718708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // and ask the target to create a defining instruction for it. 2722d16f5b0cb5ae03c4b4ff6711d543552d97243a0Jim Grosbach bool UsedBaseReg = false; 2738708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach 2748708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach MachineFrameInfo *MFI = Fn.getFrameInfo(); 2758708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo(); 27616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering &TFI = *Fn.getTarget().getFrameLowering(); 2774c207c2ddb3bda2488044b7eac2a5c1051c36bd2Jim Grosbach bool StackGrowsDown = 27816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown; 2798708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach 280864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach // Collect all of the instructions in the block that reference 281864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach // a frame index. Also store the frame index referenced to ease later 282864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach // lookup. (For any insn that has more than one FI reference, we arbitrarily 283864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach // choose the first one). 284864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach SmallVector<FrameRef, 64> FrameReferenceInsns; 2852b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach 286864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) { 2878708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) { 2888708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach MachineInstr *MI = I; 289976ef86689ed065361a748f81c44ca3510af2202Bill Wendling 29036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Debug value, stackmap and patchpoint instructions can't be out of 29136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // range, so they don't need any updates. 29236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (MI->isDebugValue() || 29336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MI->getOpcode() == TargetOpcode::STACKMAP || 29436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MI->getOpcode() == TargetOpcode::PATCHPOINT) 295dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach continue; 296976ef86689ed065361a748f81c44ca3510af2202Bill Wendling 2978708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // For now, allocate the base register(s) within the basic block 2988708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // where they're used, and don't try to keep them around outside 2998708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // of that. It may be beneficial to try sharing them more broadly 3008708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // than that, but the increased register pressure makes that a 3018708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // tricky thing to balance. Investigate if re-materializing these 3028708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // becomes an issue. 3038708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 3048708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // Consider replacing all frame index operands that reference 3058708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // an object allocated in the local block. 306dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach if (MI->getOperand(i).isFI()) { 307dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach // Don't try this with values not in the local block. 308864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach if (!MFI->isObjectPreAllocated(MI->getOperand(i).getIndex())) 309864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach break; 310db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel int Idx = MI->getOperand(i).getIndex(); 311db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel int64_t LocalOffset = LocalOffsets[Idx]; 312db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel if (!TRI->needsFrameBaseReg(MI, LocalOffset)) 313db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel break; 314864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach FrameReferenceInsns. 315db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel push_back(FrameRef(MI, LocalOffset, Idx)); 316864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach break; 317864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach } 318864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach } 319864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach } 320864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach } 321976ef86689ed065361a748f81c44ca3510af2202Bill Wendling 322864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach // Sort the frame references by local offset 323864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach array_pod_sort(FrameReferenceInsns.begin(), FrameReferenceInsns.end()); 324864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach 325976ef86689ed065361a748f81c44ca3510af2202Bill Wendling MachineBasicBlock *Entry = Fn.begin(); 326864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach 327db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel unsigned BaseReg = 0; 328db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel int64_t BaseOffset = 0; 329db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 330976ef86689ed065361a748f81c44ca3510af2202Bill Wendling // Loop through the frame references and allocate for them as necessary. 331864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach for (int ref = 0, e = FrameReferenceInsns.size(); ref < e ; ++ref) { 332db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel FrameRef &FR = FrameReferenceInsns[ref]; 333db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel MachineBasicBlock::iterator I = FR.getMachineInstr(); 334864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach MachineInstr *MI = I; 335db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel int64_t LocalOffset = FR.getLocalOffset(); 336db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel int FrameIdx = FR.getFrameIndex(); 337db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel assert(MFI->isObjectPreAllocated(FrameIdx) && 338db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel "Only pre-allocated locals expected!"); 339db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 340db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel DEBUG(dbgs() << "Considering: " << *MI); 341db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 342db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel unsigned idx = 0; 343db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel for (unsigned f = MI->getNumOperands(); idx != f; ++idx) { 344db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel if (!MI->getOperand(idx).isFI()) 345db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel continue; 346db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 347db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel if (FrameIdx == I->getOperand(idx).getIndex()) 348db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel break; 349db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel } 350db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 351db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel assert(idx < MI->getNumOperands() && "Cannot find FI operand"); 352db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 353db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel int64_t Offset = 0; 354db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel int64_t FrameSizeAdjust = StackGrowsDown ? MFI->getLocalFrameSize() : 0; 355db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 356db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel DEBUG(dbgs() << " Replacing FI in: " << *MI); 357db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 358db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // If we have a suitable base register available, use it; otherwise 359db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // create a new one. Note that any offset encoded in the 360db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // instruction itself will be taken into account by the target, 361db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // so we don't have to adjust for it here when reusing a base 362db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // register. 363db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel if (UsedBaseReg && lookupCandidateBaseReg(BaseOffset, FrameSizeAdjust, 364db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel LocalOffset, MI, TRI)) { 365db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel DEBUG(dbgs() << " Reusing base register " << BaseReg << "\n"); 366db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // We found a register to reuse. 367db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel Offset = FrameSizeAdjust + LocalOffset - BaseOffset; 368db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel } else { 369db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // No previously defined register was in range, so create a // new one. 370db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 371db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel int64_t InstrOffset = TRI->getFrameIndexInstrOffset(MI, idx); 372db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 373db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel int64_t PrevBaseOffset = BaseOffset; 374db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel BaseOffset = FrameSizeAdjust + LocalOffset + InstrOffset; 375db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 376db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // We'd like to avoid creating single-use virtual base registers. 377db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // Because the FrameRefs are in sorted order, and we've already 378db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // processed all FrameRefs before this one, just check whether or not 379db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // the next FrameRef will be able to reuse this new register. If not, 380db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // then don't bother creating it. 38136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ref + 1 >= e || 38236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines !lookupCandidateBaseReg( 38336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines BaseOffset, FrameSizeAdjust, 38436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FrameReferenceInsns[ref + 1].getLocalOffset(), 38536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FrameReferenceInsns[ref + 1].getMachineInstr(), TRI)) { 386db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel BaseOffset = PrevBaseOffset; 387db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel continue; 388db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel } 389db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 390db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel const MachineFunction *MF = MI->getParent()->getParent(); 391db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel const TargetRegisterClass *RC = TRI->getPointerRegClass(*MF); 392db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel BaseReg = Fn.getRegInfo().createVirtualRegister(RC); 393db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 394db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel DEBUG(dbgs() << " Materializing base register " << BaseReg << 395db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel " at frame local offset " << LocalOffset + InstrOffset << "\n"); 396db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 397db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // Tell the target to insert the instruction to initialize 398db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // the base register. 399db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // MachineBasicBlock::iterator InsertionPt = Entry->begin(); 400db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel TRI->materializeFrameBaseRegister(Entry, BaseReg, FrameIdx, 401db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel InstrOffset); 402db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 403db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // The base register already includes any offset specified 404db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // by the instruction, so account for that so it doesn't get 405db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // applied twice. 406db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel Offset = -InstrOffset; 407db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 408db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel ++NumBaseRegisters; 409db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel UsedBaseReg = true; 4108708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach } 411db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel assert(BaseReg != 0 && "Unable to allocate virtual base register!"); 412db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 413db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // Modify the instruction to use the new base register rather 414db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // than the frame index operand. 41536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TRI->resolveFrameIndex(*I, BaseReg, Offset); 416db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel DEBUG(dbgs() << "Resolved: " << *MI); 417db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 418db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel ++NumReplacements; 4198708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach } 420db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 4212d16f5b0cb5ae03c4b4ff6711d543552d97243a0Jim Grosbach return UsedBaseReg; 4228708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach} 423