LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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"
17 #include "llvm/Pass.h"
23 #include "llvm/Support/Debug.h"
25 
26 using namespace llvm;
27 
28 namespace {
29 class NVPTXPrologEpilogPass : public MachineFunctionPass {
30 public:
31  static char ID;
32  NVPTXPrologEpilogPass() : MachineFunctionPass(ID) {}
33 
34  virtual bool runOnMachineFunction(MachineFunction &MF);
35 
36 private:
37  void calculateFrameObjectOffsets(MachineFunction &Fn);
38 };
39 }
40 
42  return new NVPTXPrologEpilogPass();
43 }
44 
46 
47 bool NVPTXPrologEpilogPass::runOnMachineFunction(MachineFunction &MF) {
48  const TargetMachine &TM = MF.getTarget();
49  const TargetFrameLowering &TFI = *TM.getFrameLowering();
50  const TargetRegisterInfo &TRI = *TM.getRegisterInfo();
51  bool Modified = false;
52 
53  calculateFrameObjectOffsets(MF);
54 
55  for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB) {
56  for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) {
57  MachineInstr *MI = I;
58  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
59  if (!MI->getOperand(i).isFI())
60  continue;
61  TRI.eliminateFrameIndex(MI, 0, i, NULL);
62  Modified = true;
63  }
64  }
65  }
66 
67  // Add function prolog/epilog
68  TFI.emitPrologue(MF);
69 
70  for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
71  // If last instruction is a return instruction, add an epilogue
72  if (!I->empty() && I->back().isReturn())
73  TFI.emitEpilogue(MF, *I);
74  }
75 
76  return Modified;
77 }
78 
79 /// AdjustStackOffset - Helper function used to adjust the stack frame offset.
80 static inline void
82  bool StackGrowsDown, int64_t &Offset,
83  unsigned &MaxAlign) {
84  // If the stack grows down, add the object size to find the lowest address.
85  if (StackGrowsDown)
86  Offset += MFI->getObjectSize(FrameIdx);
87 
88  unsigned Align = MFI->getObjectAlignment(FrameIdx);
89 
90  // If the alignment of this object is greater than that of the stack, then
91  // increase the stack alignment to match.
92  MaxAlign = std::max(MaxAlign, Align);
93 
94  // Adjust to alignment boundary.
95  Offset = (Offset + Align - 1) / Align * Align;
96 
97  if (StackGrowsDown) {
98  DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << -Offset << "]\n");
99  MFI->setObjectOffset(FrameIdx, -Offset); // Set the computed offset
100  } else {
101  DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << Offset << "]\n");
102  MFI->setObjectOffset(FrameIdx, Offset);
103  Offset += MFI->getObjectSize(FrameIdx);
104  }
105 }
106 
107 void
108 NVPTXPrologEpilogPass::calculateFrameObjectOffsets(MachineFunction &Fn) {
109  const TargetFrameLowering &TFI = *Fn.getTarget().getFrameLowering();
110  const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo();
111 
112  bool StackGrowsDown =
114 
115  // Loop over all of the stack objects, assigning sequential addresses...
116  MachineFrameInfo *MFI = Fn.getFrameInfo();
117 
118  // Start at the beginning of the local area.
119  // The Offset is the distance from the stack top in the direction
120  // of stack growth -- so it's always nonnegative.
121  int LocalAreaOffset = TFI.getOffsetOfLocalArea();
122  if (StackGrowsDown)
123  LocalAreaOffset = -LocalAreaOffset;
124  assert(LocalAreaOffset >= 0
125  && "Local area offset should be in direction of stack growth");
126  int64_t Offset = LocalAreaOffset;
127 
128  // If there are fixed sized objects that are preallocated in the local area,
129  // non-fixed objects can't be allocated right at the start of local area.
130  // We currently don't support filling in holes in between fixed sized
131  // objects, so we adjust 'Offset' to point to the end of last fixed sized
132  // preallocated object.
133  for (int i = MFI->getObjectIndexBegin(); i != 0; ++i) {
134  int64_t FixedOff;
135  if (StackGrowsDown) {
136  // The maximum distance from the stack pointer is at lower address of
137  // the object -- which is given by offset. For down growing stack
138  // the offset is negative, so we negate the offset to get the distance.
139  FixedOff = -MFI->getObjectOffset(i);
140  } else {
141  // The maximum distance from the start pointer is at the upper
142  // address of the object.
143  FixedOff = MFI->getObjectOffset(i) + MFI->getObjectSize(i);
144  }
145  if (FixedOff > Offset) Offset = FixedOff;
146  }
147 
148  // NOTE: We do not have a call stack
149 
150  unsigned MaxAlign = MFI->getMaxAlignment();
151 
152  // No scavenger
153 
154  // FIXME: Once this is working, then enable flag will change to a target
155  // check for whether the frame is large enough to want to use virtual
156  // frame index registers. Functions which don't want/need this optimization
157  // will continue to use the existing code path.
158  if (MFI->getUseLocalStackAllocationBlock()) {
159  unsigned Align = MFI->getLocalFrameMaxAlign();
160 
161  // Adjust to alignment boundary.
162  Offset = (Offset + Align - 1) / Align * Align;
163 
164  DEBUG(dbgs() << "Local frame base offset: " << Offset << "\n");
165 
166  // Resolve offsets for objects in the local block.
167  for (unsigned i = 0, e = MFI->getLocalFrameObjectCount(); i != e; ++i) {
168  std::pair<int, int64_t> Entry = MFI->getLocalFrameObjectMap(i);
169  int64_t FIOffset = (StackGrowsDown ? -Offset : Offset) + Entry.second;
170  DEBUG(dbgs() << "alloc FI(" << Entry.first << ") at SP[" <<
171  FIOffset << "]\n");
172  MFI->setObjectOffset(Entry.first, FIOffset);
173  }
174  // Allocate the local block
175  Offset += MFI->getLocalFrameSize();
176 
177  MaxAlign = std::max(Align, MaxAlign);
178  }
179 
180  // No stack protector
181 
182  // Then assign frame offsets to stack objects that are not used to spill
183  // callee saved registers.
184  for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) {
185  if (MFI->isObjectPreAllocated(i) &&
187  continue;
188  if (MFI->isDeadObjectIndex(i))
189  continue;
190 
191  AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign);
192  }
193 
194  // No scavenger
195 
196  if (!TFI.targetHandlesStackFrameRounding()) {
197  // If we have reserved argument space for call sites in the function
198  // immediately on entry to the current function, count it as part of the
199  // overall stack size.
200  if (MFI->adjustsStack() && TFI.hasReservedCallFrame(Fn))
201  Offset += MFI->getMaxCallFrameSize();
202 
203  // Round up the size to a multiple of the alignment. If the function has
204  // any calls or alloca's, align to the target's StackAlignment value to
205  // ensure that the callee's frame or the alloca data is suitably aligned;
206  // otherwise, for leaf functions, align to the TransientStackAlignment
207  // value.
208  unsigned StackAlign;
209  if (MFI->adjustsStack() || MFI->hasVarSizedObjects() ||
210  (RegInfo->needsStackRealignment(Fn) && MFI->getObjectIndexEnd() != 0))
211  StackAlign = TFI.getStackAlignment();
212  else
213  StackAlign = TFI.getTransientStackAlignment();
214 
215  // If the frame pointer is eliminated, all frame offsets will be relative to
216  // SP not FP. Align to MaxAlign so this works.
217  StackAlign = std::max(StackAlign, MaxAlign);
218  unsigned AlignMask = StackAlign - 1;
219  Offset = (Offset + AlignMask) & ~uint64_t(AlignMask);
220  }
221 
222  // Update frame info to pretend that this is part of the stack...
223  int64_t StackSize = Offset - LocalAreaOffset;
224  MFI->setStackSize(StackSize);
225 }
unsigned getStackAlignment() const
MachineFunctionPass * createNVPTXPrologEpilogPass()
bool isObjectPreAllocated(int ObjectIdx) const
unsigned getMaxAlignment() const
virtual bool targetHandlesStackFrameRounding() const
int64_t getLocalFrameSize() const
getLocalFrameSize - Get the size of the local object blob.
Abstract Stack Frame Information.
ID
LLVM Calling Convention Representation.
Definition: CallingConv.h:26
unsigned getNumOperands() const
Definition: MachineInstr.h:265
int getObjectIndexBegin() const
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
unsigned getLocalFrameMaxAlign() const
unsigned getTransientStackAlignment() const
bundle_iterator< MachineInstr, instr_iterator > iterator
virtual bool needsStackRealignment(const MachineFunction &MF) const
void setStackSize(uint64_t Size)
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:267
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 const TargetFrameLowering * getFrameLowering() const
virtual bool hasReservedCallFrame(const MachineFunction &MF) const
int64_t getObjectOffset(int ObjectIdx) const
bool isDeadObjectIndex(int ObjectIdx) const
virtual void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const =0
unsigned getObjectAlignment(int ObjectIdx) const
getObjectAlignment - Return the alignment of the specified stack object.
unsigned getMaxCallFrameSize() const
MachineFrameInfo * getFrameInfo()
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
Definition: Debug.cpp:101
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(DefaultAlign), cl::values(clEnumValN(DefaultAlign,"arm-default-align","Generate unaligned accesses only on hardware/OS ""combinations that are known to support them"), clEnumValN(StrictAlign,"arm-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"arm-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
StackDirection getStackGrowthDirection() const
virtual void emitPrologue(MachineFunction &MF) const =0
#define I(x, y, z)
Definition: MD5.cpp:54
const TargetMachine & getTarget() const
virtual const TargetRegisterInfo * getRegisterInfo() const
bool hasVarSizedObjects() const
virtual void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=NULL) const =0
BasicBlockListType::iterator iterator
#define DEBUG(X)
Definition: Debug.h:97
void setObjectOffset(int ObjectIdx, int64_t SPOffset)
std::pair< int, int64_t > getLocalFrameObjectMap(int i)
getLocalFrameObjectMap - Get the local offset mapping for a for an object
int getObjectIndexEnd() const
int64_t getObjectSize(int ObjectIdx) const