diff options
-rw-r--r-- | llvm/include/llvm/InitializePasses.h | 1 | ||||
-rw-r--r-- | llvm/include/llvm/Transforms/Instrumentation.h | 31 | ||||
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/CMakeLists.txt | 1 | ||||
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/DebugIR.cpp | 617 | ||||
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/DebugIR.h | 98 | ||||
-rw-r--r-- | llvm/test/Transforms/DebugIR/crash.ll | 42 | ||||
-rw-r--r-- | llvm/test/Transforms/DebugIR/exception.ll | 127 | ||||
-rw-r--r-- | llvm/test/Transforms/DebugIR/function.ll | 51 | ||||
-rw-r--r-- | llvm/test/Transforms/DebugIR/simple-addrspace.ll | 11 | ||||
-rw-r--r-- | llvm/test/Transforms/DebugIR/simple.ll | 25 | ||||
-rw-r--r-- | llvm/test/Transforms/DebugIR/struct.ll | 24 | ||||
-rw-r--r-- | llvm/test/Transforms/DebugIR/vector.ll | 93 | ||||
-rw-r--r-- | llvm/tools/lli/lli.cpp | 9 | ||||
-rw-r--r-- | llvm/tools/opt/opt.cpp | 1 | ||||
-rw-r--r-- | llvm/unittests/Transforms/CMakeLists.txt | 1 | ||||
-rw-r--r-- | llvm/unittests/Transforms/DebugIR/CMakeLists.txt | 9 | ||||
-rw-r--r-- | llvm/unittests/Transforms/DebugIR/DebugIR.cpp | 308 | ||||
-rw-r--r-- | llvm/unittests/Transforms/DebugIR/Makefile | 15 | ||||
-rw-r--r-- | llvm/unittests/Transforms/Makefile | 2 |
19 files changed, 1 insertions, 1465 deletions
diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index 686ff7b701a..edce794c286 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/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/llvm/include/llvm/Transforms/Instrumentation.h b/llvm/include/llvm/Transforms/Instrumentation.h index 87422dfb176..4737cb3b0be 100644 --- a/llvm/include/llvm/Transforms/Instrumentation.h +++ b/llvm/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/llvm/lib/Transforms/Instrumentation/CMakeLists.txt b/llvm/lib/Transforms/Instrumentation/CMakeLists.txt index 139e51413d6..a6a3106041f 100644 --- a/llvm/lib/Transforms/Instrumentation/CMakeLists.txt +++ b/llvm/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/llvm/lib/Transforms/Instrumentation/DebugIR.cpp b/llvm/lib/Transforms/Instrumentation/DebugIR.cpp deleted file mode 100644 index 5234341b32e..00000000000 --- a/llvm/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 <string> - -#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<const Value *, unsigned int> Lines; - typedef ValueMap<const Value *, unsigned int>::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<DebugIntrinsicsRemover> { - 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<DebugMetadataRemover> { - 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<DIUpdater> { - /// 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<const Function *, MDNode *> SubprogramDescriptors; - DenseMap<const Type *, MDNode *> 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<MDNode *>(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 Function *, MDNode *>::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 <null> 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 Type *, MDNode *>::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<Value *, 4> 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<Value *, 1> 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<Value *, 4> 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 == "<stdin>") - return false; - - Filename = sys::path::filename(PathStr); - SmallVector<char, 16> 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<int> &fd) { - SmallVector<char, 16> 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<char, 16> 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<raw_fd_ostream> 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<Module> &DisplayM) { - if (M.getFunctionList().size() == 0) - // no functions -- no debug info needed - return; - - std::unique_ptr<ValueToValueMapTy> 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<int> 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<Module> 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/llvm/lib/Transforms/Instrumentation/DebugIR.h b/llvm/lib/Transforms/Instrumentation/DebugIR.h deleted file mode 100644 index 8d74a4ded11..00000000000 --- a/llvm/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<int> &fd); - - /// Creates DWARF CU/Subroutine metadata - void createDebugInfo(llvm::Module &M, - std::unique_ptr<llvm::Module> &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/llvm/test/Transforms/DebugIR/crash.ll b/llvm/test/Transforms/DebugIR/crash.ll deleted file mode 100644 index f4a88d7234c..00000000000 --- a/llvm/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/llvm/test/Transforms/DebugIR/exception.ll b/llvm/test/Transforms/DebugIR/exception.ll deleted file mode 100644 index 2436d38968c..00000000000 --- a/llvm/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 - -; <label>:10 ; preds = %0 - %11 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) - catch i8* bitcast (i8** @_ZTIi to i8*) ; CHECK: !dbg - %12 = extractvalue { i8*, i32 } %11, 0 ; CHECK-NEXT: !dbg - store i8* %12, i8** %4 ; CHECK-NEXT: !dbg - %13 = extractvalue { i8*, i32 } %11, 1 ; CHECK-NEXT: !dbg - store i32 %13, i32* %5 ; CHECK-NEXT: !dbg - br label %14 ; CHECK-NEXT: !dbg - -; <label>:14 ; preds = %10 - %15 = load i32* %5 ; CHECK: !dbg - %16 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) #2 ; CHECK-NEXT: !dbg - %17 = icmp eq i32 %15, %16 ; CHECK-NEXT: !dbg - br i1 %17, label %18, label %26 ; CHECK-NEXT: !dbg - -; <label>:18 ; preds = %14 - %19 = load i8** %4 ; CHECK: !dbg - %20 = call i8* @__cxa_begin_catch(i8* %19) #2 ; CHECK-NEXT: !dbg - %21 = bitcast i8* %20 to i32* ; CHECK-NEXT: !dbg - %22 = load i32* %21, align 4 ; CHECK-NEXT: !dbg - store i32 %22, i32* %e, align 4 ; CHECK-NEXT: !dbg - %23 = load i32* %e, align 4 ; CHECK-NEXT: !dbg - store i32 %23, i32* %1 ; CHECK-NEXT: !dbg - store i32 1, i32* %6 ; CHECK-NEXT: !dbg - call void @__cxa_end_catch() #2 ; CHECK-NEXT: !dbg - br label %24 ; CHECK-NEXT: !dbg - -; <label>:24 ; preds = %18 - %25 = load i32* %1 ; CHECK: !dbg - ret i32 %25 ; CHECK-NEXT: !dbg - -; <label>:26 ; preds = %14 - %27 = load i8** %4 ; CHECK: !dbg - %28 = load i32* %5 ; CHECK-NEXT: !dbg - %29 = insertvalue { i8*, i32 } undef, i8* %27, 0 ; CHECK-NEXT: !dbg - %30 = insertvalue { i8*, i32 } %29, i32 %28, 1 ; CHECK-NEXT: !dbg - resume { i8*, i32 } %30 ; CHECK-NEXT: !dbg - -; <label>:31 ; preds = %0 - unreachable ; CHECK: !dbg -} - -declare i8* @__cxa_allocate_exception(i64) - -declare void @__cxa_throw(i8*, i8*, i8*) - -declare i32 @__gxx_personality_v0(...) - -; Function Attrs: nounwind readnone -declare i32 @llvm.eh.typeid.for(i8*) #1 - -declare i8* @__cxa_begin_catch(i8*) - -declare void @__cxa_end_catch() - -attributes #0 = { 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 = { nounwind readnone } -attributes #2 = { nounwind } -attributes #3 = { noreturn } -; CHECK: = 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 24, - -; CHECK-NEXT: = metadata !{i32 28, -; CHECK-NEXT: = metadata !{i32 29, -; CHECK-NEXT: = metadata !{i32 30, -; CHECK-NEXT: = metadata !{i32 31, -; CHECK-NEXT: = metadata !{i32 32, -; CHECK-NEXT: = metadata !{i32 33, - -; CHECK-NEXT: = metadata !{i32 36, -; CHECK-NEXT: = metadata !{i32 37, -; CHECK-NEXT: = metadata !{i32 38, -; CHECK-NEXT: = metadata !{i32 39, - -; CHECK-NEXT: = metadata !{i32 42, -; CHECK-NEXT: = metadata !{i32 43, -; CHECK-NEXT: = metadata !{i32 44, -; CHECK-NEXT: = metadata !{i32 45, -; CHECK-NEXT: = metadata !{i32 46, -; CHECK-NEXT: = metadata !{i32 47, -; CHECK-NEXT: = metadata !{i32 48, -; CHECK-NEXT: = metadata !{i32 49, -; CHECK-NEXT: = metadata !{i32 50, -; CHECK-NEXT: = metadata !{i32 51, - -; CHECK-NEXT: = metadata !{i32 54, -; CHECK-NEXT: = metadata !{i32 55, - -; CHECK-NEXT: = metadata !{i32 58, -; CHECK-NEXT: = metadata !{i32 59, -; CHECK-NEXT: = metadata !{i32 60, -; CHECK-NEXT: = metadata !{i32 61, -; CHECK-NEXT: = metadata !{i32 62, -; CHECK-NEXT: = metadata !{i32 65, - -; RUN: opt %s -debug-ir -S | FileCheck %s diff --git a/llvm/test/Transforms/DebugIR/function.ll b/llvm/test/Transforms/DebugIR/function.ll deleted file mode 100644 index dba073de37e..00000000000 --- a/llvm/test/Transforms/DebugIR/function.ll +++ /dev/null @@ -1,51 +0,0 @@ -; ModuleID = 'function.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" - -; Function Attrs: nounwind uwtable -define void @blah(i32* %i) #0 { - %1 = alloca i32*, align 8 ; CHECK: !dbg - store i32* %i, i32** %1, align 8 ; CHECK-NEXT: !dbg - %2 = load i32** %1, align 8 ; CHECK-NEXT: !dbg - %3 = load i32* %2, align 4 ; CHECK-NEXT: !dbg - %4 = add nsw i32 %3, 1 ; CHECK-NEXT: !dbg - store i32 %4, i32* %2, align 4 ; CHECK-NEXT: !dbg - ret void ; CHECK-NEXT: !dbg -} - -; 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 - %i = alloca i32, align 4 ; 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 7, i32* %i, align 4 ; CHECK-NEXT: !dbg - call void @blah(i32* %i) ; CHECK-NEXT: !dbg - %4 = load i32* %i, align 4 ; CHECK-NEXT: !dbg - ret i32 %4 ; CHECK-NEXT: !dbg -} - -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" } -; CHECK: = metadata !{i32 8, -; CHECK-NEXT: = metadata !{i32 9, -; CHECK-NEXT: = metadata !{i32 10, -; CHECK-NEXT: = metadata !{i32 11, -; CHECK-NEXT: = metadata !{i32 12, -; CHECK-NEXT: = metadata !{i32 13, - -; 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, -; CHECK-NEXT: = metadata !{i32 24, -; CHECK-NEXT: = metadata !{i32 25, -; CHECK-NEXT: = metadata !{i32 26, -; CHECK-NEXT: = metadata !{i32 27, -; CHECK-NEXT: = metadata !{i32 28, - -; RUN: opt %s -debug-ir -S | FileCheck %s diff --git a/llvm/test/Transforms/DebugIR/simple-addrspace.ll b/llvm/test/Transforms/DebugIR/simple-addrspace.ll deleted file mode 100644 index 6539c8a51db..00000000000 --- a/llvm/test/Transforms/DebugIR/simple-addrspace.ll +++ /dev/null @@ -1,11 +0,0 @@ -; RUN: opt -debug-ir -S %s -o - | FileCheck %s - -target datalayout = "e-p:64:64:64-p1:16:16:16" - -define void @foo(i32 addrspace(1)*) nounwind { - ret void -} - -; Make sure the pointer size is 16 - -; CHECK: metadata !"0xf\00i32 addrspace(1)*\000\0016\002\000\000" diff --git a/llvm/test/Transforms/DebugIR/simple.ll b/llvm/test/Transforms/DebugIR/simple.ll deleted file mode 100644 index 3b188958261..00000000000 --- a/llvm/test/Transforms/DebugIR/simple.ll +++ /dev/null @@ -1,25 +0,0 @@ -; ModuleID = 'simple.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" - -; 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 - 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 - %4 = load i32* %2, align 4 ; CHECK-NEXT: !dbg - ret i32 %4 ; CHECK-NEXT: !dbg -} - -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" } - -; CHECK: = metadata !{i32 10, -; CHECK-NEXT: = metadata !{i32 11, -; CHECK-NEXT: = metadata !{i32 12, -; CHECK-NEXT: = metadata !{i32 13, -; CHECK-NEXT: = metadata !{i32 14, - -; RUN: opt %s -debug-ir -S | FileCheck %s diff --git a/llvm/test/Transforms/DebugIR/struct.ll b/llvm/test/Transforms/DebugIR/struct.ll deleted file mode 100644 index 8db3dbebe90..00000000000 --- a/llvm/test/Transforms/DebugIR/struct.ll +++ /dev/null @@ -1,24 +0,0 @@ -; ModuleID = 'struct.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" - -%struct.blah = type { i32, float, i8 } - -; Function Attrs: nounwind uwtable -define i32 @main() #0 { - %1 = alloca i32, align 4 ; CHECK: !dbg - %b = alloca %struct.blah, align 4 ; CHECK-NEXT: !dbg - store i32 0, i32* %1 ; CHECK-NEXT: !dbg - %2 = getelementptr inbounds %struct.blah* %b, i32 0, i32 0 ; CHECK-NEXT: !dbg - %3 = load i32* %2, align 4 ; CHECK-NEXT: !dbg - ret i32 %3 ; CHECK-NEXT: !dbg -} - -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" } - -; CHECK: = metadata !{i32 11, -; CHECK-NEXT: = metadata !{i32 12, -; CHECK-NEXT: = metadata !{i32 13, -; CHECK-NEXT: = metadata !{i32 14, - -; RUN: opt %s -debug-ir -S | FileCheck %s diff --git a/llvm/test/Transforms/DebugIR/vector.ll b/llvm/test/Transforms/DebugIR/vector.ll deleted file mode 100644 index 50d99ac2254..00000000000 --- a/llvm/test/Transforms/DebugIR/vector.ll +++ /dev/null @@ -1,93 +0,0 @@ -; ModuleID = 'vector.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" - -; Function Attrs: noinline nounwind uwtable -define <4 x float> @_Z3fooDv2_fS_(double %a.coerce, double %b.coerce) #0 { - %1 = alloca <2 x float>, align 8 ; CHECK: !dbg - %2 = alloca <2 x float>, align 8 ; CHECK-NEXT: !dbg - %3 = alloca <2 x float>, align 8 ; CHECK-NEXT: !dbg - %4 = alloca <2 x float>, align 8 ; CHECK-NEXT: !dbg - %c = alloca <4 x float>, align 16 ; CHECK-NEXT: !dbg - %5 = bitcast <2 x float>* %1 to double* ; CHECK-NEXT: !dbg - store double %a.coerce, double* %5, align 1 ; CHECK-NEXT: !dbg - %a = load <2 x float>* %1, align 8 ; CHECK-NEXT: !dbg - store <2 x float> %a, <2 x float>* %2, align 8 ; CHECK-NEXT: !dbg - %6 = bitcast <2 x float>* %3 to double* ; CHECK-NEXT: !dbg - store double %b.coerce, double* %6, align 1 ; CHECK-NEXT: !dbg - %b = load <2 x float>* %3, align 8 ; CHECK-NEXT: !dbg - store <2 x float> %b, <2 x float>* %4, align 8 ; CHECK-NEXT: !dbg - %7 = load <2 x float>* %2, align 8 ; CHECK-NEXT: !dbg - %8 = load <4 x float>* %c, align 16 ; CHECK-NEXT: !dbg - %9 = shufflevector <2 x float> %7, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef> ; CHECK-NEXT: !dbg - %10 = shufflevector <4 x float> %8, <4 x float> %9, <4 x i32> <i32 4, i32 1, i32 5, i32 3> ; CHECK-NEXT: !dbg - store <4 x float> %10, <4 x float>* %c, align 16 ; CHECK-NEXT: !dbg - %11 = load <2 x float>* %4, align 8 ; CHECK-NEXT: !dbg - %12 = load <4 x float>* %c, align 16 ; CHECK-NEXT: !dbg - %13 = shufflevector <2 x float> %11, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef> ; CHECK-NEXT: !dbg - %14 = shufflevector <4 x float> %12, <4 x float> %13, <4 x i32> <i32 0, i32 4, i32 2, i32 5> ; CHECK-NEXT: !dbg - store <4 x float> %14, <4 x float>* %c, align 16 ; CHECK-NEXT: !dbg - %15 = load <4 x float>* %c, align 16 ; CHECK-NEXT: !dbg - ret <4 x float> %15 ; CHECK-NEXT: !dbg -} - -; Function Attrs: nounwind uwtable -define i32 @main() #1 { - %1 = alloca i32, align 4 ; CHECK: !dbg - %a = alloca <2 x float>, align 8 ; CHECK-NEXT: !dbg - %b = alloca <2 x float>, align 8 ; CHECK-NEXT: !dbg - %x = alloca <4 x float>, align 16 ; CHECK-NEXT: !dbg - %2 = alloca <2 x float>, align 8 ; CHECK-NEXT: !dbg - %3 = alloca <2 x float>, align 8 ; CHECK-NEXT: !dbg - store i32 0, i32* %1 ; CHECK-NEXT: !dbg - store <2 x float> <float 1.000000e+00, float 2.000000e+00>, <2 x float>* %a, align 8 ; CHECK-NEXT: !dbg - store <2 x float> <float 1.000000e+00, float 2.000000e+00>, <2 x float>* %b, align 8 ; CHECK-NEXT: !dbg - %4 = load <2 x float>* %a, align 8 ; CHECK-NEXT: !dbg - %5 = load <2 x float>* %b, align 8 ; CHECK-NEXT: !dbg - store <2 x float> %4, <2 x float>* %2, align 8 ; CHECK-NEXT: !dbg - %6 = bitcast <2 x float>* %2 to double* ; CHECK-NEXT: !dbg - %7 = load double* %6, align 1 ; CHECK-NEXT: !dbg - store <2 x float> %5, <2 x float>* %3, align 8 ; CHECK-NEXT: !dbg - %8 = bitcast <2 x float>* %3 to double* ; CHECK-NEXT: !dbg - %9 = load double* %8, align 1 ; CHECK-NEXT: !dbg - %10 = call <4 x float> @_Z3fooDv2_fS_(double %7, double %9) ; CHECK-NEXT: !dbg - store <4 x float> %10, <4 x float>* %x, align 16 ; CHECK-NEXT: !dbg - %11 = load <4 x float>* %x, align 16 ; CHECK-NEXT: !dbg - %12 = extractelement <4 x float> %11, i32 0 ; CHECK-NEXT: !dbg - %13 = load <4 x float>* %x, align 16 ; CHECK-NEXT: !dbg - %14 = extractelement <4 x float> %13, i32 1 ; CHECK-NEXT: !dbg - %15 = fadd float %12, %14 ; CHECK-NEXT: !dbg - %16 = load <4 x float>* %x, align 16 ; CHECK-NEXT: !dbg - %17 = extractelement <4 x float> %16, i32 2 ; CHECK-NEXT: !dbg - %18 = fadd float %15, %17 ; CHECK-NEXT: !dbg - %19 = load <4 x float>* %x, align 16 ; CHECK-NEXT: !dbg - %20 = extractelement <4 x float> %19, i32 3 ; CHECK-NEXT: !dbg - %21 = fadd float %18, %20 ; CHECK-NEXT: !dbg - %22 = fptosi float %21 to i32 ; CHECK-NEXT: !dbg - ret i32 %22 ; CHECK-NEXT: !dbg -} - -attributes #0 = { noinline 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 = { 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" } - -; CHECK: = metadata !{i32 13, -; CHECK-NEXT: = 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, -; CHECK-NEXT: = metadata !{i32 24, -; CHECK-NEXT: = metadata !{i32 25, -; CHECK-NEXT: = metadata !{i32 26, -; CHECK-NEXT: = metadata !{i32 27, -; CHECK-NEXT: = metadata !{i32 28, -; CHECK-NEXT: = metadata !{i32 29, -; CHECK-NEXT: = metadata !{i32 30, -; CHECK-NEXT: = metadata !{i32 31, - -; RUN: opt %s -debug-ir -S | FileCheck %s diff --git a/llvm/tools/lli/lli.cpp b/llvm/tools/lli/lli.cpp index 276740b4d44..feaffef15f5 100644 --- a/llvm/tools/lli/lli.cpp +++ b/llvm/tools/lli/lli.cpp @@ -74,10 +74,6 @@ namespace { cl::desc("Force interpretation: disable JIT"), cl::init(false)); - cl::opt<bool> DebugIR( - "debug-ir", cl::desc("Generate debug information to allow debugging IR."), - cl::init(false)); - // The MCJIT supports building for a target address space separate from // the JIT compilation process. Use a forked process and a copying // memory manager with IPC to execute using this functionality. @@ -414,11 +410,6 @@ int main(int argc, char **argv, char * const *envp) { } } - if (DebugIR) { - ModulePass *DebugIRPass = createDebugIRPass(); - DebugIRPass->runOnModule(*Mod); - } - std::string ErrorMsg; EngineBuilder builder(std::move(Owner)); builder.setMArch(MArch); diff --git a/llvm/tools/opt/opt.cpp b/llvm/tools/opt/opt.cpp index cdd22e48c0c..831018d0abd 100644 --- a/llvm/tools/opt/opt.cpp +++ b/llvm/tools/opt/opt.cpp @@ -307,7 +307,6 @@ int main(int argc, char **argv) { // Initialize passes PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeCore(Registry); - initializeDebugIRPass(Registry); initializeScalarOpts(Registry); initializeObjCARCOpts(Registry); initializeVectorization(Registry); diff --git a/llvm/unittests/Transforms/CMakeLists.txt b/llvm/unittests/Transforms/CMakeLists.txt index 8ec56f10d97..e3ce185e0d5 100644 --- a/llvm/unittests/Transforms/CMakeLists.txt +++ b/llvm/unittests/Transforms/CMakeLists.txt @@ -1,2 +1 @@ -add_subdirectory(DebugIR) add_subdirectory(Utils) diff --git a/llvm/unittests/Transforms/DebugIR/CMakeLists.txt b/llvm/unittests/Transforms/DebugIR/CMakeLists.txt deleted file mode 100644 index 88734d2b8fc..00000000000 --- a/llvm/unittests/Transforms/DebugIR/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -set(LLVM_LINK_COMPONENTS - Core - Instrumentation - Support - ) - -add_llvm_unittest(DebugIRTests - DebugIR.cpp - ) diff --git a/llvm/unittests/Transforms/DebugIR/DebugIR.cpp b/llvm/unittests/Transforms/DebugIR/DebugIR.cpp deleted file mode 100644 index 41df1472168..00000000000 --- a/llvm/unittests/Transforms/DebugIR/DebugIR.cpp +++ /dev/null @@ -1,308 +0,0 @@ -//===- DebugIR.cpp - Unit tests for the DebugIR pass ----------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// The tests in this file verify the DebugIR pass that generates debug metadata -// for LLVM IR. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ADT/Triple.h" -#include "../lib/Transforms/Instrumentation/DebugIR.h" -#include "llvm/Config/config.h" -#include "llvm/IR/DIBuilder.h" -#include "llvm/IR/DebugInfo.h" -#include "llvm/IR/Module.h" -#include "llvm/Support/Errc.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Host.h" -#include "llvm/Support/Path.h" -#include "llvm/Transforms/Instrumentation.h" - -// These tests do not depend on MCJIT, but we use the TrivialModuleBuilder -// helper class to construct some trivial Modules. -#include "../unittests/ExecutionEngine/MCJIT/MCJITTestBase.h" - -#include <string> - -#include "gtest/gtest.h" - -#if defined(LLVM_ON_WIN32) -#include <direct.h> -#define getcwd_impl _getcwd -#elif defined (HAVE_GETCWD) -#include <unistd.h> -#define getcwd_impl getcwd -#endif // LLVM_ON_WIN32 - -using namespace llvm; -using namespace std; - -namespace { - -/// Insert a mock CUDescriptor with the specified producer -void insertCUDescriptor(Module *M, StringRef File, StringRef Dir, - StringRef Producer) { - DIBuilder B(*M); - B.createCompileUnit(dwarf::DW_LANG_C99, File, Dir, Producer, false, "", 0); - B.finalize(); -} - -/// Attempts to remove file at Path and returns true if it existed, or false if -/// it did not. -bool removeIfExists(StringRef Path) { - // This is an approximation, on error we don't know in general if the file - // existed or not. - std::error_code EC = sys::fs::remove(Path, false); - return EC != llvm::errc::no_such_file_or_directory; -} - -char * current_dir() { -#if defined(LLVM_ON_WIN32) || defined(HAVE_GETCWD) - // calling getcwd (or _getcwd() on windows) with a null buffer makes it - // allocate a sufficiently sized buffer to store the current working dir. - return getcwd_impl(nullptr, 0); -#else - return 0; -#endif -} - -class TestDebugIR : public ::testing::Test, public TrivialModuleBuilder { -protected: - TestDebugIR() - : TrivialModuleBuilder(sys::getProcessTriple()) - , cwd(current_dir()) {} - - ~TestDebugIR() { free(cwd); } - - /// Returns a concatenated path string consisting of Dir and Filename - string getPath(const string &Dir, const string &Filename) { - SmallVector<char, 8> Path; - sys::path::append(Path, Dir, Filename); - Path.resize(Dir.size() + Filename.size() + 2); - Path[Dir.size() + Filename.size() + 1] = '\0'; - return string(Path.data()); - } - - LLVMContext Context; - char *cwd; - std::unique_ptr<Module> M; - std::unique_ptr<DebugIR> D; -}; - -// Test empty named Module that is not supposed to be output to disk. -TEST_F(TestDebugIR, EmptyNamedModuleNoWrite) { - string Dir = "MadeUpDirectory"; - string File = "empty_module.ll"; - string Path(getPath(Dir, File)); - - M.reset(createEmptyModule(Path)); - - // constructing DebugIR with no args should not result in any file generated. - D.reset(static_cast<DebugIR *>(llvm::createDebugIRPass())); - D->runOnModule(*M); - - // verify DebugIR did not generate a file - ASSERT_FALSE(removeIfExists(Path)) << "Unexpected file " << Path; -} - -// Test a non-empty unnamed module that is output to an autogenerated file name. -TEST_F(TestDebugIR, NonEmptyUnnamedModuleWriteToAutogeneratedFile) { - M.reset(createEmptyModule()); - insertAddFunction(M.get()); - D.reset(static_cast<DebugIR *>(llvm::createDebugIRPass(true, true))); - - string Path; - D->runOnModule(*M, Path); - - // verify DebugIR generated a file, and clean it up - ASSERT_TRUE(removeIfExists(Path)) << "Missing expected file at " << Path; -} - -// Test not specifying a name in the module -- DebugIR should generate a name -// and write the file contents. -TEST_F(TestDebugIR, EmptyModuleWriteAnonymousFile) { - M.reset(createEmptyModule()); - D.reset(static_cast<DebugIR *>(llvm::createDebugIRPass(false, false))); - - string Path; - D->runOnModule(*M, Path); - - // verify DebugIR generated a file and clean it up - ASSERT_TRUE(removeIfExists(Path)) << "Missing expected file at " << Path; -} - -#ifdef HAVE_GETCWD // These tests require get_current_dir_name() - -// Test empty named Module that is to be output to path specified at Module -// construction. -TEST_F(TestDebugIR, EmptyNamedModuleWriteFile) { - string Filename("NamedFile1"); - string ExpectedPath(getPath(cwd, Filename)); - - M.reset(createEmptyModule(ExpectedPath)); - D.reset(static_cast<DebugIR *>(llvm::createDebugIRPass(true, true))); - - string Path; - D->runOnModule(*M, Path); - - // verify DebugIR was able to correctly parse the file name from module ID - ASSERT_EQ(ExpectedPath, Path); - - // verify DebugIR generated a file, and clean it up - ASSERT_TRUE(removeIfExists(Path)) << "Missing expected file at " << Path; -} - -// Test an empty unnamed module generates an output file whose path is specified -// at DebugIR construction. -TEST_F(TestDebugIR, EmptyUnnamedModuleWriteNamedFile) { - string Filename("NamedFile2"); - - M.reset(createEmptyModule()); - D.reset(static_cast<DebugIR *>(llvm::createDebugIRPass( - false, false, StringRef(cwd), StringRef(Filename)))); - string Path; - D->runOnModule(*M, Path); - - string ExpectedPath(getPath(cwd, Filename)); - ASSERT_EQ(ExpectedPath, Path); - - // verify DebugIR generated a file, and clean it up - ASSERT_TRUE(removeIfExists(Path)) << "Missing expected file at " << Path; -} - -// Test an empty named module generates an output file at the path specified -// during DebugIR construction. -TEST_F(TestDebugIR, EmptyNamedModuleWriteNamedFile) { - string Filename("NamedFile3"); - - string UnexpectedPath(getPath(cwd, "UnexpectedFilename")); - M.reset(createEmptyModule(UnexpectedPath)); - - D.reset(static_cast<DebugIR *>(llvm::createDebugIRPass( - false, false, StringRef(cwd), StringRef(Filename)))); - string Path; - D->runOnModule(*M, Path); - - string ExpectedPath(getPath(cwd, Filename)); - ASSERT_EQ(ExpectedPath, Path); - - // verify DebugIR generated a file, and clean it up - ASSERT_TRUE(removeIfExists(Path)) << "Missing expected file at " << Path; - - // verify DebugIR did not generate a file at the path specified at Module - // construction. - ASSERT_FALSE(removeIfExists(UnexpectedPath)) << "Unexpected file " << Path; -} - -// Test a non-empty named module that is not supposed to be output to disk -TEST_F(TestDebugIR, NonEmptyNamedModuleNoWrite) { - string Filename("NamedFile4"); - string ExpectedPath(getPath(cwd, Filename)); - - M.reset(createEmptyModule(ExpectedPath)); - insertAddFunction(M.get()); - - D.reset(static_cast<DebugIR *>(llvm::createDebugIRPass())); - - string Path; - D->runOnModule(*M, Path); - ASSERT_EQ(ExpectedPath, Path); - - // verify DebugIR did not generate a file - ASSERT_FALSE(removeIfExists(Path)) << "Unexpected file " << Path; -} - -// Test a non-empty named module that is output to disk. -TEST_F(TestDebugIR, NonEmptyNamedModuleWriteFile) { - string Filename("NamedFile5"); - string ExpectedPath(getPath(cwd, Filename)); - - M.reset(createEmptyModule(ExpectedPath)); - insertAddFunction(M.get()); - - D.reset(static_cast<DebugIR *>(llvm::createDebugIRPass(true, true))); - - string Path; - D->runOnModule(*M, Path); - ASSERT_EQ(ExpectedPath, Path); - - // verify DebugIR generated a file, and clean it up - ASSERT_TRUE(removeIfExists(Path)) << "Missing expected file at " << Path; -} - -// Test a non-empty unnamed module is output to a path specified at DebugIR -// construction. -TEST_F(TestDebugIR, NonEmptyUnnamedModuleWriteToNamedFile) { - string Filename("NamedFile6"); - - M.reset(createEmptyModule()); - insertAddFunction(M.get()); - - D.reset(static_cast<DebugIR *>( - llvm::createDebugIRPass(true, true, cwd, Filename))); - string Path; - D->runOnModule(*M, Path); - - string ExpectedPath(getPath(cwd, Filename)); - ASSERT_EQ(ExpectedPath, Path); - - // verify DebugIR generated a file, and clean it up - ASSERT_TRUE(removeIfExists(Path)) << "Missing expected file at " << Path; -} - -// Test that information inside existing debug metadata is retained -TEST_F(TestDebugIR, ExistingMetadataRetained) { - string Filename("NamedFile7"); - string ExpectedPath(getPath(cwd, Filename)); - - M.reset(createEmptyModule(ExpectedPath)); - insertAddFunction(M.get()); - - StringRef Producer("TestProducer"); - insertCUDescriptor(M.get(), Filename, cwd, Producer); - - DebugInfoFinder Finder; - Finder.processModule(*M); - ASSERT_EQ((unsigned)1, Finder.compile_unit_count()); - D.reset(static_cast<DebugIR *>(llvm::createDebugIRPass())); - - string Path; - D->runOnModule(*M, Path); - ASSERT_EQ(ExpectedPath, Path); - - // verify DebugIR did not generate a file - ASSERT_FALSE(removeIfExists(Path)) << "Unexpected file " << Path; - - DICompileUnit CU(*Finder.compile_units().begin()); - - // Verify original CU information is retained - ASSERT_EQ(Filename, CU.getFilename()); - ASSERT_EQ(cwd, CU.getDirectory()); - ASSERT_EQ(Producer, CU.getProducer()); -} - -#endif // HAVE_GETCWD - -#ifdef GTEST_HAS_DEATH_TEST - -// Test a non-empty unnamed module that is not supposed to be output to disk -// NOTE: this test is expected to die with LLVM_ERROR, and such depends on -// google test's "death test" mode. -TEST_F(TestDebugIR, NonEmptyUnnamedModuleNoWrite) { - M.reset(createEmptyModule(StringRef())); - insertAddFunction(M.get()); - D.reset(static_cast<DebugIR *>(llvm::createDebugIRPass())); - - // No name in module or on DebugIR construction ==> DebugIR should assert - EXPECT_DEATH(D->runOnModule(*M), - "DebugIR unable to determine file name in input."); -} - -#endif // GTEST_HAS_DEATH_TEST -} diff --git a/llvm/unittests/Transforms/DebugIR/Makefile b/llvm/unittests/Transforms/DebugIR/Makefile deleted file mode 100644 index 9ace8c33c41..00000000000 --- a/llvm/unittests/Transforms/DebugIR/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -##===- unittests/Transforms/Utils/Makefile -----------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../../.. -TESTNAME = DebugIR -LINK_COMPONENTS := Instrumentation - -include $(LEVEL)/Makefile.config -include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest diff --git a/llvm/unittests/Transforms/Makefile b/llvm/unittests/Transforms/Makefile index d5cca397b6a..599b18a057d 100644 --- a/llvm/unittests/Transforms/Makefile +++ b/llvm/unittests/Transforms/Makefile @@ -9,7 +9,7 @@ LEVEL = ../.. -PARALLEL_DIRS = DebugIR Utils +PARALLEL_DIRS = Utils include $(LEVEL)/Makefile.common |