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/Passes.h" 22 #include "llvm/Target/TargetMachine.h" 23 #include "llvm/Target/TargetFrameInfo.h" 24 #include "llvm/Function.h" 25 #include "llvm/Instructions.h" 26 #include "llvm/Support/LeakDetector.h" 27 #include "llvm/Support/GraphWriter.h" 28 #include "llvm/Config/config.h" 29 #include <fstream> 30 #include <iostream> 31 #include <sstream> 32 33 using namespace llvm; 34 35 static AnnotationID MF_AID( 36 AnnotationManager::getID("CodeGen::MachineCodeForFunction")); 37 38 39 namespace { 40 struct Printer : public MachineFunctionPass { 41 std::ostream *OS; 42 const std::string Banner; 43 44 Printer (std::ostream *_OS, const std::string &_Banner) : 45 OS (_OS), Banner (_Banner) { } 46 47 const char *getPassName() const { return "MachineFunction Printer"; } 48 49 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 50 AU.setPreservesAll(); 51 } 52 53 bool runOnMachineFunction(MachineFunction &MF) { 54 (*OS) << Banner; 55 MF.print (*OS); 56 return false; 57 } 58 }; 59 } 60 61 /// Returns a newly-created MachineFunction Printer pass. The default output 62 /// stream is std::cerr; the default banner is empty. 63 /// 64 FunctionPass *llvm::createMachineFunctionPrinterPass(std::ostream *OS, 65 const std::string &Banner){ 66 return new Printer(OS, Banner); 67 } 68 69 namespace { 70 struct Deleter : public MachineFunctionPass { 71 const char *getPassName() const { return "Machine Code Deleter"; } 72 73 bool runOnMachineFunction(MachineFunction &MF) { 74 // Delete the annotation from the function now. 75 MachineFunction::destruct(MF.getFunction()); 76 return true; 77 } 78 }; 79 } 80 81 /// MachineCodeDeletion Pass - This pass deletes all of the machine code for 82 /// the current function, which should happen after the function has been 83 /// emitted to a .s file or to memory. 84 FunctionPass *llvm::createMachineCodeDeleter() { 85 return new Deleter(); 86 } 87 88 89 90 //===---------------------------------------------------------------------===// 91 // MachineFunction implementation 92 //===---------------------------------------------------------------------===// 93 94 MachineBasicBlock* ilist_traits<MachineBasicBlock>::createSentinel() { 95 MachineBasicBlock* dummy = new MachineBasicBlock(); 96 LeakDetector::removeGarbageObject(dummy); 97 return dummy; 98 } 99 100 void ilist_traits<MachineBasicBlock>::transferNodesFromList( 101 iplist<MachineBasicBlock, ilist_traits<MachineBasicBlock> >& toList, 102 ilist_iterator<MachineBasicBlock> first, 103 ilist_iterator<MachineBasicBlock> last) { 104 if (Parent != toList.Parent) 105 for (; first != last; ++first) 106 first->Parent = toList.Parent; 107 } 108 109 MachineFunction::MachineFunction(const Function *F, 110 const TargetMachine &TM) 111 : Annotation(MF_AID), Fn(F), Target(TM), UsedPhysRegs(0) { 112 SSARegMapping = new SSARegMap(); 113 MFInfo = 0; 114 FrameInfo = new MachineFrameInfo(); 115 ConstantPool = new MachineConstantPool(); 116 BasicBlocks.Parent = this; 117 } 118 119 MachineFunction::~MachineFunction() { 120 BasicBlocks.clear(); 121 delete SSARegMapping; 122 delete MFInfo; 123 delete FrameInfo; 124 delete ConstantPool; 125 delete[] UsedPhysRegs; 126 } 127 128 void MachineFunction::dump() const { print(std::cerr); } 129 130 void MachineFunction::print(std::ostream &OS) const { 131 OS << "# Machine code for " << Fn->getName () << "():\n"; 132 133 // Print Frame Information 134 getFrameInfo()->print(*this, OS); 135 136 // Print Constant Pool 137 getConstantPool()->print(OS); 138 139 const MRegisterInfo *MRI = getTarget().getRegisterInfo(); 140 141 if (livein_begin() != livein_end()) { 142 OS << "Live Ins:"; 143 for (livein_iterator I = livein_begin(), E = livein_end(); I != E; ++I) { 144 if (MRI) 145 OS << " " << MRI->getName(I->first); 146 else 147 OS << " Reg #" << I->first; 148 } 149 OS << "\n"; 150 } 151 if (liveout_begin() != liveout_end()) { 152 OS << "Live Outs:"; 153 for (liveout_iterator I = liveout_begin(), E = liveout_end(); I != E; ++I) 154 if (MRI) 155 OS << " " << MRI->getName(*I); 156 else 157 OS << " Reg #" << *I; 158 OS << "\n"; 159 } 160 161 for (const_iterator BB = begin(); BB != end(); ++BB) 162 BB->print(OS); 163 164 OS << "\n# End machine code for " << Fn->getName () << "().\n\n"; 165 } 166 167 /// CFGOnly flag - This is used to control whether or not the CFG graph printer 168 /// prints out the contents of basic blocks or not. This is acceptable because 169 /// this code is only really used for debugging purposes. 170 /// 171 static bool CFGOnly = false; 172 173 namespace llvm { 174 template<> 175 struct DOTGraphTraits<const MachineFunction*> : public DefaultDOTGraphTraits { 176 static std::string getGraphName(const MachineFunction *F) { 177 return "CFG for '" + F->getFunction()->getName() + "' function"; 178 } 179 180 static std::string getNodeLabel(const MachineBasicBlock *Node, 181 const MachineFunction *Graph) { 182 if (CFGOnly && Node->getBasicBlock() && 183 !Node->getBasicBlock()->getName().empty()) 184 return Node->getBasicBlock()->getName() + ":"; 185 186 std::ostringstream Out; 187 if (CFGOnly) { 188 Out << Node->getNumber() << ':'; 189 return Out.str(); 190 } 191 192 Node->print(Out); 193 194 std::string OutStr = Out.str(); 195 if (OutStr[0] == '\n') OutStr.erase(OutStr.begin()); 196 197 // Process string output to make it nicer... 198 for (unsigned i = 0; i != OutStr.length(); ++i) 199 if (OutStr[i] == '\n') { // Left justify 200 OutStr[i] = '\\'; 201 OutStr.insert(OutStr.begin()+i+1, 'l'); 202 } 203 return OutStr; 204 } 205 }; 206 } 207 208 void MachineFunction::viewCFG() const 209 { 210 #ifndef NDEBUG 211 std::string Filename = "/tmp/cfg." + getFunction()->getName() + ".dot"; 212 std::cerr << "Writing '" << Filename << "'... "; 213 std::ofstream F(Filename.c_str()); 214 215 if (!F) { 216 std::cerr << " error opening file for writing!\n"; 217 return; 218 } 219 220 WriteGraph(F, this); 221 F.close(); 222 std::cerr << "\n"; 223 224 #ifdef HAVE_GRAPHVIZ 225 std::cerr << "Running 'Graphviz' program... " << std::flush; 226 if (system((LLVM_PATH_GRAPHVIZ " " + Filename).c_str())) { 227 std::cerr << "Error viewing graph: 'Graphviz' not in path?\n"; 228 } else { 229 system(("rm " + Filename).c_str()); 230 return; 231 } 232 #endif // HAVE_GRAPHVIZ 233 234 #ifdef HAVE_GV 235 std::cerr << "Running 'dot' program... " << std::flush; 236 if (system(("dot -Tps -Nfontname=Courier -Gsize=7.5,10 " + Filename 237 + " > /tmp/cfg.tempgraph.ps").c_str())) { 238 std::cerr << "Error running dot: 'dot' not in path?\n"; 239 } else { 240 std::cerr << "\n"; 241 system("gv /tmp/cfg.tempgraph.ps"); 242 } 243 system(("rm " + Filename + " /tmp/cfg.tempgraph.ps").c_str()); 244 return; 245 #endif // HAVE_GV 246 #endif // NDEBUG 247 std::cerr << "MachineFunction::viewCFG is only available in debug builds on " 248 << "systems with Graphviz or gv!\n"; 249 250 #ifndef NDEBUG 251 system(("rm " + Filename).c_str()); 252 #endif 253 } 254 255 void MachineFunction::viewCFGOnly() const 256 { 257 CFGOnly = true; 258 viewCFG(); 259 CFGOnly = false; 260 } 261 262 // The next two methods are used to construct and to retrieve 263 // the MachineCodeForFunction object for the given function. 264 // construct() -- Allocates and initializes for a given function and target 265 // get() -- Returns a handle to the object. 266 // This should not be called before "construct()" 267 // for a given Function. 268 // 269 MachineFunction& 270 MachineFunction::construct(const Function *Fn, const TargetMachine &Tar) 271 { 272 assert(Fn->getAnnotation(MF_AID) == 0 && 273 "Object already exists for this function!"); 274 MachineFunction* mcInfo = new MachineFunction(Fn, Tar); 275 Fn->addAnnotation(mcInfo); 276 return *mcInfo; 277 } 278 279 void MachineFunction::destruct(const Function *Fn) { 280 bool Deleted = Fn->deleteAnnotation(MF_AID); 281 assert(Deleted && "Machine code did not exist for function!"); 282 } 283 284 MachineFunction& MachineFunction::get(const Function *F) 285 { 286 MachineFunction *mc = (MachineFunction*)F->getAnnotation(MF_AID); 287 assert(mc && "Call construct() method first to allocate the object"); 288 return *mc; 289 } 290 291 void MachineFunction::clearSSARegMap() { 292 delete SSARegMapping; 293 SSARegMapping = 0; 294 } 295 296 //===----------------------------------------------------------------------===// 297 // MachineFrameInfo implementation 298 //===----------------------------------------------------------------------===// 299 300 /// CreateStackObject - Create a stack object for a value of the specified type. 301 /// 302 int MachineFrameInfo::CreateStackObject(const Type *Ty, const TargetData &TD) { 303 return CreateStackObject((unsigned)TD.getTypeSize(Ty), 304 TD.getTypeAlignment(Ty)); 305 } 306 307 308 void MachineFrameInfo::print(const MachineFunction &MF, std::ostream &OS) const{ 309 int ValOffset = MF.getTarget().getFrameInfo()->getOffsetOfLocalArea(); 310 311 for (unsigned i = 0, e = Objects.size(); i != e; ++i) { 312 const StackObject &SO = Objects[i]; 313 OS << " <fi #" << (int)(i-NumFixedObjects) << ">: "; 314 if (SO.Size == 0) 315 OS << "variable sized"; 316 else 317 OS << "size is " << SO.Size << " byte" << (SO.Size != 1 ? "s," : ","); 318 OS << " alignment is " << SO.Alignment << " byte" 319 << (SO.Alignment != 1 ? "s," : ","); 320 321 if (i < NumFixedObjects) 322 OS << " fixed"; 323 if (i < NumFixedObjects || SO.SPOffset != -1) { 324 int Off = SO.SPOffset - ValOffset; 325 OS << " at location [SP"; 326 if (Off > 0) 327 OS << "+" << Off; 328 else if (Off < 0) 329 OS << Off; 330 OS << "]"; 331 } 332 OS << "\n"; 333 } 334 335 if (HasVarSizedObjects) 336 OS << " Stack frame contains variable sized objects\n"; 337 } 338 339 void MachineFrameInfo::dump(const MachineFunction &MF) const { 340 print(MF, std::cerr); 341 } 342 343 344 //===----------------------------------------------------------------------===// 345 // MachineConstantPool implementation 346 //===----------------------------------------------------------------------===// 347 348 void MachineConstantPool::print(std::ostream &OS) const { 349 for (unsigned i = 0, e = Constants.size(); i != e; ++i) { 350 OS << " <cp #" << i << "> is" << *(Value*)Constants[i].first; 351 if (Constants[i].second != 0) OS << " , align=" << Constants[i].second; 352 OS << "\n"; 353 } 354 } 355 356 void MachineConstantPool::dump() const { print(std::cerr); } 357