[flang-commits] [flang] 9af92ed - [mlir:LLVM] Rewrite the LLVMIR export to use the debug info attributes
River Riddle via flang-commits
flang-commits at lists.llvm.org
Mon Oct 24 22:31:56 PDT 2022
Author: River Riddle
Date: 2022-10-24T22:31:41-07:00
New Revision: 9af92ed8a0da2c35773708dc7a23cd8e56557e2d
URL: https://github.com/llvm/llvm-project/commit/9af92ed8a0da2c35773708dc7a23cd8e56557e2d
DIFF: https://github.com/llvm/llvm-project/commit/9af92ed8a0da2c35773708dc7a23cd8e56557e2d.diff
LOG: [mlir:LLVM] Rewrite the LLVMIR export to use the debug info attributes
This has been a long standing TODO, and actually enables users to generate
debug information for LLVM using the LLVM dialect; as opposed to our
dummy placeholder that generated just enough for line table information.
Differential Revision: https://reviews.llvm.org/D136543
Added:
Modified:
flang/test/Driver/emit-asm-aarch64.f90
flang/test/Driver/emit-asm-x86.f90
flang/test/Fir/embox.fir
flang/test/Fir/ignore-missing-type-descriptor.fir
flang/test/Lower/OpenMP/omp-ordered-threads.f90
mlir/docs/Dialects/LLVM.md
mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
mlir/include/mlir/IR/Location.h
mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
mlir/lib/IR/Diagnostics.cpp
mlir/lib/Target/LLVMIR/DebugTranslation.cpp
mlir/lib/Target/LLVMIR/DebugTranslation.h
mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
mlir/test/Target/LLVMIR/llvmir-debug.mlir
mlir/test/Target/LLVMIR/llvmir.mlir
mlir/test/Target/LLVMIR/openmp-llvm.mlir
mlir/test/Target/LLVMIR/openmp-nested.mlir
Removed:
################################################################################
diff --git a/flang/test/Driver/emit-asm-aarch64.f90 b/flang/test/Driver/emit-asm-aarch64.f90
index 3713fa04cc0ff..078713329223a 100644
--- a/flang/test/Driver/emit-asm-aarch64.f90
+++ b/flang/test/Driver/emit-asm-aarch64.f90
@@ -6,7 +6,6 @@
! RUN: %flang -S -target aarch64-unknown-linux-gnu %s -o - | FileCheck %s
! CHECK-LABEL: _QQmain:
-! CHECK-NEXT: .Lfunc_begin0:
! CHECK: ret
end program
diff --git a/flang/test/Driver/emit-asm-x86.f90 b/flang/test/Driver/emit-asm-x86.f90
index 47b1e10c63d95..124289bbb27d7 100644
--- a/flang/test/Driver/emit-asm-x86.f90
+++ b/flang/test/Driver/emit-asm-x86.f90
@@ -6,7 +6,6 @@
! RUN: %flang -S -target x86_64-unknown-linux-gnu %s -o - | FileCheck %s
! CHECK-LABEL: _QQmain:
-! CHECK-NEXT: .Lfunc_begin0:
! CHECK: ret
end program
diff --git a/flang/test/Fir/embox.fir b/flang/test/Fir/embox.fir
index f5e37fbd77d9d..65a536d10c472 100644
--- a/flang/test/Fir/embox.fir
+++ b/flang/test/Fir/embox.fir
@@ -9,14 +9,14 @@ func.func @_QPtest_callee(%arg0: !fir.box<!fir.array<?xi32>>) {
// CHECK-LABEL: define void @_QPtest_slice()
func.func @_QPtest_slice() {
-// CHECK: %[[a1:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, align 8,
-// CHECK: %[[a2:.*]] = alloca [20 x i32], i64 1, align 4,
-// CHECK: %[[a3:.*]] = getelementptr [20 x i32], ptr %[[a2]], i64 0, i64 0,
+// CHECK: %[[a1:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, align 8
+// CHECK: %[[a2:.*]] = alloca [20 x i32], i64 1, align 4
+// CHECK: %[[a3:.*]] = getelementptr [20 x i32], ptr %[[a2]], i64 0, i64 0
// CHECK: %[[a4:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }
// CHECK: { ptr undef, i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64), i32 20180515, i8 1, i8 9, i8 0, i8 0, [1 x [3 x i64]]
-// CHECK: [i64 1, i64 5, i64 mul (i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64), i64 2)]] }, ptr %[[a3]], 0,
+// CHECK: [i64 1, i64 5, i64 mul (i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64), i64 2)]] }, ptr %[[a3]], 0
// CHECK: store { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %[[a4]], ptr %[[a1]], align 8
-// CHECK: call void @_QPtest_callee(ptr %[[a1]]),
+// CHECK: call void @_QPtest_callee(ptr %[[a1]])
%c20 = arith.constant 20 : index
%c1_i64 = arith.constant 1 : i64
%c10_i64 = arith.constant 10 : i64
@@ -36,17 +36,17 @@ func.func @_QPtest_dt_callee(%arg0: !fir.box<!fir.array<?xi32>>) {
// CHECK-LABEL: define void @_QPtest_dt_slice()
func.func @_QPtest_dt_slice() {
-// CHECK: %[[a1:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, align 8,
-// CHECK: %[[a3:.*]] = alloca [20 x %_QFtest_dt_sliceTt], i64 1, align 8,
-// CHECK: %[[a4:.*]] = getelementptr [20 x %_QFtest_dt_sliceTt], ptr %[[a3]], i64 0, i64 0, i32 0,
+// CHECK: %[[a1:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, align 8
+// CHECK: %[[a3:.*]] = alloca [20 x %_QFtest_dt_sliceTt], i64 1, align 8
+// CHECK: %[[a4:.*]] = getelementptr [20 x %_QFtest_dt_sliceTt], ptr %[[a3]], i64 0, i64 0, i32 0
// CHECK: %[[a5:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }
// CHECK-SAME: { ptr undef, i64 ptrtoint (ptr getelementptr (i32, ptr null, i32 1) to i64), i32 20180515, i8 1, i8 9, i8 0, i8 0, [1 x [3 x i64]]
// CHECK-SAME: [i64 1, i64 5, i64 mul
// CHECK-SAME: (i64 ptrtoint (ptr getelementptr (%_QFtest_dt_sliceTt, ptr null, i32 1) to i64), i64 2)]] }
// CHECK-SAME: , ptr %[[a4]], 0
-// CHECK: store { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %[[a5]], ptr %[[a1]], align 8,
-// CHECK: call void @_QPtest_dt_callee(ptr %[[a1]]),
+// CHECK: store { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] } %[[a5]], ptr %[[a1]], align 8
+// CHECK: call void @_QPtest_dt_callee(ptr %[[a1]])
%c20 = arith.constant 20 : index
%c1_i64 = arith.constant 1 : i64
%c10_i64 = arith.constant 10 : i64
@@ -75,8 +75,8 @@ func.func @emboxSubstring(%arg0: !fir.ref<!fir.array<2x3x!fir.char<1,4>>>) {
%1 = fir.slice %c1, %c2, %c1, %c1, %c3, %c1 substr %c1_i64, %c2_i64 : (index, index, index, index, index, index, i64, i64) -> !fir.slice<2>
%2 = fir.embox %arg0(%0) [%1] : (!fir.ref<!fir.array<2x3x!fir.char<1,4>>>, !fir.shape<2>, !fir.slice<2>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
// CHECK: %[[addr:.*]] = getelementptr [3 x [2 x [4 x i8]]], ptr %[[arg0]], i64 0, i64 0, i64 0, i64 1
- // CHECK: insertvalue {[[descriptorType:.*]]} { ptr undef, i64 mul (i64 ptrtoint (ptr getelementptr (i8, ptr null, i32 1) to i64), i64 2), i32 20180515, i8 2, i8 40, i8 0, i8 0,
- // CHECK-SAME: [2 x [3 x i64]] [{{\[}}3 x i64] [i64 1, i64 2, i64 4], [3 x i64] [i64 1, i64 3, i64 8]] },
+ // CHECK: insertvalue {[[descriptorType:.*]]} { ptr undef, i64 mul (i64 ptrtoint (ptr getelementptr (i8, ptr null, i32 1) to i64), i64 2), i32 20180515, i8 2, i8 40, i8 0, i8 0
+ // CHECK-SAME: [2 x [3 x i64]] [{{\[}}3 x i64] [i64 1, i64 2, i64 4], [3 x i64] [i64 1, i64 3, i64 8]] }
// CHECK-SAME: ptr %[[addr]], 0
fir.call @takesRank2CharBox(%2) : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> ()
diff --git a/flang/test/Fir/ignore-missing-type-descriptor.fir b/flang/test/Fir/ignore-missing-type-descriptor.fir
index 14b210f5a0de7..f55ea1238e47b 100644
--- a/flang/test/Fir/ignore-missing-type-descriptor.fir
+++ b/flang/test/Fir/ignore-missing-type-descriptor.fir
@@ -19,4 +19,4 @@ func.func @test_embox(%addr: !fir.ref<!some_freestyle_type>) {
// CHECK: insertvalue { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }
// CHECK-SAME: { ptr undef, i64 ptrtoint (ptr getelementptr (%some_not_mangled_type, ptr null, i32 1) to i64),
// CHECK-SAME: i32 20180515, i8 0, i8 42, i8 0, i8 1, ptr null, [1 x i64] undef },
-// CHECK-SAME: ptr %[[ADDR]], 0,
+// CHECK-SAME: ptr %[[ADDR]], 0
diff --git a/flang/test/Lower/OpenMP/omp-ordered-threads.f90 b/flang/test/Lower/OpenMP/omp-ordered-threads.f90
index 263832cdcc3da..3b896d24ea6d2 100644
--- a/flang/test/Lower/OpenMP/omp-ordered-threads.f90
+++ b/flang/test/Lower/OpenMP/omp-ordered-threads.f90
@@ -12,29 +12,29 @@ subroutine ordered
!FIRDialect: omp.ordered_region {
!LLVMIRDialect: omp.ordered_region {
-!LLVMIR: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB0:[0-9]+]]), !dbg !{{.*}}
-!LLVMIR-NEXT: call void @__kmpc_ordered(ptr @[[GLOB0]], i32 [[TMP0]]), !dbg !{{.*}}
+!LLVMIR: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB0:[0-9]+]])
+!LLVMIR-NEXT: call void @__kmpc_ordered(ptr @[[GLOB0]], i32 [[TMP0]])
!$OMP ORDERED
a(i) = a(i-1) + 1
!FIRDialect: omp.terminator
!FIRDialect-NEXT: }
!LLVMIRDialect: omp.terminator
!LLVMIRDialect-NEXT: }
-!LLVMIR: call void @__kmpc_end_ordered(ptr @[[GLOB0]], i32 [[TMP0]]), !dbg !{{.*}}
+!LLVMIR: call void @__kmpc_end_ordered(ptr @[[GLOB0]], i32 [[TMP0]])
!$OMP END ORDERED
!FIRDialect: omp.ordered_region {
!LLVMIRDialect: omp.ordered_region {
-!LLVMIR: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1:[0-9]+]]), !dbg !{{.*}}
-!LLVMIR-NEXT: call void @__kmpc_ordered(ptr @[[GLOB1]], i32 [[TMP1]]), !dbg !{{.*}}
+!LLVMIR: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1:[0-9]+]])
+!LLVMIR-NEXT: call void @__kmpc_ordered(ptr @[[GLOB1]], i32 [[TMP1]])
!$OMP ORDERED THREADS
a(i) = a(i-1) + 1
!FIRDialect: omp.terminator
!FIRDialect-NEXT: }
!LLVMIRDialect: omp.terminator
!LLVMIRDialect-NEXT: }
-!LLVMIR: call void @__kmpc_end_ordered(ptr @[[GLOB1]], i32 [[TMP1]]), !dbg !{{.*}}
-!LLVMIR-NEXT: ret void, !dbg !{{.*}}
+!LLVMIR: call void @__kmpc_end_ordered(ptr @[[GLOB1]], i32 [[TMP1]])
+!LLVMIR-NEXT: ret void
!$OMP END ORDERED
end
diff --git a/mlir/docs/Dialects/LLVM.md b/mlir/docs/Dialects/LLVM.md
index d1f589baa977e..53d4dfbf686e7 100644
--- a/mlir/docs/Dialects/LLVM.md
+++ b/mlir/docs/Dialects/LLVM.md
@@ -482,3 +482,13 @@ modeled as first-class operations in the LLVM dialect. Target-specific LLVM IR
intrinsics, e.g., NVVM or ROCDL, are modeled as separate dialects.
[include "Dialects/LLVMIntrinsicOps.md"]
+
+### Debug Info
+
+Debug information within the LLVM dialect is represented using locations in
+combination with a set of attributes that mirror the DINode structure defined by
+the debug info metadata within LLVM IR. Debug scoping information is attached
+to LLVM IR dialect operations using a fused location (`FusedLoc`) whose metadata
+holds the DIScopeAttr representing the debug scope. Similarly, the subprogram
+of LLVM IR dialect `FuncOp` operations is attached using a fused location whose
+metadata is a DISubprogramAttr.
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
index d78efa5c608e7..efb60e2e03c1a 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
@@ -233,21 +233,37 @@ def LLVM_CoroResumeOp : LLVM_IntrOp<"coro.resume", [], [], [], 0> {
// Debug function intrinsics.
//
-def LLVM_DbgAddrOp : LLVM_Op<"dbg.addr"> {
+class LLVM_DbgIntrOp<string name> : LLVM_Op<name> {
+ let llvmBuilder = [{
+ llvm::Module *module = builder.GetInsertBlock()->getModule();
+ llvm::LLVMContext &ctx = module->getContext();
+ llvm::Function *fn =
+ llvm::Intrinsic::getDeclaration(module, llvm::Intrinsic::}]
+ # !subst(".", "_", name) # [{);
+ builder.CreateCall(fn, {
+ llvm::MetadataAsValue::get(ctx,
+ llvm::ValueAsMetadata::get(moduleTranslation.lookupValue(opInst.getOperand(0)))),
+ llvm::MetadataAsValue::get(ctx, moduleTranslation.translateDebugInfo($varInfo)),
+ llvm::MetadataAsValue::get(ctx, llvm::DIExpression::get(ctx, llvm::None)),
+ });
+ }];
+}
+
+def LLVM_DbgAddrOp : LLVM_DbgIntrOp<"dbg.addr"> {
let summary = "Describe the current address of a local debug info variable.";
let arguments = (ins LLVM_AnyPointer:$addr, LLVM_DILocalVariableAttr:$varInfo);
let assemblyFormat = "qualified($varInfo) `=` $addr `:` type($addr) attr-dict";
}
-def LLVM_DbgDeclareOp : LLVM_Op<"dbg.declare"> {
+def LLVM_DbgDeclareOp : LLVM_DbgIntrOp<"dbg.declare"> {
let summary = "Declare the address of a local debug info variable.";
let arguments = (ins LLVM_AnyPointer:$addr, LLVM_DILocalVariableAttr:$varInfo);
let assemblyFormat = "qualified($varInfo) `=` $addr `:` type($addr) attr-dict";
}
-def LLVM_DbgValueOp : LLVM_Op<"dbg.value"> {
+def LLVM_DbgValueOp : LLVM_DbgIntrOp<"dbg.value"> {
let summary = "Describe the current value of a local debug info variable.";
let arguments = (ins LLVM_Type:$value, LLVM_DILocalVariableAttr:$varInfo);
diff --git a/mlir/include/mlir/IR/Location.h b/mlir/include/mlir/IR/Location.h
index 6691c2f769b9f..03f6e4e55896e 100644
--- a/mlir/include/mlir/IR/Location.h
+++ b/mlir/include/mlir/IR/Location.h
@@ -36,6 +36,21 @@ class LocationAttr : public Attribute {
/// Walk all of the locations nested under, and including, the current.
WalkResult walk(function_ref<WalkResult(Location)> walkFn);
+ /// Return an instance of the given location type if one is nested under the
+ /// current location. Returns nullptr if one could not be found.
+ template <typename T>
+ T findInstanceOf() {
+ T result = {};
+ walk([&](auto loc) {
+ if (auto typedLoc = llvm::dyn_cast<T>(loc)) {
+ result = typedLoc;
+ return WalkResult::interrupt();
+ }
+ return WalkResult::advance();
+ });
+ return result;
+ }
+
/// Methods for support type inquiry through isa, cast, and dyn_cast.
static bool classof(Attribute attr);
};
@@ -118,6 +133,29 @@ inline ::llvm::hash_code hash_value(Location arg) {
namespace mlir {
+//===----------------------------------------------------------------------===//
+// FusedLoc
+//===----------------------------------------------------------------------===//
+
+/// This class represents a fused location whose metadata is known to be an
+/// instance of the given type.
+template <typename MetadataT>
+class FusedLocWith : public FusedLoc {
+public:
+ using FusedLoc::FusedLoc;
+
+ /// Return the metadata associated with this fused location.
+ MetadataT getMetadata() const {
+ return FusedLoc::getMetadata().template cast<MetadataT>();
+ }
+
+ /// Support llvm style casting.
+ static bool classof(Attribute attr) {
+ auto fusedLoc = attr.dyn_cast<FusedLoc>();
+ return fusedLoc && fusedLoc.getMetadata().isa_and_nonnull<MetadataT>();
+ }
+};
+
//===----------------------------------------------------------------------===//
// OpaqueLoc
//===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
index 3dd0d769007c8..af84f8a2d7f67 100644
--- a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
+++ b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
@@ -42,6 +42,7 @@ namespace detail {
class DebugTranslation;
} // namespace detail
+class DINodeAttr;
class LLVMFuncOp;
/// Implementation class for module translation. Holds a reference to the module
@@ -175,6 +176,9 @@ class ModuleTranslation {
/// Translates the given location.
const llvm::DILocation *translateLoc(Location loc, llvm::DILocalScope *scope);
+ /// Translates the given LLVM debug info metadata.
+ llvm::Metadata *translateDebugInfo(LLVM::DINodeAttr attr);
+
/// Translates the contents of the given block to LLVM IR using this
/// translator. The LLVM IR basic block corresponding to the given block is
/// expected to exist in the mapping of this translator. Uses `builder` to
diff --git a/mlir/lib/IR/Diagnostics.cpp b/mlir/lib/IR/Diagnostics.cpp
index 14aa44f26064e..ca99c6caec61f 100644
--- a/mlir/lib/IR/Diagnostics.cpp
+++ b/mlir/lib/IR/Diagnostics.cpp
@@ -389,19 +389,6 @@ struct SourceMgrDiagnosticHandlerImpl {
} // namespace detail
} // namespace mlir
-/// Return a processable FileLineColLoc from the given location.
-static Optional<FileLineColLoc> getFileLineColLoc(Location loc) {
- Optional<FileLineColLoc> firstFileLoc;
- loc->walk([&](Location loc) {
- if (FileLineColLoc fileLoc = loc.dyn_cast<FileLineColLoc>()) {
- firstFileLoc = fileLoc;
- return WalkResult::interrupt();
- }
- return WalkResult::advance();
- });
- return firstFileLoc;
-}
-
/// Return a processable CallSiteLoc from the given location.
static Optional<CallSiteLoc> getCallSiteLoc(Location loc) {
if (auto nameLoc = dyn_cast<NameLoc>(loc))
@@ -454,7 +441,7 @@ void SourceMgrDiagnosticHandler::emitDiagnostic(Location loc, Twine message,
DiagnosticSeverity kind,
bool displaySourceLine) {
// Extract a file location from this loc.
- auto fileLoc = getFileLineColLoc(loc);
+ auto fileLoc = loc->findInstanceOf<FileLineColLoc>();
// If one doesn't exist, then print the raw message without a source location.
if (!fileLoc) {
@@ -469,7 +456,7 @@ void SourceMgrDiagnosticHandler::emitDiagnostic(Location loc, Twine message,
// Otherwise if we are displaying the source line, try to convert the file
// location to an SMLoc.
if (displaySourceLine) {
- auto smloc = convertLocToSMLoc(*fileLoc);
+ auto smloc = convertLocToSMLoc(fileLoc);
if (smloc.isValid())
return mgr.PrintMessage(os, smloc, getDiagKind(kind), message);
}
@@ -479,8 +466,8 @@ void SourceMgrDiagnosticHandler::emitDiagnostic(Location loc, Twine message,
// the constructor of SMDiagnostic that takes a location.
std::string locStr;
llvm::raw_string_ostream locOS(locStr);
- locOS << fileLoc->getFilename().getValue() << ":" << fileLoc->getLine() << ":"
- << fileLoc->getColumn();
+ locOS << fileLoc.getFilename().getValue() << ":" << fileLoc.getLine() << ":"
+ << fileLoc.getColumn();
llvm::SMDiagnostic diag(locOS.str(), getDiagKind(kind), message.str());
diag.print(nullptr, os);
}
@@ -853,8 +840,8 @@ void SourceMgrDiagnosticVerifierHandler::process(Diagnostic &diag) {
auto kind = diag.getSeverity();
// Process a FileLineColLoc.
- if (auto fileLoc = getFileLineColLoc(diag.getLocation()))
- return process(*fileLoc, diag.str(), kind);
+ if (auto fileLoc = diag.getLocation()->findInstanceOf<FileLineColLoc>())
+ return process(fileLoc, diag.str(), kind);
emitDiagnostic(diag.getLocation(),
"unexpected " + getDiagKindStr(kind) + ": " + diag.str(),
diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
index 925a7dbe0215f..6de8febdd56a8 100644
--- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
@@ -8,6 +8,7 @@
#include "DebugTranslation.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "llvm/ADT/TypeSwitch.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/FileSystem.h"
@@ -25,23 +26,15 @@ static WalkResult interruptIfValidLocation(Operation *op) {
}
DebugTranslation::DebugTranslation(Operation *module, llvm::Module &llvmModule)
- : builder(llvmModule), llvmCtx(llvmModule.getContext()),
- compileUnit(nullptr) {
-
+ : debugEmissionIsEnabled(false), llvmModule(llvmModule),
+ llvmCtx(llvmModule.getContext()) {
// If the module has no location information, there is nothing to do.
if (!module->walk(interruptIfValidLocation).wasInterrupted())
return;
+ debugEmissionIsEnabled = true;
- // TODO: Several parts of this are incorrect. Different source
- // languages may interpret
diff erent parts of the debug information
- //
diff erently. Frontends will also want to pipe in various information, like
- // flags. This is fine for now as we only emit line-table information and not
- // types or variables. This should disappear as the debug information story
- // evolves; i.e. when we have proper attributes for LLVM debug metadata.
- compileUnit = builder.createCompileUnit(
- llvm::dwarf::DW_LANG_C,
- builder.createFile(llvmModule.getModuleIdentifier(), "/"),
- /*Producer=*/"mlir", /*isOptimized=*/true, /*Flags=*/"", /*RV=*/0);
+ // TODO: The version information should be encoded on the LLVM module itself,
+ // not implicitly set here.
// Mark this module as having debug information.
StringRef debugVersionKey = "Debug Info Version";
@@ -62,24 +55,11 @@ DebugTranslation::DebugTranslation(Operation *module, llvm::Module &llvmModule)
}
/// Finalize the translation of debug information.
-void DebugTranslation::finalize() { builder.finalize(); }
-
-/// Attempt to extract a filename for the given loc.
-static FileLineColLoc extractFileLoc(Location loc) {
- if (auto fileLoc = loc.dyn_cast<FileLineColLoc>())
- return fileLoc;
- if (auto nameLoc = loc.dyn_cast<NameLoc>())
- return extractFileLoc(nameLoc.getChildLoc());
- if (auto opaqueLoc = loc.dyn_cast<OpaqueLoc>())
- return extractFileLoc(opaqueLoc.getFallbackLocation());
- return FileLineColLoc();
-}
+void DebugTranslation::finalize() {}
/// Translate the debug information for the given function.
void DebugTranslation::translate(LLVMFuncOp func, llvm::Function &llvmFunc) {
- // If the function doesn't have location information, there is nothing to
- // translate.
- if (!compileUnit || !func.walk(interruptIfValidLocation).wasInterrupted())
+ if (!debugEmissionIsEnabled)
return;
// If we are to create debug info for the function, we need to ensure that all
@@ -96,23 +76,150 @@ void DebugTranslation::translate(LLVMFuncOp func, llvm::Function &llvmFunc) {
if (hasCallWithoutDebugInfo)
return;
- FileLineColLoc fileLoc = extractFileLoc(func.getLoc());
- auto *file =
- translateFile(fileLoc ? fileLoc.getFilename().strref() : "<unknown>");
- unsigned line = fileLoc ? fileLoc.getLine() : 0;
-
- // TODO: This is the bare essentials for now. We will likely end
- // up with wrapper metadata around LLVMs metadata in the future, so this
- // doesn't need to be smart until then.
- llvm::DISubroutineType *type =
- builder.createSubroutineType(builder.getOrCreateTypeArray(llvm::None));
- llvm::DISubprogram::DISPFlags spFlags = llvm::DISubprogram::SPFlagDefinition |
- llvm::DISubprogram::SPFlagOptimized;
- llvm::DISubprogram *program =
- builder.createFunction(compileUnit, func.getName(), func.getName(), file,
- line, type, line, llvm::DINode::FlagZero, spFlags);
- llvmFunc.setSubprogram(program);
- builder.finalizeSubprogram(program);
+ // Look for a sub program attached to the function.
+ auto spLoc =
+ func.getLoc()->findInstanceOf<FusedLocWith<LLVM::DISubprogramAttr>>();
+ if (!spLoc)
+ return;
+ llvmFunc.setSubprogram(translate(spLoc.getMetadata()));
+}
+
+//===----------------------------------------------------------------------===//
+// Attributes
+//===----------------------------------------------------------------------===//
+
+llvm::DIBasicType *DebugTranslation::translateImpl(DIBasicTypeAttr attr) {
+ return llvm::DIBasicType::get(
+ llvmCtx, attr.getTag(), attr.getName(), attr.getSizeInBits(),
+ /*AlignInBits=*/0, attr.getEncoding(), llvm::DINode::FlagZero);
+}
+
+llvm::DICompileUnit *DebugTranslation::translateImpl(DICompileUnitAttr attr) {
+ llvm::DIBuilder builder(llvmModule);
+ return builder.createCompileUnit(
+ attr.getSourceLanguage(), translate(attr.getFile()), attr.getProducer(),
+ attr.getIsOptimized(), /*Flags=*/"", /*RV=*/0);
+}
+
+llvm::DICompositeType *
+DebugTranslation::translateImpl(DICompositeTypeAttr attr) {
+ SmallVector<llvm::Metadata *> elements;
+ for (auto member : attr.getElements())
+ elements.push_back(translate(member));
+ return llvm::DICompositeType::get(
+ llvmCtx, attr.getTag(), attr.getName(), translate(attr.getFile()),
+ attr.getLine(), translate(attr.getScope()), /*BaseType=*/nullptr,
+ attr.getSizeInBits(), attr.getAlignInBits(),
+ /*OffsetInBits=*/0, /*Flags=*/llvm::DINode::FlagZero,
+ llvm::MDNode::get(llvmCtx, elements),
+ /*RuntimeLang=*/0, /*VTableHolder=*/nullptr);
+}
+
+llvm::DIDerivedType *DebugTranslation::translateImpl(DIDerivedTypeAttr attr) {
+ return llvm::DIDerivedType::get(
+ llvmCtx, attr.getTag(), attr.getName(), /*File=*/nullptr, /*Line=*/0,
+ /*Scope=*/nullptr, translate(attr.getBaseType()), attr.getSizeInBits(),
+ attr.getAlignInBits(), attr.getOffsetInBits(),
+ /*DWARFAddressSpace=*/llvm::None, /*Flags=*/llvm::DINode::FlagZero);
+}
+
+llvm::DIFile *DebugTranslation::translateImpl(DIFileAttr attr) {
+ return llvm::DIFile::get(llvmCtx, attr.getName(), attr.getDirectory());
+}
+
+llvm::DILexicalBlock *DebugTranslation::translateImpl(DILexicalBlockAttr attr) {
+ return llvm::DILexicalBlock::getDistinct(llvmCtx, translate(attr.getScope()),
+ translate(attr.getFile()),
+ attr.getLine(), attr.getColumn());
+}
+
+llvm::DILexicalBlockFile *
+DebugTranslation::translateImpl(DILexicalBlockFileAttr attr) {
+ return llvm::DILexicalBlockFile::getDistinct(
+ llvmCtx, translate(attr.getScope()), translate(attr.getFile()),
+ attr.getDescriminator());
+}
+
+llvm::DILocalVariable *
+DebugTranslation::translateImpl(DILocalVariableAttr attr) {
+ return llvm::DILocalVariable::get(
+ llvmCtx, translate(attr.getScope()),
+ llvm::MDString::get(llvmCtx, attr.getName()), translate(attr.getFile()),
+ attr.getLine(), translate(attr.getType()), attr.getArg(),
+ /*Flags=*/llvm::DINode::FlagZero, attr.getAlignInBits(),
+ /*Annotations=*/nullptr);
+}
+
+llvm::DIScope *DebugTranslation::translateImpl(DIScopeAttr attr) {
+ return cast<llvm::DIScope>(translate(DINodeAttr(attr)));
+}
+
+/// Return a new subprogram that is either distinct or not, depending on
+/// `isDistinct`.
+template <class... Ts>
+static llvm::DISubprogram *getSubprogram(bool isDistinct, Ts &&...args) {
+ if (isDistinct)
+ return llvm::DISubprogram::getDistinct(std::forward<Ts>(args)...);
+ return llvm::DISubprogram::get(std::forward<Ts>(args)...);
+}
+
+llvm::DISubprogram *DebugTranslation::translateImpl(DISubprogramAttr attr) {
+ bool isDefinition = static_cast<bool>(attr.getSubprogramFlags() &
+ LLVM::DISubprogramFlags::Definition);
+ return getSubprogram(
+ isDefinition, llvmCtx, translate(attr.getScope()),
+ llvm::MDString::get(llvmCtx, attr.getName()),
+ llvm::MDString::get(llvmCtx, attr.getLinkageName()),
+ translate(attr.getFile()), attr.getLine(), translate(attr.getType()),
+ attr.getScopeLine(), /*ContainingType=*/nullptr, /*VirtualIndex=*/0,
+ /*ThisAdjustment=*/0, llvm::DINode::FlagZero,
+ static_cast<llvm::DISubprogram::DISPFlags>(attr.getSubprogramFlags()),
+ translate(attr.getCompileUnit()));
+}
+
+llvm::DISubrange *DebugTranslation::translateImpl(DISubrangeAttr attr) {
+ auto getMetadataOrNull = [&](IntegerAttr attr) -> llvm::Metadata * {
+ if (!attr)
+ return nullptr;
+ return llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
+ llvm::Type::getInt64Ty(llvmCtx), attr.getInt()));
+ };
+ return llvm::DISubrange::get(llvmCtx, getMetadataOrNull(attr.getCount()),
+ getMetadataOrNull(attr.getLowerBound()),
+ getMetadataOrNull(attr.getUpperBound()),
+ getMetadataOrNull(attr.getStride()));
+}
+
+llvm::DISubroutineType *
+DebugTranslation::translateImpl(DISubroutineTypeAttr attr) {
+ SmallVector<llvm::Metadata *> types;
+ for (auto type : attr.getTypes())
+ types.push_back(translate(type));
+ return llvm::DISubroutineType::get(
+ llvmCtx, llvm::DINode::FlagZero, attr.getCallingConvention(),
+ llvm::DITypeRefArray(llvm::MDNode::get(llvmCtx, types)));
+}
+
+llvm::DIType *DebugTranslation::translateImpl(DITypeAttr attr) {
+ return cast<llvm::DIType>(translate(DINodeAttr(attr)));
+}
+
+llvm::DINode *DebugTranslation::translate(DINodeAttr attr) {
+ if (!attr)
+ return nullptr;
+ // Check for a cached instance.
+ if (llvm::DINode *node = attrToNode.lookup(attr))
+ return node;
+
+ llvm::DINode *node =
+ TypeSwitch<DINodeAttr, llvm::DINode *>(attr)
+ .Case<DIBasicTypeAttr, DICompileUnitAttr, DICompositeTypeAttr,
+ DIDerivedTypeAttr, DIFileAttr, DILexicalBlockAttr,
+ DILexicalBlockFileAttr, DILocalVariableAttr, DISubprogramAttr,
+ DISubroutineTypeAttr>(
+ [&](auto attr) { return translateImpl(attr); });
+ attrToNode.insert({attr, node});
+ return node;
}
//===----------------------------------------------------------------------===//
@@ -122,8 +229,12 @@ void DebugTranslation::translate(LLVMFuncOp func, llvm::Function &llvmFunc) {
/// Translate the given location to an llvm debug location.
const llvm::DILocation *
DebugTranslation::translateLoc(Location loc, llvm::DILocalScope *scope) {
- if (!compileUnit)
+ if (!debugEmissionIsEnabled)
return nullptr;
+
+ // Check for a scope encoded with the location.
+ if (auto scopedLoc = loc->findInstanceOf<FusedLocWith<LLVM::DIScopeAttr>>())
+ scope = cast<llvm::DILocalScope>(translate(scopedLoc.getMetadata()));
return translateLoc(loc, scope, /*inlinedAt=*/nullptr);
}
@@ -148,7 +259,8 @@ DebugTranslation::translateLoc(Location loc, llvm::DILocalScope *scope,
} else if (auto fileLoc = loc.dyn_cast<FileLineColLoc>()) {
auto *file = translateFile(fileLoc.getFilename());
- auto *fileScope = builder.createLexicalBlockFile(scope, file);
+ auto *fileScope = llvm::DILexicalBlockFile::get(llvmCtx, scope, file,
+ /*Discriminator=*/0);
llvmLoc = llvm::DILocation::get(llvmCtx, fileLoc.getLine(),
fileLoc.getColumn(), fileScope,
const_cast<llvm::DILocation *>(inlinedAt));
@@ -210,5 +322,5 @@ llvm::DIFile *DebugTranslation::translateFile(StringRef fileName) {
fileName = fileBuf;
}
}
- return (file = builder.createFile(fileName, directory));
+ return (file = llvm::DIFile::get(llvmCtx, fileName, directory));
}
diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.h b/mlir/lib/Target/LLVMIR/DebugTranslation.h
index 3706d06fb7c9c..14bd3b5162fa7 100644
--- a/mlir/lib/Target/LLVMIR/DebugTranslation.h
+++ b/mlir/lib/Target/LLVMIR/DebugTranslation.h
@@ -14,6 +14,7 @@
#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"
@@ -39,6 +40,17 @@ class DebugTranslation {
/// 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 <typename DIAttrT>
+ auto translate(DIAttrT attr) {
+ // Infer the LLVM type from the attribute type.
+ using LLVMTypeT = std::remove_pointer_t<decltype(translateImpl(attr))>;
+ return cast_or_null<LLVMTypeT>(translate(DINodeAttr(attr)));
+ }
+
private:
/// Translate the given location to an llvm debug location with the given
/// scope and inlinedAt parameters.
@@ -48,11 +60,30 @@ class DebugTranslation {
/// 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::DIBasicType *translateImpl(DIBasicTypeAttr attr);
+ llvm::DICompileUnit *translateImpl(DICompileUnitAttr attr);
+ llvm::DICompositeType *translateImpl(DICompositeTypeAttr attr);
+ llvm::DIDerivedType *translateImpl(DIDerivedTypeAttr attr);
+ llvm::DIFile *translateImpl(DIFileAttr attr);
+ llvm::DILexicalBlock *translateImpl(DILexicalBlockAttr attr);
+ llvm::DILexicalBlockFile *translateImpl(DILexicalBlockFileAttr attr);
+ llvm::DILocalVariable *translateImpl(DILocalVariableAttr attr);
+ llvm::DIScope *translateImpl(DIScopeAttr attr);
+ llvm::DISubprogram *translateImpl(DISubprogramAttr attr);
+ llvm::DISubrange *translateImpl(DISubrangeAttr attr);
+ llvm::DISubroutineType *translateImpl(DISubroutineTypeAttr attr);
+ llvm::DIType *translateImpl(DITypeAttr attr);
+
/// A mapping between mlir location+scope and the corresponding llvm debug
/// metadata.
DenseMap<std::pair<Location, llvm::DILocalScope *>, const llvm::DILocation *>
locationToLoc;
+ /// A mapping between debug attribute and the corresponding llvm debug
+ /// metadata.
+ DenseMap<Attribute, llvm::DINode *> attrToNode;
+
/// A mapping between filename and llvm debug file.
/// TODO: Change this to DenseMap<Identifier, ...> when we can
/// access the Identifier filename in FileLineColLoc.
@@ -61,10 +92,12 @@ class DebugTranslation {
/// 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::DIBuilder builder;
+ llvm::Module &llvmModule;
llvm::LLVMContext &llvmCtx;
- llvm::DICompileUnit *compileUnit;
};
} // namespace detail
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 5e27dab3521c9..d1cdc77e4b968 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -1139,6 +1139,10 @@ ModuleTranslation::translateLoc(Location loc, llvm::DILocalScope *scope) {
return debugTranslation->translateLoc(loc, scope);
}
+llvm::Metadata *ModuleTranslation::translateDebugInfo(LLVM::DINodeAttr attr) {
+ return debugTranslation->translate(attr);
+}
+
llvm::NamedMDNode *
ModuleTranslation::getOrInsertNamedModuleMetadata(StringRef name) {
return llvmModule->getOrInsertNamedMetadata(name);
diff --git a/mlir/test/Target/LLVMIR/llvmir-debug.mlir b/mlir/test/Target/LLVMIR/llvmir-debug.mlir
index b839a825bdfe2..fd95e176e1941 100644
--- a/mlir/test/Target/LLVMIR/llvmir-debug.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir-debug.mlir
@@ -17,9 +17,38 @@ llvm.func @func_no_debug() {
llvm.return loc(unknown)
} loc(unknown)
-// CHECK-LABEL: define void @func_with_debug()
-// CHECK-SAME: !dbg ![[FUNC_LOC:[0-9]+]]
-llvm.func @func_with_debug() {
+
+#si64 = #llvm.di_basic_type<
+ tag = DW_TAG_base_type, name = "si64", sizeInBits = 0,
+ encoding = DW_ATE_signed
+>
+#file = #llvm.di_file<"foo.mlir" in "/test/">
+#cu = #llvm.di_compile_unit<
+ sourceLanguage = DW_LANG_C, file = #file, producer = "MLIR",
+ isOptimized = true, emissionKind = Full
+>
+#spType = #llvm.di_subroutine_type<callingConvention = DW_CC_normal, types = #si64>
+#sp = #llvm.di_subprogram<
+ compileUnit = #cu, scope = #file, name = "intrinsics", linkageName = "intrinsics",
+ file = #file, line = 3, scopeLine = 3, subprogramFlags = "Definition|Optimized", type = #spType
+>
+#fileScope = #llvm.di_lexical_block_file<scope = #sp, file = #file, descriminator = 0>
+#variable = #llvm.di_local_variable<scope = #fileScope, name = "arg", file = #file, line = 6, arg = 1, alignInBits = 0, type = #si64>
+
+// CHECK-LABEL: define void @func_with_debug(
+// CHECK-SAME: i64 %[[ARG:.*]]) !dbg ![[FUNC_LOC:[0-9]+]]
+llvm.func @func_with_debug(%arg: i64) {
+ // CHECK: %[[ALLOC:.*]] = alloca
+ %allocCount = llvm.mlir.constant(1 : i32) : i32
+ %alloc = llvm.alloca %allocCount x i64 : (i32) -> !llvm.ptr<i64>
+
+ // CHECK: call void @llvm.dbg.value(metadata i64 %[[ARG]], metadata ![[VAR_LOC:[0-9]+]], metadata !DIExpression())
+ // CHECK: call void @llvm.dbg.addr(metadata ptr %[[ALLOC]], metadata ![[VAR_LOC]], metadata !DIExpression())
+ // CHECK: call void @llvm.dbg.declare(metadata ptr %[[ALLOC]], metadata ![[VAR_LOC]], metadata !DIExpression())
+ llvm.dbg.value #variable = %arg : i64
+ llvm.dbg.addr #variable = %alloc : !llvm.ptr<i64>
+ llvm.dbg.declare #variable = %alloc : !llvm.ptr<i64>
+
// CHECK: call void @func_no_debug(), !dbg ![[CALLSITE_LOC:[0-9]+]]
llvm.call @func_no_debug() : () -> () loc(callsite("mysource.cc":3:4 at "mysource.cc":5:6))
@@ -33,9 +62,19 @@ llvm.func @func_with_debug() {
llvm.call @func_no_debug() : () -> () loc(fused[callsite("mysource.cc":1:1 at "mysource.cc":5:6), "mysource.cc":1:1])
llvm.return
-} loc("foo.mlir":1:1)
+} loc(fused<#sp>["foo.mlir":1:1])
+
+// CHECK: ![[CU_LOC:.*]] = distinct !DICompileUnit(language: DW_LANG_C, file: ![[CU_FILE_LOC:.*]], producer: "MLIR", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
+// CHECK: ![[CU_FILE_LOC]] = !DIFile(filename: "foo.mlir", directory: "/test/")
+
+// CHECK: ![[FUNC_LOC]] = distinct !DISubprogram(name: "intrinsics", linkageName: "intrinsics", scope: ![[CU_FILE_LOC]], file: ![[CU_FILE_LOC]], line: 3, type: ![[FUNC_TYPE:.*]], scopeLine: 3, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: ![[CU_LOC]])
+// CHECK: ![[FUNC_TYPE]] = !DISubroutineType(cc: DW_CC_normal, types: ![[ARG_TYPES:.*]])
+// CHECK: ![[ARG_TYPES]] = !{![[ARG_TYPE:.*]]}
+// CHECK: ![[ARG_TYPE]] = !DIBasicType(name: "si64", encoding: DW_ATE_signed)
+
+// CHECK: ![[VAR_LOC]] = !DILocalVariable(name: "arg", arg: 1, scope: ![[VAR_SCOPE:.*]], file: ![[CU_FILE_LOC]], line: 6, type: ![[ARG_TYPE]])
+// CHECK: ![[VAR_SCOPE]] = distinct !DILexicalBlockFile(scope: ![[FUNC_LOC]], file: ![[CU_FILE_LOC]], discriminator: 0)
-// CHECK-DAG: ![[FUNC_LOC]] = distinct !DISubprogram{{.*}}, line: 1
// CHECK-DAG: ![[CALLSITE_LOC]] = !DILocation(line: 3, column: 4,
// CHECK-DAG: ![[FILE_LOC]] = !DILocation(line: 1, column: 2,
// CHECK-DAG: ![[NAMED_LOC]] = !DILocation(line: 10, column: 10
diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir
index 8bf1070a63942..bc9c287fa9a81 100644
--- a/mlir/test/Target/LLVMIR/llvmir.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir.mlir
@@ -1615,25 +1615,25 @@ llvm.func @useInlineAsm(%arg0: i32) {
// Constraints string is checked at LLVM InlineAsm instruction construction time.
// So we can't just use "bar" everywhere, number of in/out arguments has to match.
- // CHECK-NEXT: call void asm "foo", "r"(i32 {{.*}}), !dbg !7
+ // CHECK-NEXT: call void asm "foo", "r"(i32 {{.*}})
llvm.inline_asm "foo", "r" %arg0 : (i32) -> ()
- // CHECK-NEXT: call i8 asm "foo", "=r,r"(i32 {{.*}}), !dbg !9
+ // CHECK-NEXT: call i8 asm "foo", "=r,r"(i32 {{.*}})
%0 = llvm.inline_asm "foo", "=r,r" %arg0 : (i32) -> i8
- // CHECK-NEXT: call i8 asm "foo", "=r,r,r"(i32 {{.*}}, i32 {{.*}}), !dbg !10
+ // CHECK-NEXT: call i8 asm "foo", "=r,r,r"(i32 {{.*}}, i32 {{.*}})
%1 = llvm.inline_asm "foo", "=r,r,r" %arg0, %arg0 : (i32, i32) -> i8
- // CHECK-NEXT: call i8 asm sideeffect "foo", "=r,r,r"(i32 {{.*}}, i32 {{.*}}), !dbg !11
+ // CHECK-NEXT: call i8 asm sideeffect "foo", "=r,r,r"(i32 {{.*}}, i32 {{.*}})
%2 = llvm.inline_asm has_side_effects "foo", "=r,r,r" %arg0, %arg0 : (i32, i32) -> i8
- // CHECK-NEXT: call i8 asm alignstack "foo", "=r,r,r"(i32 {{.*}}, i32 {{.*}}), !dbg !12
+ // CHECK-NEXT: call i8 asm alignstack "foo", "=r,r,r"(i32 {{.*}}, i32 {{.*}})
%3 = llvm.inline_asm is_align_stack "foo", "=r,r,r" %arg0, %arg0 : (i32, i32) -> i8
- // CHECK-NEXT: call i8 asm inteldialect "foo", "=r,r,r"(i32 {{.*}}, i32 {{.*}}), !dbg !13
+ // CHECK-NEXT: call i8 asm inteldialect "foo", "=r,r,r"(i32 {{.*}}, i32 {{.*}})
%4 = llvm.inline_asm asm_dialect = "intel" "foo", "=r,r,r" %arg0, %arg0 : (i32, i32) -> i8
- // CHECK-NEXT: call { i8, i8 } asm "foo", "=r,=r,r"(i32 {{.*}}), !dbg !14
+ // CHECK-NEXT: call { i8, i8 } asm "foo", "=r,=r,r"(i32 {{.*}})
%5 = llvm.inline_asm "foo", "=r,=r,r" %arg0 : (i32) -> !llvm.struct<(i8, i8)>
llvm.return
diff --git a/mlir/test/Target/LLVMIR/openmp-llvm.mlir b/mlir/test/Target/LLVMIR/openmp-llvm.mlir
index da6f99c9fcd6e..82a9c1fa53609 100644
--- a/mlir/test/Target/LLVMIR/openmp-llvm.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-llvm.mlir
@@ -356,11 +356,8 @@ llvm.func @test_omp_master() -> () {
// -----
// CHECK: %struct.ident_t = type
-// CHECK: @[[$parallel_loc:.*]] = private unnamed_addr constant {{.*}} c";LLVMDialectModule;wsloop_simple;{{[0-9]+}};{{[0-9]+}};;\00"
-// CHECK: @[[$parallel_loc_struct:.*]] = private unnamed_addr constant %struct.ident_t {{.*}} @[[$parallel_loc]] {{.*}}
-
-// CHECK: @[[$wsloop_loc:.*]] = private unnamed_addr constant {{.*}} c";LLVMDialectModule;wsloop_simple;{{[0-9]+}};{{[0-9]+}};;\00"
-// CHECK: @[[$wsloop_loc_struct:.*]] = private unnamed_addr constant %struct.ident_t {{.*}} @[[$wsloop_loc]] {{.*}}
+// CHECK: @[[$loc:.*]] = private unnamed_addr constant {{.*}} c";unknown;unknown;{{[0-9]+}};{{[0-9]+}};;\00"
+// CHECK: @[[$loc_struct:.*]] = private unnamed_addr constant %struct.ident_t {{.*}} @[[$loc]] {{.*}}
// CHECK-LABEL: @wsloop_simple
llvm.func @wsloop_simple(%arg0: !llvm.ptr<f32>) {
@@ -373,12 +370,12 @@ llvm.func @wsloop_simple(%arg0: !llvm.ptr<f32>) {
// The form of the emitted IR is controlled by OpenMPIRBuilder and
// tested there. Just check that the right functions are called.
// CHECK: call i32 @__kmpc_global_thread_num
- // CHECK: call void @__kmpc_for_static_init_{{.*}}(ptr @[[$wsloop_loc_struct]],
+ // CHECK: call void @__kmpc_for_static_init_{{.*}}(ptr @[[$loc_struct]],
%3 = llvm.mlir.constant(2.000000e+00 : f32) : f32
%4 = llvm.getelementptr %arg0[%arg1] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>
llvm.store %3, %4 : !llvm.ptr<f32>
omp.yield
- // CHECK: call void @__kmpc_for_static_fini(ptr @[[$wsloop_loc_struct]],
+ // CHECK: call void @__kmpc_for_static_fini(ptr @[[$loc_struct]],
}) {operand_segment_sizes = array<i32: 1, 1, 1, 0, 0, 0, 0>} : (i64, i64, i64) -> ()
omp.terminator
}
@@ -2317,7 +2314,7 @@ llvm.func @omp_task(%x: i32, %y: i32, %zaddr: !llvm.ptr<i32>) {
// CHECK-SAME: (i32 %[[x:.+]], i32 %[[y:.+]], ptr %[[zaddr:.+]])
module attributes {llvm.target_triple = "x86_64-unknown-linux-gnu"} {
llvm.func @omp_task(%x: i32, %y: i32, %zaddr: !llvm.ptr<i32>) {
- // CHECK: %[[
diff :.+]] = sub i32 %[[x]], %[[y]],
+ // CHECK: %[[
diff :.+]] = sub i32 %[[x]], %[[y]]
%
diff = llvm.sub %x, %y : i32
// CHECK: store i32 %[[
diff ]], ptr %2
llvm.store %
diff , %zaddr : !llvm.ptr<i32>
diff --git a/mlir/test/Target/LLVMIR/openmp-nested.mlir b/mlir/test/Target/LLVMIR/openmp-nested.mlir
index 3c4c0770dc270..6e0fa4295bdd5 100644
--- a/mlir/test/Target/LLVMIR/openmp-nested.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-nested.mlir
@@ -38,4 +38,4 @@ module {
// CHECK: define internal void @[[inner1]]
// CHECK: %[[structArg:.+]] = alloca { ptr }
-// CHECK: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @3, i32 1, ptr @[[inner2:.+]], ptr %[[structArg]])
+// CHECK: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @1, i32 1, ptr @[[inner2:.+]], ptr %[[structArg]])
More information about the flang-commits
mailing list