MachineFunction.cpp revision e6c3dc88ca209cd754c604f18f1d63d172ed36a0
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/Instructions.h"
27#include "llvm/Type.h"
28#include "Support/LeakDetector.h"
29#include "Support/GraphWriter.h"
30#include <fstream>
31#include <iostream>
32#include <sstream>
33
34using namespace llvm;
35
36static AnnotationID MF_AID(
37                 AnnotationManager::getID("CodeGen::MachineCodeForFunction"));
38
39
40namespace {
41  struct Printer : public MachineFunctionPass {
42    std::ostream *OS;
43    const std::string Banner;
44
45    Printer (std::ostream *_OS, const std::string &_Banner) :
46      OS (_OS), Banner (_Banner) { }
47
48    const char *getPassName() const { return "MachineFunction Printer"; }
49
50    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
51      AU.setPreservesAll();
52    }
53
54    bool runOnMachineFunction(MachineFunction &MF) {
55      (*OS) << Banner;
56      MF.print (*OS);
57      return false;
58    }
59  };
60}
61
62/// Returns a newly-created MachineFunction Printer pass. The default output
63/// stream is std::cerr; the default banner is empty.
64///
65FunctionPass *llvm::createMachineFunctionPrinterPass(std::ostream *OS,
66                                                     const std::string &Banner) {
67  return new Printer(OS, Banner);
68}
69
70namespace {
71  struct Deleter : public MachineFunctionPass {
72    const char *getPassName() const { return "Machine Code Deleter"; }
73
74    bool runOnMachineFunction(MachineFunction &MF) {
75      // Delete the annotation from the function now.
76      MachineFunction::destruct(MF.getFunction());
77      return true;
78    }
79  };
80}
81
82/// MachineCodeDeletion Pass - This pass deletes all of the machine code for
83/// the current function, which should happen after the function has been
84/// emitted to a .s file or to memory.
85FunctionPass *llvm::createMachineCodeDeleter() {
86  return new Deleter();
87}
88
89
90
91//===---------------------------------------------------------------------===//
92// MachineFunction implementation
93//===---------------------------------------------------------------------===//
94MachineBasicBlock* ilist_traits<MachineBasicBlock>::createNode()
95{
96    MachineBasicBlock* dummy = new MachineBasicBlock();
97    LeakDetector::removeGarbageObject(dummy);
98    return dummy;
99}
100
101void ilist_traits<MachineBasicBlock>::transferNodesFromList(
102    iplist<MachineBasicBlock, ilist_traits<MachineBasicBlock> >& toList,
103    ilist_iterator<MachineBasicBlock> first,
104    ilist_iterator<MachineBasicBlock> last)
105{
106    if (Parent != toList.Parent)
107        for (; first != last; ++first)
108            first->Parent = toList.Parent;
109}
110
111MachineFunction::MachineFunction(const Function *F,
112                                 const TargetMachine &TM)
113  : Annotation(MF_AID), Fn(F), Target(TM) {
114  SSARegMapping = new SSARegMap();
115  MFInfo = new MachineFunctionInfo(*this);
116  FrameInfo = new MachineFrameInfo();
117  ConstantPool = new MachineConstantPool();
118  BasicBlocks.Parent = this;
119}
120
121MachineFunction::~MachineFunction() {
122  BasicBlocks.clear();
123  delete SSARegMapping;
124  delete MFInfo;
125  delete FrameInfo;
126  delete ConstantPool;
127}
128
129void MachineFunction::dump() const { print(std::cerr); }
130
131void MachineFunction::print(std::ostream &OS) const {
132  OS << "# Machine code for " << Fn->getName () << "():\n";
133
134  // Print Frame Information
135  getFrameInfo()->print(*this, OS);
136
137  // Print Constant Pool
138  getConstantPool()->print(OS);
139
140  for (const_iterator BB = begin(); BB != end(); ++BB)
141    BB->print(OS);
142
143  OS << "\n# End machine code for " << Fn->getName () << "().\n\n";
144}
145
146/// CFGOnly flag - This is used to control whether or not the CFG graph printer
147/// prints out the contents of basic blocks or not.  This is acceptable because
148/// this code is only really used for debugging purposes.
149///
150static bool CFGOnly = false;
151
152namespace llvm {
153template<>
154struct DOTGraphTraits<const MachineFunction*> : public DefaultDOTGraphTraits {
155  static std::string getGraphName(const MachineFunction *F) {
156    return "CFG for '" + F->getFunction()->getName() + "' function";
157  }
158
159  static std::string getNodeLabel(const MachineBasicBlock *Node,
160                                  const MachineFunction *Graph) {
161    if (CFGOnly && Node->getBasicBlock() &&
162        !Node->getBasicBlock()->getName().empty())
163      return Node->getBasicBlock()->getName() + ":";
164
165    std::ostringstream Out;
166    if (CFGOnly) {
167      Out << Node->getNumber() << ':';
168      return Out.str();
169    }
170
171    Node->print(Out);
172
173    std::string OutStr = Out.str();
174    if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());
175
176    // Process string output to make it nicer...
177    for (unsigned i = 0; i != OutStr.length(); ++i)
178      if (OutStr[i] == '\n') {                            // Left justify
179        OutStr[i] = '\\';
180        OutStr.insert(OutStr.begin()+i+1, 'l');
181      }
182    return OutStr;
183  }
184};
185}
186
187void MachineFunction::viewCFG() const
188{
189  std::string Filename = "/tmp/cfg." + getFunction()->getName() + ".dot";
190  std::cerr << "Writing '" << Filename << "'... ";
191  std::ofstream F(Filename.c_str());
192
193  if (!F) {
194    std::cerr << "  error opening file for writing!\n";
195    return;
196  }
197
198  WriteGraph(F, this);
199  F.close();
200  std::cerr << "\n";
201
202  std::cerr << "Running 'dot' program... " << std::flush;
203  if (system(("dot -Tps -Nfontname=Courier -Gsize=7.5,10 " + Filename
204              + " > /tmp/cfg.tempgraph.ps").c_str())) {
205    std::cerr << "Error running dot: 'dot' not in path?\n";
206  } else {
207    std::cerr << "\n";
208    system("gv /tmp/cfg.tempgraph.ps");
209  }
210  system(("rm " + Filename + " /tmp/cfg.tempgraph.ps").c_str());
211}
212
213void MachineFunction::viewCFGOnly() const
214{
215  CFGOnly = true;
216  viewCFG();
217  CFGOnly = false;
218}
219
220// The next two methods are used to construct and to retrieve
221// the MachineCodeForFunction object for the given function.
222// construct() -- Allocates and initializes for a given function and target
223// get()       -- Returns a handle to the object.
224//                This should not be called before "construct()"
225//                for a given Function.
226//
227MachineFunction&
228MachineFunction::construct(const Function *Fn, const TargetMachine &Tar)
229{
230  assert(Fn->getAnnotation(MF_AID) == 0 &&
231         "Object already exists for this function!");
232  MachineFunction* mcInfo = new MachineFunction(Fn, Tar);
233  Fn->addAnnotation(mcInfo);
234  return *mcInfo;
235}
236
237void MachineFunction::destruct(const Function *Fn) {
238  bool Deleted = Fn->deleteAnnotation(MF_AID);
239  assert(Deleted && "Machine code did not exist for function!");
240}
241
242MachineFunction& MachineFunction::get(const Function *F)
243{
244  MachineFunction *mc = (MachineFunction*)F->getAnnotation(MF_AID);
245  assert(mc && "Call construct() method first to allocate the object");
246  return *mc;
247}
248
249void MachineFunction::clearSSARegMap() {
250  delete SSARegMapping;
251  SSARegMapping = 0;
252}
253
254//===----------------------------------------------------------------------===//
255//  MachineFrameInfo implementation
256//===----------------------------------------------------------------------===//
257
258/// CreateStackObject - Create a stack object for a value of the specified type.
259///
260int MachineFrameInfo::CreateStackObject(const Type *Ty, const TargetData &TD) {
261  return CreateStackObject(TD.getTypeSize(Ty), TD.getTypeAlignment(Ty));
262}
263
264
265void MachineFrameInfo::print(const MachineFunction &MF, std::ostream &OS) const{
266  int ValOffset = MF.getTarget().getFrameInfo()->getOffsetOfLocalArea();
267
268  for (unsigned i = 0, e = Objects.size(); i != e; ++i) {
269    const StackObject &SO = Objects[i];
270    OS << "  <fi #" << (int)(i-NumFixedObjects) << "> is ";
271    if (SO.Size == 0)
272      OS << "variable sized";
273    else
274      OS << SO.Size << " byte" << (SO.Size != 1 ? "s" : " ");
275
276    if (i < NumFixedObjects)
277      OS << " fixed";
278    if (i < NumFixedObjects || SO.SPOffset != -1) {
279      int Off = SO.SPOffset - ValOffset;
280      OS << " at location [SP";
281      if (Off > 0)
282	OS << "+" << Off;
283      else if (Off < 0)
284	OS << Off;
285      OS << "]";
286    }
287    OS << "\n";
288  }
289
290  if (HasVarSizedObjects)
291    OS << "  Stack frame contains variable sized objects\n";
292}
293
294void MachineFrameInfo::dump(const MachineFunction &MF) const {
295  print(MF, std::cerr);
296}
297
298
299//===----------------------------------------------------------------------===//
300//  MachineConstantPool implementation
301//===----------------------------------------------------------------------===//
302
303void MachineConstantPool::print(std::ostream &OS) const {
304  for (unsigned i = 0, e = Constants.size(); i != e; ++i)
305    OS << "  <cp #" << i << "> is" << *(Value*)Constants[i] << "\n";
306}
307
308void MachineConstantPool::dump() const { print(std::cerr); }
309
310//===----------------------------------------------------------------------===//
311//  MachineFunctionInfo implementation
312//  NOTE: MachineFunctionInfo and its methods are specific to the SparcV9
313//  target - don't use them in other targets.
314//===----------------------------------------------------------------------===//
315
316static unsigned
317ComputeMaxOptionalArgsSize(const TargetMachine& target, const Function *F,
318                           unsigned &maxOptionalNumArgs)
319{
320  unsigned maxSize = 0;
321
322  for (Function::const_iterator BB = F->begin(), BBE = F->end(); BB !=BBE; ++BB)
323    for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I)
324      if (const CallInst *callInst = dyn_cast<CallInst>(I))
325        {
326          unsigned numOperands = callInst->getNumOperands() - 1;
327          int numExtra = numOperands-6;
328          if (numExtra <= 0)
329            continue;
330
331          unsigned sizeForThisCall = numExtra * 8;
332
333          if (maxSize < sizeForThisCall)
334            maxSize = sizeForThisCall;
335
336          if ((int)maxOptionalNumArgs < numExtra)
337            maxOptionalNumArgs = (unsigned) numExtra;
338        }
339
340  return maxSize;
341}
342
343// Align data larger than one L1 cache line on L1 cache line boundaries.
344// Align all smaller data on the next higher 2^x boundary (4, 8, ...),
345// but not higher than the alignment of the largest type we support
346// (currently a double word). -- see class TargetData).
347//
348// This function is similar to the corresponding function in EmitAssembly.cpp
349// but they are unrelated.  This one does not align at more than a
350// double-word boundary whereas that one might.
351//
352inline unsigned
353SizeToAlignment(unsigned size, const TargetMachine& target)
354{
355  const unsigned short cacheLineSize = 16;
356  if (size > (unsigned) cacheLineSize / 2)
357    return cacheLineSize;
358  else
359    for (unsigned sz=1; /*no condition*/; sz *= 2)
360      if (sz >= size || sz >= target.getTargetData().getDoubleAlignment())
361        return sz;
362}
363
364
365void MachineFunctionInfo::CalculateArgSize() {
366  maxOptionalArgsSize = ComputeMaxOptionalArgsSize(MF.getTarget(),
367						   MF.getFunction(),
368                                                   maxOptionalNumArgs);
369  staticStackSize = maxOptionalArgsSize + 176;
370}
371
372int
373MachineFunctionInfo::computeOffsetforLocalVar(const Value* val,
374					      unsigned &getPaddedSize,
375					      unsigned  sizeToUse)
376{
377  if (sizeToUse == 0) {
378    // All integer types smaller than ints promote to 4 byte integers.
379    if (val->getType()->isIntegral() && val->getType()->getPrimitiveSize() < 4)
380      sizeToUse = 4;
381    else
382      sizeToUse = MF.getTarget().getTargetData().getTypeSize(val->getType());
383  }
384  unsigned align = SizeToAlignment(sizeToUse, MF.getTarget());
385
386  bool growUp;
387  int firstOffset = MF.getTarget().getFrameInfo()->getFirstAutomaticVarOffset(MF,
388						 			     growUp);
389  int offset = growUp? firstOffset + getAutomaticVarsSize()
390                     : firstOffset - (getAutomaticVarsSize() + sizeToUse);
391
392  int aligned = MF.getTarget().getFrameInfo()->adjustAlignment(offset, growUp, align);
393  getPaddedSize = sizeToUse + abs(aligned - offset);
394
395  return aligned;
396}
397
398
399int MachineFunctionInfo::allocateLocalVar(const Value* val,
400                                          unsigned sizeToUse) {
401  assert(! automaticVarsAreaFrozen &&
402         "Size of auto vars area has been used to compute an offset so "
403         "no more automatic vars should be allocated!");
404
405  // Check if we've allocated a stack slot for this value already
406  //
407  hash_map<const Value*, int>::const_iterator pair = offsets.find(val);
408  if (pair != offsets.end())
409    return pair->second;
410
411  unsigned getPaddedSize;
412  unsigned offset = computeOffsetforLocalVar(val, getPaddedSize, sizeToUse);
413  offsets[val] = offset;
414  incrementAutomaticVarsSize(getPaddedSize);
415  return offset;
416}
417
418int
419MachineFunctionInfo::allocateSpilledValue(const Type* type)
420{
421  assert(! spillsAreaFrozen &&
422         "Size of reg spills area has been used to compute an offset so "
423         "no more register spill slots should be allocated!");
424
425  unsigned size  = MF.getTarget().getTargetData().getTypeSize(type);
426  unsigned char align = MF.getTarget().getTargetData().getTypeAlignment(type);
427
428  bool growUp;
429  int firstOffset = MF.getTarget().getFrameInfo()->getRegSpillAreaOffset(MF, growUp);
430
431  int offset = growUp? firstOffset + getRegSpillsSize()
432                     : firstOffset - (getRegSpillsSize() + size);
433
434  int aligned = MF.getTarget().getFrameInfo()->adjustAlignment(offset, growUp, align);
435  size += abs(aligned - offset); // include alignment padding in size
436
437  incrementRegSpillsSize(size);  // update size of reg. spills area
438
439  return aligned;
440}
441
442int
443MachineFunctionInfo::pushTempValue(unsigned size)
444{
445  unsigned align = SizeToAlignment(size, MF.getTarget());
446
447  bool growUp;
448  int firstOffset = MF.getTarget().getFrameInfo()->getTmpAreaOffset(MF, growUp);
449
450  int offset = growUp? firstOffset + currentTmpValuesSize
451                     : firstOffset - (currentTmpValuesSize + size);
452
453  int aligned = MF.getTarget().getFrameInfo()->adjustAlignment(offset, growUp,
454							      align);
455  size += abs(aligned - offset); // include alignment padding in size
456
457  incrementTmpAreaSize(size);    // update "current" size of tmp area
458
459  return aligned;
460}
461
462void MachineFunctionInfo::popAllTempValues() {
463  resetTmpAreaSize();            // clear tmp area to reuse
464}
465