[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