LLVM API Documentation
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); }