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