8c73de33fe89f9c5c24bd1d83d5bae68b2d225eb
[oota-llvm.git] / lib / CodeGen / MachineFunction.cpp
1 //===-- MachineFunction.cpp -----------------------------------------------===//
2 // 
3 // Collect native machine code information for a function.  This allows
4 // target-specific information about the generated code to be stored with each
5 // function.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/CodeGen/MachineFunction.h"
10 #include "llvm/CodeGen/MachineInstr.h"
11 #include "llvm/CodeGen/MachineCodeForInstruction.h"
12 #include "llvm/CodeGen/SSARegMap.h"
13 #include "llvm/CodeGen/MachineFunctionInfo.h"
14 #include "llvm/CodeGen/FunctionFrameInfo.h"
15 #include "llvm/Target/TargetMachine.h"
16 #include "llvm/Target/TargetFrameInfo.h"
17 #include "llvm/Target/MachineCacheInfo.h"
18 #include "llvm/Function.h"
19 #include "llvm/iOther.h"
20 #include "llvm/Pass.h"
21 #include <limits.h>
22
23 const int INVALID_FRAME_OFFSET = INT_MAX; // std::numeric_limits<int>::max();
24
25 static AnnotationID MF_AID(
26                  AnnotationManager::getID("CodeGen::MachineCodeForFunction"));
27
28
29 //===---------------------------------------------------------------------===//
30 // Code generation/destruction passes
31 //===---------------------------------------------------------------------===//
32
33 namespace {
34   class ConstructMachineFunction : public FunctionPass {
35     TargetMachine &Target;
36   public:
37     ConstructMachineFunction(TargetMachine &T) : Target(T) {}
38     
39     const char *getPassName() const {
40       return "ConstructMachineFunction";
41     }
42     
43     bool runOnFunction(Function &F) {
44       MachineFunction::construct(&F, Target).getInfo()->CalculateArgSize();
45       return false;
46     }
47   };
48
49   struct DestroyMachineFunction : public FunctionPass {
50     const char *getPassName() const { return "FreeMachineFunction"; }
51     
52     static void freeMachineCode(Instruction &I) {
53       MachineCodeForInstruction::destroy(&I);
54     }
55     
56     bool runOnFunction(Function &F) {
57       for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
58         for (BasicBlock::iterator I = FI->begin(), E = FI->end(); I != E; ++I)
59           MachineCodeForInstruction::get(I).dropAllReferences();
60       
61       for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
62         for_each(FI->begin(), FI->end(), freeMachineCode);
63       
64       return false;
65     }
66   };
67
68   struct Printer : public FunctionPass {
69     const char *getPassName() const { return "MachineFunction Printer"; }
70
71     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
72       AU.setPreservesAll();
73     }
74
75     bool runOnFunction(Function &F) {
76       MachineFunction::get(&F).dump();
77       return false;
78     }
79   };
80 }
81
82 Pass *createMachineCodeConstructionPass(TargetMachine &Target) {
83   return new ConstructMachineFunction(Target);
84 }
85
86 Pass *createMachineCodeDestructionPass() {
87   return new DestroyMachineFunction();
88 }
89
90 Pass *createMachineFunctionPrinterPass() {
91   return new Printer();
92 }
93
94
95 //===---------------------------------------------------------------------===//
96 // MachineFunction implementation
97 //===---------------------------------------------------------------------===//
98
99 MachineFunction::MachineFunction(const Function *F,
100                                  const TargetMachine &TM)
101   : Annotation(MF_AID), Fn(F), Target(TM) {
102   SSARegMapping = new SSARegMap();
103   MFInfo = new MachineFunctionInfo(*this);
104   FrameInfo = new FunctionFrameInfo();
105 }
106
107 MachineFunction::~MachineFunction() { 
108   delete SSARegMapping;
109   delete MFInfo;
110   delete FrameInfo;
111 }
112
113 void MachineFunction::dump() const { print(std::cerr); }
114
115 void MachineFunction::print(std::ostream &OS) const {
116   OS << "\n" << *(Value*)Fn->getFunctionType() << " \"" << Fn->getName()
117      << "\"\n";
118
119   // Print Frame Information
120   getFrameInfo()->print(OS);
121   
122   for (const_iterator BB = begin(); BB != end(); ++BB) {
123     BasicBlock *LBB = BB->getBasicBlock();
124     OS << "\n" << LBB->getName() << " (" << (const void*)LBB << "):\n";
125     for (MachineBasicBlock::const_iterator I = BB->begin(); I != BB->end();++I){
126       OS << "\t";
127       (*I)->print(OS, Target);
128     }
129   }
130   OS << "\nEnd function \"" << Fn->getName() << "\"\n\n";
131 }
132
133
134 // The next two methods are used to construct and to retrieve
135 // the MachineCodeForFunction object for the given function.
136 // construct() -- Allocates and initializes for a given function and target
137 // get()       -- Returns a handle to the object.
138 //                This should not be called before "construct()"
139 //                for a given Function.
140 // 
141 MachineFunction&
142 MachineFunction::construct(const Function *Fn, const TargetMachine &Tar)
143 {
144   assert(Fn->getAnnotation(MF_AID) == 0 &&
145          "Object already exists for this function!");
146   MachineFunction* mcInfo = new MachineFunction(Fn, Tar);
147   Fn->addAnnotation(mcInfo);
148   return *mcInfo;
149 }
150
151 void
152 MachineFunction::destruct(const Function *Fn)
153 {
154   bool Deleted = Fn->deleteAnnotation(MF_AID);
155   assert(Deleted && "Machine code did not exist for function!");
156 }
157
158 MachineFunction& MachineFunction::get(const Function *F)
159 {
160   MachineFunction *mc = (MachineFunction*)F->getAnnotation(MF_AID);
161   assert(mc && "Call construct() method first to allocate the object");
162   return *mc;
163 }
164
165 void MachineFunction::clearSSARegMap() {
166   delete SSARegMapping;
167   SSARegMapping = 0;
168 }
169
170 //===----------------------------------------------------------------------===//
171 //  FunctionFrameInfo implementation
172 //===----------------------------------------------------------------------===//
173
174 void FunctionFrameInfo::print(std::ostream &OS) const {
175   for (unsigned i = 0, e = Objects.size(); i != e; ++i) {
176     const StackObject &SO = Objects[i];
177     OS << "  <fi# " << (int)(i-NumFixedObjects) << "> is ";
178     if (SO.Size == 0)
179       OS << "variable sized";
180     else
181       OS << SO.Size << " byte" << (SO.Size != 1 ? "s" : " ");
182     
183     if (i < NumFixedObjects)
184       OS << " fixed";
185     if (i < NumFixedObjects || SO.SPOffset != -1) {
186       OS << " at location [SP";
187       if (SO.SPOffset > 0)
188         OS << "+" << SO.SPOffset;
189       else if (SO.SPOffset < 0)
190         OS << SO.SPOffset;
191       OS << "]";
192     }
193     OS << "\n";
194   }
195
196   if (HasVarSizedObjects)
197     OS << "  Stack frame contains variable sized objects\n";
198 }
199
200 void FunctionFrameInfo::dump() const { print(std::cerr); }
201
202
203 //===----------------------------------------------------------------------===//
204 //  MachineFunctionInfo implementation
205 //===----------------------------------------------------------------------===//
206
207 static unsigned
208 ComputeMaxOptionalArgsSize(const TargetMachine& target, const Function *F,
209                            unsigned &maxOptionalNumArgs)
210 {
211   const TargetFrameInfo &frameInfo = target.getFrameInfo();
212   
213   unsigned maxSize = 0;
214   
215   for (Function::const_iterator BB = F->begin(), BBE = F->end(); BB !=BBE; ++BB)
216     for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I)
217       if (const CallInst *callInst = dyn_cast<CallInst>(&*I))
218         {
219           unsigned numOperands = callInst->getNumOperands() - 1;
220           int numExtra = (int)numOperands-frameInfo.getNumFixedOutgoingArgs();
221           if (numExtra <= 0)
222             continue;
223           
224           unsigned sizeForThisCall;
225           if (frameInfo.argsOnStackHaveFixedSize())
226             {
227               int argSize = frameInfo.getSizeOfEachArgOnStack(); 
228               sizeForThisCall = numExtra * (unsigned) argSize;
229             }
230           else
231             {
232               assert(0 && "UNTESTED CODE: Size per stack argument is not "
233                      "fixed on this architecture: use actual arg sizes to "
234                      "compute MaxOptionalArgsSize");
235               sizeForThisCall = 0;
236               for (unsigned i = 0; i < numOperands; ++i)
237                 sizeForThisCall += target.getTargetData().getTypeSize(callInst->
238                                               getOperand(i)->getType());
239             }
240           
241           if (maxSize < sizeForThisCall)
242             maxSize = sizeForThisCall;
243           
244           if ((int)maxOptionalNumArgs < numExtra)
245             maxOptionalNumArgs = (unsigned) numExtra;
246         }
247   
248   return maxSize;
249 }
250
251 // Align data larger than one L1 cache line on L1 cache line boundaries.
252 // Align all smaller data on the next higher 2^x boundary (4, 8, ...),
253 // but not higher than the alignment of the largest type we support
254 // (currently a double word). -- see class TargetData).
255 //
256 // This function is similar to the corresponding function in EmitAssembly.cpp
257 // but they are unrelated.  This one does not align at more than a
258 // double-word boundary whereas that one might.
259 // 
260 inline unsigned
261 SizeToAlignment(unsigned size, const TargetMachine& target)
262 {
263   unsigned short cacheLineSize = target.getCacheInfo().getCacheLineSize(1); 
264   if (size > (unsigned) cacheLineSize / 2)
265     return cacheLineSize;
266   else
267     for (unsigned sz=1; /*no condition*/; sz *= 2)
268       if (sz >= size || sz >= target.getTargetData().getDoubleAlignment())
269         return sz;
270 }
271
272
273 void MachineFunctionInfo::CalculateArgSize() {
274   maxOptionalArgsSize = ComputeMaxOptionalArgsSize(MF.getTarget(),
275                                                    MF.getFunction(),
276                                                    maxOptionalNumArgs);
277   staticStackSize = maxOptionalArgsSize
278     + MF.getTarget().getFrameInfo().getMinStackFrameSize();
279 }
280
281 int
282 MachineFunctionInfo::computeOffsetforLocalVar(const Value* val,
283                                               unsigned &getPaddedSize,
284                                               unsigned  sizeToUse)
285 {
286   if (sizeToUse == 0)
287     sizeToUse = MF.getTarget().findOptimalStorageSize(val->getType());
288   unsigned align = SizeToAlignment(sizeToUse, MF.getTarget());
289
290   bool growUp;
291   int firstOffset = MF.getTarget().getFrameInfo().getFirstAutomaticVarOffset(MF,
292                                                                              growUp);
293   int offset = growUp? firstOffset + getAutomaticVarsSize()
294                      : firstOffset - (getAutomaticVarsSize() + sizeToUse);
295
296   int aligned = MF.getTarget().getFrameInfo().adjustAlignment(offset, growUp, align);
297   getPaddedSize = sizeToUse + abs(aligned - offset);
298
299   return aligned;
300 }
301
302 int
303 MachineFunctionInfo::allocateLocalVar(const Value* val,
304                                       unsigned sizeToUse)
305 {
306   assert(! automaticVarsAreaFrozen &&
307          "Size of auto vars area has been used to compute an offset so "
308          "no more automatic vars should be allocated!");
309   
310   // Check if we've allocated a stack slot for this value already
311   // 
312   int offset = getOffset(val);
313   if (offset == INVALID_FRAME_OFFSET)
314     {
315       unsigned getPaddedSize;
316       offset = computeOffsetforLocalVar(val, getPaddedSize, sizeToUse);
317       offsets[val] = offset;
318       incrementAutomaticVarsSize(getPaddedSize);
319     }
320   return offset;
321 }
322
323 int
324 MachineFunctionInfo::allocateSpilledValue(const Type* type)
325 {
326   assert(! spillsAreaFrozen &&
327          "Size of reg spills area has been used to compute an offset so "
328          "no more register spill slots should be allocated!");
329   
330   unsigned size  = MF.getTarget().getTargetData().getTypeSize(type);
331   unsigned char align = MF.getTarget().getTargetData().getTypeAlignment(type);
332   
333   bool growUp;
334   int firstOffset = MF.getTarget().getFrameInfo().getRegSpillAreaOffset(MF, growUp);
335   
336   int offset = growUp? firstOffset + getRegSpillsSize()
337                      : firstOffset - (getRegSpillsSize() + size);
338
339   int aligned = MF.getTarget().getFrameInfo().adjustAlignment(offset, growUp, align);
340   size += abs(aligned - offset); // include alignment padding in size
341   
342   incrementRegSpillsSize(size);  // update size of reg. spills area
343
344   return aligned;
345 }
346
347 int
348 MachineFunctionInfo::pushTempValue(unsigned size)
349 {
350   unsigned align = SizeToAlignment(size, MF.getTarget());
351
352   bool growUp;
353   int firstOffset = MF.getTarget().getFrameInfo().getTmpAreaOffset(MF, growUp);
354
355   int offset = growUp? firstOffset + currentTmpValuesSize
356                      : firstOffset - (currentTmpValuesSize + size);
357
358   int aligned = MF.getTarget().getFrameInfo().adjustAlignment(offset, growUp,
359                                                               align);
360   size += abs(aligned - offset); // include alignment padding in size
361
362   incrementTmpAreaSize(size);    // update "current" size of tmp area
363
364   return aligned;
365 }
366
367 void MachineFunctionInfo::popAllTempValues() {
368   resetTmpAreaSize();            // clear tmp area to reuse
369 }
370
371 int
372 MachineFunctionInfo::getOffset(const Value* val) const
373 {
374   hash_map<const Value*, int>::const_iterator pair = offsets.find(val);
375   return (pair == offsets.end()) ? INVALID_FRAME_OFFSET : pair->second;
376 }