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