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