LLVM  8.0.1
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"
24 #include "llvm/Pass.h"
25 #include "llvm/Support/Debug.h"
27 
28 using namespace llvm;
29 
30 #define DEBUG_TYPE "nvptx-prolog-epilog"
31 
32 namespace {
33 class NVPTXPrologEpilogPass : public MachineFunctionPass {
34 public:
35  static char ID;
36  NVPTXPrologEpilogPass() : MachineFunctionPass(ID) {}
37 
38  bool runOnMachineFunction(MachineFunction &MF) override;
39 
40 private:
41  void calculateFrameObjectOffsets(MachineFunction &Fn);
42 };
43 }
44 
46  return new NVPTXPrologEpilogPass();
47 }
48 
50 
51 bool NVPTXPrologEpilogPass::runOnMachineFunction(MachineFunction &MF) {
52  const TargetSubtargetInfo &STI = MF.getSubtarget();
53  const TargetFrameLowering &TFI = *STI.getFrameLowering();
54  const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
55  bool Modified = false;
56 
57  calculateFrameObjectOffsets(MF);
58 
59  for (MachineBasicBlock &MBB : MF) {
60  for (MachineInstr &MI : MBB) {
61  for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
62  if (!MI.getOperand(i).isFI())
63  continue;
64 
65  // Frame indices in debug values are encoded in a target independent
66  // way with simply the frame index and offset rather than any
67  // target-specific addressing mode.
68  if (MI.isDebugValue()) {
69  assert(i == 0 && "Frame indices can only appear as the first "
70  "operand of a DBG_VALUE machine instruction");
71  unsigned Reg;
72  int64_t Offset =
73  TFI.getFrameIndexReference(MF, MI.getOperand(0).getIndex(), Reg);
74  MI.getOperand(0).ChangeToRegister(Reg, /*isDef=*/false);
75  MI.getOperand(0).setIsDebug();
76  auto *DIExpr = DIExpression::prepend(MI.getDebugExpression(),
78  MI.getOperand(3).setMetadata(DIExpr);
79  continue;
80  }
81 
82  TRI.eliminateFrameIndex(MI, 0, i, nullptr);
83  Modified = true;
84  }
85  }
86  }
87 
88  // Add function prolog/epilog
89  TFI.emitPrologue(MF, MF.front());
90 
91  for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
92  // If last instruction is a return instruction, add an epilogue
93  if (I->isReturnBlock())
94  TFI.emitEpilogue(MF, *I);
95  }
96 
97  return Modified;
98 }
99 
100 /// AdjustStackOffset - Helper function used to adjust the stack frame offset.
101 static inline void
103  bool StackGrowsDown, int64_t &Offset,
104  unsigned &MaxAlign) {
105  // If the stack grows down, add the object size to find the lowest address.
106  if (StackGrowsDown)
107  Offset += MFI.getObjectSize(FrameIdx);
108 
109  unsigned Align = MFI.getObjectAlignment(FrameIdx);
110 
111  // If the alignment of this object is greater than that of the stack, then
112  // increase the stack alignment to match.
113  MaxAlign = std::max(MaxAlign, Align);
114 
115  // Adjust to alignment boundary.
116  Offset = (Offset + Align - 1) / Align * Align;
117 
118  if (StackGrowsDown) {
119  LLVM_DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << -Offset
120  << "]\n");
121  MFI.setObjectOffset(FrameIdx, -Offset); // Set the computed offset
122  } else {
123  LLVM_DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << Offset
124  << "]\n");
125  MFI.setObjectOffset(FrameIdx, Offset);
126  Offset += MFI.getObjectSize(FrameIdx);
127  }
128 }
129 
130 void
131 NVPTXPrologEpilogPass::calculateFrameObjectOffsets(MachineFunction &Fn) {
133  const TargetRegisterInfo *RegInfo = Fn.getSubtarget().getRegisterInfo();
134 
135  bool StackGrowsDown =
137 
138  // Loop over all of the stack objects, assigning sequential addresses...
139  MachineFrameInfo &MFI = Fn.getFrameInfo();
140 
141  // Start at the beginning of the local area.
142  // The Offset is the distance from the stack top in the direction
143  // of stack growth -- so it's always nonnegative.
144  int LocalAreaOffset = TFI.getOffsetOfLocalArea();
145  if (StackGrowsDown)
146  LocalAreaOffset = -LocalAreaOffset;
147  assert(LocalAreaOffset >= 0
148  && "Local area offset should be in direction of stack growth");
149  int64_t Offset = LocalAreaOffset;
150 
151  // If there are fixed sized objects that are preallocated in the local area,
152  // non-fixed objects can't be allocated right at the start of local area.
153  // We currently don't support filling in holes in between fixed sized
154  // objects, so we adjust 'Offset' to point to the end of last fixed sized
155  // preallocated object.
156  for (int i = MFI.getObjectIndexBegin(); i != 0; ++i) {
157  int64_t FixedOff;
158  if (StackGrowsDown) {
159  // The maximum distance from the stack pointer is at lower address of
160  // the object -- which is given by offset. For down growing stack
161  // the offset is negative, so we negate the offset to get the distance.
162  FixedOff = -MFI.getObjectOffset(i);
163  } else {
164  // The maximum distance from the start pointer is at the upper
165  // address of the object.
166  FixedOff = MFI.getObjectOffset(i) + MFI.getObjectSize(i);
167  }
168  if (FixedOff > Offset) Offset = FixedOff;
169  }
170 
171  // NOTE: We do not have a call stack
172 
173  unsigned MaxAlign = MFI.getMaxAlignment();
174 
175  // No scavenger
176 
177  // FIXME: Once this is working, then enable flag will change to a target
178  // check for whether the frame is large enough to want to use virtual
179  // frame index registers. Functions which don't want/need this optimization
180  // will continue to use the existing code path.
182  unsigned Align = MFI.getLocalFrameMaxAlign();
183 
184  // Adjust to alignment boundary.
185  Offset = (Offset + Align - 1) / Align * Align;
186 
187  LLVM_DEBUG(dbgs() << "Local frame base offset: " << Offset << "\n");
188 
189  // Resolve offsets for objects in the local block.
190  for (unsigned i = 0, e = MFI.getLocalFrameObjectCount(); i != e; ++i) {
191  std::pair<int, int64_t> Entry = MFI.getLocalFrameObjectMap(i);
192  int64_t FIOffset = (StackGrowsDown ? -Offset : Offset) + Entry.second;
193  LLVM_DEBUG(dbgs() << "alloc FI(" << Entry.first << ") at SP[" << FIOffset
194  << "]\n");
195  MFI.setObjectOffset(Entry.first, FIOffset);
196  }
197  // Allocate the local block
198  Offset += MFI.getLocalFrameSize();
199 
200  MaxAlign = std::max(Align, MaxAlign);
201  }
202 
203  // No stack protector
204 
205  // Then assign frame offsets to stack objects that are not used to spill
206  // callee saved registers.
207  for (unsigned i = 0, e = MFI.getObjectIndexEnd(); i != e; ++i) {
208  if (MFI.isObjectPreAllocated(i) &&
210  continue;
211  if (MFI.isDeadObjectIndex(i))
212  continue;
213 
214  AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign);
215  }
216 
217  // No scavenger
218 
219  if (!TFI.targetHandlesStackFrameRounding()) {
220  // If we have reserved argument space for call sites in the function
221  // immediately on entry to the current function, count it as part of the
222  // overall stack size.
223  if (MFI.adjustsStack() && TFI.hasReservedCallFrame(Fn))
224  Offset += MFI.getMaxCallFrameSize();
225 
226  // Round up the size to a multiple of the alignment. If the function has
227  // any calls or alloca's, align to the target's StackAlignment value to
228  // ensure that the callee's frame or the alloca data is suitably aligned;
229  // otherwise, for leaf functions, align to the TransientStackAlignment
230  // value.
231  unsigned StackAlign;
232  if (MFI.adjustsStack() || MFI.hasVarSizedObjects() ||
233  (RegInfo->needsStackRealignment(Fn) && MFI.getObjectIndexEnd() != 0))
234  StackAlign = TFI.getStackAlignment();
235  else
236  StackAlign = TFI.getTransientStackAlignment();
237 
238  // If the frame pointer is eliminated, all frame offsets will be relative to
239  // SP not FP. Align to MaxAlign so this works.
240  StackAlign = std::max(StackAlign, MaxAlign);
241  unsigned AlignMask = StackAlign - 1;
242  Offset = (Offset + AlignMask) & ~uint64_t(AlignMask);
243  }
244 
245  // Update frame info to pretend that this is part of the stack...
246  int64_t StackSize = Offset - LocalAreaOffset;
247  MFI.setStackSize(StackSize);
248 }
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
This class represents lattice values for constants.
Definition: AllocatorList.h:24
virtual int getFrameIndexReference(const MachineFunction &MF, int FI, unsigned &FrameReg) const
getFrameIndexReference - This method should return the base register and offset used to reference a f...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
bool isDeadObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a dead object.
int64_t getLocalFrameSize() const
Get the size of the local object blob.
unsigned Reg
MachineFunctionPass * createNVPTXPrologEpilogPass()
unsigned const TargetRegisterInfo * TRI
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
int getOffsetOfLocalArea() const
getOffsetOfLocalArea - This method returns the offset of the local area from the stack pointer on ent...
static DIExpression * prepend(const DIExpression *Expr, bool DerefBefore, int64_t Offset=0, bool DerefAfter=false, bool StackValue=false)
Prepend DIExpr with a deref and offset operation and optionally turn it into a stack value...
std::pair< int, int64_t > getLocalFrameObjectMap(int i) const
Get the local offset mapping for a for an object.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
bool getUseLocalStackAllocationBlock() const
Get whether the local allocation blob should be allocated together or let PEI allocate the locals in ...
static void AdjustStackOffset(MachineFrameInfo &MFI, int FrameIdx, bool StackGrowsDown, int64_t &Offset, unsigned &MaxAlign)
AdjustStackOffset - Helper function used to adjust the stack frame offset.
virtual bool targetHandlesStackFrameRounding() const
targetHandlesStackFrameRounding - Returns true if the target is responsible for rounding up the stack...
int getObjectIndexBegin() const
Return the minimum frame object index.
bool isObjectPreAllocated(int ObjectIdx) const
Return true if the object was pre-allocated into the local block.
int getObjectIndexEnd() const
Return one past the maximum frame object index.
virtual void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const =0
This method must be overriden to eliminate abstract frame indices from instructions which may use the...
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
virtual void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const =0
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void setStackSize(uint64_t Size)
Set the size of the stack.
StackDirection getStackGrowthDirection() const
getStackGrowthDirection - Return the direction the stack grows
unsigned getMaxAlignment() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
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.
Iterator for intrusive lists based on ilist_node.
unsigned getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call...
virtual void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const =0
Information about stack frame layout on the target.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:133
unsigned getTransientStackAlignment() const
getTransientStackAlignment - This method returns the number of bytes to which the stack pointer must ...
TargetSubtargetInfo - Generic base class for all target subtargets.
Representation of each machine instruction.
Definition: MachineInstr.h:64
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned getLocalFrameMaxAlign() const
Return the required alignment of the local object blob.
virtual const TargetFrameLowering * getFrameLowering() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool needsStackRealignment(const MachineFunction &MF) const
True if storage within the function requires the stack pointer to be aligned more than the normal cal...
void setObjectOffset(int ObjectIdx, int64_t SPOffset)
Set the stack frame offset of the specified object.
IRTranslator LLVM IR MI
#define LLVM_DEBUG(X)
Definition: Debug.h:123
int64_t getLocalFrameObjectCount() const
Return the number of objects allocated into the local object block.