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