[llvm] 2904949 - [coroutine] Salvage dbg.values in the original function as well

Felipe de Azevedo Piovezan via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 21 06:31:35 PDT 2023


Author: Felipe de Azevedo Piovezan
Date: 2023-04-21T09:31:39-04:00
New Revision: 290494955c6c1deac9e876fa895cb14b9be37dd2

URL: https://github.com/llvm/llvm-project/commit/290494955c6c1deac9e876fa895cb14b9be37dd2
DIFF: https://github.com/llvm/llvm-project/commit/290494955c6c1deac9e876fa895cb14b9be37dd2.diff

LOG: [coroutine] Salvage dbg.values in the original function as well

D97673 implemented salvaging o dbg.value inside coroutine funclets, but
left the original function untouched. Before, only dbg.addr and dbg.decl
would get salvaged.

D121324 implemented salvaging of dbg.addr and dbg.decl in the original
function as well, but not of dbg.values.

This patch unifies salvaging in the original function and related
funclets, so that all intrinsics are salvaged in all functions. This is
particularly useful for ABIs where the original function is also
rewritten to receive the frame pointer as an argument.

Differential Revision: https://reviews.llvm.org/D148745

Added: 
    

Modified: 
    llvm/lib/Transforms/Coroutines/CoroInternal.h
    llvm/lib/Transforms/Coroutines/CoroSplit.cpp
    llvm/test/Transforms/Coroutines/coro-debug-dbg.values.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Coroutines/CoroInternal.h b/llvm/lib/Transforms/Coroutines/CoroInternal.h
index 13bdaaf177561..9af853a163535 100644
--- a/llvm/lib/Transforms/Coroutines/CoroInternal.h
+++ b/llvm/lib/Transforms/Coroutines/CoroInternal.h
@@ -25,8 +25,11 @@ bool declaresIntrinsics(const Module &M,
                         const std::initializer_list<StringRef>);
 void replaceCoroFree(CoroIdInst *CoroId, bool Elide);
 
-/// Recover a dbg.declare prepared by the frontend and emit an alloca
-/// holding a pointer to the coroutine frame.
+/// Attempts to rewrite the location operand of debug intrinsics in terms of
+/// the coroutine frame pointer, folding pointer offsets into the DIExpression
+/// of the intrinsic.
+/// If the frame pointer is an Argument, store it into an alloca if
+/// OptimizeFrame is false.
 void salvageDebugInfo(
     SmallDenseMap<llvm::Value *, llvm::AllocaInst *, 4> &DbgPtrAllocaCache,
     DbgVariableIntrinsic *DVI, bool OptimizeFrame);

diff  --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
index 589cf193f35d3..152dedd7775bf 100644
--- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp
@@ -680,17 +680,24 @@ static void replaceSwiftErrorOps(Function &F, coro::Shape &Shape,
   }
 }
 
+/// Returns all DbgVariableIntrinsic in F.
+static SmallVector<DbgVariableIntrinsic *, 8>
+collectDbgVariableIntrinsics(Function &F) {
+  SmallVector<DbgVariableIntrinsic *, 8> Intrinsics;
+  for (auto &I : instructions(F))
+    if (auto *DVI = dyn_cast<DbgVariableIntrinsic>(&I))
+      Intrinsics.push_back(DVI);
+  return Intrinsics;
+}
+
 void CoroCloner::replaceSwiftErrorOps() {
   ::replaceSwiftErrorOps(*NewF, Shape, &VMap);
 }
 
 void CoroCloner::salvageDebugInfo() {
-  SmallVector<DbgVariableIntrinsic *, 8> Worklist;
+  SmallVector<DbgVariableIntrinsic *, 8> Worklist =
+      collectDbgVariableIntrinsics(*NewF);
   SmallDenseMap<llvm::Value *, llvm::AllocaInst *, 4> DbgPtrAllocaCache;
-  for (auto &BB : *NewF)
-    for (auto &I : BB)
-      if (auto *DVI = dyn_cast<DbgVariableIntrinsic>(&I))
-        Worklist.push_back(DVI);
   for (DbgVariableIntrinsic *DVI : Worklist)
     coro::salvageDebugInfo(DbgPtrAllocaCache, DVI, Shape.OptimizeFrame);
 
@@ -1971,20 +1978,11 @@ splitCoroutine(Function &F, SmallVectorImpl<Function *> &Clones,
   // This invalidates SwiftErrorOps in the Shape.
   replaceSwiftErrorOps(F, Shape, nullptr);
 
-  // Finally, salvage the llvm.dbg.declare in our original function that point
-  // into the coroutine frame. We only do this for the current function since
-  // the Cloner salvaged debug info for us in the new coroutine funclets.
-  SmallVector<DbgVariableIntrinsic *, 8> Worklist;
+  // Salvage debug intrinsics that point into the coroutine frame in the
+  // original function. The Cloner has already salvaged debug info in the new
+  // coroutine funclets.
   SmallDenseMap<llvm::Value *, llvm::AllocaInst *, 4> DbgPtrAllocaCache;
-  for (auto &BB : F) {
-    for (auto &I : BB) {
-      if (auto *DDI = dyn_cast<DbgDeclareInst>(&I)) {
-        Worklist.push_back(DDI);
-        continue;
-      }
-    }
-  }
-  for (auto *DDI : Worklist)
+  for (auto *DDI : collectDbgVariableIntrinsics(F))
     coro::salvageDebugInfo(DbgPtrAllocaCache, DDI, Shape.OptimizeFrame);
 
   return Shape;

diff  --git a/llvm/test/Transforms/Coroutines/coro-debug-dbg.values.ll b/llvm/test/Transforms/Coroutines/coro-debug-dbg.values.ll
index 1d0233c0617fa..fa6c6e9b8d2cf 100644
--- a/llvm/test/Transforms/Coroutines/coro-debug-dbg.values.ll
+++ b/llvm/test/Transforms/Coroutines/coro-debug-dbg.values.ll
@@ -2,13 +2,34 @@
 ; RUN: opt < %s -passes='module(coro-early),cgscc(coro-split,coro-split)' -S | FileCheck %s
 ;
 ; This file is based on coro-debug-frame-variable.ll.
-; CHECK:  define internal fastcc void @f.resume(ptr noundef nonnull align 16 dereferenceable(80) %begin) !dbg ![[RESUME_FN_DBG_NUM:[0-9]+]]
+; CHECK-LABEL: define void @f(
+; CHECK:       %[[frame:.*]] = call {{.*}} @llvm.coro.begin
+; CHECK:       call void @llvm.dbg.value(metadata ptr %[[frame]]
+; CHECK-SAME:    !DIExpression(DW_OP_plus_uconst, [[OffsetX:[0-9]*]]))
+;                                                                   ^ No deref at the end, as this variable ("x") is an array;
+;                                                                     its value is its address. The entire array is in the frame.
+; CHECK:       call void @llvm.dbg.value(metadata ptr %[[frame]]
+; CHECK-SAME:    !DIExpression(DW_OP_plus_uconst, [[OffsetSpill:[0-9]*]], DW_OP_deref))
+; CHECK:       call void @llvm.dbg.value(metadata ptr %[[frame]]
+; CHECK-SAME:    !DIExpression(DW_OP_plus_uconst, [[OffsetI:[0-9]*]], DW_OP_deref))
+; CHECK:       call void @llvm.dbg.value(metadata ptr %[[frame]]
+; CHECK-SAME:    !DIExpression(DW_OP_plus_uconst, [[OffsetJ:[0-9]*]], DW_OP_deref))
+
+; CHECK-LABEL: void @f.resume(
+; CHECK-SAME:                 ptr {{.*}} %[[frame:.*]])
+; CHECK-SAME:  !dbg ![[RESUME_FN_DBG_NUM:[0-9]+]]
+; CHECK:         %[[frame_alloca:.*]] = alloca ptr
+; CHECK-NEXT:    store ptr %[[frame]], ptr %[[frame_alloca]]
 ; CHECK:       init.ready:
-; CHECK:         call void @llvm.dbg.value(metadata ptr %begin.debug, metadata ![[XVAR_RESUME:[0-9]+]],
+; CHECK:         call void @llvm.dbg.value(metadata ptr %[[frame_alloca]], metadata ![[XVAR_RESUME:[0-9]+]],
+; CHECK-SAME:        !DIExpression(DW_OP_deref, DW_OP_plus_uconst, [[OffsetX]])
 ; CHECK:       await.ready:
-; CHECK:         call void @llvm.dbg.value(metadata ptr %begin.debug, metadata ![[SPILL_RESUME:[0-9]+]]
-; CHECK:         call void @llvm.dbg.value(metadata ptr %begin.debug, metadata ![[IVAR_RESUME:[0-9]+]], metadata !DIExpression(
-; CHECK:         call void @llvm.dbg.value(metadata ptr %begin.debug, metadata ![[JVAR_RESUME:[0-9]+]], metadata !DIExpression(
+; CHECK:         call void @llvm.dbg.value(metadata ptr %[[frame_alloca]], metadata ![[SPILL_RESUME:[0-9]+]]
+; CHECK-SAME:        !DIExpression(DW_OP_deref, DW_OP_plus_uconst, [[OffsetSpill]], DW_OP_deref)
+; CHECK:         call void @llvm.dbg.value(metadata ptr %[[frame_alloca]], metadata ![[IVAR_RESUME:[0-9]+]],
+; CHECK-SAME:        !DIExpression(DW_OP_deref, DW_OP_plus_uconst, [[OffsetI]], DW_OP_deref)
+; CHECK:         call void @llvm.dbg.value(metadata ptr %[[frame_alloca]], metadata ![[JVAR_RESUME:[0-9]+]],
+; CHECK-SAME:        !DIExpression(DW_OP_deref, DW_OP_plus_uconst, [[OffsetJ]], DW_OP_deref)
 ;
 ; CHECK: ![[RESUME_FN_DBG_NUM]] = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov"
 ; CHECK: ![[IVAR_RESUME]] = !DILocalVariable(name: "i"
@@ -16,7 +37,6 @@
 ; CHECK: ![[JVAR_RESUME]] = !DILocalVariable(name: "j"
 ; CHECK: ![[SPILL_RESUME]] = !DILocalVariable(name: "produced"
 
-source_filename = "../llvm/test/Transforms/Coroutines/coro-debug-dbg.values-O2.ll"
 declare void @consume(i32)
 
 define void @f(i32 %i, i32 %j) presplitcoroutine !dbg !8 {


        


More information about the llvm-commits mailing list