LLVM API Documentation

MachineFunction.cpp

Go to the documentation of this file.
00001 //===-- MachineFunction.cpp -----------------------------------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file was developed by the LLVM research group and is distributed under
00006 // the University of Illinois Open Source License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // Collect native machine code information for a function.  This allows
00011 // target-specific information about the generated code to be stored with each
00012 // function.
00013 //
00014 //===----------------------------------------------------------------------===//
00015 
00016 #include "llvm/CodeGen/MachineFunctionPass.h"
00017 #include "llvm/CodeGen/MachineInstr.h"
00018 #include "llvm/CodeGen/SSARegMap.h"
00019 #include "llvm/CodeGen/MachineFrameInfo.h"
00020 #include "llvm/CodeGen/MachineConstantPool.h"
00021 #include "llvm/CodeGen/Passes.h"
00022 #include "llvm/Target/TargetMachine.h"
00023 #include "llvm/Target/TargetFrameInfo.h"
00024 #include "llvm/Function.h"
00025 #include "llvm/Instructions.h"
00026 #include "llvm/Support/LeakDetector.h"
00027 #include "llvm/Support/GraphWriter.h"
00028 #include "llvm/Config/config.h"
00029 #include <fstream>
00030 #include <iostream>
00031 #include <sstream>
00032 
00033 using namespace llvm;
00034 
00035 static AnnotationID MF_AID(
00036   AnnotationManager::getID("CodeGen::MachineCodeForFunction"));
00037 
00038 
00039 namespace {
00040   struct Printer : public MachineFunctionPass {
00041     std::ostream *OS;
00042     const std::string Banner;
00043 
00044     Printer (std::ostream *_OS, const std::string &_Banner) :
00045       OS (_OS), Banner (_Banner) { }
00046 
00047     const char *getPassName() const { return "MachineFunction Printer"; }
00048 
00049     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
00050       AU.setPreservesAll();
00051     }
00052 
00053     bool runOnMachineFunction(MachineFunction &MF) {
00054       (*OS) << Banner;
00055       MF.print (*OS);
00056       return false;
00057     }
00058   };
00059 }
00060 
00061 /// Returns a newly-created MachineFunction Printer pass. The default output
00062 /// stream is std::cerr; the default banner is empty.
00063 ///
00064 FunctionPass *llvm::createMachineFunctionPrinterPass(std::ostream *OS,
00065                                                      const std::string &Banner){
00066   return new Printer(OS, Banner);
00067 }
00068 
00069 namespace {
00070   struct Deleter : public MachineFunctionPass {
00071     const char *getPassName() const { return "Machine Code Deleter"; }
00072 
00073     bool runOnMachineFunction(MachineFunction &MF) {
00074       // Delete the annotation from the function now.
00075       MachineFunction::destruct(MF.getFunction());
00076       return true;
00077     }
00078   };
00079 }
00080 
00081 /// MachineCodeDeletion Pass - This pass deletes all of the machine code for
00082 /// the current function, which should happen after the function has been
00083 /// emitted to a .s file or to memory.
00084 FunctionPass *llvm::createMachineCodeDeleter() {
00085   return new Deleter();
00086 }
00087 
00088 
00089 
00090 //===---------------------------------------------------------------------===//
00091 // MachineFunction implementation
00092 //===---------------------------------------------------------------------===//
00093 
00094 MachineBasicBlock* ilist_traits<MachineBasicBlock>::createSentinel() {
00095   MachineBasicBlock* dummy = new MachineBasicBlock();
00096   LeakDetector::removeGarbageObject(dummy);
00097   return dummy;
00098 }
00099 
00100 void ilist_traits<MachineBasicBlock>::transferNodesFromList(
00101   iplist<MachineBasicBlock, ilist_traits<MachineBasicBlock> >& toList,
00102   ilist_iterator<MachineBasicBlock> first,
00103   ilist_iterator<MachineBasicBlock> last) {
00104   if (Parent != toList.Parent)
00105     for (; first != last; ++first)
00106       first->Parent = toList.Parent;
00107 }
00108 
00109 MachineFunction::MachineFunction(const Function *F,
00110                                  const TargetMachine &TM)
00111   : Annotation(MF_AID), Fn(F), Target(TM), UsedPhysRegs(0) {
00112   SSARegMapping = new SSARegMap();
00113   MFInfo = 0;
00114   FrameInfo = new MachineFrameInfo();
00115   ConstantPool = new MachineConstantPool(TM.getTargetData());
00116   BasicBlocks.Parent = this;
00117 }
00118 
00119 MachineFunction::~MachineFunction() {
00120   BasicBlocks.clear();
00121   delete SSARegMapping;
00122   delete MFInfo;
00123   delete FrameInfo;
00124   delete ConstantPool;
00125   delete[] UsedPhysRegs;
00126 }
00127 
00128 void MachineFunction::dump() const { print(std::cerr); }
00129 
00130 void MachineFunction::print(std::ostream &OS) const {
00131   OS << "# Machine code for " << Fn->getName () << "():\n";
00132 
00133   // Print Frame Information
00134   getFrameInfo()->print(*this, OS);
00135 
00136   // Print Constant Pool
00137   getConstantPool()->print(OS);
00138   
00139   const MRegisterInfo *MRI = getTarget().getRegisterInfo();
00140   
00141   if (livein_begin() != livein_end()) {
00142     OS << "Live Ins:";
00143     for (livein_iterator I = livein_begin(), E = livein_end(); I != E; ++I) {
00144       if (MRI)
00145         OS << " " << MRI->getName(I->first);
00146       else
00147         OS << " Reg #" << I->first;
00148     }
00149     OS << "\n";
00150   }
00151   if (liveout_begin() != liveout_end()) {
00152     OS << "Live Outs:";
00153     for (liveout_iterator I = liveout_begin(), E = liveout_end(); I != E; ++I)
00154       if (MRI)
00155         OS << " " << MRI->getName(*I);
00156       else
00157         OS << " Reg #" << *I;
00158     OS << "\n";
00159   }
00160   
00161   for (const_iterator BB = begin(); BB != end(); ++BB)
00162     BB->print(OS);
00163 
00164   OS << "\n# End machine code for " << Fn->getName () << "().\n\n";
00165 }
00166 
00167 /// CFGOnly flag - This is used to control whether or not the CFG graph printer
00168 /// prints out the contents of basic blocks or not.  This is acceptable because
00169 /// this code is only really used for debugging purposes.
00170 ///
00171 static bool CFGOnly = false;
00172 
00173 namespace llvm {
00174   template<>
00175   struct DOTGraphTraits<const MachineFunction*> : public DefaultDOTGraphTraits {
00176     static std::string getGraphName(const MachineFunction *F) {
00177       return "CFG for '" + F->getFunction()->getName() + "' function";
00178     }
00179 
00180     static std::string getNodeLabel(const MachineBasicBlock *Node,
00181                                     const MachineFunction *Graph) {
00182       if (CFGOnly && Node->getBasicBlock() &&
00183           !Node->getBasicBlock()->getName().empty())
00184         return Node->getBasicBlock()->getName() + ":";
00185 
00186       std::ostringstream Out;
00187       if (CFGOnly) {
00188         Out << Node->getNumber() << ':';
00189         return Out.str();
00190       }
00191 
00192       Node->print(Out);
00193 
00194       std::string OutStr = Out.str();
00195       if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());
00196 
00197       // Process string output to make it nicer...
00198       for (unsigned i = 0; i != OutStr.length(); ++i)
00199         if (OutStr[i] == '\n') {                            // Left justify
00200           OutStr[i] = '\\';
00201           OutStr.insert(OutStr.begin()+i+1, 'l');
00202         }
00203       return OutStr;
00204     }
00205   };
00206 }
00207 
00208 void MachineFunction::viewCFG() const
00209 {
00210 #ifndef NDEBUG
00211   std::string Filename = "/tmp/cfg." + getFunction()->getName() + ".dot";
00212   std::cerr << "Writing '" << Filename << "'... ";
00213   std::ofstream F(Filename.c_str());
00214 
00215   if (!F) {
00216     std::cerr << "  error opening file for writing!\n";
00217     return;
00218   }
00219 
00220   WriteGraph(F, this);
00221   F.close();
00222   std::cerr << "\n";
00223 
00224 #ifdef HAVE_GRAPHVIZ
00225   std::cerr << "Running 'Graphviz' program... " << std::flush;
00226   if (system((LLVM_PATH_GRAPHVIZ " " + Filename).c_str())) {
00227     std::cerr << "Error viewing graph: 'Graphviz' not in path?\n";
00228   } else {
00229     system(("rm " + Filename).c_str());
00230     return;
00231   }
00232 #endif  // HAVE_GRAPHVIZ
00233 
00234 #ifdef HAVE_GV
00235   std::cerr << "Running 'dot' program... " << std::flush;
00236   if (system(("dot -Tps -Nfontname=Courier -Gsize=7.5,10 " + Filename
00237               + " > /tmp/cfg.tempgraph.ps").c_str())) {
00238     std::cerr << "Error running dot: 'dot' not in path?\n";
00239   } else {
00240     std::cerr << "\n";
00241     system("gv /tmp/cfg.tempgraph.ps");
00242   }
00243   system(("rm " + Filename + " /tmp/cfg.tempgraph.ps").c_str());
00244   return;
00245 #endif  // HAVE_GV
00246 #endif  // NDEBUG
00247   std::cerr << "MachineFunction::viewCFG is only available in debug builds on "
00248             << "systems with Graphviz or gv!\n";
00249 
00250 #ifndef NDEBUG
00251   system(("rm " + Filename).c_str());
00252 #endif
00253 }
00254 
00255 void MachineFunction::viewCFGOnly() const
00256 {
00257   CFGOnly = true;
00258   viewCFG();
00259   CFGOnly = false;
00260 }
00261 
00262 // The next two methods are used to construct and to retrieve
00263 // the MachineCodeForFunction object for the given function.
00264 // construct() -- Allocates and initializes for a given function and target
00265 // get()       -- Returns a handle to the object.
00266 //                This should not be called before "construct()"
00267 //                for a given Function.
00268 //
00269 MachineFunction&
00270 MachineFunction::construct(const Function *Fn, const TargetMachine &Tar)
00271 {
00272   assert(Fn->getAnnotation(MF_AID) == 0 &&
00273          "Object already exists for this function!");
00274   MachineFunction* mcInfo = new MachineFunction(Fn, Tar);
00275   Fn->addAnnotation(mcInfo);
00276   return *mcInfo;
00277 }
00278 
00279 void MachineFunction::destruct(const Function *Fn) {
00280   bool Deleted = Fn->deleteAnnotation(MF_AID);
00281   assert(Deleted && "Machine code did not exist for function!");
00282 }
00283 
00284 MachineFunction& MachineFunction::get(const Function *F)
00285 {
00286   MachineFunction *mc = (MachineFunction*)F->getAnnotation(MF_AID);
00287   assert(mc && "Call construct() method first to allocate the object");
00288   return *mc;
00289 }
00290 
00291 void MachineFunction::clearSSARegMap() {
00292   delete SSARegMapping;
00293   SSARegMapping = 0;
00294 }
00295 
00296 //===----------------------------------------------------------------------===//
00297 //  MachineFrameInfo implementation
00298 //===----------------------------------------------------------------------===//
00299 
00300 void MachineFrameInfo::print(const MachineFunction &MF, std::ostream &OS) const{
00301   int ValOffset = MF.getTarget().getFrameInfo()->getOffsetOfLocalArea();
00302 
00303   for (unsigned i = 0, e = Objects.size(); i != e; ++i) {
00304     const StackObject &SO = Objects[i];
00305     OS << "  <fi #" << (int)(i-NumFixedObjects) << ">: ";
00306     if (SO.Size == 0)
00307       OS << "variable sized";
00308     else
00309       OS << "size is " << SO.Size << " byte" << (SO.Size != 1 ? "s," : ",");
00310     OS << " alignment is " << SO.Alignment << " byte"
00311        << (SO.Alignment != 1 ? "s," : ",");
00312 
00313     if (i < NumFixedObjects)
00314       OS << " fixed";
00315     if (i < NumFixedObjects || SO.SPOffset != -1) {
00316       int Off = SO.SPOffset - ValOffset;
00317       OS << " at location [SP";
00318       if (Off > 0)
00319         OS << "+" << Off;
00320       else if (Off < 0)
00321         OS << Off;
00322       OS << "]";
00323     }
00324     OS << "\n";
00325   }
00326 
00327   if (HasVarSizedObjects)
00328     OS << "  Stack frame contains variable sized objects\n";
00329 }
00330 
00331 void MachineFrameInfo::dump(const MachineFunction &MF) const {
00332   print(MF, std::cerr);
00333 }
00334 
00335 
00336 //===----------------------------------------------------------------------===//
00337 //  MachineConstantPool implementation
00338 //===----------------------------------------------------------------------===//
00339 
00340 /// getConstantPoolIndex - Create a new entry in the constant pool or return
00341 /// an existing one.  User must specify an alignment in bytes for the object.
00342 ///
00343 unsigned MachineConstantPool::getConstantPoolIndex(Constant *C, 
00344                                                    unsigned Alignment) {
00345   assert(Alignment && "Alignment must be specified!");
00346   if (Alignment > PoolAlignment) PoolAlignment = Alignment;
00347   
00348   // Check to see if we already have this constant.
00349   //
00350   // FIXME, this could be made much more efficient for large constant pools.
00351   unsigned AlignMask = (1 << Alignment)-1;
00352   for (unsigned i = 0, e = Constants.size(); i != e; ++i)
00353     if (Constants[i].Val == C && (Constants[i].Offset & AlignMask) == 0)
00354       return i;
00355   
00356   unsigned Offset = 0;
00357   if (!Constants.empty()) {
00358     Offset = Constants.back().Offset;
00359     Offset += TD.getTypeSize(Constants.back().Val->getType());
00360     Offset = (Offset+AlignMask)&~AlignMask;
00361   }
00362   
00363   Constants.push_back(MachineConstantPoolEntry(C, Offset));
00364   return Constants.size()-1;
00365 }
00366 
00367 
00368 void MachineConstantPool::print(std::ostream &OS) const {
00369   for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
00370     OS << "  <cp #" << i << "> is" << *(Value*)Constants[i].Val;
00371     OS << " , offset=" << Constants[i].Offset;
00372     OS << "\n";
00373   }
00374 }
00375 
00376 void MachineConstantPool::dump() const { print(std::cerr); }