LLVM  3.7.0
NVPTXPrologEpilogPass.cpp
Go to the documentation of this file.
1 //===-- NVPTXPrologEpilogPass.cpp - NVPTX prolog/epilog inserter ----------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file is a copy of the generic LLVM PrologEpilogInserter pass, modified
11 // to remove unneeded functionality and to handle virtual registers. Most code
12 // here is a copy of PrologEpilogInserter.cpp.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #include "NVPTX.h"
20 #include "llvm/Pass.h"
21 #include "llvm/Support/Debug.h"
26 
27 using namespace llvm;
28 
29 #define DEBUG_TYPE "nvptx-prolog-epilog"
30 
31 namespace {
32 class NVPTXPrologEpilogPass : public MachineFunctionPass {
33 public:
34  static char ID;
35  NVPTXPrologEpilogPass() : MachineFunctionPass(ID) {}
36 
37  bool runOnMachineFunction(MachineFunction &MF) override;
38 
39 private:
40  void calculateFrameObjectOffsets(MachineFunction &Fn);
41 };
42 }
43 
45  return new NVPTXPrologEpilogPass();
46 }
47 
49 
50 bool NVPTXPrologEpilogPass::runOnMachineFunction(MachineFunction &MF) {
51  const TargetSubtargetInfo &STI = MF.getSubtarget();
52  const TargetFrameLowering &TFI = *STI.getFrameLowering();
53  const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
54  bool Modified = false;
55 
56  calculateFrameObjectOffsets(MF);
57 
58  for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB) {
59  for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) {
60  MachineInstr *MI = I;
61  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
62  if (!MI->getOperand(i).isFI())
63  continue;
64  TRI.eliminateFrameIndex(MI, 0, i, nullptr);
65  Modified = true;
66  }
67  }
68  }
69 
70  // Add function prolog/epilog
71  TFI.emitPrologue(MF, MF.front());
72 
73  for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
74  // If last instruction is a return instruction, add an epilogue
75  if (!I->empty() && I->back().isReturn())
76  TFI.emitEpilogue(MF, *I);
77  }
78 
79  return Modified;
80 }
81 
82 /// AdjustStackOffset - Helper function used to adjust the stack frame offset.
83 static inline void
85  bool StackGrowsDown, int64_t &Offset,
86  unsigned &MaxAlign) {
87  // If the stack grows down, add the object size to find the lowest address.
88  if (StackGrowsDown)
89  Offset += MFI->getObjectSize(FrameIdx);
90 
91  unsigned Align = MFI->getObjectAlignment(FrameIdx);
92 
93  // If the alignment of this object is greater than that of the stack, then
94  // increase the stack alignment to match.
95  MaxAlign = std::max(MaxAlign, Align);
96 
97  // Adjust to alignment boundary.
98  Offset = (Offset + Align - 1) / Align * Align;
99 
100  if (StackGrowsDown) {
101  DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << -Offset << "]\n");
102  MFI->setObjectOffset(FrameIdx, -Offset); // Set the computed offset
103  } else {
104  DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << Offset << "]\n");
105  MFI->setObjectOffset(FrameIdx, Offset);
106  Offset += MFI->getObjectSize(FrameIdx);
107  }
108 }
109 
110 void
111 NVPTXPrologEpilogPass::calculateFrameObjectOffsets(MachineFunction &Fn) {
113  const TargetRegisterInfo *RegInfo = Fn.getSubtarget().getRegisterInfo();
114 
115  bool StackGrowsDown =
117 
118  // Loop over all of the stack objects, assigning sequential addresses...
119  MachineFrameInfo *MFI = Fn.getFrameInfo();
120 
121  // Start at the beginning of the local area.
122  // The Offset is the distance from the stack top in the direction
123  // of stack growth -- so it's always nonnegative.
124  int LocalAreaOffset = TFI.getOffsetOfLocalArea();
125  if (StackGrowsDown)
126  LocalAreaOffset = -LocalAreaOffset;
127  assert(LocalAreaOffset >= 0
128  && "Local area offset should be in direction of stack growth");
129  int64_t Offset = LocalAreaOffset;
130 
131  // If there are fixed sized objects that are preallocated in the local area,
132  // non-fixed objects can't be allocated right at the start of local area.
133  // We currently don't support filling in holes in between fixed sized
134  // objects, so we adjust 'Offset' to point to the end of last fixed sized
135  // preallocated object.
136  for (int i = MFI->getObjectIndexBegin(); i != 0; ++i) {
137  int64_t FixedOff;
138  if (StackGrowsDown) {
139  // The maximum distance from the stack pointer is at lower address of
140  // the object -- which is given by offset. For down growing stack
141  // the offset is negative, so we negate the offset to get the distance.
142  FixedOff = -MFI->getObjectOffset(i);
143  } else {
144  // The maximum distance from the start pointer is at the upper
145  // address of the object.
146  FixedOff = MFI->getObjectOffset(i) + MFI->getObjectSize(i);
147  }
148  if (FixedOff > Offset) Offset = FixedOff;
149  }
150 
151  // NOTE: We do not have a call stack
152 
153  unsigned MaxAlign = MFI->getMaxAlignment();
154 
155  // No scavenger
156 
157  // FIXME: Once this is working, then enable flag will change to a target
158  // check for whether the frame is large enough to want to use virtual
159  // frame index registers. Functions which don't want/need this optimization
160  // will continue to use the existing code path.
161  if (MFI->getUseLocalStackAllocationBlock()) {
162  unsigned Align = MFI->getLocalFrameMaxAlign();
163 
164  // Adjust to alignment boundary.
165  Offset = (Offset + Align - 1) / Align * Align;
166 
167  DEBUG(dbgs() << "Local frame base offset: " << Offset << "\n");
168 
169  // Resolve offsets for objects in the local block.
170  for (unsigned i = 0, e = MFI->getLocalFrameObjectCount(); i != e; ++i) {
171  std::pair<int, int64_t> Entry = MFI->getLocalFrameObjectMap(i);
172  int64_t FIOffset = (StackGrowsDown ? -Offset : Offset) + Entry.second;
173  DEBUG(dbgs() << "alloc FI(" << Entry.first << ") at SP[" <<
174  FIOffset << "]\n");
175  MFI->setObjectOffset(Entry.first, FIOffset);
176  }
177  // Allocate the local block
178  Offset += MFI->getLocalFrameSize();
179 
180  MaxAlign = std::max(Align, MaxAlign);
181  }
182 
183  // No stack protector
184 
185  // Then assign frame offsets to stack objects that are not used to spill
186  // callee saved registers.
187  for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) {
188  if (MFI->isObjectPreAllocated(i) &&
190  continue;
191  if (MFI->isDeadObjectIndex(i))
192  continue;
193 
194  AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign);
195  }
196 
197  // No scavenger
198 
199  if (!TFI.targetHandlesStackFrameRounding()) {
200  // If we have reserved argument space for call sites in the function
201  // immediately on entry to the current function, count it as part of the
202  // overall stack size.
203  if (MFI->adjustsStack() && TFI.hasReservedCallFrame(Fn))
204  Offset += MFI->getMaxCallFrameSize();
205 
206  // Round up the size to a multiple of the alignment. If the function has
207  // any calls or alloca's, align to the target's StackAlignment value to
208  // ensure that the callee's frame or the alloca data is suitably aligned;
209  // otherwise, for leaf functions, align to the TransientStackAlignment
210  // value.
211  unsigned StackAlign;
212  if (MFI->adjustsStack() || MFI->hasVarSizedObjects() ||
213  (RegInfo->needsStackRealignment(Fn) && MFI->getObjectIndexEnd() != 0))
214  StackAlign = TFI.getStackAlignment();
215  else
216  StackAlign = TFI.getTransientStackAlignment();
217 
218  // If the frame pointer is eliminated, all frame offsets will be relative to
219  // SP not FP. Align to MaxAlign so this works.
220  StackAlign = std::max(StackAlign, MaxAlign);
221  unsigned AlignMask = StackAlign - 1;
222  Offset = (Offset + AlignMask) & ~uint64_t(AlignMask);
223  }
224 
225  // Update frame info to pretend that this is part of the stack...
226  int64_t StackSize = Offset - LocalAreaOffset;
227  MFI->setStackSize(StackSize);
228 }
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
MachineFunctionPass * createNVPTXPrologEpilogPass()
bool isObjectPreAllocated(int ObjectIdx) const
Return true if the object was pre-allocated into the local block.
unsigned getMaxAlignment() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
virtual bool targetHandlesStackFrameRounding() const
targetHandlesStackFrameRounding - Returns true if the target is responsible for rounding up the stack...
int64_t getLocalFrameSize() const
Get the size of the local object blob.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
unsigned getNumOperands() const
Access to explicit operands of the instruction.
Definition: MachineInstr.h:271
const MachineBasicBlock & front() const
int getObjectIndexBegin() const
Return the minimum frame object index.
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
unsigned getLocalFrameMaxAlign() const
Return the required alignment of the local object blob.
virtual void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const =0
eliminateFrameIndex - This method must be overriden to eliminate abstract frame indices from instruct...
unsigned getTransientStackAlignment() const
getTransientStackAlignment - This method returns the number of bytes to which the stack pointer must ...
virtual void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const =0
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
bundle_iterator< MachineInstr, instr_iterator > iterator
virtual bool needsStackRealignment(const MachineFunction &MF) const
needsStackRealignment - true if storage within the function requires the stack pointer to be aligned ...
bool getUseLocalStackAllocationBlock()
Get whether the local allocation blob should be allocated together or let PEI allocate the locals in ...
void setStackSize(uint64_t Size)
Set the size of the stack.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:273
static void AdjustStackOffset(MachineFrameInfo *MFI, int FrameIdx, bool StackGrowsDown, int64_t &Offset, unsigned &MaxAlign)
AdjustStackOffset - Helper function used to adjust the stack frame offset.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual bool hasReservedCallFrame(const MachineFunction &MF) const
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required, we reserve argument space for call sites in the function immediately on entry to the current function.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
bool isDeadObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a dead object.
virtual const TargetFrameLowering * getFrameLowering() const
int64_t getLocalFrameObjectCount()
Return the number of objects allocated into the local object block.
virtual void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const =0
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
int getOffsetOfLocalArea() const
getOffsetOfLocalArea - This method returns the offset of the local area from the stack pointer on ent...
unsigned getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call...
Information about stack frame layout on the target.
MachineFrameInfo * getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(NoStrictAlign), cl::values(clEnumValN(StrictAlign,"aarch64-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"aarch64-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:123
TargetSubtargetInfo - Generic base class for all target subtargets.
Representation of each machine instruction.
Definition: MachineInstr.h:51
StackDirection getStackGrowthDirection() const
getStackGrowthDirection - Return the direction the stack grows
#define I(x, y, z)
Definition: MD5.cpp:54
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
BasicBlockListType::iterator iterator
#define DEBUG(X)
Definition: Debug.h:92
void setObjectOffset(int ObjectIdx, int64_t SPOffset)
Set the stack frame offset of the specified object.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
std::pair< int, int64_t > getLocalFrameObjectMap(int i)
Get the local offset mapping for a for an object.
int getObjectIndexEnd() const
Return one past the maximum frame object index.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.