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