15443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski//===-- NVPTXPrologEpilogPass.cpp - NVPTX prolog/epilog inserter ----------===// 25443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski// 35443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski// The LLVM Compiler Infrastructure 45443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski// 55443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski// This file is distributed under the University of Illinois Open Source 65443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski// License. See LICENSE.TXT for details. 75443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski// 85443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski//===----------------------------------------------------------------------===// 95443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski// 105443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski// This file is a copy of the generic LLVM PrologEpilogInserter pass, modified 115443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski// to remove unneeded functionality and to handle virtual registers. Most code 125443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski// here is a copy of PrologEpilogInserter.cpp. 135443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski// 145443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski//===----------------------------------------------------------------------===// 155443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 165443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski#include "NVPTX.h" 175443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski#include "llvm/CodeGen/MachineFrameInfo.h" 185443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski#include "llvm/CodeGen/MachineFunction.h" 195443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski#include "llvm/CodeGen/MachineFunctionPass.h" 2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Pass.h" 215443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski#include "llvm/Support/Debug.h" 225443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski#include "llvm/Support/raw_ostream.h" 2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Target/TargetFrameLowering.h" 2436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Target/TargetRegisterInfo.h" 2537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Target/TargetSubtargetInfo.h" 265443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 275443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinskiusing namespace llvm; 285443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 29dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "nvptx-prolog-epilog" 30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 315443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinskinamespace { 325443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinskiclass NVPTXPrologEpilogPass : public MachineFunctionPass { 335443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinskipublic: 345443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski static char ID; 355443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski NVPTXPrologEpilogPass() : MachineFunctionPass(ID) {} 365443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 37dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool runOnMachineFunction(MachineFunction &MF) override; 385443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 395443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinskiprivate: 405443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski void calculateFrameObjectOffsets(MachineFunction &Fn); 415443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski}; 425443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski} 435443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 445443e7d79044f3198f2da044f1b389b40d9bea6fJustin HolewinskiMachineFunctionPass *llvm::createNVPTXPrologEpilogPass() { 455443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski return new NVPTXPrologEpilogPass(); 465443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski} 475443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 485443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinskichar NVPTXPrologEpilogPass::ID = 0; 495443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 505443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinskibool NVPTXPrologEpilogPass::runOnMachineFunction(MachineFunction &MF) { 51ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const TargetSubtargetInfo &STI = MF.getSubtarget(); 52ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const TargetFrameLowering &TFI = *STI.getFrameLowering(); 53ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const TargetRegisterInfo &TRI = *STI.getRegisterInfo(); 545443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski bool Modified = false; 555443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 565443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski calculateFrameObjectOffsets(MF); 575443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 58de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (MachineBasicBlock &MBB : MF) { 59de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (MachineInstr &MI : MBB) { 60de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { 61de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (!MI.getOperand(i).isFI()) 625443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski continue; 63dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TRI.eliminateFrameIndex(MI, 0, i, nullptr); 645443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski Modified = true; 655443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski } 665443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski } 675443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski } 685443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 695443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // Add function prolog/epilog 706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar TFI.emitPrologue(MF, MF.front()); 715443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 725443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) { 735443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // If last instruction is a return instruction, add an epilogue 74f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (I->isReturnBlock()) 755443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski TFI.emitEpilogue(MF, *I); 765443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski } 775443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 785443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski return Modified; 795443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski} 805443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 815443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski/// AdjustStackOffset - Helper function used to adjust the stack frame offset. 825443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinskistatic inline void 835443e7d79044f3198f2da044f1b389b40d9bea6fJustin HolewinskiAdjustStackOffset(MachineFrameInfo *MFI, int FrameIdx, 845443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski bool StackGrowsDown, int64_t &Offset, 855443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski unsigned &MaxAlign) { 865443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // If the stack grows down, add the object size to find the lowest address. 875443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski if (StackGrowsDown) 885443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski Offset += MFI->getObjectSize(FrameIdx); 895443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 905443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski unsigned Align = MFI->getObjectAlignment(FrameIdx); 915443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 925443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // If the alignment of this object is greater than that of the stack, then 935443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // increase the stack alignment to match. 945443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski MaxAlign = std::max(MaxAlign, Align); 955443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 965443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // Adjust to alignment boundary. 975443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski Offset = (Offset + Align - 1) / Align * Align; 985443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 995443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski if (StackGrowsDown) { 1005443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << -Offset << "]\n"); 1015443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski MFI->setObjectOffset(FrameIdx, -Offset); // Set the computed offset 1025443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski } else { 1035443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << Offset << "]\n"); 1045443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski MFI->setObjectOffset(FrameIdx, Offset); 1055443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski Offset += MFI->getObjectSize(FrameIdx); 1065443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski } 1075443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski} 1085443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 1095443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinskivoid 1105443e7d79044f3198f2da044f1b389b40d9bea6fJustin HolewinskiNVPTXPrologEpilogPass::calculateFrameObjectOffsets(MachineFunction &Fn) { 11137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const TargetFrameLowering &TFI = *Fn.getSubtarget().getFrameLowering(); 11237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const TargetRegisterInfo *RegInfo = Fn.getSubtarget().getRegisterInfo(); 1135443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 1145443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski bool StackGrowsDown = 1155443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown; 1165443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 1175443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // Loop over all of the stack objects, assigning sequential addresses... 1185443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski MachineFrameInfo *MFI = Fn.getFrameInfo(); 1195443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 1205443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // Start at the beginning of the local area. 1215443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // The Offset is the distance from the stack top in the direction 1225443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // of stack growth -- so it's always nonnegative. 1235443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski int LocalAreaOffset = TFI.getOffsetOfLocalArea(); 1245443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski if (StackGrowsDown) 1255443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski LocalAreaOffset = -LocalAreaOffset; 1265443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski assert(LocalAreaOffset >= 0 1275443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski && "Local area offset should be in direction of stack growth"); 1285443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski int64_t Offset = LocalAreaOffset; 1295443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 1305443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // If there are fixed sized objects that are preallocated in the local area, 1315443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // non-fixed objects can't be allocated right at the start of local area. 1325443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // We currently don't support filling in holes in between fixed sized 1335443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // objects, so we adjust 'Offset' to point to the end of last fixed sized 1345443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // preallocated object. 1355443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski for (int i = MFI->getObjectIndexBegin(); i != 0; ++i) { 1365443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski int64_t FixedOff; 1375443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski if (StackGrowsDown) { 1385443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // The maximum distance from the stack pointer is at lower address of 1395443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // the object -- which is given by offset. For down growing stack 1405443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // the offset is negative, so we negate the offset to get the distance. 1415443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski FixedOff = -MFI->getObjectOffset(i); 1425443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski } else { 1435443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // The maximum distance from the start pointer is at the upper 1445443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // address of the object. 1455443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski FixedOff = MFI->getObjectOffset(i) + MFI->getObjectSize(i); 1465443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski } 1475443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski if (FixedOff > Offset) Offset = FixedOff; 1485443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski } 1495443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 1505443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // NOTE: We do not have a call stack 1515443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 1525443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski unsigned MaxAlign = MFI->getMaxAlignment(); 1535443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 1545443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // No scavenger 1555443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 1565443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // FIXME: Once this is working, then enable flag will change to a target 1575443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // check for whether the frame is large enough to want to use virtual 1585443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // frame index registers. Functions which don't want/need this optimization 1595443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // will continue to use the existing code path. 1605443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski if (MFI->getUseLocalStackAllocationBlock()) { 1615443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski unsigned Align = MFI->getLocalFrameMaxAlign(); 1625443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 1635443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // Adjust to alignment boundary. 1645443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski Offset = (Offset + Align - 1) / Align * Align; 1655443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 1665443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski DEBUG(dbgs() << "Local frame base offset: " << Offset << "\n"); 1675443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 1685443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // Resolve offsets for objects in the local block. 1695443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski for (unsigned i = 0, e = MFI->getLocalFrameObjectCount(); i != e; ++i) { 1705443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski std::pair<int, int64_t> Entry = MFI->getLocalFrameObjectMap(i); 1715443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski int64_t FIOffset = (StackGrowsDown ? -Offset : Offset) + Entry.second; 1725443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski DEBUG(dbgs() << "alloc FI(" << Entry.first << ") at SP[" << 1735443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski FIOffset << "]\n"); 1745443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski MFI->setObjectOffset(Entry.first, FIOffset); 1755443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski } 1765443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // Allocate the local block 1775443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski Offset += MFI->getLocalFrameSize(); 1785443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 1795443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski MaxAlign = std::max(Align, MaxAlign); 1805443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski } 1815443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 1825443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // No stack protector 1835443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 1845443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // Then assign frame offsets to stack objects that are not used to spill 1855443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // callee saved registers. 1865443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) { 1875443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski if (MFI->isObjectPreAllocated(i) && 1885443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski MFI->getUseLocalStackAllocationBlock()) 1895443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski continue; 1905443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski if (MFI->isDeadObjectIndex(i)) 1915443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski continue; 1925443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 1935443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign); 1945443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski } 1955443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 1965443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // No scavenger 1975443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 1985443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski if (!TFI.targetHandlesStackFrameRounding()) { 1995443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // If we have reserved argument space for call sites in the function 2005443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // immediately on entry to the current function, count it as part of the 2015443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // overall stack size. 2025443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski if (MFI->adjustsStack() && TFI.hasReservedCallFrame(Fn)) 2035443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski Offset += MFI->getMaxCallFrameSize(); 2045443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 2055443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // Round up the size to a multiple of the alignment. If the function has 2065443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // any calls or alloca's, align to the target's StackAlignment value to 2075443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // ensure that the callee's frame or the alloca data is suitably aligned; 2085443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // otherwise, for leaf functions, align to the TransientStackAlignment 2095443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // value. 2105443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski unsigned StackAlign; 2115443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski if (MFI->adjustsStack() || MFI->hasVarSizedObjects() || 2125443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski (RegInfo->needsStackRealignment(Fn) && MFI->getObjectIndexEnd() != 0)) 2135443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski StackAlign = TFI.getStackAlignment(); 2145443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski else 2155443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski StackAlign = TFI.getTransientStackAlignment(); 2165443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 2175443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // If the frame pointer is eliminated, all frame offsets will be relative to 2185443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // SP not FP. Align to MaxAlign so this works. 2195443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski StackAlign = std::max(StackAlign, MaxAlign); 2205443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski unsigned AlignMask = StackAlign - 1; 2215443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski Offset = (Offset + AlignMask) & ~uint64_t(AlignMask); 2225443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski } 2235443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 2245443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // Update frame info to pretend that this is part of the stack... 2255443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski int64_t StackSize = Offset - LocalAreaOffset; 2265443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski MFI->setStackSize(StackSize); 2275443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski} 228