1 | //===- DebugImporter.h - LLVM to MLIR Debug conversion -------*- C++ -*----===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file implements the translation between LLVMIR debug information and |
10 | // the corresponding MLIR representation. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef MLIR_LIB_TARGET_LLVMIR_DEBUGIMPORTER_H_ |
15 | #define MLIR_LIB_TARGET_LLVMIR_DEBUGIMPORTER_H_ |
16 | |
17 | #include "mlir/Dialect/LLVMIR/LLVMDialect.h" |
18 | #include "mlir/IR/BuiltinOps.h" |
19 | #include "mlir/IR/MLIRContext.h" |
20 | #include "mlir/Support/CyclicReplacerCache.h" |
21 | #include "llvm/ADT/MapVector.h" |
22 | #include "llvm/IR/DebugInfoMetadata.h" |
23 | |
24 | namespace mlir { |
25 | class Operation; |
26 | |
27 | namespace LLVM { |
28 | class LLVMFuncOp; |
29 | |
30 | namespace detail { |
31 | |
32 | class DebugImporter { |
33 | public: |
34 | DebugImporter(ModuleOp mlirModule, bool dropDICompositeTypeElements); |
35 | |
36 | /// Translates the given LLVM debug location to an MLIR location. |
37 | Location translateLoc(llvm::DILocation *loc); |
38 | |
39 | /// Translates the LLVM DWARF expression metadata to MLIR. |
40 | DIExpressionAttr translateExpression(llvm::DIExpression *node); |
41 | |
42 | /// Translates the LLVM DWARF global variable expression metadata to MLIR. |
43 | DIGlobalVariableExpressionAttr |
44 | translateGlobalVariableExpression(llvm::DIGlobalVariableExpression *node); |
45 | |
46 | /// Translates the debug information for the given function into a Location. |
47 | /// Returns UnknownLoc if `func` has no debug information attached to it. |
48 | Location translateFuncLocation(llvm::Function *func); |
49 | |
50 | /// Translates the given LLVM debug metadata to MLIR. |
51 | DINodeAttr translate(llvm::DINode *node); |
52 | |
53 | /// Infers the metadata type and translates it to MLIR. |
54 | template <typename DINodeT> |
55 | auto translate(DINodeT *node) { |
56 | // Infer the MLIR type from the LLVM metadata type. |
57 | using MLIRTypeT = decltype(translateImpl(node)); |
58 | return cast_or_null<MLIRTypeT>( |
59 | translate(node: static_cast<llvm::DINode *>(node))); |
60 | } |
61 | |
62 | private: |
63 | /// Translates the given LLVM debug metadata to the corresponding attribute. |
64 | DIBasicTypeAttr translateImpl(llvm::DIBasicType *node); |
65 | DICompileUnitAttr translateImpl(llvm::DICompileUnit *node); |
66 | DICompositeTypeAttr translateImpl(llvm::DICompositeType *node); |
67 | DIDerivedTypeAttr translateImpl(llvm::DIDerivedType *node); |
68 | DIStringTypeAttr translateImpl(llvm::DIStringType *node); |
69 | DIFileAttr translateImpl(llvm::DIFile *node); |
70 | DILabelAttr translateImpl(llvm::DILabel *node); |
71 | DILexicalBlockAttr translateImpl(llvm::DILexicalBlock *node); |
72 | DILexicalBlockFileAttr translateImpl(llvm::DILexicalBlockFile *node); |
73 | DIGlobalVariableAttr translateImpl(llvm::DIGlobalVariable *node); |
74 | DILocalVariableAttr translateImpl(llvm::DILocalVariable *node); |
75 | DIVariableAttr translateImpl(llvm::DIVariable *node); |
76 | DIModuleAttr translateImpl(llvm::DIModule *node); |
77 | DINamespaceAttr translateImpl(llvm::DINamespace *node); |
78 | DIImportedEntityAttr translateImpl(llvm::DIImportedEntity *node); |
79 | DIScopeAttr translateImpl(llvm::DIScope *node); |
80 | DISubprogramAttr translateImpl(llvm::DISubprogram *node); |
81 | DISubrangeAttr translateImpl(llvm::DISubrange *node); |
82 | DIGenericSubrangeAttr translateImpl(llvm::DIGenericSubrange *node); |
83 | DICommonBlockAttr translateImpl(llvm::DICommonBlock *node); |
84 | DISubroutineTypeAttr translateImpl(llvm::DISubroutineType *node); |
85 | DITypeAttr translateImpl(llvm::DIType *node); |
86 | |
87 | /// Constructs a StringAttr from the MDString if it is non-null. Returns a |
88 | /// null attribute otherwise. |
89 | StringAttr getStringAttrOrNull(llvm::MDString *stringNode); |
90 | |
91 | /// Get the DistinctAttr used to represent `node` if one was already created |
92 | /// for it, or create a new one if not. |
93 | DistinctAttr getOrCreateDistinctID(llvm::DINode *node); |
94 | |
95 | std::optional<DINodeAttr> createRecSelf(llvm::DINode *node); |
96 | |
97 | /// A mapping between distinct LLVM debug metadata nodes and the corresponding |
98 | /// distinct id attribute. |
99 | DenseMap<llvm::DINode *, DistinctAttr> nodeToDistinctAttr; |
100 | |
101 | /// A mapping between DINodes that are recursive, and their assigned recId. |
102 | /// This is kept so that repeated occurrences of the same node can reuse the |
103 | /// same ID and be deduplicated. |
104 | DenseMap<llvm::DINode *, DistinctAttr> nodeToRecId; |
105 | |
106 | CyclicReplacerCache<llvm::DINode *, DINodeAttr> cache; |
107 | |
108 | MLIRContext *context; |
109 | ModuleOp mlirModule; |
110 | |
111 | /// An option to control if DICompositeTypes should always be imported without |
112 | /// converting their elements. If set, the option avoids the recursive |
113 | /// traversal of composite type debug information, which can be expensive for |
114 | /// adversarial inputs. |
115 | bool dropDICompositeTypeElements; |
116 | }; |
117 | |
118 | } // namespace detail |
119 | } // namespace LLVM |
120 | } // namespace mlir |
121 | |
122 | #endif // MLIR_LIB_TARGET_LLVMIR_DEBUGIMPORTER_H_ |
123 | |