• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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"
18 #include "llvm/CodeGen/MachineFrameInfo.h"
19 #include "llvm/CodeGen/MachineFunction.h"
20 #include "llvm/CodeGen/MachineFunctionPass.h"
21 #include "llvm/Target/TargetFrameLowering.h"
22 #include "llvm/Target/TargetRegisterInfo.h"
23 #include "llvm/Support/Debug.h"
24 #include "llvm/Support/raw_ostream.h"
25 
26 using namespace llvm;
27 
28 namespace {
29 class NVPTXPrologEpilogPass : public MachineFunctionPass {
30 public:
31   static char ID;
NVPTXPrologEpilogPass()32   NVPTXPrologEpilogPass() : MachineFunctionPass(ID) {}
33 
34   virtual bool runOnMachineFunction(MachineFunction &MF);
35 
36 private:
37   void calculateFrameObjectOffsets(MachineFunction &Fn);
38 };
39 }
40 
createNVPTXPrologEpilogPass()41 MachineFunctionPass *llvm::createNVPTXPrologEpilogPass() {
42   return new NVPTXPrologEpilogPass();
43 }
44 
45 char NVPTXPrologEpilogPass::ID = 0;
46 
runOnMachineFunction(MachineFunction & MF)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
AdjustStackOffset(MachineFrameInfo * MFI,int FrameIdx,bool StackGrowsDown,int64_t & Offset,unsigned & MaxAlign)81 AdjustStackOffset(MachineFrameInfo *MFI, int FrameIdx,
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
calculateFrameObjectOffsets(MachineFunction & Fn)108 NVPTXPrologEpilogPass::calculateFrameObjectOffsets(MachineFunction &Fn) {
109   const TargetFrameLowering &TFI = *Fn.getTarget().getFrameLowering();
110   const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo();
111 
112   bool StackGrowsDown =
113     TFI.getStackGrowthDirection() == TargetFrameLowering::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) &&
186         MFI->getUseLocalStackAllocationBlock())
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 }
226