[Mlir-commits] [mlir] [MLIR][LLVM] Exporter skip over caller frame without debug scope (PR #90915)

Billy Zhu llvmlistbot at llvm.org
Thu May 2 16:11:57 PDT 2024


https://github.com/zyx-billy created https://github.com/llvm/llvm-project/pull/90915

Followup to #90759.

Instead of just returning null when the caller scope is not translatable, "jump over" the current caller scope and use the outer scope as the caller if that is available. This means that in an inlined call stack if there are frames without debug scope, those frames are skipped to preserve what is available. In the original example where
```
func A {
  foo loc(fused<#A>["a":1:1])
}
func B {
  call @A loc("b":1:1)
}
func C {
  call @B loc(fused<#C>["c":1:1])
}
```
is inlined into
```
func C {
  foo loc(callsite(
            callsite(fused<#A>["a":1:1] at loc("b":1:1))
           at
            fused<#C>["c":1:1]))
}
```
The translated result would be `!1`:
```
!0 = !DILocation(line: 1, column: 1, scope: !C)
!1 = !DILocation(line: 1, column: 1, scope: !A, inlinedAt: !0)
```

This has a neat benefit in maintaining callsite associativity: No matter if we have `callsite(callsite(A at B) at C)` or `callsite(A at callsite(B at C))`, the translation now is the same. The previous solution did not provide this guarantee, which meant the callsite construction would somehow impact this translation.

>From b1fefdc7f7350bf0c07ae9a94819393017f8a66e Mon Sep 17 00:00:00 2001
From: Billy Zhu <billyzhu at modular.com>
Date: Thu, 2 May 2024 16:00:42 -0700
Subject: [PATCH] use inlinedAt when available

---
 mlir/lib/Target/LLVMIR/DebugTranslation.cpp | 13 +++++++++----
 mlir/test/Target/LLVMIR/llvmir-debug.mlir   |  8 ++++----
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
index f02939abc5fe18..2aa1b6b85ac02e 100644
--- a/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/DebugTranslation.cpp
@@ -406,10 +406,15 @@ llvm::DILocation *DebugTranslation::translateLoc(Location loc,
   if (auto callLoc = dyn_cast<CallSiteLoc>(loc)) {
     // For callsites, the caller is fed as the inlinedAt for the callee.
     auto *callerLoc = translateLoc(callLoc.getCaller(), scope, inlinedAt);
-    // If the caller scope does not exist, the callsite cannot be represented
-    // in LLVM (the callee scope may not match the function it is in).
-    if (!callerLoc)
-      return nullptr;
+    // If the caller scope is not translatable, the overall callsite cannot be
+    // represented in LLVM (the callee scope may not match the parent function).
+    if (!callerLoc) {
+      // If there is an inlinedAt scope (an outer caller), skip to that
+      // directly. Otherwise, cannot translate.
+      if (!inlinedAt)
+        return nullptr;
+      callerLoc = inlinedAt;
+    }
     llvmLoc = translateLoc(callLoc.getCallee(), nullptr, callerLoc);
     // Fallback: Ignore callee if it has no debug scope.
     if (!llvmLoc)
diff --git a/mlir/test/Target/LLVMIR/llvmir-debug.mlir b/mlir/test/Target/LLVMIR/llvmir-debug.mlir
index e8a3d65209afde..1f0fc969364ac8 100644
--- a/mlir/test/Target/LLVMIR/llvmir-debug.mlir
+++ b/mlir/test/Target/LLVMIR/llvmir-debug.mlir
@@ -114,13 +114,13 @@ llvm.func @func_with_debug(%arg: i64) {
   // CHECK: call void @func_no_debug(), !dbg ![[MY_SOURCE_LOC]]
   llvm.call @func_no_debug() : () -> () loc(callsite("nodebug.cc":3:4 at fused<#sp0>["mysource.cc":5:6]))
 
-  // CHECK: call void @func_no_debug(), !dbg ![[MY_SOURCE_LOC]]
-  llvm.call @func_no_debug() : () -> () loc(callsite(callsite(fused<#callee>["nodebug.cc":3:4] at "foo.mlir":2:4) at fused<#sp0>["mysource.cc":5:6]))
-
   // CHECK: call void @func_no_debug(), !dbg ![[FUSED_LOC:[0-9]+]]
   llvm.call @func_no_debug() : () -> () loc(fused[callsite(fused<#callee>["mysource.cc":5:6] at "mysource.cc":1:1), "mysource.cc":1:1])
 
-  // CHECK: add i64 %[[ARG]], %[[ARG]], !dbg ![[FUSEDWITH_LOC:[0-9]+]]
+  // CHECK: call void @func_no_debug(), !dbg ![[FUSEDWITH_LOC:[0-9]+]]
+  llvm.call @func_no_debug() : () -> () loc(callsite(callsite(fused<#callee>["foo.mlir":2:4] at "foo.mlir":1:1) at fused<#sp0>["foo.mlir":28:5]))
+
+  // CHECK: add i64 %[[ARG]], %[[ARG]], !dbg ![[FUSEDWITH_LOC]]
   %sum = llvm.add %arg, %arg : i64 loc(callsite(fused<#callee>["foo.mlir":2:4] at fused<#sp0>["foo.mlir":28:5]))
 
   llvm.return



More information about the Mlir-commits mailing list