[Mlir-commits] [mlir] [MLIR][LLVM] Extend DIScopeForLLVMFuncOp to handle cross-file operatio… (PR #167844)
Zichen Lu
llvmlistbot at llvm.org
Wed Nov 19 21:15:05 PST 2025
https://github.com/MikaOvO updated https://github.com/llvm/llvm-project/pull/167844
>From ba373a41b96081616c7fad9da147105245911687 Mon Sep 17 00:00:00 2001
From: Zichen Lu <mikaovo2000 at gmail.com>
Date: Thu, 13 Nov 2025 14:37:54 +0800
Subject: [PATCH] [MLIR][LLVM] Extend DIScopeForLLVMFuncOp to handle cross-file
operations without CallSiteLoc
---
.../Transforms/DIScopeForLLVMFuncOp.cpp | 45 ++++++++++++++++++-
.../LLVMIR/add-debuginfo-func-scope.mlir | 19 ++++++++
2 files changed, 63 insertions(+), 1 deletion(-)
diff --git a/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp b/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp
index 67573c4ee6061..12dd22581a979 100644
--- a/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp
+++ b/mlir/lib/Dialect/LLVMIR/Transforms/DIScopeForLLVMFuncOp.cpp
@@ -109,8 +109,12 @@ static Location getNestedLoc(Operation *op, LLVM::DIScopeAttr scopeAttr,
return FusedLoc::get(context, {loc}, lexicalBlockFileAttr);
}
+/// Adds DILexicalBlockFileAttr for operations with CallSiteLoc and operations
+/// from different files than their containing function.
static void setLexicalBlockFileAttr(Operation *op) {
- if (auto callSiteLoc = dyn_cast<CallSiteLoc>(op->getLoc())) {
+ Location opLoc = op->getLoc();
+
+ if (auto callSiteLoc = dyn_cast<CallSiteLoc>(opLoc)) {
auto callerLoc = callSiteLoc.getCaller();
auto calleeLoc = callSiteLoc.getCallee();
LLVM::DIScopeAttr scopeAttr;
@@ -122,6 +126,45 @@ static void setLexicalBlockFileAttr(Operation *op) {
op->setLoc(
CallSiteLoc::get(getNestedLoc(op, scopeAttr, calleeLoc), callerLoc));
}
+
+ return;
+ }
+
+ auto funcOp = op->getParentOfType<LLVM::LLVMFuncOp>();
+ if (!funcOp)
+ return;
+
+ FileLineColLoc opFileLoc = extractFileLoc(opLoc);
+ if (!opFileLoc)
+ return;
+
+ FileLineColLoc funcFileLoc = extractFileLoc(funcOp.getLoc());
+ if (!funcFileLoc)
+ return;
+
+ StringRef opFile = opFileLoc.getFilename().getValue();
+ StringRef funcFile = funcFileLoc.getFilename().getValue();
+
+ // Handle cross-file operations: add DILexicalBlockFileAttr when the
+ // operation's source file differs from its containing function.
+ if (opFile != funcFile) {
+ auto funcOpLoc = llvm::dyn_cast_if_present<FusedLoc>(funcOp.getLoc());
+ if (!funcOpLoc)
+ return;
+ auto scopeAttr = dyn_cast<LLVM::DISubprogramAttr>(funcOpLoc.getMetadata());
+ if (!scopeAttr)
+ return;
+
+ auto *context = op->getContext();
+ LLVM::DIFileAttr opFileAttr =
+ LLVM::DIFileAttr::get(context, llvm::sys::path::filename(opFile),
+ llvm::sys::path::parent_path(opFile));
+
+ LLVM::DILexicalBlockFileAttr lexicalBlockFileAttr =
+ LLVM::DILexicalBlockFileAttr::get(context, scopeAttr, opFileAttr, 0);
+
+ Location newLoc = FusedLoc::get(context, {opLoc}, lexicalBlockFileAttr);
+ op->setLoc(newLoc);
}
}
diff --git a/mlir/test/Dialect/LLVMIR/add-debuginfo-func-scope.mlir b/mlir/test/Dialect/LLVMIR/add-debuginfo-func-scope.mlir
index dfbf992f34c10..ffeb871d56c6c 100644
--- a/mlir/test/Dialect/LLVMIR/add-debuginfo-func-scope.mlir
+++ b/mlir/test/Dialect/LLVMIR/add-debuginfo-func-scope.mlir
@@ -141,3 +141,22 @@ module {
llvm.func @func_callsiteloc() loc(callsite("foo" at "mysource.cc":10:8))
} loc(unknown)
+// -----
+
+// CHECK-LABEL: llvm.func @func_cross_file_op()
+// CHECK: #di_file = #llvm.di_file<"<unknown>" in "">
+// CHECK: #di_file1 = #llvm.di_file<"caller.py" in "">
+// CHECK: #di_file2 = #llvm.di_file<"callee.py" in "">
+// CHECK: #di_subroutine_type = #llvm.di_subroutine_type<callingConvention = DW_CC_normal>
+// CHECK: #di_subprogram = #llvm.di_subprogram<id = distinct[1]<>, compileUnit = #di_compile_unit, scope = #di_file1, name = "func_cross_file_op", linkageName = "func_cross_file_op", file = #di_file1, line = 5, scopeLine = 5, subprogramFlags = "Definition|Optimized", type = #di_subroutine_type>
+// CHECK: #di_lexical_block_file = #llvm.di_lexical_block_file<scope = #di_subprogram, file = #di_file2, discriminator = 0>
+
+#loc = loc("caller.py":5:1)
+#loc1 = loc("callee.py":10:5)
+
+module {
+ llvm.func @func_cross_file_op() {
+ llvm.return loc(#loc1)
+ } loc(#loc)
+} loc(unknown)
+
More information about the Mlir-commits
mailing list