| //===- DebugImporter.h - LLVM to MLIR Debug conversion -------*- 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 implements the translation between LLVMIR debug information and | |
| // the corresponding MLIR representation. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #ifndef MLIR_LIB_TARGET_LLVMIR_DEBUGIMPORTER_H_ | |
| #define MLIR_LIB_TARGET_LLVMIR_DEBUGIMPORTER_H_ | |
| #include "mlir/Dialect/LLVMIR/LLVMDialect.h" | |
| #include "mlir/IR/BuiltinOps.h" | |
| #include "mlir/IR/MLIRContext.h" | |
| #include "mlir/Support/CyclicReplacerCache.h" | |
| #include "llvm/ADT/MapVector.h" | |
| #include "llvm/IR/DebugInfoMetadata.h" | |
| namespace mlir { | |
| class Operation; | |
| namespace LLVM { | |
| class LLVMFuncOp; | |
| namespace detail { | |
| class DebugImporter { | |
| public: | |
| DebugImporter(ModuleOp mlirModule, bool dropDICompositeTypeElements); | |
| /// Translates the given LLVM debug location to an MLIR location. | |
| Location translateLoc(llvm::DILocation *loc); | |
| /// Translates the LLVM DWARF expression metadata to MLIR. | |
| DIExpressionAttr translateExpression(llvm::DIExpression *node); | |
| /// Translates the LLVM DWARF global variable expression metadata to MLIR. | |
| DIGlobalVariableExpressionAttr | |
| translateGlobalVariableExpression(llvm::DIGlobalVariableExpression *node); | |
| /// Translates the debug information for the given function into a Location. | |
| /// Returns UnknownLoc if `func` has no debug information attached to it. | |
| Location translateFuncLocation(llvm::Function *func); | |
| /// Translates the given LLVM debug metadata to MLIR. | |
| DINodeAttr translate(llvm::DINode *node); | |
| /// Infers the metadata type and translates it to MLIR. | |
| template <typename DINodeT> | |
| auto translate(DINodeT *node) { | |
| // Infer the MLIR type from the LLVM metadata type. | |
| using MLIRTypeT = decltype(translateImpl(node)); | |
| return cast_or_null<MLIRTypeT>( | |
| translate(static_cast<llvm::DINode *>(node))); | |
| } | |
| private: | |
| /// Translates the given LLVM debug metadata to the corresponding attribute. | |
| DIBasicTypeAttr translateImpl(llvm::DIBasicType *node); | |
| DICompileUnitAttr translateImpl(llvm::DICompileUnit *node); | |
| DICompositeTypeAttr translateImpl(llvm::DICompositeType *node); | |
| DIDerivedTypeAttr translateImpl(llvm::DIDerivedType *node); | |
| DIStringTypeAttr translateImpl(llvm::DIStringType *node); | |
| DIFileAttr translateImpl(llvm::DIFile *node); | |
| DILabelAttr translateImpl(llvm::DILabel *node); | |
| DILexicalBlockAttr translateImpl(llvm::DILexicalBlock *node); | |
| DILexicalBlockFileAttr translateImpl(llvm::DILexicalBlockFile *node); | |
| DIGlobalVariableAttr translateImpl(llvm::DIGlobalVariable *node); | |
| DILocalVariableAttr translateImpl(llvm::DILocalVariable *node); | |
| DIVariableAttr translateImpl(llvm::DIVariable *node); | |
| DIModuleAttr translateImpl(llvm::DIModule *node); | |
| DINamespaceAttr translateImpl(llvm::DINamespace *node); | |
| DIImportedEntityAttr translateImpl(llvm::DIImportedEntity *node); | |
| DIScopeAttr translateImpl(llvm::DIScope *node); | |
| DISubprogramAttr translateImpl(llvm::DISubprogram *node); | |
| DISubrangeAttr translateImpl(llvm::DISubrange *node); | |
| DIGenericSubrangeAttr translateImpl(llvm::DIGenericSubrange *node); | |
| DICommonBlockAttr translateImpl(llvm::DICommonBlock *node); | |
| DISubroutineTypeAttr translateImpl(llvm::DISubroutineType *node); | |
| DITypeAttr translateImpl(llvm::DIType *node); | |
| /// Constructs a StringAttr from the MDString if it is non-null. Returns a | |
| /// null attribute otherwise. | |
| StringAttr getStringAttrOrNull(llvm::MDString *stringNode); | |
| /// Get the DistinctAttr used to represent `node` if one was already created | |
| /// for it, or create a new one if not. | |
| DistinctAttr getOrCreateDistinctID(llvm::DINode *node); | |
| std::optional<DINodeAttr> createRecSelf(llvm::DINode *node); | |
| /// A mapping between distinct LLVM debug metadata nodes and the corresponding | |
| /// distinct id attribute. | |
| DenseMap<llvm::DINode *, DistinctAttr> nodeToDistinctAttr; | |
| /// A mapping between DINodes that are recursive, and their assigned recId. | |
| /// This is kept so that repeated occurrences of the same node can reuse the | |
| /// same ID and be deduplicated. | |
| DenseMap<llvm::DINode *, DistinctAttr> nodeToRecId; | |
| CyclicReplacerCache<llvm::DINode *, DINodeAttr> cache; | |
| MLIRContext *context; | |
| ModuleOp mlirModule; | |
| /// An option to control if DICompositeTypes should always be imported without | |
| /// converting their elements. If set, the option avoids the recursive | |
| /// traversal of composite type debug information, which can be expensive for | |
| /// adversarial inputs. | |
| bool dropDICompositeTypeElements; | |
| }; | |
| } // namespace detail | |
| } // namespace LLVM | |
| } // namespace mlir | |
| #endif // MLIR_LIB_TARGET_LLVMIR_DEBUGIMPORTER_H_ |