LLVM API Documentation

DebugIR.cpp
Go to the documentation of this file.
00001 //===--- DebugIR.cpp - Transform debug metadata to allow debugging IR -----===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // A Module transform pass that emits a succinct version of the IR and replaces
00011 // the source file metadata to allow debuggers to step through the IR.
00012 //
00013 // FIXME: instead of replacing debug metadata, this pass should allow for
00014 // additional metadata to be used to point capable debuggers to the IR file
00015 // without destroying the mapping to the original source file.
00016 //
00017 //===----------------------------------------------------------------------===//
00018 
00019 #include "llvm/IR/ValueMap.h"
00020 #include "DebugIR.h"
00021 #include "llvm/IR/AssemblyAnnotationWriter.h"
00022 #include "llvm/IR/DIBuilder.h"
00023 #include "llvm/IR/DataLayout.h"
00024 #include "llvm/IR/DebugInfo.h"
00025 #include "llvm/IR/InstVisitor.h"
00026 #include "llvm/IR/Instruction.h"
00027 #include "llvm/IR/LLVMContext.h"
00028 #include "llvm/IR/Module.h"
00029 #include "llvm/Support/Debug.h"
00030 #include "llvm/Support/FileSystem.h"
00031 #include "llvm/Support/FormattedStream.h"
00032 #include "llvm/Support/Path.h"
00033 #include "llvm/Support/ToolOutputFile.h"
00034 #include "llvm/Transforms/Instrumentation.h"
00035 #include "llvm/Transforms/Utils/Cloning.h"
00036 #include <string>
00037 
00038 #define STR_HELPER(x) #x
00039 #define STR(x) STR_HELPER(x)
00040 
00041 using namespace llvm;
00042 
00043 #define DEBUG_TYPE "debug-ir"
00044 
00045 namespace {
00046 
00047 /// Builds a map of Value* to line numbers on which the Value appears in a
00048 /// textual representation of the IR by plugging into the AssemblyWriter by
00049 /// masquerading as an AssemblyAnnotationWriter.
00050 class ValueToLineMap : public AssemblyAnnotationWriter {
00051   ValueMap<const Value *, unsigned int> Lines;
00052   typedef ValueMap<const Value *, unsigned int>::const_iterator LineIter;
00053 
00054   void addEntry(const Value *V, formatted_raw_ostream &Out) {
00055     Out.flush();
00056     Lines.insert(std::make_pair(V, Out.getLine() + 1));
00057   }
00058 
00059 public:
00060 
00061   /// Prints Module to a null buffer in order to build the map of Value pointers
00062   /// to line numbers.
00063   ValueToLineMap(const Module *M) {
00064     raw_null_ostream ThrowAway;
00065     M->print(ThrowAway, this);
00066   }
00067 
00068   // This function is called after an Instruction, GlobalValue, or GlobalAlias
00069   // is printed.
00070   void printInfoComment(const Value &V, formatted_raw_ostream &Out) override {
00071     addEntry(&V, Out);
00072   }
00073 
00074   void emitFunctionAnnot(const Function *F,
00075                          formatted_raw_ostream &Out) override {
00076     addEntry(F, Out);
00077   }
00078 
00079   /// If V appears on a line in the textual IR representation, sets Line to the
00080   /// line number and returns true, otherwise returns false.
00081   bool getLine(const Value *V, unsigned int &Line) const {
00082     LineIter i = Lines.find(V);
00083     if (i != Lines.end()) {
00084       Line = i->second;
00085       return true;
00086     }
00087     return false;
00088   }
00089 };
00090 
00091 /// Removes debug intrisncs like llvm.dbg.declare and llvm.dbg.value.
00092 class DebugIntrinsicsRemover : public InstVisitor<DebugIntrinsicsRemover> {
00093   void remove(Instruction &I) { I.eraseFromParent(); }
00094 
00095 public:
00096   static void process(Module &M) {
00097     DebugIntrinsicsRemover Remover;
00098     Remover.visit(&M);
00099   }
00100   void visitDbgDeclareInst(DbgDeclareInst &I) { remove(I); }
00101   void visitDbgValueInst(DbgValueInst &I) { remove(I); }
00102   void visitDbgInfoIntrinsic(DbgInfoIntrinsic &I) { remove(I); }
00103 };
00104 
00105 /// Removes debug metadata (!dbg) nodes from all instructions, and optionally
00106 /// metadata named "llvm.dbg.cu" if RemoveNamedInfo is true.
00107 class DebugMetadataRemover : public InstVisitor<DebugMetadataRemover> {
00108   bool RemoveNamedInfo;
00109 
00110 public:
00111   static void process(Module &M, bool RemoveNamedInfo = true) {
00112     DebugMetadataRemover Remover(RemoveNamedInfo);
00113     Remover.run(&M);
00114   }
00115 
00116   DebugMetadataRemover(bool RemoveNamedInfo)
00117       : RemoveNamedInfo(RemoveNamedInfo) {}
00118 
00119   void visitInstruction(Instruction &I) {
00120     if (I.getMetadata(LLVMContext::MD_dbg))
00121       I.setMetadata(LLVMContext::MD_dbg, nullptr);
00122   }
00123 
00124   void run(Module *M) {
00125     // Remove debug metadata attached to instructions
00126     visit(M);
00127 
00128     if (RemoveNamedInfo) {
00129       // Remove CU named metadata (and all children nodes)
00130       NamedMDNode *Node = M->getNamedMetadata("llvm.dbg.cu");
00131       if (Node)
00132         M->eraseNamedMetadata(Node);
00133     }
00134   }
00135 };
00136 
00137 /// Updates debug metadata in a Module:
00138 ///   - changes Filename/Directory to values provided on construction
00139 ///   - adds/updates line number (DebugLoc) entries associated with each
00140 ///     instruction to reflect the instruction's location in an LLVM IR file
00141 class DIUpdater : public InstVisitor<DIUpdater> {
00142   /// Builder of debug information
00143   DIBuilder Builder;
00144 
00145   /// Helper for type attributes/sizes/etc
00146   DataLayout Layout;
00147 
00148   /// Map of Value* to line numbers
00149   const ValueToLineMap LineTable;
00150 
00151   /// Map of Value* (in original Module) to Value* (in optional cloned Module)
00152   const ValueToValueMapTy *VMap;
00153 
00154   /// Directory of debug metadata
00155   DebugInfoFinder Finder;
00156 
00157   /// Source filename and directory
00158   StringRef Filename;
00159   StringRef Directory;
00160 
00161   // CU nodes needed when creating DI subprograms
00162   MDNode *FileNode;
00163   MDNode *LexicalBlockFileNode;
00164   const MDNode *CUNode;
00165 
00166   ValueMap<const Function *, MDNode *> SubprogramDescriptors;
00167   DenseMap<const Type *, MDNode *> TypeDescriptors;
00168 
00169 public:
00170   DIUpdater(Module &M, StringRef Filename = StringRef(),
00171             StringRef Directory = StringRef(), const Module *DisplayM = nullptr,
00172             const ValueToValueMapTy *VMap = nullptr)
00173       : Builder(M), Layout(&M), LineTable(DisplayM ? DisplayM : &M), VMap(VMap),
00174         Finder(), Filename(Filename), Directory(Directory), FileNode(nullptr),
00175         LexicalBlockFileNode(nullptr), CUNode(nullptr) {
00176     Finder.processModule(M);
00177     visit(&M);
00178   }
00179 
00180   ~DIUpdater() { Builder.finalize(); }
00181 
00182   void visitModule(Module &M) {
00183     if (Finder.compile_unit_count() > 1)
00184       report_fatal_error("DebugIR pass supports only a signle compile unit per "
00185                          "Module.");
00186     createCompileUnit(Finder.compile_unit_count() == 1 ?
00187                       (MDNode*)*Finder.compile_units().begin() : nullptr);
00188   }
00189 
00190   void visitFunction(Function &F) {
00191     if (F.isDeclaration() || findDISubprogram(&F))
00192       return;
00193 
00194     StringRef MangledName = F.getName();
00195     DICompositeType Sig = createFunctionSignature(&F);
00196 
00197     // find line of function declaration
00198     unsigned Line = 0;
00199     if (!findLine(&F, Line)) {
00200       DEBUG(dbgs() << "WARNING: No line for Function " << F.getName().str()
00201                    << "\n");
00202       return;
00203     }
00204 
00205     Instruction *FirstInst = F.begin()->begin();
00206     unsigned ScopeLine = 0;
00207     if (!findLine(FirstInst, ScopeLine)) {
00208       DEBUG(dbgs() << "WARNING: No line for 1st Instruction in Function "
00209                    << F.getName().str() << "\n");
00210       return;
00211     }
00212 
00213     bool Local = F.hasInternalLinkage();
00214     bool IsDefinition = !F.isDeclaration();
00215     bool IsOptimized = false;
00216 
00217     int FuncFlags = llvm::DIDescriptor::FlagPrototyped;
00218     assert(CUNode && FileNode);
00219     DISubprogram Sub = Builder.createFunction(
00220         DICompileUnit(CUNode), F.getName(), MangledName, DIFile(FileNode), Line,
00221         Sig, Local, IsDefinition, ScopeLine, FuncFlags, IsOptimized, &F);
00222     assert(Sub.isSubprogram());
00223     DEBUG(dbgs() << "create subprogram mdnode " << *Sub << ": "
00224                  << "\n");
00225 
00226     SubprogramDescriptors.insert(std::make_pair(&F, Sub));
00227   }
00228 
00229   void visitInstruction(Instruction &I) {
00230     DebugLoc Loc(I.getDebugLoc());
00231 
00232     /// If a ValueToValueMap is provided, use it to get the real instruction as
00233     /// the line table was generated on a clone of the module on which we are
00234     /// operating.
00235     Value *RealInst = nullptr;
00236     if (VMap)
00237       RealInst = VMap->lookup(&I);
00238 
00239     if (!RealInst)
00240       RealInst = &I;
00241 
00242     unsigned Col = 0; // FIXME: support columns
00243     unsigned Line;
00244     if (!LineTable.getLine(RealInst, Line)) {
00245       // Instruction has no line, it may have been removed (in the module that
00246       // will be passed to the debugger) so there is nothing to do here.
00247       DEBUG(dbgs() << "WARNING: no LineTable entry for instruction " << RealInst
00248                    << "\n");
00249       DEBUG(RealInst->dump());
00250       return;
00251     }
00252 
00253     DebugLoc NewLoc;
00254     if (!Loc.isUnknown())
00255       // I had a previous debug location: re-use the DebugLoc
00256       NewLoc = DebugLoc::get(Line, Col, Loc.getScope(RealInst->getContext()),
00257                              Loc.getInlinedAt(RealInst->getContext()));
00258     else if (MDNode *scope = findScope(&I))
00259       NewLoc = DebugLoc::get(Line, Col, scope, nullptr);
00260     else {
00261       DEBUG(dbgs() << "WARNING: no valid scope for instruction " << &I
00262                    << ". no DebugLoc will be present."
00263                    << "\n");
00264       return;
00265     }
00266 
00267     addDebugLocation(I, NewLoc);
00268   }
00269 
00270 private:
00271 
00272   void createCompileUnit(MDNode *CUToReplace) {
00273     std::string Flags;
00274     bool IsOptimized = false;
00275     StringRef Producer;
00276     unsigned RuntimeVersion(0);
00277     StringRef SplitName;
00278 
00279     if (CUToReplace) {
00280       // save fields from existing CU to re-use in the new CU
00281       DICompileUnit ExistingCU(CUToReplace);
00282       Producer = ExistingCU.getProducer();
00283       IsOptimized = ExistingCU.isOptimized();
00284       Flags = ExistingCU.getFlags();
00285       RuntimeVersion = ExistingCU.getRunTimeVersion();
00286       SplitName = ExistingCU.getSplitDebugFilename();
00287     } else {
00288       Producer =
00289           "LLVM Version " STR(LLVM_VERSION_MAJOR) "." STR(LLVM_VERSION_MINOR);
00290     }
00291 
00292     CUNode =
00293         Builder.createCompileUnit(dwarf::DW_LANG_C99, Filename, Directory,
00294                                   Producer, IsOptimized, Flags, RuntimeVersion);
00295 
00296     if (CUToReplace)
00297       CUToReplace->replaceAllUsesWith(const_cast<MDNode *>(CUNode));
00298 
00299     DICompileUnit CU(CUNode);
00300     FileNode = Builder.createFile(Filename, Directory);
00301     LexicalBlockFileNode = Builder.createLexicalBlockFile(CU, DIFile(FileNode));
00302   }
00303 
00304   /// Returns the MDNode* that represents the DI scope to associate with I
00305   MDNode *findScope(const Instruction *I) {
00306     const Function *F = I->getParent()->getParent();
00307     if (MDNode *ret = findDISubprogram(F))
00308       return ret;
00309 
00310     DEBUG(dbgs() << "WARNING: Using fallback lexical block file scope "
00311                  << LexicalBlockFileNode << " as scope for instruction " << I
00312                  << "\n");
00313     return LexicalBlockFileNode;
00314   }
00315 
00316   /// Returns the MDNode* that is the descriptor for F
00317   MDNode *findDISubprogram(const Function *F) {
00318     typedef ValueMap<const Function *, MDNode *>::const_iterator FuncNodeIter;
00319     FuncNodeIter i = SubprogramDescriptors.find(F);
00320     if (i != SubprogramDescriptors.end())
00321       return i->second;
00322 
00323     DEBUG(dbgs() << "searching for DI scope node for Function " << F
00324                  << " in a list of " << Finder.subprogram_count()
00325                  << " subprogram nodes"
00326                  << "\n");
00327 
00328     for (DISubprogram S : Finder.subprograms()) {
00329       if (S.getFunction() == F) {
00330         DEBUG(dbgs() << "Found DISubprogram " << S << " for function "
00331                      << S.getFunction() << "\n");
00332         return S;
00333       }
00334     }
00335     DEBUG(dbgs() << "unable to find DISubprogram node for function "
00336                  << F->getName().str() << "\n");
00337     return nullptr;
00338   }
00339 
00340   /// Sets Line to the line number on which V appears and returns true. If a
00341   /// line location for V is not found, returns false.
00342   bool findLine(const Value *V, unsigned &Line) {
00343     if (LineTable.getLine(V, Line))
00344       return true;
00345 
00346     if (VMap) {
00347       Value *mapped = VMap->lookup(V);
00348       if (mapped && LineTable.getLine(mapped, Line))
00349         return true;
00350     }
00351     return false;
00352   }
00353 
00354   std::string getTypeName(Type *T) {
00355     std::string TypeName;
00356     raw_string_ostream TypeStream(TypeName);
00357     if (T)
00358       T->print(TypeStream);
00359     else
00360       TypeStream << "Printing <null> Type";
00361     TypeStream.flush();
00362     return TypeName;
00363   }
00364 
00365   /// Returns the MDNode that represents type T if it is already created, or 0
00366   /// if it is not.
00367   MDNode *getType(const Type *T) {
00368     typedef DenseMap<const Type *, MDNode *>::const_iterator TypeNodeIter;
00369     TypeNodeIter i = TypeDescriptors.find(T);
00370     if (i != TypeDescriptors.end())
00371       return i->second;
00372     return nullptr;
00373   }
00374 
00375   /// Returns a DebugInfo type from an LLVM type T.
00376   DIDerivedType getOrCreateType(Type *T) {
00377     MDNode *N = getType(T);
00378     if (N)
00379       return DIDerivedType(N);
00380     else if (T->isVoidTy())
00381       return DIDerivedType(nullptr);
00382     else if (T->isStructTy()) {
00383       N = Builder.createStructType(
00384           DIScope(LexicalBlockFileNode), T->getStructName(), DIFile(FileNode),
00385           0, Layout.getTypeSizeInBits(T), Layout.getABITypeAlignment(T), 0,
00386           DIType(nullptr), DIArray(nullptr)); // filled in later
00387 
00388       // N is added to the map (early) so that element search below can find it,
00389       // so as to avoid infinite recursion for structs that contain pointers to
00390       // their own type.
00391       TypeDescriptors[T] = N;
00392       DICompositeType StructDescriptor(N);
00393 
00394       SmallVector<Value *, 4> Elements;
00395       for (unsigned i = 0; i < T->getStructNumElements(); ++i)
00396         Elements.push_back(getOrCreateType(T->getStructElementType(i)));
00397 
00398       // set struct elements
00399       StructDescriptor.setArrays(Builder.getOrCreateArray(Elements));
00400     } else if (T->isPointerTy()) {
00401       Type *PointeeTy = T->getPointerElementType();
00402       if (!(N = getType(PointeeTy)))
00403         N = Builder.createPointerType(
00404             getOrCreateType(PointeeTy), Layout.getPointerTypeSizeInBits(T),
00405             Layout.getPrefTypeAlignment(T), getTypeName(T));
00406     } else if (T->isArrayTy()) {
00407       SmallVector<Value *, 1> Subrange;
00408       Subrange.push_back(
00409           Builder.getOrCreateSubrange(0, T->getArrayNumElements() - 1));
00410 
00411       N = Builder.createArrayType(Layout.getTypeSizeInBits(T),
00412                                   Layout.getPrefTypeAlignment(T),
00413                                   getOrCreateType(T->getArrayElementType()),
00414                                   Builder.getOrCreateArray(Subrange));
00415     } else {
00416       int encoding = llvm::dwarf::DW_ATE_signed;
00417       if (T->isIntegerTy())
00418         encoding = llvm::dwarf::DW_ATE_unsigned;
00419       else if (T->isFloatingPointTy())
00420         encoding = llvm::dwarf::DW_ATE_float;
00421 
00422       N = Builder.createBasicType(getTypeName(T), T->getPrimitiveSizeInBits(),
00423                                   0, encoding);
00424     }
00425     TypeDescriptors[T] = N;
00426     return DIDerivedType(N);
00427   }
00428 
00429   /// Returns a DebugInfo type that represents a function signature for Func.
00430   DICompositeType createFunctionSignature(const Function *Func) {
00431     SmallVector<Value *, 4> Params;
00432     DIDerivedType ReturnType(getOrCreateType(Func->getReturnType()));
00433     Params.push_back(ReturnType);
00434 
00435     const Function::ArgumentListType &Args(Func->getArgumentList());
00436     for (Function::ArgumentListType::const_iterator i = Args.begin(),
00437                                                     e = Args.end();
00438          i != e; ++i) {
00439       Type *T(i->getType());
00440       Params.push_back(getOrCreateType(T));
00441     }
00442 
00443     DITypeArray ParamArray = Builder.getOrCreateTypeArray(Params);
00444     return Builder.createSubroutineType(DIFile(FileNode), ParamArray);
00445   }
00446 
00447   /// Associates Instruction I with debug location Loc.
00448   void addDebugLocation(Instruction &I, DebugLoc Loc) {
00449     MDNode *MD = Loc.getAsMDNode(I.getContext());
00450     I.setMetadata(LLVMContext::MD_dbg, MD);
00451   }
00452 };
00453 
00454 /// Sets Filename/Directory from the Module identifier and returns true, or
00455 /// false if source information is not present.
00456 bool getSourceInfoFromModule(const Module &M, std::string &Directory,
00457                              std::string &Filename) {
00458   std::string PathStr(M.getModuleIdentifier());
00459   if (PathStr.length() == 0 || PathStr == "<stdin>")
00460     return false;
00461 
00462   Filename = sys::path::filename(PathStr);
00463   SmallVector<char, 16> Path(PathStr.begin(), PathStr.end());
00464   sys::path::remove_filename(Path);
00465   Directory = StringRef(Path.data(), Path.size());
00466   return true;
00467 }
00468 
00469 // Sets Filename/Directory from debug information in M and returns true, or
00470 // false if no debug information available, or cannot be parsed.
00471 bool getSourceInfoFromDI(const Module &M, std::string &Directory,
00472                          std::string &Filename) {
00473   NamedMDNode *CUNode = M.getNamedMetadata("llvm.dbg.cu");
00474   if (!CUNode || CUNode->getNumOperands() == 0)
00475     return false;
00476 
00477   DICompileUnit CU(CUNode->getOperand(0));
00478   if (!CU.Verify())
00479     return false;
00480 
00481   Filename = CU.getFilename();
00482   Directory = CU.getDirectory();
00483   return true;
00484 }
00485 
00486 } // anonymous namespace
00487 
00488 namespace llvm {
00489 
00490 bool DebugIR::getSourceInfo(const Module &M) {
00491   ParsedPath = getSourceInfoFromDI(M, Directory, Filename) ||
00492                getSourceInfoFromModule(M, Directory, Filename);
00493   return ParsedPath;
00494 }
00495 
00496 bool DebugIR::updateExtension(StringRef NewExtension) {
00497   size_t dot = Filename.find_last_of(".");
00498   if (dot == std::string::npos)
00499     return false;
00500 
00501   Filename.erase(dot);
00502   Filename += NewExtension.str();
00503   return true;
00504 }
00505 
00506 void DebugIR::generateFilename(std::unique_ptr<int> &fd) {
00507   SmallVector<char, 16> PathVec;
00508   fd.reset(new int);
00509   sys::fs::createTemporaryFile("debug-ir", "ll", *fd, PathVec);
00510   StringRef Path(PathVec.data(), PathVec.size());
00511   Filename = sys::path::filename(Path);
00512   sys::path::remove_filename(PathVec);
00513   Directory = StringRef(PathVec.data(), PathVec.size());
00514 
00515   GeneratedPath = true;
00516 }
00517 
00518 std::string DebugIR::getPath() {
00519   SmallVector<char, 16> Path;
00520   sys::path::append(Path, Directory, Filename);
00521   Path.resize(Filename.size() + Directory.size() + 2);
00522   Path[Filename.size() + Directory.size() + 1] = '\0';
00523   return std::string(Path.data());
00524 }
00525 
00526 void DebugIR::writeDebugBitcode(const Module *M, int *fd) {
00527   std::unique_ptr<raw_fd_ostream> Out;
00528   std::error_code EC;
00529 
00530   if (!fd) {
00531     std::string Path = getPath();
00532     Out.reset(new raw_fd_ostream(Path, EC, sys::fs::F_Text));
00533     DEBUG(dbgs() << "WRITING debug bitcode from Module " << M << " to file "
00534                  << Path << "\n");
00535   } else {
00536     DEBUG(dbgs() << "WRITING debug bitcode from Module " << M << " to fd "
00537                  << *fd << "\n");
00538     Out.reset(new raw_fd_ostream(*fd, true));
00539   }
00540 
00541   M->print(*Out, nullptr);
00542   Out->close();
00543 }
00544 
00545 void DebugIR::createDebugInfo(Module &M, std::unique_ptr<Module> &DisplayM) {
00546   if (M.getFunctionList().size() == 0)
00547     // no functions -- no debug info needed
00548     return;
00549 
00550   std::unique_ptr<ValueToValueMapTy> VMap;
00551 
00552   if (WriteSourceToDisk && (HideDebugIntrinsics || HideDebugMetadata)) {
00553     VMap.reset(new ValueToValueMapTy);
00554     DisplayM.reset(CloneModule(&M, *VMap));
00555 
00556     if (HideDebugIntrinsics)
00557       DebugIntrinsicsRemover::process(*DisplayM);
00558 
00559     if (HideDebugMetadata)
00560       DebugMetadataRemover::process(*DisplayM);
00561   }
00562 
00563   DIUpdater R(M, Filename, Directory, DisplayM.get(), VMap.get());
00564 }
00565 
00566 bool DebugIR::isMissingPath() { return Filename.empty() || Directory.empty(); }
00567 
00568 bool DebugIR::runOnModule(Module &M) {
00569   std::unique_ptr<int> fd;
00570 
00571   if (isMissingPath() && !getSourceInfo(M)) {
00572     if (!WriteSourceToDisk)
00573       report_fatal_error("DebugIR unable to determine file name in input. "
00574                          "Ensure Module contains an identifier, a valid "
00575                          "DICompileUnit, or construct DebugIR with "
00576                          "non-empty Filename/Directory parameters.");
00577     else
00578       generateFilename(fd);
00579   }
00580 
00581   if (!GeneratedPath && WriteSourceToDisk)
00582     updateExtension(".debug-ll");
00583 
00584   // Clear line numbers. Keep debug info (if any) if we were able to read the
00585   // file name from the DICompileUnit descriptor.
00586   DebugMetadataRemover::process(M, !ParsedPath);
00587 
00588   std::unique_ptr<Module> DisplayM;
00589   createDebugInfo(M, DisplayM);
00590   if (WriteSourceToDisk) {
00591     Module *OutputM = DisplayM.get() ? DisplayM.get() : &M;
00592     writeDebugBitcode(OutputM, fd.get());
00593   }
00594 
00595   DEBUG(M.dump());
00596   return true;
00597 }
00598 
00599 bool DebugIR::runOnModule(Module &M, std::string &Path) {
00600   bool result = runOnModule(M);
00601   Path = getPath();
00602   return result;
00603 }
00604 
00605 } // llvm namespace
00606 
00607 char DebugIR::ID = 0;
00608 INITIALIZE_PASS(DebugIR, "debug-ir", "Enable debugging IR", false, false)
00609 
00610 ModulePass *llvm::createDebugIRPass(bool HideDebugIntrinsics,
00611                                     bool HideDebugMetadata, StringRef Directory,
00612                                     StringRef Filename) {
00613   return new DebugIR(HideDebugIntrinsics, HideDebugMetadata, Directory,
00614                      Filename);
00615 }
00616 
00617 ModulePass *llvm::createDebugIRPass() { return new DebugIR(); }