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" 3937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Target/TargetSubtargetInfo.h" 403d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 413d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbachusing namespace llvm; 423d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 43dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "localstackalloc" 44dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 458708ead5a46f4ec8f2d5f832be23381924d72b8dJim GrosbachSTATISTIC(NumAllocations, "Number of frame indices allocated into local block"); 468708ead5a46f4ec8f2d5f832be23381924d72b8dJim GrosbachSTATISTIC(NumBaseRegisters, "Number of virtual frame base registers allocated"); 478708ead5a46f4ec8f2d5f832be23381924d72b8dJim GrosbachSTATISTIC(NumReplacements, "Number of frame indices references replaced"); 483d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 493d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbachnamespace { 50864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach class FrameRef { 51864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach MachineBasicBlock::iterator MI; // Instr referencing the frame 52864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach int64_t LocalOffset; // Local offset of the frame idx referenced 53db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel int FrameIdx; // The frame index 54864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach public: 55db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel FrameRef(MachineBasicBlock::iterator I, int64_t Offset, int Idx) : 56db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel MI(I), LocalOffset(Offset), FrameIdx(Idx) {} 57864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach bool operator<(const FrameRef &RHS) const { 58864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach return LocalOffset < RHS.LocalOffset; 59864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach } 60db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel MachineBasicBlock::iterator getMachineInstr() const { return MI; } 61db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel int64_t getLocalOffset() const { return LocalOffset; } 62db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel int getFrameIndex() const { return FrameIdx; } 63864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach }; 64864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach 653d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach class LocalStackSlotPass: public MachineFunctionPass { 662b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach SmallVector<int64_t,16> LocalOffsets; 6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// StackObjSet - A set of stack object indexes 6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines typedef SmallSetVector<int, 8> StackObjSet; 698708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach 702b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach void AdjustStackOffset(MachineFrameInfo *MFI, int FrameIdx, int64_t &Offset, 7167ff81a08319f916571cea90ed92e17015c8584fJim Grosbach bool StackGrowsDown, unsigned &MaxAlign); 7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void AssignProtectedObjSet(const StackObjSet &UnassignedObjs, 7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallSet<int, 16> &ProtectedObjs, 7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachineFrameInfo *MFI, bool StackGrowsDown, 7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines int64_t &Offset, unsigned &MaxAlign); 762b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach void calculateFrameObjectOffsets(MachineFunction &Fn); 772d16f5b0cb5ae03c4b4ff6711d543552d97243a0Jim Grosbach bool insertFrameReferenceRegisters(MachineFunction &Fn); 783d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach public: 793d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach static char ID; // Pass identification, replacement for typeid 8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines explicit LocalStackSlotPass() : MachineFunctionPass(ID) { 8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines initializeLocalStackSlotPassPass(*PassRegistry::getPassRegistry()); 8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool runOnMachineFunction(MachineFunction &MF) override; 843d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override { 863d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach AU.setPreservesCFG(); 8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AU.addRequired<StackProtector>(); 883d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach MachineFunctionPass::getAnalysisUsage(AU); 893d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach } 903d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 913d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach private: 923d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach }; 933d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach} // end anonymous namespace 943d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 953d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbachchar LocalStackSlotPass::ID = 0; 961dd8c8560d45d36a8e507cd014352f1d313f9f9eAndrew Trickchar &llvm::LocalStackSlotAllocationID = LocalStackSlotPass::ID; 9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesINITIALIZE_PASS_BEGIN(LocalStackSlotPass, "localstackalloc", 9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "Local Stack Slot Allocation", false, false) 9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesINITIALIZE_PASS_DEPENDENCY(StackProtector) 10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesINITIALIZE_PASS_END(LocalStackSlotPass, "localstackalloc", 10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "Local Stack Slot Allocation", false, false) 10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1033d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 1043d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbachbool LocalStackSlotPass::runOnMachineFunction(MachineFunction &MF) { 1052b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach MachineFrameInfo *MFI = MF.getFrameInfo(); 10637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); 1072b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach unsigned LocalObjectCount = MFI->getObjectIndexEnd(); 1082b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach 109a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbach // If the target doesn't want/need this pass, or if there are no locals 110a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbach // to consider, early exit. 111a273442891ae20fd8192526132e3819ea9e5eda9Jim Grosbach if (!TRI->requiresVirtualBaseRegisters(MF) || LocalObjectCount == 0) 1122b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach return true; 1132b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach 1142b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach // Make sure we have enough space to store the local offsets. 1152b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach LocalOffsets.resize(MFI->getObjectIndexEnd()); 1162b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach 1178708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // Lay out the local blob. 1183d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach calculateFrameObjectOffsets(MF); 1198708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach 1208708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // Insert virtual base registers to resolve frame index references. 1212d16f5b0cb5ae03c4b4ff6711d543552d97243a0Jim Grosbach bool UsedBaseRegs = insertFrameReferenceRegisters(MF); 1222b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach 123a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach // Tell MFI whether any base registers were allocated. PEI will only 124a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach // want to use the local block allocations from this pass if there were any. 125a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach // Otherwise, PEI can do a bit better job of getting the alignment right 126a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach // without a hole at the start since it knows the alignment of the stack 127a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach // at the start of local allocation, and this pass doesn't. 1282d16f5b0cb5ae03c4b4ff6711d543552d97243a0Jim Grosbach MFI->setUseLocalStackAllocationBlock(UsedBaseRegs); 129a0fc005321ac163f10ebc5216a85068a496969dfJim Grosbach 1303d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach return true; 1313d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach} 1323d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 1333d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach/// AdjustStackOffset - Helper function used to adjust the stack frame offset. 1342b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbachvoid LocalStackSlotPass::AdjustStackOffset(MachineFrameInfo *MFI, 1352b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach int FrameIdx, int64_t &Offset, 13667ff81a08319f916571cea90ed92e17015c8584fJim Grosbach bool StackGrowsDown, 1372b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach unsigned &MaxAlign) { 13867ff81a08319f916571cea90ed92e17015c8584fJim Grosbach // If the stack grows down, add the object size to find the lowest address. 13967ff81a08319f916571cea90ed92e17015c8584fJim Grosbach if (StackGrowsDown) 14067ff81a08319f916571cea90ed92e17015c8584fJim Grosbach Offset += MFI->getObjectSize(FrameIdx); 14167ff81a08319f916571cea90ed92e17015c8584fJim Grosbach 1423d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach unsigned Align = MFI->getObjectAlignment(FrameIdx); 1433d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 1443d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // If the alignment of this object is greater than that of the stack, then 1453d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // increase the stack alignment to match. 1463d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach MaxAlign = std::max(MaxAlign, Align); 1473d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 1483d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // Adjust to alignment boundary. 1493d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach Offset = (Offset + Align - 1) / Align * Align; 1503d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 15167ff81a08319f916571cea90ed92e17015c8584fJim Grosbach int64_t LocalOffset = StackGrowsDown ? -Offset : Offset; 1523d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach DEBUG(dbgs() << "Allocate FI(" << FrameIdx << ") to local offset " 15367ff81a08319f916571cea90ed92e17015c8584fJim Grosbach << LocalOffset << "\n"); 1542b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach // Keep the offset available for base register allocation 15567ff81a08319f916571cea90ed92e17015c8584fJim Grosbach LocalOffsets[FrameIdx] = LocalOffset; 1562b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach // And tell MFI about it for PEI to use later 15767ff81a08319f916571cea90ed92e17015c8584fJim Grosbach MFI->mapLocalFrameObject(FrameIdx, LocalOffset); 15867ff81a08319f916571cea90ed92e17015c8584fJim Grosbach 15967ff81a08319f916571cea90ed92e17015c8584fJim Grosbach if (!StackGrowsDown) 16067ff81a08319f916571cea90ed92e17015c8584fJim Grosbach Offset += MFI->getObjectSize(FrameIdx); 1613d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 1623d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach ++NumAllocations; 1633d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach} 1643d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 16536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// AssignProtectedObjSet - Helper function to assign large stack objects (i.e., 16636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// those required to be close to the Stack Protector) to stack offsets. 16736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid LocalStackSlotPass::AssignProtectedObjSet(const StackObjSet &UnassignedObjs, 16836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallSet<int, 16> &ProtectedObjs, 16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachineFrameInfo *MFI, 17036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool StackGrowsDown, int64_t &Offset, 17136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned &MaxAlign) { 17236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 17336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (StackObjSet::const_iterator I = UnassignedObjs.begin(), 17436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines E = UnassignedObjs.end(); I != E; ++I) { 17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines int i = *I; 17636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AdjustStackOffset(MFI, i, Offset, StackGrowsDown, MaxAlign); 17736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ProtectedObjs.insert(i); 17836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 17936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 18036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1813d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach/// calculateFrameObjectOffsets - Calculate actual frame offsets for all of the 1823d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach/// abstract stack objects. 1833d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach/// 1843d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbachvoid LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) { 1853d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // Loop over all of the stack objects, assigning sequential addresses... 1863d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach MachineFrameInfo *MFI = Fn.getFrameInfo(); 18737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const TargetFrameLowering &TFI = *Fn.getSubtarget().getFrameLowering(); 18867ff81a08319f916571cea90ed92e17015c8584fJim Grosbach bool StackGrowsDown = 18916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown; 1903d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach int64_t Offset = 0; 1914861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach unsigned MaxAlign = 0; 19236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StackProtector *SP = &getAnalysis<StackProtector>(); 1933d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 1943d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // Make sure that the stack protector comes before the local variables on the 1953d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // stack. 19636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallSet<int, 16> ProtectedObjs; 1973d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach if (MFI->getStackProtectorIndex() >= 0) { 19836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StackObjSet LargeArrayObjs; 19936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StackObjSet SmallArrayObjs; 20036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StackObjSet AddrOfObjs; 20136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 20267ff81a08319f916571cea90ed92e17015c8584fJim Grosbach AdjustStackOffset(MFI, MFI->getStackProtectorIndex(), Offset, 20367ff81a08319f916571cea90ed92e17015c8584fJim Grosbach StackGrowsDown, MaxAlign); 2043d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 2053d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // Assign large stack objects first. 2063d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) { 2073d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach if (MFI->isDeadObjectIndex(i)) 2083d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach continue; 2093d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach if (MFI->getStackProtectorIndex() == (int)i) 2103d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach continue; 2113d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 21236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (SP->getSSPLayout(MFI->getObjectAllocation(i))) { 21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case StackProtector::SSPLK_None: 21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case StackProtector::SSPLK_SmallArray: 21636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallArrayObjs.insert(i); 21736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 21836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case StackProtector::SSPLK_AddrOf: 21936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AddrOfObjs.insert(i); 22036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 22136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case StackProtector::SSPLK_LargeArray: 22236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LargeArrayObjs.insert(i); 22336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 22436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 22536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines llvm_unreachable("Unexpected SSPLayoutKind."); 2263d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach } 22736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AssignProtectedObjSet(LargeArrayObjs, ProtectedObjs, MFI, StackGrowsDown, 22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Offset, MaxAlign); 23036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AssignProtectedObjSet(SmallArrayObjs, ProtectedObjs, MFI, StackGrowsDown, 23136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Offset, MaxAlign); 23236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines AssignProtectedObjSet(AddrOfObjs, ProtectedObjs, MFI, StackGrowsDown, 23336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Offset, MaxAlign); 2343d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach } 2353d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 2363d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // Then assign frame offsets to stack objects that are not used to spill 2373d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // callee saved registers. 2383d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) { 2393d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach if (MFI->isDeadObjectIndex(i)) 2403d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach continue; 2413d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach if (MFI->getStackProtectorIndex() == (int)i) 2423d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach continue; 24336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ProtectedObjs.count(i)) 2443d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach continue; 2453d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 24667ff81a08319f916571cea90ed92e17015c8584fJim Grosbach AdjustStackOffset(MFI, i, Offset, StackGrowsDown, MaxAlign); 2473d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach } 2483d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach 2493d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach // Remember how big this blob of stack space is 25063249347c2700fe2481e0bc36caa63f6e2cf6eabJim Grosbach MFI->setLocalFrameSize(Offset); 2514861ed60ac68a543d1b88e631e9fe2c55583b24bJim Grosbach MFI->setLocalFrameMaxAlign(MaxAlign); 2523d72367d30c9ce6f387764a028763f7a366cc443Jim Grosbach} 2538708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach 25474d803a58c7935c067397bb19afc05ec464d8159Jim Grosbachstatic inline bool 2554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarlookupCandidateBaseReg(unsigned BaseReg, 2564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar int64_t BaseOffset, 25767ff81a08319f916571cea90ed92e17015c8584fJim Grosbach int64_t FrameSizeAdjust, 2582b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach int64_t LocalFrameOffset, 25974d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach const MachineInstr *MI, 26074d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach const TargetRegisterInfo *TRI) { 261db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // Check if the relative offset from the where the base register references 262db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // to the target address is in range for the instruction. 263db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel int64_t Offset = FrameSizeAdjust + LocalFrameOffset - BaseOffset; 2644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return TRI->isFrameOffsetLegal(MI, BaseReg, Offset); 26574d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach} 26674d803a58c7935c067397bb19afc05ec464d8159Jim Grosbach 2672d16f5b0cb5ae03c4b4ff6711d543552d97243a0Jim Grosbachbool LocalStackSlotPass::insertFrameReferenceRegisters(MachineFunction &Fn) { 2688708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // Scan the function's instructions looking for frame index references. 2698708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // For each, ask the target if it wants a virtual base register for it 2708708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // based on what we can tell it about where the local will end up in the 2718708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // stack frame. If it wants one, re-use a suitable one we've previously 2728708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // allocated, or if there isn't one that fits the bill, allocate a new one 2738708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // and ask the target to create a defining instruction for it. 2742d16f5b0cb5ae03c4b4ff6711d543552d97243a0Jim Grosbach bool UsedBaseReg = false; 2758708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach 2768708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach MachineFrameInfo *MFI = Fn.getFrameInfo(); 27737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const TargetRegisterInfo *TRI = Fn.getSubtarget().getRegisterInfo(); 27837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const TargetFrameLowering &TFI = *Fn.getSubtarget().getFrameLowering(); 2794c207c2ddb3bda2488044b7eac2a5c1051c36bd2Jim Grosbach bool StackGrowsDown = 28016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown; 2818708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach 282864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach // Collect all of the instructions in the block that reference 283864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach // a frame index. Also store the frame index referenced to ease later 284864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach // lookup. (For any insn that has more than one FI reference, we arbitrarily 285864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach // choose the first one). 286864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach SmallVector<FrameRef, 64> FrameReferenceInsns; 2872b1e202e1c2137b03f7c6ecc18668e40819fa22fJim Grosbach 288864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) { 2898708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) { 2908708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach MachineInstr *MI = I; 291976ef86689ed065361a748f81c44ca3510af2202Bill Wendling 29236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Debug value, stackmap and patchpoint instructions can't be out of 29336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // range, so they don't need any updates. 29436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (MI->isDebugValue() || 295ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines MI->getOpcode() == TargetOpcode::STATEPOINT || 29636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MI->getOpcode() == TargetOpcode::STACKMAP || 29736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MI->getOpcode() == TargetOpcode::PATCHPOINT) 298dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach continue; 299976ef86689ed065361a748f81c44ca3510af2202Bill Wendling 3008708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // For now, allocate the base register(s) within the basic block 3018708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // where they're used, and don't try to keep them around outside 3028708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // of that. It may be beneficial to try sharing them more broadly 3038708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // than that, but the increased register pressure makes that a 3048708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // tricky thing to balance. Investigate if re-materializing these 3058708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // becomes an issue. 3068708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 3078708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // Consider replacing all frame index operands that reference 3088708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach // an object allocated in the local block. 309dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach if (MI->getOperand(i).isFI()) { 310dc140c6e7b8350ca51aa1d408c10e25a27826e2cJim Grosbach // Don't try this with values not in the local block. 311864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach if (!MFI->isObjectPreAllocated(MI->getOperand(i).getIndex())) 312864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach break; 313db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel int Idx = MI->getOperand(i).getIndex(); 314db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel int64_t LocalOffset = LocalOffsets[Idx]; 315db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel if (!TRI->needsFrameBaseReg(MI, LocalOffset)) 316db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel break; 317864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach FrameReferenceInsns. 318db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel push_back(FrameRef(MI, LocalOffset, Idx)); 319864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach break; 320864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach } 321864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach } 322864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach } 323864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach } 324976ef86689ed065361a748f81c44ca3510af2202Bill Wendling 325864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach // Sort the frame references by local offset 326864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach array_pod_sort(FrameReferenceInsns.begin(), FrameReferenceInsns.end()); 327864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach 328976ef86689ed065361a748f81c44ca3510af2202Bill Wendling MachineBasicBlock *Entry = Fn.begin(); 329864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach 330db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel unsigned BaseReg = 0; 331db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel int64_t BaseOffset = 0; 332db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 333976ef86689ed065361a748f81c44ca3510af2202Bill Wendling // Loop through the frame references and allocate for them as necessary. 334864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach for (int ref = 0, e = FrameReferenceInsns.size(); ref < e ; ++ref) { 335db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel FrameRef &FR = FrameReferenceInsns[ref]; 336db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel MachineBasicBlock::iterator I = FR.getMachineInstr(); 337864d22ea72ac418ba06feb5e09b18c35ec53b4b2Jim Grosbach MachineInstr *MI = I; 338db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel int64_t LocalOffset = FR.getLocalOffset(); 339db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel int FrameIdx = FR.getFrameIndex(); 340db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel assert(MFI->isObjectPreAllocated(FrameIdx) && 341db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel "Only pre-allocated locals expected!"); 342db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 343db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel DEBUG(dbgs() << "Considering: " << *MI); 344db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 345db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel unsigned idx = 0; 346db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel for (unsigned f = MI->getNumOperands(); idx != f; ++idx) { 347db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel if (!MI->getOperand(idx).isFI()) 348db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel continue; 349db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 350db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel if (FrameIdx == I->getOperand(idx).getIndex()) 351db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel break; 352db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel } 353db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 354db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel assert(idx < MI->getNumOperands() && "Cannot find FI operand"); 355db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 356db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel int64_t Offset = 0; 357db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel int64_t FrameSizeAdjust = StackGrowsDown ? MFI->getLocalFrameSize() : 0; 358db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 359db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel DEBUG(dbgs() << " Replacing FI in: " << *MI); 360db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 361db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // If we have a suitable base register available, use it; otherwise 362db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // create a new one. Note that any offset encoded in the 363db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // instruction itself will be taken into account by the target, 364db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // so we don't have to adjust for it here when reusing a base 365db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // register. 3664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (UsedBaseReg && lookupCandidateBaseReg(BaseReg, BaseOffset, 3674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar FrameSizeAdjust, LocalOffset, MI, 3684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar TRI)) { 369db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel DEBUG(dbgs() << " Reusing base register " << BaseReg << "\n"); 370db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // We found a register to reuse. 371db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel Offset = FrameSizeAdjust + LocalOffset - BaseOffset; 372db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel } else { 373db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // No previously defined register was in range, so create a // new one. 374db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 375db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel int64_t InstrOffset = TRI->getFrameIndexInstrOffset(MI, idx); 376db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 377db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel int64_t PrevBaseOffset = BaseOffset; 378db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel BaseOffset = FrameSizeAdjust + LocalOffset + InstrOffset; 379db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 380db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // We'd like to avoid creating single-use virtual base registers. 381db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // Because the FrameRefs are in sorted order, and we've already 382db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // processed all FrameRefs before this one, just check whether or not 383db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // the next FrameRef will be able to reuse this new register. If not, 384db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // then don't bother creating it. 38536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ref + 1 >= e || 38636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines !lookupCandidateBaseReg( 3874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar BaseReg, BaseOffset, FrameSizeAdjust, 38836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FrameReferenceInsns[ref + 1].getLocalOffset(), 38936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FrameReferenceInsns[ref + 1].getMachineInstr(), TRI)) { 390db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel BaseOffset = PrevBaseOffset; 391db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel continue; 392db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel } 393db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 394db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel const MachineFunction *MF = MI->getParent()->getParent(); 395db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel const TargetRegisterClass *RC = TRI->getPointerRegClass(*MF); 396db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel BaseReg = Fn.getRegInfo().createVirtualRegister(RC); 397db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 398db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel DEBUG(dbgs() << " Materializing base register " << BaseReg << 399db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel " at frame local offset " << LocalOffset + InstrOffset << "\n"); 400db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 401db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // Tell the target to insert the instruction to initialize 402db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // the base register. 403db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // MachineBasicBlock::iterator InsertionPt = Entry->begin(); 404db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel TRI->materializeFrameBaseRegister(Entry, BaseReg, FrameIdx, 405db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel InstrOffset); 406db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 407db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // The base register already includes any offset specified 408db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // by the instruction, so account for that so it doesn't get 409db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // applied twice. 410db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel Offset = -InstrOffset; 411db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 412db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel ++NumBaseRegisters; 413db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel UsedBaseReg = true; 4148708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach } 415db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel assert(BaseReg != 0 && "Unable to allocate virtual base register!"); 416db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 417db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // Modify the instruction to use the new base register rather 418db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel // than the frame index operand. 41936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TRI->resolveFrameIndex(*I, BaseReg, Offset); 420db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel DEBUG(dbgs() << "Resolved: " << *MI); 421db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 422db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel ++NumReplacements; 4238708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach } 424db31bd31d62b5b85dddd5fbecae1a04a02201adcHal Finkel 4252d16f5b0cb5ae03c4b4ff6711d543552d97243a0Jim Grosbach return UsedBaseReg; 4268708ead5a46f4ec8f2d5f832be23381924d72b8dJim Grosbach} 427