//===- DebugTranslation.h - MLIR to LLVM 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 an MLIR debug information and // the corresponding LLVMIR representation. // //===----------------------------------------------------------------------===// #ifndef MLIR_LIB_TARGET_LLVMIR_DEBUGTRANSLATION_H_ #define MLIR_LIB_TARGET_LLVMIR_DEBUGTRANSLATION_H_ #include "mlir/Dialect/LLVMIR/LLVMDialect.h" #include "mlir/IR/Location.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringMap.h" #include "llvm/IR/DIBuilder.h" namespace mlir { class Operation; namespace LLVM { class LLVMFuncOp; namespace detail { class DebugTranslation { public: DebugTranslation(Operation *module, llvm::Module &llvmModule); /// Adds the necessary module flags to the module, if not yet present. void addModuleFlagsIfNotPresent(); /// Translate the given location to an llvm debug location. llvm::DILocation *translateLoc(Location loc, llvm::DILocalScope *scope); /// Translates the given DWARF expression metadata to to LLVM. llvm::DIExpression *translateExpression(LLVM::DIExpressionAttr attr); /// Translates the given DWARF global variable expression to LLVM. llvm::DIGlobalVariableExpression * translateGlobalVariableExpression(LLVM::DIGlobalVariableExpressionAttr attr); /// Translate the debug information for the given function. void translate(LLVMFuncOp func, llvm::Function &llvmFunc); /// Translate the given LLVM debug metadata to LLVM. llvm::DINode *translate(DINodeAttr attr); /// Translate the given derived LLVM debug metadata to LLVM. template auto translate(DIAttrT attr) { // Infer the LLVM type from the attribute type. using LLVMTypeT = std::remove_pointer_t; return cast_or_null(translate(DINodeAttr(attr))); } private: /// Translate the given location to an llvm debug location with the given /// scope and inlinedAt parameters. llvm::DILocation *translateLoc(Location loc, llvm::DILocalScope *scope, llvm::DILocation *inlinedAt); /// Create an llvm debug file for the given file path. llvm::DIFile *translateFile(StringRef fileName); /// Translate the given attribute to the corresponding llvm debug metadata. llvm::DIType *translateImpl(DINullTypeAttr attr); llvm::DIBasicType *translateImpl(DIBasicTypeAttr attr); llvm::DICompileUnit *translateImpl(DICompileUnitAttr attr); llvm::DICompositeType *translateImpl(DICompositeTypeAttr attr); llvm::DIDerivedType *translateImpl(DIDerivedTypeAttr attr); llvm::DIStringType *translateImpl(DIStringTypeAttr attr); llvm::DIFile *translateImpl(DIFileAttr attr); llvm::DIImportedEntity *translateImpl(DIImportedEntityAttr attr); llvm::DILabel *translateImpl(DILabelAttr attr); llvm::DILexicalBlock *translateImpl(DILexicalBlockAttr attr); llvm::DILexicalBlockFile *translateImpl(DILexicalBlockFileAttr attr); llvm::DILocalScope *translateImpl(DILocalScopeAttr attr); llvm::DILocalVariable *translateImpl(DILocalVariableAttr attr); llvm::DIGlobalVariable *translateImpl(DIGlobalVariableAttr attr); llvm::DIVariable *translateImpl(DIVariableAttr attr); llvm::DIModule *translateImpl(DIModuleAttr attr); llvm::DINamespace *translateImpl(DINamespaceAttr attr); llvm::DIScope *translateImpl(DIScopeAttr attr); llvm::DISubprogram *translateImpl(DISubprogramAttr attr); llvm::DIGenericSubrange *translateImpl(DIGenericSubrangeAttr attr); llvm::DISubrange *translateImpl(DISubrangeAttr attr); llvm::DICommonBlock *translateImpl(DICommonBlockAttr attr); llvm::DISubroutineType *translateImpl(DISubroutineTypeAttr attr); llvm::DIType *translateImpl(DITypeAttr attr); /// Attributes that support self recursion need to implement an additional /// method to hook into `translateRecursive`. /// - ` translateTemporaryImpl()`: /// Create a temporary translation of the DI attr without recursively /// translating any nested DI attrs. llvm::DINode *translateRecursive(DIRecursiveTypeAttrInterface attr); /// Translate the given attribute to a temporary llvm debug metadata of the /// corresponding type. llvm::TempDICompositeType translateTemporaryImpl(DICompositeTypeAttr attr); llvm::TempDISubprogram translateTemporaryImpl(DISubprogramAttr attr); /// Constructs a string metadata node from the string attribute. Returns /// nullptr if `stringAttr` is null or contains and empty string. llvm::MDString *getMDStringOrNull(StringAttr stringAttr); /// Constructs a tuple metadata node from the `elements`. Returns nullptr if /// `elements` is empty. llvm::MDTuple *getMDTupleOrNull(ArrayRef elements); /// Constructs a DIExpression metadata node from the DIExpressionAttr. Returns /// nullptr if `DIExpressionAttr` is null. llvm::DIExpression *getExpressionAttrOrNull(DIExpressionAttr attr); /// A mapping between mlir location+scope and the corresponding llvm debug /// metadata. DenseMap, llvm::DILocation *> locationToLoc; /// A mapping between debug attribute and the corresponding llvm debug /// metadata. DenseMap attrToNode; /// A mapping between recursive ID and the translated DINode. llvm::MapVector recursiveNodeMap; /// A mapping between a distinct ID and the translated LLVM metadata node. /// This helps identify attrs that should translate into the same LLVM debug /// node. DenseMap distinctAttrToNode; /// A mapping between filename and llvm debug file. /// TODO: Change this to DenseMap when we can /// access the Identifier filename in FileLineColLoc. llvm::StringMap fileMap; /// A string containing the current working directory of the compiler. SmallString<256> currentWorkingDir; /// Flag indicating if debug information should be emitted. bool debugEmissionIsEnabled; /// Debug information fields. llvm::Module &llvmModule; llvm::LLVMContext &llvmCtx; }; } // namespace detail } // namespace LLVM } // namespace mlir #endif // MLIR_LIB_TARGET_LLVMIR_DEBUGTRANSLATION_H_