MachineFunction.cpp revision 37efe6764568a3829fee26aba532283131d1a104
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/MachineFrameInfo.h"
20#include "llvm/CodeGen/MachineConstantPool.h"
21#include "llvm/CodeGen/MachineJumpTableInfo.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/Support/LeakDetector.h"
28#include "llvm/Support/GraphWriter.h"
29#include "llvm/Config/config.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//===---------------------------------------------------------------------===//
94
95MachineBasicBlock* ilist_traits<MachineBasicBlock>::createSentinel() {
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  if (Parent != toList.Parent)
106    for (; first != last; ++first)
107      first->Parent = toList.Parent;
108}
109
110MachineFunction::MachineFunction(const Function *F,
111                                 const TargetMachine &TM)
112  : Annotation(MF_AID), Fn(F), Target(TM), UsedPhysRegs(0) {
113  SSARegMapping = new SSARegMap();
114  MFInfo = 0;
115  FrameInfo = new MachineFrameInfo();
116  ConstantPool = new MachineConstantPool(TM.getTargetData());
117  JumpTableInfo = new MachineJumpTableInfo(TM.getTargetData());
118  BasicBlocks.Parent = this;
119}
120
121MachineFunction::~MachineFunction() {
122  BasicBlocks.clear();
123  delete SSARegMapping;
124  delete MFInfo;
125  delete FrameInfo;
126  delete ConstantPool;
127  delete JumpTableInfo;
128  delete[] UsedPhysRegs;
129}
130
131void MachineFunction::dump() const { print(std::cerr); }
132
133void MachineFunction::print(std::ostream &OS) const {
134  OS << "# Machine code for " << Fn->getName () << "():\n";
135
136  // Print Frame Information
137  getFrameInfo()->print(*this, OS);
138
139  // Print JumpTable Information
140  getJumpTableInfo()->print(OS);
141
142  // Print Constant Pool
143  getConstantPool()->print(OS);
144
145  const MRegisterInfo *MRI = getTarget().getRegisterInfo();
146
147  if (livein_begin() != livein_end()) {
148    OS << "Live Ins:";
149    for (livein_iterator I = livein_begin(), E = livein_end(); I != E; ++I) {
150      if (MRI)
151        OS << " " << MRI->getName(I->first);
152      else
153        OS << " Reg #" << I->first;
154    }
155    OS << "\n";
156  }
157  if (liveout_begin() != liveout_end()) {
158    OS << "Live Outs:";
159    for (liveout_iterator I = liveout_begin(), E = liveout_end(); I != E; ++I)
160      if (MRI)
161        OS << " " << MRI->getName(*I);
162      else
163        OS << " Reg #" << *I;
164    OS << "\n";
165  }
166
167  for (const_iterator BB = begin(); BB != end(); ++BB)
168    BB->print(OS);
169
170  OS << "\n# End machine code for " << Fn->getName () << "().\n\n";
171}
172
173/// CFGOnly flag - This is used to control whether or not the CFG graph printer
174/// prints out the contents of basic blocks or not.  This is acceptable because
175/// this code is only really used for debugging purposes.
176///
177static bool CFGOnly = false;
178
179namespace llvm {
180  template<>
181  struct DOTGraphTraits<const MachineFunction*> : public DefaultDOTGraphTraits {
182    static std::string getGraphName(const MachineFunction *F) {
183      return "CFG for '" + F->getFunction()->getName() + "' function";
184    }
185
186    static std::string getNodeLabel(const MachineBasicBlock *Node,
187                                    const MachineFunction *Graph) {
188      if (CFGOnly && Node->getBasicBlock() &&
189          !Node->getBasicBlock()->getName().empty())
190        return Node->getBasicBlock()->getName() + ":";
191
192      std::ostringstream Out;
193      if (CFGOnly) {
194        Out << Node->getNumber() << ':';
195        return Out.str();
196      }
197
198      Node->print(Out);
199
200      std::string OutStr = Out.str();
201      if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());
202
203      // Process string output to make it nicer...
204      for (unsigned i = 0; i != OutStr.length(); ++i)
205        if (OutStr[i] == '\n') {                            // Left justify
206          OutStr[i] = '\\';
207          OutStr.insert(OutStr.begin()+i+1, 'l');
208        }
209      return OutStr;
210    }
211  };
212}
213
214void MachineFunction::viewCFG() const
215{
216#ifndef NDEBUG
217  std::string Filename = "/tmp/cfg." + getFunction()->getName() + ".dot";
218  std::cerr << "Writing '" << Filename << "'... ";
219  std::ofstream F(Filename.c_str());
220
221  if (!F) {
222    std::cerr << "  error opening file for writing!\n";
223    return;
224  }
225
226  WriteGraph(F, this);
227  F.close();
228  std::cerr << "\n";
229
230#ifdef HAVE_GRAPHVIZ
231  std::cerr << "Running 'Graphviz' program... " << std::flush;
232  if (system((LLVM_PATH_GRAPHVIZ " " + Filename).c_str())) {
233    std::cerr << "Error viewing graph: 'Graphviz' not in path?\n";
234  } else {
235    system(("rm " + Filename).c_str());
236    return;
237  }
238#endif  // HAVE_GRAPHVIZ
239
240#ifdef HAVE_GV
241  std::cerr << "Running 'dot' program... " << std::flush;
242  if (system(("dot -Tps -Nfontname=Courier -Gsize=7.5,10 " + Filename
243              + " > /tmp/cfg.tempgraph.ps").c_str())) {
244    std::cerr << "Error running dot: 'dot' not in path?\n";
245  } else {
246    std::cerr << "\n";
247    system("gv /tmp/cfg.tempgraph.ps");
248  }
249  system(("rm " + Filename + " /tmp/cfg.tempgraph.ps").c_str());
250  return;
251#endif  // HAVE_GV
252#endif  // NDEBUG
253  std::cerr << "MachineFunction::viewCFG is only available in debug builds on "
254            << "systems with Graphviz or gv!\n";
255
256#ifndef NDEBUG
257  system(("rm " + Filename).c_str());
258#endif
259}
260
261void MachineFunction::viewCFGOnly() const
262{
263  CFGOnly = true;
264  viewCFG();
265  CFGOnly = false;
266}
267
268// The next two methods are used to construct and to retrieve
269// the MachineCodeForFunction object for the given function.
270// construct() -- Allocates and initializes for a given function and target
271// get()       -- Returns a handle to the object.
272//                This should not be called before "construct()"
273//                for a given Function.
274//
275MachineFunction&
276MachineFunction::construct(const Function *Fn, const TargetMachine &Tar)
277{
278  assert(Fn->getAnnotation(MF_AID) == 0 &&
279         "Object already exists for this function!");
280  MachineFunction* mcInfo = new MachineFunction(Fn, Tar);
281  Fn->addAnnotation(mcInfo);
282  return *mcInfo;
283}
284
285void MachineFunction::destruct(const Function *Fn) {
286  bool Deleted = Fn->deleteAnnotation(MF_AID);
287  assert(Deleted && "Machine code did not exist for function!");
288}
289
290MachineFunction& MachineFunction::get(const Function *F)
291{
292  MachineFunction *mc = (MachineFunction*)F->getAnnotation(MF_AID);
293  assert(mc && "Call construct() method first to allocate the object");
294  return *mc;
295}
296
297void MachineFunction::clearSSARegMap() {
298  delete SSARegMapping;
299  SSARegMapping = 0;
300}
301
302//===----------------------------------------------------------------------===//
303//  MachineFrameInfo implementation
304//===----------------------------------------------------------------------===//
305
306void MachineFrameInfo::print(const MachineFunction &MF, std::ostream &OS) const{
307  int ValOffset = MF.getTarget().getFrameInfo()->getOffsetOfLocalArea();
308
309  for (unsigned i = 0, e = Objects.size(); i != e; ++i) {
310    const StackObject &SO = Objects[i];
311    OS << "  <fi #" << (int)(i-NumFixedObjects) << ">: ";
312    if (SO.Size == 0)
313      OS << "variable sized";
314    else
315      OS << "size is " << SO.Size << " byte" << (SO.Size != 1 ? "s," : ",");
316    OS << " alignment is " << SO.Alignment << " byte"
317       << (SO.Alignment != 1 ? "s," : ",");
318
319    if (i < NumFixedObjects)
320      OS << " fixed";
321    if (i < NumFixedObjects || SO.SPOffset != -1) {
322      int Off = SO.SPOffset - ValOffset;
323      OS << " at location [SP";
324      if (Off > 0)
325        OS << "+" << Off;
326      else if (Off < 0)
327        OS << Off;
328      OS << "]";
329    }
330    OS << "\n";
331  }
332
333  if (HasVarSizedObjects)
334    OS << "  Stack frame contains variable sized objects\n";
335}
336
337void MachineFrameInfo::dump(const MachineFunction &MF) const {
338  print(MF, std::cerr);
339}
340
341
342//===----------------------------------------------------------------------===//
343//  MachineJumpTableInfo implementation
344//===----------------------------------------------------------------------===//
345
346/// getJumpTableIndex - Create a new jump table entry in the jump table info
347/// or return an existing one.
348///
349unsigned MachineJumpTableInfo::getJumpTableIndex(
350                                     std::vector<MachineBasicBlock*> &DestBBs) {
351  for (unsigned i = 0, e = JumpTables.size(); i != e; ++i)
352    if (JumpTables[i].MBBs == DestBBs)
353      return i;
354
355  JumpTables.push_back(MachineJumpTableEntry(DestBBs));
356  return JumpTables.size()-1;
357}
358
359
360void MachineJumpTableInfo::print(std::ostream &OS) const {
361  // FIXME: this is lame, maybe we could print out the MBB numbers or something
362  // like {1, 2, 4, 5, 3, 0}
363  for (unsigned i = 0, e = JumpTables.size(); i != e; ++i) {
364    OS << "  <jt #" << i << "> has " << JumpTables[i].MBBs.size()
365       << " entries\n";
366  }
367}
368
369void MachineJumpTableInfo::dump() const { print(std::cerr); }
370
371
372//===----------------------------------------------------------------------===//
373//  MachineConstantPool implementation
374//===----------------------------------------------------------------------===//
375
376/// getConstantPoolIndex - Create a new entry in the constant pool or return
377/// an existing one.  User must specify an alignment in bytes for the object.
378///
379unsigned MachineConstantPool::getConstantPoolIndex(Constant *C,
380                                                   unsigned Alignment) {
381  assert(Alignment && "Alignment must be specified!");
382  if (Alignment > PoolAlignment) PoolAlignment = Alignment;
383
384  // Check to see if we already have this constant.
385  //
386  // FIXME, this could be made much more efficient for large constant pools.
387  unsigned AlignMask = (1 << Alignment)-1;
388  for (unsigned i = 0, e = Constants.size(); i != e; ++i)
389    if (Constants[i].Val == C && (Constants[i].Offset & AlignMask) == 0)
390      return i;
391
392  unsigned Offset = 0;
393  if (!Constants.empty()) {
394    Offset = Constants.back().Offset;
395    Offset += TD.getTypeSize(Constants.back().Val->getType());
396    Offset = (Offset+AlignMask)&~AlignMask;
397  }
398
399  Constants.push_back(MachineConstantPoolEntry(C, Offset));
400  return Constants.size()-1;
401}
402
403
404void MachineConstantPool::print(std::ostream &OS) const {
405  for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
406    OS << "  <cp #" << i << "> is" << *(Value*)Constants[i].Val;
407    OS << " , offset=" << Constants[i].Offset;
408    OS << "\n";
409  }
410}
411
412void MachineConstantPool::dump() const { print(std::cerr); }
413