From 9416f9c57dcee94886561b8501d33fcb4a0fcc5e Mon Sep 17 00:00:00 2001 From: "Duncan P. N. Exon Smith" Date: Sat, 29 Nov 2014 03:15:47 +0000 Subject: [PATCH] DebugIR: Delete -debug-ir git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222945 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/InitializePasses.h | 1 - include/llvm/Transforms/Instrumentation.h | 31 - lib/Transforms/Instrumentation/CMakeLists.txt | 1 - lib/Transforms/Instrumentation/DebugIR.cpp | 617 ------------------ lib/Transforms/Instrumentation/DebugIR.h | 98 --- test/Transforms/DebugIR/crash.ll | 42 -- test/Transforms/DebugIR/exception.ll | 127 ---- test/Transforms/DebugIR/function.ll | 51 -- test/Transforms/DebugIR/simple-addrspace.ll | 11 - test/Transforms/DebugIR/simple.ll | 25 - test/Transforms/DebugIR/struct.ll | 24 - test/Transforms/DebugIR/vector.ll | 93 --- tools/lli/lli.cpp | 9 - tools/opt/opt.cpp | 1 - unittests/Transforms/CMakeLists.txt | 1 - unittests/Transforms/DebugIR/CMakeLists.txt | 9 - unittests/Transforms/DebugIR/DebugIR.cpp | 308 --------- unittests/Transforms/DebugIR/Makefile | 15 - unittests/Transforms/Makefile | 2 +- 19 files changed, 1 insertion(+), 1465 deletions(-) delete mode 100644 lib/Transforms/Instrumentation/DebugIR.cpp delete mode 100644 lib/Transforms/Instrumentation/DebugIR.h delete mode 100644 test/Transforms/DebugIR/crash.ll delete mode 100644 test/Transforms/DebugIR/exception.ll delete mode 100644 test/Transforms/DebugIR/function.ll delete mode 100644 test/Transforms/DebugIR/simple-addrspace.ll delete mode 100644 test/Transforms/DebugIR/simple.ll delete mode 100644 test/Transforms/DebugIR/struct.ll delete mode 100644 test/Transforms/DebugIR/vector.ll delete mode 100644 unittests/Transforms/DebugIR/CMakeLists.txt delete mode 100644 unittests/Transforms/DebugIR/DebugIR.cpp delete mode 100644 unittests/Transforms/DebugIR/Makefile diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index 686ff7b701a..edce794c286 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -106,7 +106,6 @@ void initializeDAEPass(PassRegistry&); void initializeDAHPass(PassRegistry&); void initializeDCEPass(PassRegistry&); void initializeDSEPass(PassRegistry&); -void initializeDebugIRPass(PassRegistry&); void initializeDebugInfoVerifierLegacyPassPass(PassRegistry &); void initializeDeadInstEliminationPass(PassRegistry&); void initializeDeadMachineInstructionElimPass(PassRegistry&); diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h index 87422dfb176..4737cb3b0be 100644 --- a/include/llvm/Transforms/Instrumentation.h +++ b/include/llvm/Transforms/Instrumentation.h @@ -93,37 +93,6 @@ inline ModulePass *createDataFlowSanitizerPassForJIT(StringRef ABIListFile = // checking on loads, stores, and other memory intrinsics. FunctionPass *createBoundsCheckingPass(); -/// createDebugIRPass - Enable interactive stepping through LLVM IR in LLDB (or -/// GDB) and generate a file with the LLVM IR to be -/// displayed in the debugger. -/// -/// Existing debug metadata is preserved (but may be modified) in order to allow -/// accessing variables in the original source. The line table and file -/// information is modified to correspond to the lines in the LLVM IR. If -/// Filename and Directory are empty, a file name is generated based on existing -/// debug information. If no debug information is available, a temporary file -/// name is generated. -/// -/// @param HideDebugIntrinsics Omit debug intrinsics in emitted IR source file. -/// @param HideDebugMetadata Omit debug metadata in emitted IR source file. -/// @param Directory Embed this directory in the debug information. -/// @param Filename Embed this file name in the debug information. -ModulePass *createDebugIRPass(bool HideDebugIntrinsics, - bool HideDebugMetadata, - StringRef Directory = StringRef(), - StringRef Filename = StringRef()); - -/// createDebugIRPass - Enable interactive stepping through LLVM IR in LLDB -/// (or GDB) with an existing IR file on disk. When creating -/// a DebugIR pass with this function, no source file is -/// output to disk and the existing one is unmodified. Debug -/// metadata in the Module is created/updated to point to -/// the existing textual IR file on disk. -/// NOTE: If the IR file to be debugged is not on disk, use the version of this -/// function with parameters in order to generate the file that will be -/// seen by the debugger. -ModulePass *createDebugIRPass(); - } // End llvm namespace #endif diff --git a/lib/Transforms/Instrumentation/CMakeLists.txt b/lib/Transforms/Instrumentation/CMakeLists.txt index 139e51413d6..a6a3106041f 100644 --- a/lib/Transforms/Instrumentation/CMakeLists.txt +++ b/lib/Transforms/Instrumentation/CMakeLists.txt @@ -2,7 +2,6 @@ add_llvm_library(LLVMInstrumentation AddressSanitizer.cpp BoundsChecking.cpp DataFlowSanitizer.cpp - DebugIR.cpp GCOVProfiling.cpp MemorySanitizer.cpp Instrumentation.cpp diff --git a/lib/Transforms/Instrumentation/DebugIR.cpp b/lib/Transforms/Instrumentation/DebugIR.cpp deleted file mode 100644 index 5234341b32e..00000000000 --- a/lib/Transforms/Instrumentation/DebugIR.cpp +++ /dev/null @@ -1,617 +0,0 @@ -//===--- DebugIR.cpp - Transform debug metadata to allow debugging IR -----===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// A Module transform pass that emits a succinct version of the IR and replaces -// the source file metadata to allow debuggers to step through the IR. -// -// FIXME: instead of replacing debug metadata, this pass should allow for -// additional metadata to be used to point capable debuggers to the IR file -// without destroying the mapping to the original source file. -// -//===----------------------------------------------------------------------===// - -#include "llvm/IR/ValueMap.h" -#include "DebugIR.h" -#include "llvm/IR/AssemblyAnnotationWriter.h" -#include "llvm/IR/DIBuilder.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/IR/DebugInfo.h" -#include "llvm/IR/InstVisitor.h" -#include "llvm/IR/Instruction.h" -#include "llvm/IR/LLVMContext.h" -#include "llvm/IR/Module.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/FormattedStream.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/ToolOutputFile.h" -#include "llvm/Transforms/Instrumentation.h" -#include "llvm/Transforms/Utils/Cloning.h" -#include - -#define STR_HELPER(x) #x -#define STR(x) STR_HELPER(x) - -using namespace llvm; - -#define DEBUG_TYPE "debug-ir" - -namespace { - -/// Builds a map of Value* to line numbers on which the Value appears in a -/// textual representation of the IR by plugging into the AssemblyWriter by -/// masquerading as an AssemblyAnnotationWriter. -class ValueToLineMap : public AssemblyAnnotationWriter { - ValueMap Lines; - typedef ValueMap::const_iterator LineIter; - - void addEntry(const Value *V, formatted_raw_ostream &Out) { - Out.flush(); - Lines.insert(std::make_pair(V, Out.getLine() + 1)); - } - -public: - - /// Prints Module to a null buffer in order to build the map of Value pointers - /// to line numbers. - ValueToLineMap(const Module *M) { - raw_null_ostream ThrowAway; - M->print(ThrowAway, this); - } - - // This function is called after an Instruction, GlobalValue, or GlobalAlias - // is printed. - void printInfoComment(const Value &V, formatted_raw_ostream &Out) override { - addEntry(&V, Out); - } - - void emitFunctionAnnot(const Function *F, - formatted_raw_ostream &Out) override { - addEntry(F, Out); - } - - /// If V appears on a line in the textual IR representation, sets Line to the - /// line number and returns true, otherwise returns false. - bool getLine(const Value *V, unsigned int &Line) const { - LineIter i = Lines.find(V); - if (i != Lines.end()) { - Line = i->second; - return true; - } - return false; - } -}; - -/// Removes debug intrisncs like llvm.dbg.declare and llvm.dbg.value. -class DebugIntrinsicsRemover : public InstVisitor { - void remove(Instruction &I) { I.eraseFromParent(); } - -public: - static void process(Module &M) { - DebugIntrinsicsRemover Remover; - Remover.visit(&M); - } - void visitDbgDeclareInst(DbgDeclareInst &I) { remove(I); } - void visitDbgValueInst(DbgValueInst &I) { remove(I); } - void visitDbgInfoIntrinsic(DbgInfoIntrinsic &I) { remove(I); } -}; - -/// Removes debug metadata (!dbg) nodes from all instructions, and optionally -/// metadata named "llvm.dbg.cu" if RemoveNamedInfo is true. -class DebugMetadataRemover : public InstVisitor { - bool RemoveNamedInfo; - -public: - static void process(Module &M, bool RemoveNamedInfo = true) { - DebugMetadataRemover Remover(RemoveNamedInfo); - Remover.run(&M); - } - - DebugMetadataRemover(bool RemoveNamedInfo) - : RemoveNamedInfo(RemoveNamedInfo) {} - - void visitInstruction(Instruction &I) { - if (I.getMetadata(LLVMContext::MD_dbg)) - I.setMetadata(LLVMContext::MD_dbg, nullptr); - } - - void run(Module *M) { - // Remove debug metadata attached to instructions - visit(M); - - if (RemoveNamedInfo) { - // Remove CU named metadata (and all children nodes) - NamedMDNode *Node = M->getNamedMetadata("llvm.dbg.cu"); - if (Node) - M->eraseNamedMetadata(Node); - } - } -}; - -/// Updates debug metadata in a Module: -/// - changes Filename/Directory to values provided on construction -/// - adds/updates line number (DebugLoc) entries associated with each -/// instruction to reflect the instruction's location in an LLVM IR file -class DIUpdater : public InstVisitor { - /// Builder of debug information - DIBuilder Builder; - - /// Helper for type attributes/sizes/etc - DataLayout Layout; - - /// Map of Value* to line numbers - const ValueToLineMap LineTable; - - /// Map of Value* (in original Module) to Value* (in optional cloned Module) - const ValueToValueMapTy *VMap; - - /// Directory of debug metadata - DebugInfoFinder Finder; - - /// Source filename and directory - StringRef Filename; - StringRef Directory; - - // CU nodes needed when creating DI subprograms - MDNode *FileNode; - MDNode *LexicalBlockFileNode; - const MDNode *CUNode; - - ValueMap SubprogramDescriptors; - DenseMap TypeDescriptors; - -public: - DIUpdater(Module &M, StringRef Filename = StringRef(), - StringRef Directory = StringRef(), const Module *DisplayM = nullptr, - const ValueToValueMapTy *VMap = nullptr) - : Builder(M), Layout(&M), LineTable(DisplayM ? DisplayM : &M), VMap(VMap), - Finder(), Filename(Filename), Directory(Directory), FileNode(nullptr), - LexicalBlockFileNode(nullptr), CUNode(nullptr) { - Finder.processModule(M); - visit(&M); - } - - ~DIUpdater() { Builder.finalize(); } - - void visitModule(Module &M) { - if (Finder.compile_unit_count() > 1) - report_fatal_error("DebugIR pass supports only a signle compile unit per " - "Module."); - createCompileUnit(Finder.compile_unit_count() == 1 ? - (MDNode*)*Finder.compile_units().begin() : nullptr); - } - - void visitFunction(Function &F) { - if (F.isDeclaration() || findDISubprogram(&F)) - return; - - StringRef MangledName = F.getName(); - DICompositeType Sig = createFunctionSignature(&F); - - // find line of function declaration - unsigned Line = 0; - if (!findLine(&F, Line)) { - DEBUG(dbgs() << "WARNING: No line for Function " << F.getName().str() - << "\n"); - return; - } - - Instruction *FirstInst = F.begin()->begin(); - unsigned ScopeLine = 0; - if (!findLine(FirstInst, ScopeLine)) { - DEBUG(dbgs() << "WARNING: No line for 1st Instruction in Function " - << F.getName().str() << "\n"); - return; - } - - bool Local = F.hasInternalLinkage(); - bool IsDefinition = !F.isDeclaration(); - bool IsOptimized = false; - - int FuncFlags = llvm::DIDescriptor::FlagPrototyped; - assert(CUNode && FileNode); - DISubprogram Sub = Builder.createFunction( - DICompileUnit(CUNode), F.getName(), MangledName, DIFile(FileNode), Line, - Sig, Local, IsDefinition, ScopeLine, FuncFlags, IsOptimized, &F); - assert(Sub.isSubprogram()); - DEBUG(dbgs() << "create subprogram mdnode " << *Sub << ": " - << "\n"); - - SubprogramDescriptors.insert(std::make_pair(&F, Sub)); - } - - void visitInstruction(Instruction &I) { - DebugLoc Loc(I.getDebugLoc()); - - /// If a ValueToValueMap is provided, use it to get the real instruction as - /// the line table was generated on a clone of the module on which we are - /// operating. - Value *RealInst = nullptr; - if (VMap) - RealInst = VMap->lookup(&I); - - if (!RealInst) - RealInst = &I; - - unsigned Col = 0; // FIXME: support columns - unsigned Line; - if (!LineTable.getLine(RealInst, Line)) { - // Instruction has no line, it may have been removed (in the module that - // will be passed to the debugger) so there is nothing to do here. - DEBUG(dbgs() << "WARNING: no LineTable entry for instruction " << RealInst - << "\n"); - DEBUG(RealInst->dump()); - return; - } - - DebugLoc NewLoc; - if (!Loc.isUnknown()) - // I had a previous debug location: re-use the DebugLoc - NewLoc = DebugLoc::get(Line, Col, Loc.getScope(RealInst->getContext()), - Loc.getInlinedAt(RealInst->getContext())); - else if (MDNode *scope = findScope(&I)) - NewLoc = DebugLoc::get(Line, Col, scope, nullptr); - else { - DEBUG(dbgs() << "WARNING: no valid scope for instruction " << &I - << ". no DebugLoc will be present." - << "\n"); - return; - } - - addDebugLocation(I, NewLoc); - } - -private: - - void createCompileUnit(MDNode *CUToReplace) { - std::string Flags; - bool IsOptimized = false; - StringRef Producer; - unsigned RuntimeVersion(0); - StringRef SplitName; - - if (CUToReplace) { - // save fields from existing CU to re-use in the new CU - DICompileUnit ExistingCU(CUToReplace); - Producer = ExistingCU.getProducer(); - IsOptimized = ExistingCU.isOptimized(); - Flags = ExistingCU.getFlags(); - RuntimeVersion = ExistingCU.getRunTimeVersion(); - SplitName = ExistingCU.getSplitDebugFilename(); - } else { - Producer = - "LLVM Version " STR(LLVM_VERSION_MAJOR) "." STR(LLVM_VERSION_MINOR); - } - - CUNode = - Builder.createCompileUnit(dwarf::DW_LANG_C99, Filename, Directory, - Producer, IsOptimized, Flags, RuntimeVersion); - - if (CUToReplace) - CUToReplace->replaceAllUsesWith(const_cast(CUNode)); - - DICompileUnit CU(CUNode); - FileNode = Builder.createFile(Filename, Directory); - LexicalBlockFileNode = Builder.createLexicalBlockFile(CU, DIFile(FileNode)); - } - - /// Returns the MDNode* that represents the DI scope to associate with I - MDNode *findScope(const Instruction *I) { - const Function *F = I->getParent()->getParent(); - if (MDNode *ret = findDISubprogram(F)) - return ret; - - DEBUG(dbgs() << "WARNING: Using fallback lexical block file scope " - << LexicalBlockFileNode << " as scope for instruction " << I - << "\n"); - return LexicalBlockFileNode; - } - - /// Returns the MDNode* that is the descriptor for F - MDNode *findDISubprogram(const Function *F) { - typedef ValueMap::const_iterator FuncNodeIter; - FuncNodeIter i = SubprogramDescriptors.find(F); - if (i != SubprogramDescriptors.end()) - return i->second; - - DEBUG(dbgs() << "searching for DI scope node for Function " << F - << " in a list of " << Finder.subprogram_count() - << " subprogram nodes" - << "\n"); - - for (DISubprogram S : Finder.subprograms()) { - if (S.getFunction() == F) { - DEBUG(dbgs() << "Found DISubprogram " << S << " for function " - << S.getFunction() << "\n"); - return S; - } - } - DEBUG(dbgs() << "unable to find DISubprogram node for function " - << F->getName().str() << "\n"); - return nullptr; - } - - /// Sets Line to the line number on which V appears and returns true. If a - /// line location for V is not found, returns false. - bool findLine(const Value *V, unsigned &Line) { - if (LineTable.getLine(V, Line)) - return true; - - if (VMap) { - Value *mapped = VMap->lookup(V); - if (mapped && LineTable.getLine(mapped, Line)) - return true; - } - return false; - } - - std::string getTypeName(Type *T) { - std::string TypeName; - raw_string_ostream TypeStream(TypeName); - if (T) - T->print(TypeStream); - else - TypeStream << "Printing Type"; - TypeStream.flush(); - return TypeName; - } - - /// Returns the MDNode that represents type T if it is already created, or 0 - /// if it is not. - MDNode *getType(const Type *T) { - typedef DenseMap::const_iterator TypeNodeIter; - TypeNodeIter i = TypeDescriptors.find(T); - if (i != TypeDescriptors.end()) - return i->second; - return nullptr; - } - - /// Returns a DebugInfo type from an LLVM type T. - DIDerivedType getOrCreateType(Type *T) { - MDNode *N = getType(T); - if (N) - return DIDerivedType(N); - else if (T->isVoidTy()) - return DIDerivedType(nullptr); - else if (T->isStructTy()) { - N = Builder.createStructType( - DIScope(LexicalBlockFileNode), T->getStructName(), DIFile(FileNode), - 0, Layout.getTypeSizeInBits(T), Layout.getABITypeAlignment(T), 0, - DIType(nullptr), DIArray(nullptr)); // filled in later - - // N is added to the map (early) so that element search below can find it, - // so as to avoid infinite recursion for structs that contain pointers to - // their own type. - TypeDescriptors[T] = N; - DICompositeType StructDescriptor(N); - - SmallVector Elements; - for (unsigned i = 0; i < T->getStructNumElements(); ++i) - Elements.push_back(getOrCreateType(T->getStructElementType(i))); - - // set struct elements - StructDescriptor.setArrays(Builder.getOrCreateArray(Elements)); - } else if (T->isPointerTy()) { - Type *PointeeTy = T->getPointerElementType(); - if (!(N = getType(PointeeTy))) - N = Builder.createPointerType( - getOrCreateType(PointeeTy), Layout.getPointerTypeSizeInBits(T), - Layout.getPrefTypeAlignment(T), getTypeName(T)); - } else if (T->isArrayTy()) { - SmallVector Subrange; - Subrange.push_back( - Builder.getOrCreateSubrange(0, T->getArrayNumElements() - 1)); - - N = Builder.createArrayType(Layout.getTypeSizeInBits(T), - Layout.getPrefTypeAlignment(T), - getOrCreateType(T->getArrayElementType()), - Builder.getOrCreateArray(Subrange)); - } else { - int encoding = llvm::dwarf::DW_ATE_signed; - if (T->isIntegerTy()) - encoding = llvm::dwarf::DW_ATE_unsigned; - else if (T->isFloatingPointTy()) - encoding = llvm::dwarf::DW_ATE_float; - - N = Builder.createBasicType(getTypeName(T), T->getPrimitiveSizeInBits(), - 0, encoding); - } - TypeDescriptors[T] = N; - return DIDerivedType(N); - } - - /// Returns a DebugInfo type that represents a function signature for Func. - DICompositeType createFunctionSignature(const Function *Func) { - SmallVector Params; - DIDerivedType ReturnType(getOrCreateType(Func->getReturnType())); - Params.push_back(ReturnType); - - const Function::ArgumentListType &Args(Func->getArgumentList()); - for (Function::ArgumentListType::const_iterator i = Args.begin(), - e = Args.end(); - i != e; ++i) { - Type *T(i->getType()); - Params.push_back(getOrCreateType(T)); - } - - DITypeArray ParamArray = Builder.getOrCreateTypeArray(Params); - return Builder.createSubroutineType(DIFile(FileNode), ParamArray); - } - - /// Associates Instruction I with debug location Loc. - void addDebugLocation(Instruction &I, DebugLoc Loc) { - MDNode *MD = Loc.getAsMDNode(I.getContext()); - I.setMetadata(LLVMContext::MD_dbg, MD); - } -}; - -/// Sets Filename/Directory from the Module identifier and returns true, or -/// false if source information is not present. -bool getSourceInfoFromModule(const Module &M, std::string &Directory, - std::string &Filename) { - std::string PathStr(M.getModuleIdentifier()); - if (PathStr.length() == 0 || PathStr == "") - return false; - - Filename = sys::path::filename(PathStr); - SmallVector Path(PathStr.begin(), PathStr.end()); - sys::path::remove_filename(Path); - Directory = StringRef(Path.data(), Path.size()); - return true; -} - -// Sets Filename/Directory from debug information in M and returns true, or -// false if no debug information available, or cannot be parsed. -bool getSourceInfoFromDI(const Module &M, std::string &Directory, - std::string &Filename) { - NamedMDNode *CUNode = M.getNamedMetadata("llvm.dbg.cu"); - if (!CUNode || CUNode->getNumOperands() == 0) - return false; - - DICompileUnit CU(CUNode->getOperand(0)); - if (!CU.Verify()) - return false; - - Filename = CU.getFilename(); - Directory = CU.getDirectory(); - return true; -} - -} // anonymous namespace - -namespace llvm { - -bool DebugIR::getSourceInfo(const Module &M) { - ParsedPath = getSourceInfoFromDI(M, Directory, Filename) || - getSourceInfoFromModule(M, Directory, Filename); - return ParsedPath; -} - -bool DebugIR::updateExtension(StringRef NewExtension) { - size_t dot = Filename.find_last_of("."); - if (dot == std::string::npos) - return false; - - Filename.erase(dot); - Filename += NewExtension.str(); - return true; -} - -void DebugIR::generateFilename(std::unique_ptr &fd) { - SmallVector PathVec; - fd.reset(new int); - sys::fs::createTemporaryFile("debug-ir", "ll", *fd, PathVec); - StringRef Path(PathVec.data(), PathVec.size()); - Filename = sys::path::filename(Path); - sys::path::remove_filename(PathVec); - Directory = StringRef(PathVec.data(), PathVec.size()); - - GeneratedPath = true; -} - -std::string DebugIR::getPath() { - SmallVector Path; - sys::path::append(Path, Directory, Filename); - Path.resize(Filename.size() + Directory.size() + 2); - Path[Filename.size() + Directory.size() + 1] = '\0'; - return std::string(Path.data()); -} - -void DebugIR::writeDebugBitcode(const Module *M, int *fd) { - std::unique_ptr Out; - std::error_code EC; - - if (!fd) { - std::string Path = getPath(); - Out.reset(new raw_fd_ostream(Path, EC, sys::fs::F_Text)); - DEBUG(dbgs() << "WRITING debug bitcode from Module " << M << " to file " - << Path << "\n"); - } else { - DEBUG(dbgs() << "WRITING debug bitcode from Module " << M << " to fd " - << *fd << "\n"); - Out.reset(new raw_fd_ostream(*fd, true)); - } - - M->print(*Out, nullptr); - Out->close(); -} - -void DebugIR::createDebugInfo(Module &M, std::unique_ptr &DisplayM) { - if (M.getFunctionList().size() == 0) - // no functions -- no debug info needed - return; - - std::unique_ptr VMap; - - if (WriteSourceToDisk && (HideDebugIntrinsics || HideDebugMetadata)) { - VMap.reset(new ValueToValueMapTy); - DisplayM.reset(CloneModule(&M, *VMap)); - - if (HideDebugIntrinsics) - DebugIntrinsicsRemover::process(*DisplayM); - - if (HideDebugMetadata) - DebugMetadataRemover::process(*DisplayM); - } - - DIUpdater R(M, Filename, Directory, DisplayM.get(), VMap.get()); -} - -bool DebugIR::isMissingPath() { return Filename.empty() || Directory.empty(); } - -bool DebugIR::runOnModule(Module &M) { - std::unique_ptr fd; - - if (isMissingPath() && !getSourceInfo(M)) { - if (!WriteSourceToDisk) - report_fatal_error("DebugIR unable to determine file name in input. " - "Ensure Module contains an identifier, a valid " - "DICompileUnit, or construct DebugIR with " - "non-empty Filename/Directory parameters."); - else - generateFilename(fd); - } - - if (!GeneratedPath && WriteSourceToDisk) - updateExtension(".debug-ll"); - - // Clear line numbers. Keep debug info (if any) if we were able to read the - // file name from the DICompileUnit descriptor. - DebugMetadataRemover::process(M, !ParsedPath); - - std::unique_ptr DisplayM; - createDebugInfo(M, DisplayM); - if (WriteSourceToDisk) { - Module *OutputM = DisplayM.get() ? DisplayM.get() : &M; - writeDebugBitcode(OutputM, fd.get()); - } - - DEBUG(M.dump()); - return true; -} - -bool DebugIR::runOnModule(Module &M, std::string &Path) { - bool result = runOnModule(M); - Path = getPath(); - return result; -} - -} // llvm namespace - -char DebugIR::ID = 0; -INITIALIZE_PASS(DebugIR, "debug-ir", "Enable debugging IR", false, false) - -ModulePass *llvm::createDebugIRPass(bool HideDebugIntrinsics, - bool HideDebugMetadata, StringRef Directory, - StringRef Filename) { - return new DebugIR(HideDebugIntrinsics, HideDebugMetadata, Directory, - Filename); -} - -ModulePass *llvm::createDebugIRPass() { return new DebugIR(); } diff --git a/lib/Transforms/Instrumentation/DebugIR.h b/lib/Transforms/Instrumentation/DebugIR.h deleted file mode 100644 index 8d74a4ded11..00000000000 --- a/lib/Transforms/Instrumentation/DebugIR.h +++ /dev/null @@ -1,98 +0,0 @@ -//===- llvm/Transforms/Instrumentation/DebugIR.h - Interface ----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the interface of the DebugIR pass. For most users, -// including Instrumentation.h and calling createDebugIRPass() is sufficient and -// there is no need to include this file. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_TRANSFORMS_INSTRUMENTATION_DEBUGIR_H -#define LLVM_LIB_TRANSFORMS_INSTRUMENTATION_DEBUGIR_H - -#include "llvm/Pass.h" - -namespace llvm { - -class DebugIR : public llvm::ModulePass { - /// If true, write a source file to disk. - bool WriteSourceToDisk; - - /// Hide certain (non-essential) debug information (only relevant if - /// createSource is true. - bool HideDebugIntrinsics; - bool HideDebugMetadata; - - /// The location of the source file. - std::string Directory; - std::string Filename; - - /// True if a temporary file name was generated. - bool GeneratedPath; - - /// True if the file name was read from the Module. - bool ParsedPath; - -public: - static char ID; - - const char *getPassName() const override { return "DebugIR"; } - - /// Generate a file on disk to be displayed in a debugger. If Filename and - /// Directory are empty, a temporary path will be generated. - DebugIR(bool HideDebugIntrinsics, bool HideDebugMetadata, - llvm::StringRef Directory, llvm::StringRef Filename) - : ModulePass(ID), WriteSourceToDisk(true), - HideDebugIntrinsics(HideDebugIntrinsics), - HideDebugMetadata(HideDebugMetadata), Directory(Directory), - Filename(Filename), GeneratedPath(false), ParsedPath(false) {} - - /// Modify input in-place; do not generate additional files, and do not hide - /// any debug intrinsics/metadata that might be present. - DebugIR() - : ModulePass(ID), WriteSourceToDisk(false), HideDebugIntrinsics(false), - HideDebugMetadata(false), GeneratedPath(false), ParsedPath(false) {} - - /// Run pass on M and set Path to the source file path in the output module. - bool runOnModule(llvm::Module &M, std::string &Path); - bool runOnModule(llvm::Module &M) override; - -private: - - /// Returns the concatenated Directory + Filename, without error checking - std::string getPath(); - - /// Attempts to read source information from debug information in M, and if - /// that fails, from M's identifier. Returns true on success, false otherwise. - bool getSourceInfo(const llvm::Module &M); - - /// Replace the extension of Filename with NewExtension, and return true if - /// successful. Return false if extension could not be found or Filename is - /// empty. - bool updateExtension(llvm::StringRef NewExtension); - - /// Generate a temporary filename and open an fd - void generateFilename(std::unique_ptr &fd); - - /// Creates DWARF CU/Subroutine metadata - void createDebugInfo(llvm::Module &M, - std::unique_ptr &DisplayM); - - /// Returns true if either Directory or Filename is missing, false otherwise. - bool isMissingPath(); - - /// Write M to disk, optionally passing in an fd to an open file which is - /// closed by this function after writing. If no fd is specified, a new file - /// is opened, written, and closed. - void writeDebugBitcode(const llvm::Module *M, int *fd = nullptr); -}; - -} // llvm namespace - -#endif diff --git a/test/Transforms/DebugIR/crash.ll b/test/Transforms/DebugIR/crash.ll deleted file mode 100644 index f4a88d7234c..00000000000 --- a/test/Transforms/DebugIR/crash.ll +++ /dev/null @@ -1,42 +0,0 @@ -; ModuleID = 'crash.c' -target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" -target triple = "x86_64-pc-linux-gnu" - -@.str = private unnamed_addr constant [18 x i8] c"Hello, segfault!\0A\00", align 1 -@.str1 = private unnamed_addr constant [14 x i8] c"Now crash %d\0A\00", align 1 - -; Function Attrs: nounwind uwtable -define i32 @main(i32 %argc, i8** %argv) #0 { - %1 = alloca i32, align 4 ;CHECK: !dbg - %2 = alloca i32, align 4 ;CHECK-NEXT: !dbg - %3 = alloca i8**, align 8 ;CHECK-NEXT: !dbg - %null_ptr = alloca i32*, align 8 ;CHECK-NEXT: !dbg - store i32 0, i32* %1 ;CHECK-NEXT: !dbg - store i32 %argc, i32* %2, align 4 ;CHECK-NEXT: !dbg - store i8** %argv, i8*** %3, align 8 ;CHECK-NEXT: !dbg - store i32* null, i32** %null_ptr, align 8 ;CHECK-NEXT: !dbg - %4 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([18 x i8]* @.str, i32 0, i32 0)) ;CHECK-NEXT: !dbg - %5 = load i32** %null_ptr, align 8 ;CHECK-NEXT: !dbg - %6 = load i32* %5, align 4 ;CHECK-NEXT: !dbg - %7 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([14 x i8]* @.str1, i32 0, i32 0), i32 %6) ;CHECK-NEXT: !dbg - %8 = load i32* %2, align 4 ;CHECK-NEXT: !dbg - ret i32 %8 ;CHECK-NEXT: !dbg -} - -declare i32 @printf(i8*, ...) #1 - -attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } -attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } - -; CHECK: = metadata !{i32 14, -; CHECK-NEXT: = metadata !{i32 15, -; CHECK-NEXT: = metadata !{i32 16, -; CHECK-NEXT: = metadata !{i32 17, -; CHECK-NEXT: = metadata !{i32 18, -; CHECK-NEXT: = metadata !{i32 19, -; CHECK-NEXT: = metadata !{i32 20, -; CHECK-NEXT: = metadata !{i32 21, -; CHECK-NEXT: = metadata !{i32 22, -; CHECK-NEXT: = metadata !{i32 23, - -; RUN: opt %s -debug-ir -S | FileCheck %s diff --git a/test/Transforms/DebugIR/exception.ll b/test/Transforms/DebugIR/exception.ll deleted file mode 100644 index 2436d38968c..00000000000 --- a/test/Transforms/DebugIR/exception.ll +++ /dev/null @@ -1,127 +0,0 @@ -; ModuleID = 'exception.cpp' -target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" -target triple = "x86_64-pc-linux-gnu" - -@_ZTIi = external constant i8* - -; Function Attrs: uwtable -define i32 @main(i32 %argc, i8** %argv) #0 { - %1 = alloca i32, align 4 ; CHECK: !dbg - %2 = alloca i32, align 4 ; CHECK-NEXT: !dbg - %3 = alloca i8**, align 8 ; CHECK-NEXT: !dbg - %4 = alloca i8* ; CHECK-NEXT: !dbg - %5 = alloca i32 ; CHECK-NEXT: !dbg - %e = alloca i32, align 4 ; CHECK-NEXT: !dbg - %6 = alloca i32 ; CHECK-NEXT: !dbg - store i32 0, i32* %1 ; CHECK-NEXT: !dbg - store i32 %argc, i32* %2, align 4 ; CHECK-NEXT: !dbg - store i8** %argv, i8*** %3, align 8 ; CHECK-NEXT: !dbg - %7 = call i8* @__cxa_allocate_exception(i64 4) #2 ; CHECK-NEXT: !dbg - %8 = bitcast i8* %7 to i32* ; CHECK-NEXT: !dbg - %9 = load i32* %2, align 4 ; CHECK-NEXT: !dbg - store i32 %9, i32* %8 ; CHECK-NEXT: !dbg - invoke void @__cxa_throw(i8* %7, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #3 - to label %31 unwind label %10 ; CHECK: !dbg - -;