[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
CarlosAlbertoEnciso wrote: > @CarlosAlbertoEnciso If this needs another pair of eyes, do not hesitate to > add me as reviewer. Cheers! @jalopezg-git Thanks; that would be great. https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
CarlosAlbertoEnciso wrote: Uploaded new patch to address @jmorse comments. https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -2124,6 +2125,138 @@ layout and given the number of matches. - Total 71 8 +IR (Textual representation and bitcode) SUPPORT +~~~ +The below example is used to show the IR output generated by +:program:`llvm-debuginfo-analyzer`. We compiled the example for a +IR 64-bit target with Clang (-O0 -g --target=x86_64-linux): + +.. code-block:: c++ + + 1 using INTPTR = const int *; + 2 int foo(INTPTR ParamPtr, unsigned ParamUnsigned, bool ParamBool) { + 3if (ParamBool) { + 4 typedef int INTEGER; + 5 const INTEGER CONSTANT = 7; + 6 return CONSTANT; + 7} + 8return ParamUnsigned; + 9 } + +PRINT BASIC DETAILS +^^^ +The following command prints basic details for all the logical elements +sorted by the debug information internal offset; it includes its lexical +level and debug info format. + +.. code-block:: none + + llvm-debuginfo-analyzer --attribute=level,format + --output-sort=offset + --print=scopes,symbols,types,lines,instructions + test-clang.ll + +or + +.. code-block:: none + + llvm-debuginfo-analyzer --attribute=level,format + --output-sort=offset + --print=elements + test-clang.ll + +Each row represents an element that is present within the debug +information. The first column represents the scope level, followed by +the associated line number (if any), and finally the description of +the element. + +.. code-block:: none + + Logical View: + [000] {File} 'test-clang.ll' -> Textual IR + + [001] {CompileUnit} 'test.cpp' + [002] 2 {Function} extern not_inlined 'foo' -> 'int' + [003] {Block} + [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER' + [004] 5 {Line} + [004] {Code} 'store i32 7, ptr %CONSTANT, align 4, !dbg !32' + [004] 6 {Line} + [004] {Code} 'store i32 7, ptr %retval, align 4, !dbg !33' + [004] 6 {Line} + [004] {Code} 'br label %return, !dbg !33' + [003] 2 {Parameter} 'ParamPtr' -> 'INTPTR' + [003] 2 {Parameter} 'ParamUnsigned' -> 'unsigned int' + [003] 2 {Parameter} 'ParamBool' -> 'bool' + [003] 4 {TypeAlias} 'INTEGER' -> 'int' + [003] 2 {Line} + [003] {Code} '%retval = alloca i32, align 4' + [003] {Code} '%ParamPtr.addr = alloca ptr, align 8' + [003] {Code} '%ParamUnsigned.addr = alloca i32, align 4' + [003] {Code} '%ParamBool.addr = alloca i8, align 1' + [003] {Code} '%CONSTANT = alloca i32, align 4' + [003] {Code} 'store ptr %ParamPtr, ptr %ParamPtr.addr, align 8' + [003] {Code} 'store i32 %ParamUnsigned, ptr %ParamUnsigned.addr, align 4' + [003] {Code} '%storedv = zext i1 %ParamBool to i8' + [003] {Code} 'store i8 %storedv, ptr %ParamBool.addr, align 1' + [003] 8 {Line} + [003] {Code} '%1 = load i32, ptr %ParamUnsigned.addr, align 4, !dbg !34' + [003] 8 {Line} + [003] {Code} 'store i32 %1, ptr %retval, align 4, !dbg !35' + [003] 8 {Line} + [003] {Code} 'br label %return, !dbg !35' + [003] 9 {Line} + [003] {Code} '%2 = load i32, ptr %retval, align 4, !dbg !36' + [003] 9 {Line} + [003] {Code} 'ret i32 %2, !dbg !36' + [003] 3 {Line} + [003] 3 {Line} + [003] 3 {Line} + [003] {Code} 'br i1 %loadedv, label %if.then, label %if.end, !dbg !26' + [002] 1 {TypeAlias} 'INTPTR' -> '* const int' + +SELECT LOGICAL ELEMENTS +^^^ +The following prints all *instructions*, *symbols* and *types* that +contain **'block'** or **'.store'** in their names or types, using a tab +layout and given the number of matches. + +.. code-block:: none CarlosAlbertoEnciso wrote: I think it is a good point. Added that specific example to the documentation and test cases. `--attribute=level --select=INTPTR --report=list --print=symbols,types,summary` https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,300 @@ +//===-- LVIRReader.h *- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This file defines the LVIRReader class, which is used to describe a +// LLVM IR reader. +// +//===--===// + +#ifndef LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H +#define LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H + +#include "llvm/DebugInfo/LogicalView/Core/LVReader.h" +#include "llvm/Transforms/Utils/DebugSSAUpdater.h" + +namespace llvm { +class DIFile; +class DINode; +class DILocation; +class DIScope; +class DISubprogram; +class DIVariable; +class BasicBlock; + +namespace object { +class IRObjectFile; +} + +namespace logicalview { + +class LVElement; +class LVLine; +class LVScopeCompileUnit; +class LVSymbol; +class LVType; + +class LVIRReader final : public LVReader { + object::IRObjectFile *BitCodeIR = nullptr; + MemoryBufferRef *TextualIR = nullptr; + + // Symbols with locations for current compile unit. + LVSymbols SymbolsWithLocations; + + LVSectionIndex SectionIndex = 0; + + const DICompileUnit *CUNode = nullptr; + + // The Dwarf Version (from the module flags). + unsigned DwarfVersion; + + // Location index for global variables. + uint64_t PoolAddressIndex = 0; + + // Whether to emit all linkage names, or just abstract subprograms. + bool UseAllLinkageNames = true; + + // Dependencies on external options (llc, etc). + bool includeMinimalInlineScopes() const; + bool useAllLinkageNames() const { return UseAllLinkageNames; } + + bool LanguageIsFortran = false; + void mapFortranLanguage(unsigned DWLang); + bool moduleIsInFortran() const { return LanguageIsFortran; } + + // Generate logical debug line before prologue. + bool GenerateLineBeforePrologue = true; CarlosAlbertoEnciso wrote: Good point. Moved to be a local variable to `processBasicBlocks`. https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,2348 @@ +//===-- LVIRReader.cpp ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This implements the LVIRReader class. +// It supports LLVM text IR and bitcode format. +// +//===--===// + +#include "llvm/DebugInfo/LogicalView/Readers/LVIRReader.h" +#include "llvm/CodeGen/DebugHandlerBase.h" +#include "llvm/DebugInfo/LogicalView/Core/LVLine.h" +#include "llvm/DebugInfo/LogicalView/Core/LVScope.h" +#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h" +#include "llvm/DebugInfo/LogicalView/Core/LVType.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Module.h" +#include "llvm/IRReader/IRReader.h" +#include "llvm/Object/Error.h" +#include "llvm/Object/IRObjectFile.h" +#include "llvm/Support/FormatAdapters.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/SourceMgr.h" + +using namespace llvm; +using namespace llvm::object; +using namespace llvm::logicalview; + +#define DEBUG_TYPE "IRReader" + +// Extra debug traces. Default is false +#define DEBUG_ALL + +// These flavours of DINodes are not handled: +// DW_TAG_APPLE_property = 19896 +// DW_TAG_atomic_type = 71 +// DW_TAG_common_block = 26 +// DW_TAG_file_type= 41 +// DW_TAG_friend = 42 +// DW_TAG_generic_subrange = 69 +// DW_TAG_immutable_type = 75 +// DW_TAG_module = 30 + +// Create a logical element and setup the following information: +// - Name, DWARF tag, line +// - Collect any file information +LVElement *LVIRReader::constructElement(const DINode *DN) { + dwarf::Tag Tag = DN->getTag(); + LVElement *Element = createElement(Tag); + if (Element) { +Element->setTag(Tag); +addMD(DN, Element); + +StringRef Name = getMDName(DN); +if (!Name.empty()) + Element->setName(Name); + +// Record any file information. +if (const DIFile *File = getMDFile(DN)) + getOrCreateSourceID(File); + } + + return Element; +} + +void LVIRReader::mapFortranLanguage(unsigned DWLang) { + switch (DWLang) { + case dwarf::DW_LANG_Fortran77: + case dwarf::DW_LANG_Fortran90: + case dwarf::DW_LANG_Fortran95: + case dwarf::DW_LANG_Fortran03: + case dwarf::DW_LANG_Fortran08: + case dwarf::DW_LANG_Fortran18: +LanguageIsFortran = true; +break; + default: +LanguageIsFortran = false; + } +} + +// Looking at IR generated with the '-gdwarf -gsplit-dwarf=split' the only +// difference is setting the 'DICompileUnit::splitDebugFilename' to the +// name of the split filename: "xxx.dwo". +bool LVIRReader::includeMinimalInlineScopes() const { + return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly; +} + +// For the given 'DIFile' generate an index 1-based to indicate the +// source file where the logical element is declared. +// In DWARF v4, the files are 1-indexed. +// In DWARF v5, the files are 0-indexed. CarlosAlbertoEnciso wrote: Good point. That comment was carried over from the DWARF reader. Removed. https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,2348 @@ +//===-- LVIRReader.cpp ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This implements the LVIRReader class. +// It supports LLVM text IR and bitcode format. +// +//===--===// + +#include "llvm/DebugInfo/LogicalView/Readers/LVIRReader.h" +#include "llvm/CodeGen/DebugHandlerBase.h" +#include "llvm/DebugInfo/LogicalView/Core/LVLine.h" +#include "llvm/DebugInfo/LogicalView/Core/LVScope.h" +#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h" +#include "llvm/DebugInfo/LogicalView/Core/LVType.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Module.h" +#include "llvm/IRReader/IRReader.h" +#include "llvm/Object/Error.h" +#include "llvm/Object/IRObjectFile.h" +#include "llvm/Support/FormatAdapters.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/SourceMgr.h" + +using namespace llvm; +using namespace llvm::object; +using namespace llvm::logicalview; + +#define DEBUG_TYPE "IRReader" + +// Extra debug traces. Default is false +#define DEBUG_ALL + +// These flavours of DINodes are not handled: +// DW_TAG_APPLE_property = 19896 +// DW_TAG_atomic_type = 71 +// DW_TAG_common_block = 26 +// DW_TAG_file_type= 41 +// DW_TAG_friend = 42 +// DW_TAG_generic_subrange = 69 +// DW_TAG_immutable_type = 75 +// DW_TAG_module = 30 + +// Create a logical element and setup the following information: +// - Name, DWARF tag, line +// - Collect any file information +LVElement *LVIRReader::constructElement(const DINode *DN) { + dwarf::Tag Tag = DN->getTag(); + LVElement *Element = createElement(Tag); + if (Element) { +Element->setTag(Tag); +addMD(DN, Element); + +StringRef Name = getMDName(DN); +if (!Name.empty()) + Element->setName(Name); + +// Record any file information. +if (const DIFile *File = getMDFile(DN)) + getOrCreateSourceID(File); + } + + return Element; +} + +void LVIRReader::mapFortranLanguage(unsigned DWLang) { + switch (DWLang) { + case dwarf::DW_LANG_Fortran77: + case dwarf::DW_LANG_Fortran90: + case dwarf::DW_LANG_Fortran95: + case dwarf::DW_LANG_Fortran03: + case dwarf::DW_LANG_Fortran08: + case dwarf::DW_LANG_Fortran18: +LanguageIsFortran = true; +break; + default: +LanguageIsFortran = false; + } +} + +// Looking at IR generated with the '-gdwarf -gsplit-dwarf=split' the only +// difference is setting the 'DICompileUnit::splitDebugFilename' to the +// name of the split filename: "xxx.dwo". +bool LVIRReader::includeMinimalInlineScopes() const { + return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly; +} + +// For the given 'DIFile' generate an index 1-based to indicate the +// source file where the logical element is declared. +// In DWARF v4, the files are 1-indexed. +// In DWARF v5, the files are 0-indexed. +// The IR reader expects the indexes as 1-indexed. +// Each compile unit, keeps track of the last assigned index. +size_t LVIRReader::getOrCreateSourceID(const DIFile *File) { CarlosAlbertoEnciso wrote: The initial implementation of this function failed, because it assumed only one `DICompileUnit`. Later on, it was adjusted to handle multiple `DICompileUnit`. The internal regression suite uses 'llvm-link` to combine several bitcode files into a single bitcode file. I can check with a test case. https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -190,11 +206,11 @@ Error LVReaderHandler::handleBuffer(LVReaders &Readers, StringRef Filename, return handleFile(Readers, PdbPath.get(), Filename); } - Expected> BinOrErr = createBinary(Buffer); + LLVMContext Context; + Expected> BinOrErr = createBinary(Buffer, &Context); if (errorToErrorCode(BinOrErr.takeError())) { -return createStringError(errc::not_supported, - "Binary object format in '%s' is not supported.", - Filename.str().c_str()); CarlosAlbertoEnciso wrote: `handleObject` prints an appropriated error message if it can not read the input. https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,2348 @@ +//===-- LVIRReader.cpp ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This implements the LVIRReader class. +// It supports LLVM text IR and bitcode format. +// +//===--===// + +#include "llvm/DebugInfo/LogicalView/Readers/LVIRReader.h" +#include "llvm/CodeGen/DebugHandlerBase.h" +#include "llvm/DebugInfo/LogicalView/Core/LVLine.h" +#include "llvm/DebugInfo/LogicalView/Core/LVScope.h" +#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h" +#include "llvm/DebugInfo/LogicalView/Core/LVType.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Module.h" +#include "llvm/IRReader/IRReader.h" +#include "llvm/Object/Error.h" +#include "llvm/Object/IRObjectFile.h" +#include "llvm/Support/FormatAdapters.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/SourceMgr.h" + +using namespace llvm; +using namespace llvm::object; +using namespace llvm::logicalview; + +#define DEBUG_TYPE "IRReader" + +// Extra debug traces. Default is false +#define DEBUG_ALL + +// These flavours of DINodes are not handled: +// DW_TAG_APPLE_property = 19896 +// DW_TAG_atomic_type = 71 +// DW_TAG_common_block = 26 +// DW_TAG_file_type= 41 +// DW_TAG_friend = 42 +// DW_TAG_generic_subrange = 69 +// DW_TAG_immutable_type = 75 +// DW_TAG_module = 30 + +// Create a logical element and setup the following information: +// - Name, DWARF tag, line +// - Collect any file information +LVElement *LVIRReader::constructElement(const DINode *DN) { + dwarf::Tag Tag = DN->getTag(); + LVElement *Element = createElement(Tag); + if (Element) { +Element->setTag(Tag); +addMD(DN, Element); + +StringRef Name = getMDName(DN); +if (!Name.empty()) + Element->setName(Name); + +// Record any file information. +if (const DIFile *File = getMDFile(DN)) + getOrCreateSourceID(File); + } + + return Element; +} + +void LVIRReader::mapFortranLanguage(unsigned DWLang) { + switch (DWLang) { + case dwarf::DW_LANG_Fortran77: + case dwarf::DW_LANG_Fortran90: + case dwarf::DW_LANG_Fortran95: + case dwarf::DW_LANG_Fortran03: + case dwarf::DW_LANG_Fortran08: + case dwarf::DW_LANG_Fortran18: +LanguageIsFortran = true; +break; + default: +LanguageIsFortran = false; + } +} + +// Looking at IR generated with the '-gdwarf -gsplit-dwarf=split' the only +// difference is setting the 'DICompileUnit::splitDebugFilename' to the +// name of the split filename: "xxx.dwo". +bool LVIRReader::includeMinimalInlineScopes() const { + return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly; +} + +// For the given 'DIFile' generate an index 1-based to indicate the +// source file where the logical element is declared. +// In DWARF v4, the files are 1-indexed. +// In DWARF v5, the files are 0-indexed. +// The IR reader expects the indexes as 1-indexed. +// Each compile unit, keeps track of the last assigned index. +size_t LVIRReader::getOrCreateSourceID(const DIFile *File) { + if (!File) +return 0; + +#ifdef DEBUG_ALL + LLVM_DEBUG({ +dbgs() << "\n[getOrCreateSourceID] DIFile\n"; +File->dump(); + }); +#endif + + addMD(File, CompileUnit); + + LLVM_DEBUG({ +dbgs() << "Directory: '" << File->getDirectory() << "'\n"; +dbgs() << "Filename: '" << File->getFilename() << "'\n"; + }); + size_t FileIndex = 0; + LVCompileUnitFiles::iterator Iter = CompileUnitFiles.find(File); + if (Iter == CompileUnitFiles.cend()) { +FileIndex = getFileIndex(CompileUnit); +std::string Directory(File->getDirectory()); +if (Directory.empty()) + Directory = std::string(CompileUnit->getCompilationDirectory()); + +std::string FullName; +raw_string_ostream Out(FullName); +Out << Directory << "/" << llvm::sys::path::filename(File->getFilename()); +CompileUnit->addFilename(transformPath(FullName)); +CompileUnitFiles.emplace(File, ++FileIndex); +updateFileIndex(CompileUnit, FileIndex); + } else { +FileIndex = Iter->second; + } + + LLVM_DEBUG({ dbgs() << "FileIndex: " << FileIndex << "\n"; }); + return FileIndex; +} + +void LVIRReader::addSourceLine(LVElement *Element, unsigned Line, + const DIFile *File) { + if (Line == 0) +return; + + // After the scopes are created, the generic reader traverses the 'Children' + // and perform additional setting tasks (resolve types names, references, + // etc.). One of those tasks is select the correct string pool index based on + // the commmand line o
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,300 @@ +//===-- LVIRReader.h *- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This file defines the LVIRReader class, which is used to describe a +// LLVM IR reader. +// +//===--===// + +#ifndef LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H +#define LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H + +#include "llvm/DebugInfo/LogicalView/Core/LVReader.h" +#include "llvm/Transforms/Utils/DebugSSAUpdater.h" + +namespace llvm { +class DIFile; +class DINode; +class DILocation; +class DIScope; +class DISubprogram; +class DIVariable; +class BasicBlock; + +namespace object { +class IRObjectFile; +} + +namespace logicalview { + +class LVElement; +class LVLine; +class LVScopeCompileUnit; +class LVSymbol; +class LVType; + +class LVIRReader final : public LVReader { + object::IRObjectFile *BitCodeIR = nullptr; + MemoryBufferRef *TextualIR = nullptr; + + // Symbols with locations for current compile unit. + LVSymbols SymbolsWithLocations; + + LVSectionIndex SectionIndex = 0; + + const DICompileUnit *CUNode = nullptr; + + // The Dwarf Version (from the module flags). + unsigned DwarfVersion; + + // Location index for global variables. + uint64_t PoolAddressIndex = 0; + + // Whether to emit all linkage names, or just abstract subprograms. + bool UseAllLinkageNames = true; + + // Dependencies on external options (llc, etc). + bool includeMinimalInlineScopes() const; + bool useAllLinkageNames() const { return UseAllLinkageNames; } + + bool LanguageIsFortran = false; + void mapFortranLanguage(unsigned DWLang); + bool moduleIsInFortran() const { return LanguageIsFortran; } + + // Generate logical debug line before prologue. + bool GenerateLineBeforePrologue = true; + + // We assume a constante increase between instructions. + const unsigned OffsetIncrease = 4; + void updateLineOffset() { CurrentOffset += OffsetIncrease; } + + // An anonymous type for index type. + LVType *NodeIndexType = nullptr; + + std::unique_ptr DbgValueRanges; + + // Record the last assigned file index for each compile unit. + using LVIndexFiles = std::map; + LVIndexFiles IndexFiles; + + void updateFileIndex(LVScopeCompileUnit *CompileUnit, size_t FileIndex) { +LVIndexFiles::iterator Iter = IndexFiles.find(CompileUnit); +if (Iter == IndexFiles.end()) + IndexFiles.emplace(CompileUnit, FileIndex); +else + Iter->second = FileIndex; + } + + // Get the current assigned index file for the given compile unit. + size_t getFileIndex(LVScopeCompileUnit *CompileUnit) { +size_t FileIndex = 0; +LVIndexFiles::iterator Iter = IndexFiles.find(CompileUnit); +if (Iter != IndexFiles.end()) + FileIndex = Iter->second; +return FileIndex; + } + + // Collect the compile unit metadata files. + using LVCompileUnitFiles = std::map; + LVCompileUnitFiles CompileUnitFiles; + + size_t getOrCreateSourceID(const DIFile *File); + + // Associate the logical elements to metadata objects. + using LVMDObjects = std::map; + LVMDObjects MDObjects; + + void addMD(const MDNode *MD, LVElement *Element) { +if (MDObjects.find(MD) == MDObjects.end()) + MDObjects.emplace(MD, Element); + } + LVElement *getElementForSeenMD(const MDNode *MD) const { +LVMDObjects::const_iterator Iter = MDObjects.find(MD); +return Iter != MDObjects.end() ? Iter->second : nullptr; + } + LVScope *getScopeForSeenMD(const MDNode *MD) const { +return static_cast(getElementForSeenMD(MD)); + } + LVSymbol *getSymbolForSeenMD(const MDNode *MD) const { +return static_cast(getElementForSeenMD(MD)); + } + LVType *getTypeForSeenMD(const MDNode *MD) const { +return static_cast(getElementForSeenMD(MD)); + } + LVType *getLineForSeenMD(const MDNode *MD) const { +return static_cast(getElementForSeenMD(MD)); + } + + // Inlined concrete scopes with its associated inlined abstract scopes. + // When creating abstract scopes, there is no direct information to find + // the correct lexical scope. + using LVInlinedScopes = std::map; + LVInlinedScopes InlinedScopes; + + void addInlinedScope(LVScope *ConcreteScope, LVScope *AbstractScope) { +if (InlinedScopes.find(ConcreteScope) == InlinedScopes.end()) + InlinedScopes.emplace(ConcreteScope, AbstractScope); + } + LVScope *getInlinedScope(LVScope *ConcreteScope) const { CarlosAlbertoEnciso wrote: For clarity these are the names used: `InlinedScope` --> inlined scopes created at the point where the inlined function is called. `AbstractScope` --> scopes in the inlined function definition. https://github.com/llvm/llvm-project/pull/13
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,2348 @@ +//===-- LVIRReader.cpp ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This implements the LVIRReader class. +// It supports LLVM text IR and bitcode format. +// +//===--===// + +#include "llvm/DebugInfo/LogicalView/Readers/LVIRReader.h" +#include "llvm/CodeGen/DebugHandlerBase.h" +#include "llvm/DebugInfo/LogicalView/Core/LVLine.h" +#include "llvm/DebugInfo/LogicalView/Core/LVScope.h" +#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h" +#include "llvm/DebugInfo/LogicalView/Core/LVType.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Module.h" +#include "llvm/IRReader/IRReader.h" +#include "llvm/Object/Error.h" +#include "llvm/Object/IRObjectFile.h" +#include "llvm/Support/FormatAdapters.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/SourceMgr.h" + +using namespace llvm; +using namespace llvm::object; +using namespace llvm::logicalview; + +#define DEBUG_TYPE "IRReader" + +// Extra debug traces. Default is false +#define DEBUG_ALL + +// These flavours of DINodes are not handled: +// DW_TAG_APPLE_property = 19896 +// DW_TAG_atomic_type = 71 +// DW_TAG_common_block = 26 +// DW_TAG_file_type= 41 +// DW_TAG_friend = 42 +// DW_TAG_generic_subrange = 69 +// DW_TAG_immutable_type = 75 +// DW_TAG_module = 30 + +// Create a logical element and setup the following information: +// - Name, DWARF tag, line +// - Collect any file information +LVElement *LVIRReader::constructElement(const DINode *DN) { + dwarf::Tag Tag = DN->getTag(); + LVElement *Element = createElement(Tag); + if (Element) { +Element->setTag(Tag); +addMD(DN, Element); + +StringRef Name = getMDName(DN); +if (!Name.empty()) + Element->setName(Name); + +// Record any file information. +if (const DIFile *File = getMDFile(DN)) + getOrCreateSourceID(File); + } + + return Element; +} + +void LVIRReader::mapFortranLanguage(unsigned DWLang) { + switch (DWLang) { + case dwarf::DW_LANG_Fortran77: + case dwarf::DW_LANG_Fortran90: + case dwarf::DW_LANG_Fortran95: + case dwarf::DW_LANG_Fortran03: + case dwarf::DW_LANG_Fortran08: + case dwarf::DW_LANG_Fortran18: +LanguageIsFortran = true; +break; + default: +LanguageIsFortran = false; + } +} + +// Looking at IR generated with the '-gdwarf -gsplit-dwarf=split' the only +// difference is setting the 'DICompileUnit::splitDebugFilename' to the +// name of the split filename: "xxx.dwo". +bool LVIRReader::includeMinimalInlineScopes() const { + return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly; +} + +// For the given 'DIFile' generate an index 1-based to indicate the +// source file where the logical element is declared. +// In DWARF v4, the files are 1-indexed. +// In DWARF v5, the files are 0-indexed. +// The IR reader expects the indexes as 1-indexed. +// Each compile unit, keeps track of the last assigned index. +size_t LVIRReader::getOrCreateSourceID(const DIFile *File) { + if (!File) +return 0; + +#ifdef DEBUG_ALL + LLVM_DEBUG({ +dbgs() << "\n[getOrCreateSourceID] DIFile\n"; +File->dump(); + }); +#endif + + addMD(File, CompileUnit); + + LLVM_DEBUG({ +dbgs() << "Directory: '" << File->getDirectory() << "'\n"; +dbgs() << "Filename: '" << File->getFilename() << "'\n"; + }); + size_t FileIndex = 0; + LVCompileUnitFiles::iterator Iter = CompileUnitFiles.find(File); + if (Iter == CompileUnitFiles.cend()) { +FileIndex = getFileIndex(CompileUnit); +std::string Directory(File->getDirectory()); +if (Directory.empty()) + Directory = std::string(CompileUnit->getCompilationDirectory()); + +std::string FullName; +raw_string_ostream Out(FullName); +Out << Directory << "/" << llvm::sys::path::filename(File->getFilename()); +CompileUnit->addFilename(transformPath(FullName)); +CompileUnitFiles.emplace(File, ++FileIndex); +updateFileIndex(CompileUnit, FileIndex); + } else { +FileIndex = Iter->second; + } + + LLVM_DEBUG({ dbgs() << "FileIndex: " << FileIndex << "\n"; }); + return FileIndex; +} + +void LVIRReader::addSourceLine(LVElement *Element, unsigned Line, + const DIFile *File) { + if (Line == 0) +return; + + // After the scopes are created, the generic reader traverses the 'Children' + // and perform additional setting tasks (resolve types names, references, + // etc.). One of those tasks is select the correct string pool index based on + // the commmand line o
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,2348 @@ +//===-- LVIRReader.cpp ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This implements the LVIRReader class. +// It supports LLVM text IR and bitcode format. +// +//===--===// + +#include "llvm/DebugInfo/LogicalView/Readers/LVIRReader.h" +#include "llvm/CodeGen/DebugHandlerBase.h" +#include "llvm/DebugInfo/LogicalView/Core/LVLine.h" +#include "llvm/DebugInfo/LogicalView/Core/LVScope.h" +#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h" +#include "llvm/DebugInfo/LogicalView/Core/LVType.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Module.h" +#include "llvm/IRReader/IRReader.h" +#include "llvm/Object/Error.h" +#include "llvm/Object/IRObjectFile.h" +#include "llvm/Support/FormatAdapters.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/SourceMgr.h" + +using namespace llvm; +using namespace llvm::object; +using namespace llvm::logicalview; + +#define DEBUG_TYPE "IRReader" + +// Extra debug traces. Default is false +#define DEBUG_ALL + +// These flavours of DINodes are not handled: +// DW_TAG_APPLE_property = 19896 +// DW_TAG_atomic_type = 71 +// DW_TAG_common_block = 26 +// DW_TAG_file_type= 41 +// DW_TAG_friend = 42 +// DW_TAG_generic_subrange = 69 +// DW_TAG_immutable_type = 75 +// DW_TAG_module = 30 + +// Create a logical element and setup the following information: +// - Name, DWARF tag, line +// - Collect any file information +LVElement *LVIRReader::constructElement(const DINode *DN) { + dwarf::Tag Tag = DN->getTag(); + LVElement *Element = createElement(Tag); + if (Element) { +Element->setTag(Tag); +addMD(DN, Element); + +StringRef Name = getMDName(DN); +if (!Name.empty()) + Element->setName(Name); + +// Record any file information. +if (const DIFile *File = getMDFile(DN)) + getOrCreateSourceID(File); + } + + return Element; +} + +void LVIRReader::mapFortranLanguage(unsigned DWLang) { + switch (DWLang) { + case dwarf::DW_LANG_Fortran77: + case dwarf::DW_LANG_Fortran90: + case dwarf::DW_LANG_Fortran95: + case dwarf::DW_LANG_Fortran03: + case dwarf::DW_LANG_Fortran08: + case dwarf::DW_LANG_Fortran18: +LanguageIsFortran = true; +break; + default: +LanguageIsFortran = false; + } +} + +// Looking at IR generated with the '-gdwarf -gsplit-dwarf=split' the only +// difference is setting the 'DICompileUnit::splitDebugFilename' to the +// name of the split filename: "xxx.dwo". +bool LVIRReader::includeMinimalInlineScopes() const { + return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly; +} + +// For the given 'DIFile' generate an index 1-based to indicate the +// source file where the logical element is declared. +// In DWARF v4, the files are 1-indexed. +// In DWARF v5, the files are 0-indexed. +// The IR reader expects the indexes as 1-indexed. +// Each compile unit, keeps track of the last assigned index. +size_t LVIRReader::getOrCreateSourceID(const DIFile *File) { + if (!File) +return 0; + +#ifdef DEBUG_ALL + LLVM_DEBUG({ +dbgs() << "\n[getOrCreateSourceID] DIFile\n"; +File->dump(); + }); +#endif + + addMD(File, CompileUnit); + + LLVM_DEBUG({ +dbgs() << "Directory: '" << File->getDirectory() << "'\n"; +dbgs() << "Filename: '" << File->getFilename() << "'\n"; + }); + size_t FileIndex = 0; + LVCompileUnitFiles::iterator Iter = CompileUnitFiles.find(File); + if (Iter == CompileUnitFiles.cend()) { +FileIndex = getFileIndex(CompileUnit); +std::string Directory(File->getDirectory()); +if (Directory.empty()) + Directory = std::string(CompileUnit->getCompilationDirectory()); + +std::string FullName; +raw_string_ostream Out(FullName); +Out << Directory << "/" << llvm::sys::path::filename(File->getFilename()); +CompileUnit->addFilename(transformPath(FullName)); +CompileUnitFiles.emplace(File, ++FileIndex); +updateFileIndex(CompileUnit, FileIndex); + } else { +FileIndex = Iter->second; + } + + LLVM_DEBUG({ dbgs() << "FileIndex: " << FileIndex << "\n"; }); + return FileIndex; +} + +void LVIRReader::addSourceLine(LVElement *Element, unsigned Line, + const DIFile *File) { + if (Line == 0) +return; + + // After the scopes are created, the generic reader traverses the 'Children' + // and perform additional setting tasks (resolve types names, references, + // etc.). One of those tasks is select the correct string pool index based on + // the commmand line o
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -29,7 +30,9 @@ namespace logicalview { using LVReaders = std::vector>; using ArgVector = std::vector; -using PdbOrObj = PointerUnion; +using PdbOrObjOrIr = +PointerUnion; CarlosAlbertoEnciso wrote: Changed to `InputHandle`. https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,300 @@ +//===-- LVIRReader.h *- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This file defines the LVIRReader class, which is used to describe a +// LLVM IR reader. +// +//===--===// + +#ifndef LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H +#define LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H + +#include "llvm/DebugInfo/LogicalView/Core/LVReader.h" +#include "llvm/Transforms/Utils/DebugSSAUpdater.h" + +namespace llvm { +class DIFile; +class DINode; +class DILocation; +class DIScope; +class DISubprogram; +class DIVariable; +class BasicBlock; + +namespace object { +class IRObjectFile; +} + +namespace logicalview { + +class LVElement; +class LVLine; +class LVScopeCompileUnit; +class LVSymbol; +class LVType; + +class LVIRReader final : public LVReader { + object::IRObjectFile *BitCodeIR = nullptr; + MemoryBufferRef *TextualIR = nullptr; + + // Symbols with locations for current compile unit. + LVSymbols SymbolsWithLocations; + + LVSectionIndex SectionIndex = 0; + + const DICompileUnit *CUNode = nullptr; + + // The Dwarf Version (from the module flags). + unsigned DwarfVersion; + + // Location index for global variables. + uint64_t PoolAddressIndex = 0; + + // Whether to emit all linkage names, or just abstract subprograms. + bool UseAllLinkageNames = true; + + // Dependencies on external options (llc, etc). + bool includeMinimalInlineScopes() const; + bool useAllLinkageNames() const { return UseAllLinkageNames; } + + bool LanguageIsFortran = false; + void mapFortranLanguage(unsigned DWLang); + bool moduleIsInFortran() const { return LanguageIsFortran; } + + // Generate logical debug line before prologue. + bool GenerateLineBeforePrologue = true; + + // We assume a constante increase between instructions. + const unsigned OffsetIncrease = 4; + void updateLineOffset() { CurrentOffset += OffsetIncrease; } + + // An anonymous type for index type. + LVType *NodeIndexType = nullptr; + + std::unique_ptr DbgValueRanges; + + // Record the last assigned file index for each compile unit. + using LVIndexFiles = std::map; + LVIndexFiles IndexFiles; + + void updateFileIndex(LVScopeCompileUnit *CompileUnit, size_t FileIndex) { +LVIndexFiles::iterator Iter = IndexFiles.find(CompileUnit); +if (Iter == IndexFiles.end()) + IndexFiles.emplace(CompileUnit, FileIndex); +else + Iter->second = FileIndex; + } + + // Get the current assigned index file for the given compile unit. + size_t getFileIndex(LVScopeCompileUnit *CompileUnit) { +size_t FileIndex = 0; +LVIndexFiles::iterator Iter = IndexFiles.find(CompileUnit); +if (Iter != IndexFiles.end()) + FileIndex = Iter->second; +return FileIndex; + } + + // Collect the compile unit metadata files. + using LVCompileUnitFiles = std::map; + LVCompileUnitFiles CompileUnitFiles; + + size_t getOrCreateSourceID(const DIFile *File); + + // Associate the logical elements to metadata objects. CarlosAlbertoEnciso wrote: You are correct. Flip comments. https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,300 @@ +//===-- LVIRReader.h *- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This file defines the LVIRReader class, which is used to describe a +// LLVM IR reader. +// +//===--===// + +#ifndef LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H +#define LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H + +#include "llvm/DebugInfo/LogicalView/Core/LVReader.h" +#include "llvm/Transforms/Utils/DebugSSAUpdater.h" + +namespace llvm { +class DIFile; +class DINode; +class DILocation; +class DIScope; +class DISubprogram; +class DIVariable; +class BasicBlock; + +namespace object { +class IRObjectFile; +} + +namespace logicalview { + +class LVElement; +class LVLine; +class LVScopeCompileUnit; +class LVSymbol; +class LVType; + +class LVIRReader final : public LVReader { CarlosAlbertoEnciso wrote: The style that `debuginfo-analyzer` uses is to keep the data members as close as possible to its associated methods. https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,300 @@ +//===-- LVIRReader.h *- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This file defines the LVIRReader class, which is used to describe a +// LLVM IR reader. +// +//===--===// + +#ifndef LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H +#define LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H + +#include "llvm/DebugInfo/LogicalView/Core/LVReader.h" +#include "llvm/Transforms/Utils/DebugSSAUpdater.h" + +namespace llvm { +class DIFile; +class DINode; +class DILocation; +class DIScope; +class DISubprogram; +class DIVariable; +class BasicBlock; + +namespace object { +class IRObjectFile; +} + +namespace logicalview { + +class LVElement; +class LVLine; +class LVScopeCompileUnit; +class LVSymbol; +class LVType; + +class LVIRReader final : public LVReader { + object::IRObjectFile *BitCodeIR = nullptr; + MemoryBufferRef *TextualIR = nullptr; + + // Symbols with locations for current compile unit. + LVSymbols SymbolsWithLocations; + + LVSectionIndex SectionIndex = 0; + + const DICompileUnit *CUNode = nullptr; + + // The Dwarf Version (from the module flags). + unsigned DwarfVersion; + + // Location index for global variables. + uint64_t PoolAddressIndex = 0; + + // Whether to emit all linkage names, or just abstract subprograms. + bool UseAllLinkageNames = true; + + // Dependencies on external options (llc, etc). + bool includeMinimalInlineScopes() const; + bool useAllLinkageNames() const { return UseAllLinkageNames; } + + bool LanguageIsFortran = false; CarlosAlbertoEnciso wrote: In the case of Fortran, `DWLang` can be `dwarf::DW_LANG_Fortran77`, `dwarf::DW_LANG_Fortran90`, `dwarf::DW_LANG_Fortran95`, `dwarf::DW_LANG_Fortran03`, `dwarf::DW_LANG_Fortran08`, `dwarf::DW_LANG_Fortran18`. The mapping is done by `mapFortranLanguage`. https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,300 @@ +//===-- LVIRReader.h *- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This file defines the LVIRReader class, which is used to describe a +// LLVM IR reader. +// +//===--===// + +#ifndef LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H +#define LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H + +#include "llvm/DebugInfo/LogicalView/Core/LVReader.h" +#include "llvm/Transforms/Utils/DebugSSAUpdater.h" + +namespace llvm { +class DIFile; +class DINode; +class DILocation; +class DIScope; +class DISubprogram; +class DIVariable; +class BasicBlock; + +namespace object { +class IRObjectFile; +} + +namespace logicalview { + +class LVElement; +class LVLine; +class LVScopeCompileUnit; +class LVSymbol; +class LVType; + +class LVIRReader final : public LVReader { + object::IRObjectFile *BitCodeIR = nullptr; + MemoryBufferRef *TextualIR = nullptr; + + // Symbols with locations for current compile unit. + LVSymbols SymbolsWithLocations; + + LVSectionIndex SectionIndex = 0; + + const DICompileUnit *CUNode = nullptr; + + // The Dwarf Version (from the module flags). + unsigned DwarfVersion; + + // Location index for global variables. + uint64_t PoolAddressIndex = 0; + + // Whether to emit all linkage names, or just abstract subprograms. + bool UseAllLinkageNames = true; + + // Dependencies on external options (llc, etc). + bool includeMinimalInlineScopes() const; + bool useAllLinkageNames() const { return UseAllLinkageNames; } + + bool LanguageIsFortran = false; + void mapFortranLanguage(unsigned DWLang); + bool moduleIsInFortran() const { return LanguageIsFortran; } + + // Generate logical debug line before prologue. + bool GenerateLineBeforePrologue = true; + + // We assume a constante increase between instructions. + const unsigned OffsetIncrease = 4; + void updateLineOffset() { CurrentOffset += OffsetIncrease; } + + // An anonymous type for index type. + LVType *NodeIndexType = nullptr; + + std::unique_ptr DbgValueRanges; + + // Record the last assigned file index for each compile unit. + using LVIndexFiles = std::map; + LVIndexFiles IndexFiles; + + void updateFileIndex(LVScopeCompileUnit *CompileUnit, size_t FileIndex) { +LVIndexFiles::iterator Iter = IndexFiles.find(CompileUnit); +if (Iter == IndexFiles.end()) + IndexFiles.emplace(CompileUnit, FileIndex); +else + Iter->second = FileIndex; + } + + // Get the current assigned index file for the given compile unit. + size_t getFileIndex(LVScopeCompileUnit *CompileUnit) { +size_t FileIndex = 0; +LVIndexFiles::iterator Iter = IndexFiles.find(CompileUnit); +if (Iter != IndexFiles.end()) + FileIndex = Iter->second; +return FileIndex; + } + + // Collect the compile unit metadata files. + using LVCompileUnitFiles = std::map; + LVCompileUnitFiles CompileUnitFiles; + + size_t getOrCreateSourceID(const DIFile *File); + + // Associate the logical elements to metadata objects. + using LVMDObjects = std::map; + LVMDObjects MDObjects; + + void addMD(const MDNode *MD, LVElement *Element) { +if (MDObjects.find(MD) == MDObjects.end()) + MDObjects.emplace(MD, Element); + } + LVElement *getElementForSeenMD(const MDNode *MD) const { +LVMDObjects::const_iterator Iter = MDObjects.find(MD); +return Iter != MDObjects.end() ? Iter->second : nullptr; + } + LVScope *getScopeForSeenMD(const MDNode *MD) const { +return static_cast(getElementForSeenMD(MD)); + } + LVSymbol *getSymbolForSeenMD(const MDNode *MD) const { +return static_cast(getElementForSeenMD(MD)); + } + LVType *getTypeForSeenMD(const MDNode *MD) const { +return static_cast(getElementForSeenMD(MD)); + } + LVType *getLineForSeenMD(const MDNode *MD) const { +return static_cast(getElementForSeenMD(MD)); + } + + // Inlined concrete scopes with its associated inlined abstract scopes. + // When creating abstract scopes, there is no direct information to find + // the correct lexical scope. + using LVInlinedScopes = std::map; + LVInlinedScopes InlinedScopes; + + void addInlinedScope(LVScope *ConcreteScope, LVScope *AbstractScope) { +if (InlinedScopes.find(ConcreteScope) == InlinedScopes.end()) + InlinedScopes.emplace(ConcreteScope, AbstractScope); + } + LVScope *getInlinedScope(LVScope *ConcreteScope) const { CarlosAlbertoEnciso wrote: The name is correct. The name issues are related to the general naming used when these functions `addInlinedScope` and `getInlinedScope` are called. https://github.com/llvm/llvm-project/pull/135440
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,300 @@ +//===-- LVIRReader.h *- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This file defines the LVIRReader class, which is used to describe a +// LLVM IR reader. +// +//===--===// + +#ifndef LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H +#define LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H + +#include "llvm/DebugInfo/LogicalView/Core/LVReader.h" +#include "llvm/Transforms/Utils/DebugSSAUpdater.h" + +namespace llvm { +class DIFile; +class DINode; +class DILocation; +class DIScope; +class DISubprogram; +class DIVariable; +class BasicBlock; + +namespace object { +class IRObjectFile; +} + +namespace logicalview { + +class LVElement; +class LVLine; +class LVScopeCompileUnit; +class LVSymbol; +class LVType; + +class LVIRReader final : public LVReader { + object::IRObjectFile *BitCodeIR = nullptr; + MemoryBufferRef *TextualIR = nullptr; + + // Symbols with locations for current compile unit. + LVSymbols SymbolsWithLocations; + + LVSectionIndex SectionIndex = 0; + + const DICompileUnit *CUNode = nullptr; + + // The Dwarf Version (from the module flags). + unsigned DwarfVersion; + + // Location index for global variables. + uint64_t PoolAddressIndex = 0; + + // Whether to emit all linkage names, or just abstract subprograms. + bool UseAllLinkageNames = true; + + // Dependencies on external options (llc, etc). + bool includeMinimalInlineScopes() const; + bool useAllLinkageNames() const { return UseAllLinkageNames; } + + bool LanguageIsFortran = false; + void mapFortranLanguage(unsigned DWLang); + bool moduleIsInFortran() const { return LanguageIsFortran; } + + // Generate logical debug line before prologue. + bool GenerateLineBeforePrologue = true; + + // We assume a constante increase between instructions. + const unsigned OffsetIncrease = 4; + void updateLineOffset() { CurrentOffset += OffsetIncrease; } + + // An anonymous type for index type. + LVType *NodeIndexType = nullptr; + + std::unique_ptr DbgValueRanges; + + // Record the last assigned file index for each compile unit. + using LVIndexFiles = std::map; + LVIndexFiles IndexFiles; CarlosAlbertoEnciso wrote: Added your suggested comment. https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,2348 @@ +//===-- LVIRReader.cpp ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This implements the LVIRReader class. +// It supports LLVM text IR and bitcode format. +// +//===--===// + +#include "llvm/DebugInfo/LogicalView/Readers/LVIRReader.h" +#include "llvm/CodeGen/DebugHandlerBase.h" +#include "llvm/DebugInfo/LogicalView/Core/LVLine.h" +#include "llvm/DebugInfo/LogicalView/Core/LVScope.h" +#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h" +#include "llvm/DebugInfo/LogicalView/Core/LVType.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Module.h" +#include "llvm/IRReader/IRReader.h" +#include "llvm/Object/Error.h" +#include "llvm/Object/IRObjectFile.h" +#include "llvm/Support/FormatAdapters.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/SourceMgr.h" + +using namespace llvm; +using namespace llvm::object; +using namespace llvm::logicalview; + +#define DEBUG_TYPE "IRReader" + +// Extra debug traces. Default is false +#define DEBUG_ALL + +// These flavours of DINodes are not handled: +// DW_TAG_APPLE_property = 19896 +// DW_TAG_atomic_type = 71 +// DW_TAG_common_block = 26 +// DW_TAG_file_type= 41 +// DW_TAG_friend = 42 +// DW_TAG_generic_subrange = 69 +// DW_TAG_immutable_type = 75 +// DW_TAG_module = 30 + +// Create a logical element and setup the following information: +// - Name, DWARF tag, line +// - Collect any file information +LVElement *LVIRReader::constructElement(const DINode *DN) { + dwarf::Tag Tag = DN->getTag(); + LVElement *Element = createElement(Tag); + if (Element) { +Element->setTag(Tag); +addMD(DN, Element); + +StringRef Name = getMDName(DN); +if (!Name.empty()) + Element->setName(Name); + +// Record any file information. +if (const DIFile *File = getMDFile(DN)) + getOrCreateSourceID(File); + } + + return Element; +} + +void LVIRReader::mapFortranLanguage(unsigned DWLang) { + switch (DWLang) { + case dwarf::DW_LANG_Fortran77: + case dwarf::DW_LANG_Fortran90: + case dwarf::DW_LANG_Fortran95: + case dwarf::DW_LANG_Fortran03: + case dwarf::DW_LANG_Fortran08: + case dwarf::DW_LANG_Fortran18: +LanguageIsFortran = true; +break; + default: +LanguageIsFortran = false; + } +} + +// Looking at IR generated with the '-gdwarf -gsplit-dwarf=split' the only +// difference is setting the 'DICompileUnit::splitDebugFilename' to the +// name of the split filename: "xxx.dwo". +bool LVIRReader::includeMinimalInlineScopes() const { + return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly; +} + +// For the given 'DIFile' generate an index 1-based to indicate the +// source file where the logical element is declared. +// In DWARF v4, the files are 1-indexed. +// In DWARF v5, the files are 0-indexed. +// The IR reader expects the indexes as 1-indexed. +// Each compile unit, keeps track of the last assigned index. +size_t LVIRReader::getOrCreateSourceID(const DIFile *File) { + if (!File) +return 0; + +#ifdef DEBUG_ALL + LLVM_DEBUG({ +dbgs() << "\n[getOrCreateSourceID] DIFile\n"; +File->dump(); + }); +#endif + + addMD(File, CompileUnit); + + LLVM_DEBUG({ +dbgs() << "Directory: '" << File->getDirectory() << "'\n"; +dbgs() << "Filename: '" << File->getFilename() << "'\n"; + }); + size_t FileIndex = 0; + LVCompileUnitFiles::iterator Iter = CompileUnitFiles.find(File); + if (Iter == CompileUnitFiles.cend()) { CarlosAlbertoEnciso wrote: Changed to `end()` https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -22,6 +22,30 @@ using namespace llvm::logicalview; #define DEBUG_TYPE "Reader" +// Traverse all the logical elements and print its basic information. +void printCollectedElements(LVScope *Root) { + std::function TraverseScope = [&](LVScope *Parent) { +// Print the elements. +auto Print = [&](const auto &Set) { + if (Set) CarlosAlbertoEnciso wrote: Good catch. Changed. https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [llvm-debuginfo-analyzer] Add support for LLVM IR format. (PR #135440)
@@ -0,0 +1,2348 @@ +//===-- LVIRReader.cpp ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This implements the LVIRReader class. +// It supports LLVM text IR and bitcode format. +// +//===--===// + +#include "llvm/DebugInfo/LogicalView/Readers/LVIRReader.h" +#include "llvm/CodeGen/DebugHandlerBase.h" +#include "llvm/DebugInfo/LogicalView/Core/LVLine.h" +#include "llvm/DebugInfo/LogicalView/Core/LVScope.h" +#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h" +#include "llvm/DebugInfo/LogicalView/Core/LVType.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Module.h" +#include "llvm/IRReader/IRReader.h" +#include "llvm/Object/Error.h" +#include "llvm/Object/IRObjectFile.h" +#include "llvm/Support/FormatAdapters.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/SourceMgr.h" + +using namespace llvm; +using namespace llvm::object; +using namespace llvm::logicalview; + +#define DEBUG_TYPE "IRReader" + +// Extra debug traces. Default is false +#define DEBUG_ALL + +// These flavours of DINodes are not handled: CarlosAlbertoEnciso wrote: Changed comment to: `// These flavours of DINodes are not implemented but technically possible:` https://github.com/llvm/llvm-project/pull/135440 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits