[Mlir-commits] [mlir] 3f63889 - [mlir][llvm] Import additional debug info from LLVMIR.
Tobias Gysi
llvmlistbot at llvm.org
Fri Nov 18 00:48:59 PST 2022
Author: Tobias Gysi
Date: 2022-11-18T09:44:40+01:00
New Revision: 3f63889d58c363348832eaf789e340f11d0d0ee8
URL: https://github.com/llvm/llvm-project/commit/3f63889d58c363348832eaf789e340f11d0d0ee8
DIFF: https://github.com/llvm/llvm-project/commit/3f63889d58c363348832eaf789e340f11d0d0ee8.diff
LOG: [mlir][llvm] Import additional debug info from LLVMIR.
Add a DebugImporter to convert LLVMIR debug metadata into
MLIR debug attributes. It is the counterpart to the
DebugTranslation class and supports the same attributes.
The revision only supports the translation of instruction,
function, and module debug information. The import of
intrinsics is left to a later revision.
Depends on D138206
Reviewed By: rriddle
Differential Revision: https://reviews.llvm.org/D138209
Added:
mlir/lib/Target/LLVMIR/DebugImporter.cpp
mlir/lib/Target/LLVMIR/DebugImporter.h
Modified:
mlir/lib/Target/LLVMIR/CMakeLists.txt
mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
mlir/test/Target/LLVMIR/Import/debug-info.ll
Removed:
################################################################################
diff --git a/mlir/lib/Target/LLVMIR/CMakeLists.txt b/mlir/lib/Target/LLVMIR/CMakeLists.txt
index 3ee83820b1e2e..caf3621854748 100644
--- a/mlir/lib/Target/LLVMIR/CMakeLists.txt
+++ b/mlir/lib/Target/LLVMIR/CMakeLists.txt
@@ -4,6 +4,7 @@ set(LLVM_OPTIONAL_SOURCES
ConvertFromLLVMIR.cpp
ConvertToLLVMIR.cpp
DebugTranslation.cpp
+ DebugImporter.cpp
ModuleTranslation.cpp
TypeToLLVM.cpp
TypeFromLLVM.cpp
@@ -50,6 +51,7 @@ add_mlir_translation_library(MLIRToLLVMIRTranslationRegistration
add_mlir_translation_library(MLIRTargetLLVMIRImport
ConvertFromLLVMIR.cpp
+ DebugImporter.cpp
TypeFromLLVM.cpp
ADDITIONAL_HEADER_DIRS
diff --git a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
index 18cff0c466771..78b5e226fb484 100644
--- a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
+++ b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
@@ -10,6 +10,7 @@
//
//===----------------------------------------------------------------------===//
+#include "DebugImporter.h"
#include "mlir/Target/LLVMIR/Import.h"
#include "mlir/Dialect/DLTI/DLTI.h"
@@ -42,6 +43,7 @@
using namespace mlir;
using namespace mlir::LLVM;
+using mlir::LLVM::detail::DebugImporter;
#include "mlir/Dialect/LLVMIR/LLVMConversionEnumsFromLLVM.inc"
@@ -329,7 +331,7 @@ class Importer {
public:
Importer(MLIRContext *context, ModuleOp module)
: builder(context), context(context), module(module),
- typeTranslator(*context) {
+ typeTranslator(*context), debugImporter(context) {
builder.setInsertionPointToStart(module.getBody());
}
@@ -369,12 +371,15 @@ class Importer {
/// Converts `value` to an integer attribute. Asserts if the conversion fails.
IntegerAttr matchIntegerAttr(Value value);
- /// Translate the debug location to a FileLineColLoc, if `loc` is non-null.
- /// Otherwise, return UnknownLoc.
- Location translateLoc(llvm::DILocation *loc);
+ /// Translates the debug location.
+ Location translateLoc(llvm::DILocation *loc) {
+ return debugImporter.translateLoc(loc);
+ }
/// Converts the type from LLVM to MLIR LLVM dialect.
- Type convertType(llvm::Type *type);
+ Type convertType(llvm::Type *type) {
+ return typeTranslator.translateType(type);
+ }
/// Converts an LLVM intrinsic to an MLIR LLVM dialect operation if an MLIR
/// counterpart exists. Otherwise, returns failure.
@@ -450,21 +455,11 @@ class Importer {
DenseMap<llvm::GlobalVariable *, GlobalOp> globals;
/// The stateful type translator (contains named structs).
LLVM::TypeFromLLVMIRTranslator typeTranslator;
+ /// Stateful debug information importer.
+ DebugImporter debugImporter;
};
} // namespace
-Location Importer::translateLoc(llvm::DILocation *loc) {
- if (!loc)
- return UnknownLoc::get(context);
-
- return FileLineColLoc::get(context, loc->getFilename(), loc->getLine(),
- loc->getColumn());
-}
-
-Type Importer::convertType(llvm::Type *type) {
- return typeTranslator.translateType(type);
-}
-
LogicalResult Importer::convertIntrinsic(OpBuilder &odsBuilder,
llvm::CallInst *inst) {
// Check if the callee is an intrinsic.
@@ -1064,6 +1059,9 @@ LogicalResult Importer::processFunction(llvm::Function *func) {
UnknownLoc::get(context), func->getName(), functionType,
convertLinkageFromLLVM(func->getLinkage()), dsoLocal, cconv);
+ // Set the function debug information if available.
+ debugImporter.translate(func, funcOp);
+
for (const auto &it : llvm::enumerate(functionType.getParams())) {
llvm::SmallVector<NamedAttribute, 1> argAttrs;
if (auto *type = func->getParamByValType(it.index())) {
@@ -1150,8 +1148,9 @@ mlir::translateLLVMIRToModule(std::unique_ptr<llvm::Module> llvmModule,
MLIRContext *context) {
context->loadDialect<LLVMDialect>();
context->loadDialect<DLTIDialect>();
- OwningOpRef<ModuleOp> module(ModuleOp::create(
- FileLineColLoc::get(context, "", /*line=*/0, /*column=*/0)));
+ OwningOpRef<ModuleOp> module(ModuleOp::create(FileLineColLoc::get(
+ StringAttr::get(context, llvmModule->getSourceFileName()), /*line=*/0,
+ /*column=*/0)));
DataLayoutSpecInterface dlSpec =
translateDataLayout(llvmModule->getDataLayout(), context);
diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.cpp b/mlir/lib/Target/LLVMIR/DebugImporter.cpp
new file mode 100644
index 0000000000000..cd1f58f632146
--- /dev/null
+++ b/mlir/lib/Target/LLVMIR/DebugImporter.cpp
@@ -0,0 +1,209 @@
+//===- DebugImporter.cpp - LLVM to MLIR Debug conversion ------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "DebugImporter.h"
+#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
+#include "mlir/IR/Attributes.h"
+#include "mlir/IR/BuiltinAttributes.h"
+#include "mlir/IR/Location.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+
+using namespace mlir;
+using namespace mlir::LLVM;
+using namespace mlir::LLVM::detail;
+
+void DebugImporter::translate(llvm::Function *func, LLVMFuncOp funcOp) {
+ if (!func->getSubprogram())
+ return;
+
+ // Add a fused location to link the subprogram information.
+ StringAttr name = StringAttr::get(context, func->getSubprogram()->getName());
+ funcOp->setLoc(FusedLocWith<DISubprogramAttr>::get(
+ {NameLoc::get(name)}, translate(func->getSubprogram()), context));
+}
+
+//===----------------------------------------------------------------------===//
+// Attributes
+//===----------------------------------------------------------------------===//
+
+DIBasicTypeAttr DebugImporter::translateImpl(llvm::DIBasicType *node) {
+ return DIBasicTypeAttr::get(context, node->getTag(), node->getName(),
+ node->getSizeInBits(), node->getEncoding());
+}
+
+DICompileUnitAttr DebugImporter::translateImpl(llvm::DICompileUnit *node) {
+ Optional<DIEmissionKind> emissionKind =
+ symbolizeDIEmissionKind(node->getEmissionKind());
+ return DICompileUnitAttr::get(context, node->getSourceLanguage(),
+ translate(node->getFile()),
+ StringAttr::get(context, node->getProducer()),
+ node->isOptimized(), emissionKind.value());
+}
+
+DICompositeTypeAttr DebugImporter::translateImpl(llvm::DICompositeType *node) {
+ Optional<DIFlags> flags = symbolizeDIFlags(node->getFlags());
+ SmallVector<DINodeAttr> elements;
+ for (llvm::DINode *element : node->getElements()) {
+ assert(element && "expected a non-null element type");
+ elements.push_back(translate(element));
+ }
+ return DICompositeTypeAttr::get(
+ context, node->getTag(), StringAttr::get(context, node->getName()),
+ translate(node->getFile()), node->getLine(), translate(node->getScope()),
+ translate(node->getBaseType()), flags.value_or(DIFlags::Zero),
+ node->getSizeInBits(), node->getAlignInBits(), elements);
+}
+
+DIDerivedTypeAttr DebugImporter::translateImpl(llvm::DIDerivedType *node) {
+ return DIDerivedTypeAttr::get(
+ context, node->getTag(),
+ node->getRawName() ? StringAttr::get(context, node->getName()) : nullptr,
+ translate(node->getBaseType()), node->getSizeInBits(),
+ node->getAlignInBits(), node->getOffsetInBits());
+}
+
+DIFileAttr DebugImporter::translateImpl(llvm::DIFile *node) {
+ return DIFileAttr::get(context, node->getFilename(), node->getDirectory());
+}
+
+DILexicalBlockAttr DebugImporter::translateImpl(llvm::DILexicalBlock *node) {
+ return DILexicalBlockAttr::get(context, translate(node->getScope()),
+ translate(node->getFile()), node->getLine(),
+ node->getColumn());
+}
+
+DILexicalBlockFileAttr
+DebugImporter::translateImpl(llvm::DILexicalBlockFile *node) {
+ return DILexicalBlockFileAttr::get(context, translate(node->getScope()),
+ translate(node->getFile()),
+ node->getDiscriminator());
+}
+
+DILocalVariableAttr DebugImporter::translateImpl(llvm::DILocalVariable *node) {
+ return DILocalVariableAttr::get(context, translate(node->getScope()),
+ StringAttr::get(context, node->getName()),
+ translate(node->getFile()), node->getLine(),
+ node->getArg(), node->getAlignInBits(),
+ translate(node->getType()));
+}
+
+DIScopeAttr DebugImporter::translateImpl(llvm::DIScope *node) {
+ return cast<DIScopeAttr>(translate(static_cast<llvm::DINode *>(node)));
+}
+
+DISubprogramAttr DebugImporter::translateImpl(llvm::DISubprogram *node) {
+ Optional<DISubprogramFlags> subprogramFlags =
+ symbolizeDISubprogramFlags(node->getSubprogram()->getSPFlags());
+ return DISubprogramAttr::get(
+ context, translate(node->getUnit()), translate(node->getScope()),
+ StringAttr::get(context, node->getName()),
+ node->getRawLinkageName()
+ ? StringAttr::get(context, node->getLinkageName())
+ : nullptr,
+ translate(node->getFile()), node->getLine(), node->getScopeLine(),
+ subprogramFlags.value(), translate(node->getType()));
+}
+
+DISubrangeAttr DebugImporter::translateImpl(llvm::DISubrange *node) {
+ auto getIntegerAttrOrNull = [&](llvm::DISubrange::BoundType data) {
+ if (auto *constInt = llvm::dyn_cast_or_null<llvm::ConstantInt *>(data))
+ return IntegerAttr::get(IntegerType::get(context, 64),
+ constInt->getSExtValue());
+ return IntegerAttr();
+ };
+ return DISubrangeAttr::get(context, getIntegerAttrOrNull(node->getCount()),
+ getIntegerAttrOrNull(node->getLowerBound()),
+ getIntegerAttrOrNull(node->getUpperBound()),
+ getIntegerAttrOrNull(node->getStride()));
+}
+
+DISubroutineTypeAttr
+DebugImporter::translateImpl(llvm::DISubroutineType *node) {
+ // Separate the result type since it is null for void functions.
+ DITypeAttr resultType = translate(*node->getTypeArray().begin());
+ SmallVector<DITypeAttr> argumentTypes;
+ for (llvm::DIType *type : llvm::drop_begin(node->getTypeArray())) {
+ assert(type && "expected a non-null argument type");
+ argumentTypes.push_back(translate(type));
+ }
+ return DISubroutineTypeAttr::get(context, node->getCC(), resultType,
+ argumentTypes);
+}
+
+DITypeAttr DebugImporter::translateImpl(llvm::DIType *node) {
+ return cast<DITypeAttr>(translate(static_cast<llvm::DINode *>(node)));
+}
+
+DINodeAttr DebugImporter::translate(llvm::DINode *node) {
+ if (!node)
+ return nullptr;
+
+ // Check for a cached instance.
+ if (DINodeAttr attr = nodeToAttr.lookup(node))
+ return attr;
+
+ // Convert the debug metadata if possible.
+ auto translateNode = [this](llvm::DINode *node) -> DINodeAttr {
+ if (auto *casted = dyn_cast<llvm::DIBasicType>(node))
+ return translateImpl(casted);
+ if (auto *casted = dyn_cast<llvm::DICompileUnit>(node))
+ return translateImpl(casted);
+ if (auto *casted = dyn_cast<llvm::DICompositeType>(node))
+ return translateImpl(casted);
+ if (auto *casted = dyn_cast<llvm::DIDerivedType>(node))
+ return translateImpl(casted);
+ if (auto *casted = dyn_cast<llvm::DIFile>(node))
+ return translateImpl(casted);
+ if (auto *casted = dyn_cast<llvm::DILexicalBlock>(node))
+ return translateImpl(casted);
+ if (auto *casted = dyn_cast<llvm::DILexicalBlockFile>(node))
+ return translateImpl(casted);
+ if (auto *casted = dyn_cast<llvm::DILocalVariable>(node))
+ return translateImpl(casted);
+ if (auto *casted = dyn_cast<llvm::DISubprogram>(node))
+ return translateImpl(casted);
+ if (auto *casted = dyn_cast<llvm::DISubrange>(node))
+ return translateImpl(casted);
+ if (auto *casted = dyn_cast<llvm::DISubroutineType>(node))
+ return translateImpl(casted);
+ return nullptr;
+ };
+ if (DINodeAttr attr = translateNode(node)) {
+ nodeToAttr.insert({node, attr});
+ return attr;
+ }
+ return nullptr;
+}
+
+//===----------------------------------------------------------------------===//
+// Locations
+//===----------------------------------------------------------------------===//
+
+Location DebugImporter::translateLoc(llvm::DILocation *loc) {
+ if (!loc)
+ return UnknownLoc::get(context);
+
+ // Get the file location of the instruction.
+ Location result = FileLineColLoc::get(context, loc->getFilename(),
+ loc->getLine(), loc->getColumn());
+
+ // Add call site information, if available.
+ if (llvm::DILocation *inlinedAt = loc->getInlinedAt())
+ result = CallSiteLoc::get(result, translateLoc(inlinedAt));
+
+ // Add scope information.
+ assert(loc->getScope() && "expected non-null scope");
+ result = FusedLocWith<DIScopeAttr>::get({result}, translate(loc->getScope()),
+ context);
+ return result;
+}
diff --git a/mlir/lib/Target/LLVMIR/DebugImporter.h b/mlir/lib/Target/LLVMIR/DebugImporter.h
new file mode 100644
index 0000000000000..4be4aa13b2481
--- /dev/null
+++ b/mlir/lib/Target/LLVMIR/DebugImporter.h
@@ -0,0 +1,78 @@
+//===- 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_DEBUGIMPORT_H_
+#define MLIR_LIB_TARGET_LLVMIR_DEBUGIMPORT_H_
+
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/IR/BuiltinOps.h"
+#include "mlir/IR/MLIRContext.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+
+namespace mlir {
+class Operation;
+
+namespace LLVM {
+class LLVMFuncOp;
+
+namespace detail {
+
+class DebugImporter {
+public:
+ DebugImporter(MLIRContext *context) : context(context) {}
+
+ /// Translates the given LLVM debug location to an MLIR location.
+ Location translateLoc(llvm::DILocation *loc);
+
+ /// Translates the debug information for the given function.
+ void translate(llvm::Function *func, LLVMFuncOp funcOp);
+
+ /// 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);
+ DIFileAttr translateImpl(llvm::DIFile *node);
+ DILexicalBlockAttr translateImpl(llvm::DILexicalBlock *node);
+ DILexicalBlockFileAttr translateImpl(llvm::DILexicalBlockFile *node);
+ DILocalVariableAttr translateImpl(llvm::DILocalVariable *node);
+ DIScopeAttr translateImpl(llvm::DIScope *node);
+ DISubprogramAttr translateImpl(llvm::DISubprogram *node);
+ DISubrangeAttr translateImpl(llvm::DISubrange *node);
+ DISubroutineTypeAttr translateImpl(llvm::DISubroutineType *node);
+ DITypeAttr translateImpl(llvm::DIType *node);
+
+ /// A mapping between LLVM debug metadata and the corresponding attribute.
+ DenseMap<llvm::DINode *, DINodeAttr> nodeToAttr;
+
+ MLIRContext *context;
+};
+
+} // namespace detail
+} // namespace LLVM
+} // namespace mlir
+
+#endif // MLIR_LIB_TARGET_LLVMIR_DEBUIMPORTN_H_
diff --git a/mlir/test/Target/LLVMIR/Import/debug-info.ll b/mlir/test/Target/LLVMIR/Import/debug-info.ll
index 31f3f82171ed4..575ac0194b23d 100644
--- a/mlir/test/Target/LLVMIR/Import/debug-info.ll
+++ b/mlir/test/Target/LLVMIR/Import/debug-info.ll
@@ -17,26 +17,212 @@ next:
; // -----
-; CHECK-LABEL: @known_loc(
-define i32 @known_loc(i32 %0) {
-entry:
- br label %next
-end:
- ; CHECK: ^{{.*}}(%{{.+}}: i32 loc("known_loc.cpp":5:2)):
- %1 = phi i32 [ %2, %next ], !dbg !4
- ret i32 %1
-next:
- ; CHECK: = llvm.mul %{{.+}}, %{{.+}} : i32 loc(#[[LOC:.+]])
- %2 = mul i32 %0, %0, !dbg !5
- br label %end
+; CHECK: #[[$SP:.+]] = #llvm.di_subprogram<compileUnit = #{{.*}}, scope = #{{.*}}, name = "instruction_loc"
+; CHECK: #[[$CALLEE:.+]] = #llvm.di_subprogram<compileUnit = #{{.*}}, scope = #{{.*}}, name = "callee"
+
+; CHECK-LABEL: @instruction_loc
+define i32 @instruction_loc(i32 %arg1) {
+ ; CHECK llvm.add {{.*}} loc(#[[FILE_LOC:.*]])
+ %1 = add i32 %arg1, %arg1, !dbg !5
+
+ ; CHECK llvm.mul {{.*}} loc(#[[CALLSITE_LOC:.*]])
+ %2 = mul i32 %1, %1, !dbg !7
+
+ ret i32 %2
+}
+; CHECK #[[FILE_LOC]] = loc(fused<#[[$SP]]>["debug-info.ll":1:2])
+; CHECK #[[CALLSITE_LOC]] = loc(fused<#[[$CALLEE]]>[callsite("debug-info.ll":7:4 at fused<#[[$SP]]>["debug-info.ll":2:2])])
+
+!llvm.dbg.cu = !{!1}
+!llvm.module.flags = !{!0}
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = distinct !DICompileUnit(language: DW_LANG_C, file: !2)
+!2 = !DIFile(filename: "debug-info.ll", directory: "/")
+!3 = distinct !DISubprogram(name: "instruction_loc", scope: !2, file: !2, line: 42, scopeLine: 42, spFlags: DISPFlagDefinition, unit: !1)
+!4 = distinct !DISubprogram(name: "callee", scope: !2, file: !2, line: 43, scopeLine: 42, spFlags: DISPFlagDefinition, unit: !1)
+!5 = !DILocation(line: 1, column: 2, scope: !3)
+!6 = !DILocation(line: 2, column: 2, scope: !3)
+!7 = !DILocation(line: 7, column: 4, scope: !4, inlinedAt: !6)
+
+; // -----
+
+; CHECK: #[[FILE:.+]] = #llvm.di_file<"debug-info.ll" in "/">
+; CHECK: #[[SP:.+]] = #llvm.di_subprogram<compileUnit =
+; CHECK: #[[$LB0:.+]] = #llvm.di_lexical_block<scope = #[[SP]], line = 0, column = 0>
+; CHECK: #[[$LB1:.+]] = #llvm.di_lexical_block<scope = #[[SP]], file = #[[FILE]], line = 2, column = 2>
+
+; CHECK-LABEL: @lexical_block
+define i32 @lexical_block(i32 %arg1) {
+ ; CHECK llvm.add {{.*}} loc(#[[LOC0:.*]])
+ %1 = add i32 %arg1, %arg1, !dbg !6
+
+ ; CHECK llvm.mul {{.*}} loc(#[[LOC1:.*]])
+ %2 = mul i32 %arg1, %arg1, !dbg !7
+
+ ret i32 %2
+}
+; CHECK #[[LOC0]] = loc(fused<#[[$LB0]]>["debug-info.ll":1:2])
+; CHECK #[[LOC1]] = loc(fused<#[[$LB1]]>["debug-info.ll":1:2])
+
+!llvm.dbg.cu = !{!1}
+!llvm.module.flags = !{!0}
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = distinct !DICompileUnit(language: DW_LANG_C, file: !2)
+!2 = !DIFile(filename: "debug-info.ll", directory: "/")
+!3 = distinct !DISubprogram(name: "lexical_block", scope: !2, file: !2, line: 42, scopeLine: 42, spFlags: DISPFlagDefinition, unit: !1)
+!4 = !DILexicalBlock(scope: !3)
+!5 = !DILexicalBlock(scope: !3, file: !2, line: 2, column: 2)
+!6 = !DILocation(line: 1, column: 2, scope: !4)
+!7 = !DILocation(line: 2, column: 2, scope: !5)
+
+; // -----
+
+; CHECK: #[[FILE:.+]] = #llvm.di_file<"debug-info.ll" in "/">
+; CHECK: #[[SP:.+]] = #llvm.di_subprogram<compileUnit =
+; CHECK: #[[$LB0:.+]] = #llvm.di_lexical_block_file<scope = #[[SP]], discriminator = 0>
+; CHECK: #[[$LB1:.+]] = #llvm.di_lexical_block_file<scope = #[[SP]], file = #[[FILE]], discriminator = 0>
+
+; CHECK-LABEL: @lexical_block_file
+define i32 @lexical_block_file(i32 %arg1) {
+ ; CHECK llvm.add {{.*}} loc(#[[LOC0:.*]])
+ %1 = add i32 %arg1, %arg1, !dbg !6
+
+ ; CHECK llvm.mul {{.*}} loc(#[[LOC1:.*]])
+ %2 = mul i32 %arg1, %arg1, !dbg !7
+
+ ret i32 %2
+}
+; CHECK #[[LOC0]] = loc(fused<#[[$LB0]]>["debug-info.ll":1:2]))
+; CHECK #[[LOC1]] = loc(fused<#[[$LB1]]>["debug-info.ll":2:2]))
+
+!llvm.dbg.cu = !{!1}
+!llvm.module.flags = !{!0}
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = distinct !DICompileUnit(language: DW_LANG_C, file: !2)
+!2 = !DIFile(filename: "debug-info.ll", directory: "/")
+!3 = distinct !DISubprogram(name: "lexical_block_file", scope: !2, file: !2, line: 42, scopeLine: 42, spFlags: DISPFlagDefinition, unit: !1)
+!4 = !DILexicalBlockFile(scope: !3, discriminator: 0)
+!5 = !DILexicalBlockFile(scope: !3, file: !2, discriminator: 0)
+!6 = !DILocation(line: 1, column: 2, scope: !4)
+!7 = !DILocation(line: 2, column: 2, scope: !5)
+
+; // -----
+
+; CHECK: #[[INT1:.+]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "int1">
+; CHECK: #[[INT2:.+]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "int2", sizeInBits = 32, encoding = DW_ATE_signed>
+; CHECK: #llvm.di_subroutine_type<argumentTypes = #[[INT1]], #[[INT2]]>
+
+define void @basic_type() !dbg !3 {
+ ret void
+}
+
+!llvm.dbg.cu = !{!1}
+!llvm.module.flags = !{!0}
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = distinct !DICompileUnit(language: DW_LANG_C, file: !2)
+!2 = !DIFile(filename: "debug-info.ll", directory: "/")
+!3 = distinct !DISubprogram(name: "basic_type", scope: !2, file: !2, line: 42, scopeLine: 42, spFlags: DISPFlagDefinition, unit: !1, type: !4)
+!4 = !DISubroutineType(types: !5)
+!5 = !{null, !6, !7}
+!6 = !DIBasicType(name: "int1")
+!7 = !DIBasicType(name: "int2", encoding: DW_ATE_signed, size: 32)
+
+; // -----
+
+; CHECK: #[[INT:.+]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "int">
+; CHECK: #[[PTR1:.+]] = #llvm.di_derived_type<tag = DW_TAG_pointer_type, baseType = #[[INT]], sizeInBits = 0, alignInBits = 0, offsetInBits = 0>
+; CHECK: #[[PTR2:.+]] = #llvm.di_derived_type<tag = DW_TAG_pointer_type, name = "mypointer", baseType = #[[INT]], sizeInBits = 64, alignInBits = 32, offsetInBits = 4>
+; CHECK: #llvm.di_subroutine_type<argumentTypes = #[[PTR1]], #[[PTR2]]>
+
+define void @derived_type() !dbg !3 {
+ ret void
}
-; CHECK: #[[LOC]] = loc("known_loc.cpp":8:3)
-!llvm.dbg.cu = !{!0}
-!llvm.module.flags = !{!1}
-!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !2)
-!1 = !{i32 2, !"Debug Info Version", i32 3}
-!2 = !DIFile(filename: "known_loc.cpp", directory: "/")
-!3 = distinct !DISubprogram(name: "known_loc", scope: !0, file: !2, line: 1, scopeLine: 1, unit: !0)
-!4 = !DILocation(line: 5, column: 2, scope: !3)
-!5 = !DILocation(line: 8, column: 3, scope: !3)
+!llvm.dbg.cu = !{!1}
+!llvm.module.flags = !{!0}
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = distinct !DICompileUnit(language: DW_LANG_C, file: !2)
+!2 = !DIFile(filename: "debug-info.ll", directory: "/")
+!3 = distinct !DISubprogram(name: "derived_type", scope: !2, file: !2, line: 42, scopeLine: 42, spFlags: DISPFlagDefinition, unit: !1, type: !4)
+!4 = !DISubroutineType(types: !5)
+!5 = !{null, !7, !8}
+!6 = !DIBasicType(name: "int")
+!7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6)
+!8 = !DIDerivedType(name: "mypointer", tag: DW_TAG_pointer_type, baseType: !6, size: 64, align: 32, offset: 4)
+
+; // -----
+
+; CHECK: #[[INT:.+]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "int">
+; CHECK: #[[FILE:.+]] = #llvm.di_file<"debug-info.ll" in "/">
+; CHECK: #[[COMP1:.+]] = #llvm.di_composite_type<tag = DW_TAG_array_type, name = "array1", line = 10, sizeInBits = 128, alignInBits = 32>
+; CHECK: #[[COMP2:.+]] = #llvm.di_composite_type<{{.*}}, file = #[[FILE]], line = 0, scope = #[[FILE]], baseType = #[[INT]], sizeInBits = 0, alignInBits = 0>
+; CHECK: #[[COMP3:.+]] = #llvm.di_composite_type<{{.*}}, flags = Vector, {{.*}}, elements = #llvm.di_subrange<count = 4 : i64>>
+; CHECK: #[[COMP4:.+]] = #llvm.di_composite_type<{{.*}}, elements = #llvm.di_subrange<lowerBound = 0 : i64, upperBound = 4 : i64, stride = 1 : i64>>
+; CHECK: #llvm.di_subroutine_type<argumentTypes = #[[COMP1]], #[[COMP2]], #[[COMP3]], #[[COMP4]]>
+
+define void @composite_type() !dbg !3 {
+ ret void
+}
+
+!llvm.dbg.cu = !{!1}
+!llvm.module.flags = !{!0}
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = distinct !DICompileUnit(language: DW_LANG_C, file: !2)
+!2 = !DIFile(filename: "debug-info.ll", directory: "/")
+!3 = distinct !DISubprogram(name: "composite_type", scope: !2, file: !2, line: 42, scopeLine: 42, spFlags: DISPFlagDefinition, unit: !1, type: !4)
+!4 = !DISubroutineType(types: !5)
+!5 = !{null, !7, !8, !9, !10}
+!6 = !DIBasicType(name: "int")
+!7 = !DICompositeType(tag: DW_TAG_array_type, name: "array1", line: 10, size: 128, align: 32)
+!8 = !DICompositeType(tag: DW_TAG_array_type, name: "array2", file: !2, scope: !2, baseType: !6)
+!9 = !DICompositeType(tag: DW_TAG_array_type, name: "array3", flags: DIFlagVector, elements: !13)
+!10 = !DICompositeType(tag: DW_TAG_array_type, name: "array4", flags: DIFlagVector, elements: !14)
+!11 = !DISubrange(count: 4)
+!12 = !DISubrange(lowerBound: 0, upperBound: 4, stride: 1)
+!13 = !{!11}
+!14 = !{!12}
+
+; // -----
+
+; CHECK: #[[INT:.+]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "int">
+; CHECK: #[[FILE:.+]] = #llvm.di_file<"debug-info.ll" in "/">
+; CHECK: #[[CU:.+]] = #llvm.di_compile_unit<sourceLanguage = DW_LANG_C, file = #[[FILE]], producer = "", isOptimized = false, emissionKind = None>
+; CHECK: #[[SP_TYPE:.+]] = #llvm.di_subroutine_type<callingConvention = DW_CC_normal, resultType = #[[INT]], argumentTypes = #[[INT]]>
+; CHECK: #[[SP:.+]] = #llvm.di_subprogram<compileUnit = #[[CU]], scope = #[[FILE]], name = "subprogram", linkageName = "subprogram", file = #[[FILE]], line = 42, scopeLine = 42, subprogramFlags = Definition, type = #[[SP_TYPE]]>
+
+define void @subprogram() !dbg !3 {
+ ret void
+}
+
+!llvm.dbg.cu = !{!1}
+!llvm.module.flags = !{!0}
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = distinct !DICompileUnit(language: DW_LANG_C, file: !2)
+!2 = !DIFile(filename: "debug-info.ll", directory: "/")
+!3 = distinct !DISubprogram(name: "subprogram", linkageName: "subprogram", scope: !2, file: !2, line: 42, scopeLine: 42, spFlags: DISPFlagDefinition, unit: !1, type: !4)
+!4 = !DISubroutineType(cc: DW_CC_normal, types: !5)
+!5 = !{!6, !6}
+!6 = !DIBasicType(name: "int")
+
+; // -----
+
+; CHECK: #[[$SP:.+]] = #llvm.di_subprogram<compileUnit = #{{.*}}, scope = #{{.*}}, name = "func_loc", file = #{{.*}}, line = 42, scopeLine = 42, subprogramFlags = Definition>
+
+; CHECK-LABEL: @func_loc
+define void @func_loc() !dbg !3 {
+ ret void
+}
+; CHECK: loc(fused<#[[$SP]]>["func_loc"])
+
+!llvm.dbg.cu = !{!1}
+!llvm.module.flags = !{!0}
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = distinct !DICompileUnit(language: DW_LANG_C, file: !2)
+!2 = !DIFile(filename: "debug-info.ll", directory: "/")
+!3 = distinct !DISubprogram(name: "func_loc", scope: !2, file: !2, line: 42, scopeLine: 42, spFlags: DISPFlagDefinition, unit: !1)
+
+; // -----
+
+; Verify the module location is set to the source filename.
+; CHECK: loc("debug-info.ll":0:0)
+source_filename = "debug-info.ll"
More information about the Mlir-commits
mailing list