Index: llvm/lib/Transforms/Coroutines/CoroFrame.cpp =================================================================== --- llvm/lib/Transforms/Coroutines/CoroFrame.cpp +++ llvm/lib/Transforms/Coroutines/CoroFrame.cpp @@ -2188,34 +2188,10 @@ else break; } - // Store a pointer to the coroutine frame object in an alloca so it - // is available throughout the function when producing unoptimized - // code. Extending the lifetime this way is correct because the - // variable has been declared by a dbg.declare intrinsic. - if (auto Arg = dyn_cast_or_null(Storage)) { - auto &Cached = DbgPtrAllocaCache[Storage]; - if (!Cached) { - Cached = Builder.CreateAlloca(Storage->getType(), 0, nullptr, - Arg->getName() + ".debug"); - Builder.CreateStore(Storage, Cached); - } - Storage = Cached; - // FIXME: LLVM lacks nuanced semantics to differentiate between - // memory and direct locations at the IR level. The backend will - // turn a dbg.declare(alloca, ..., DIExpression()) into a memory - // location. Thus, if there are deref and offset operations in the - // expression, we need to add a DW_OP_deref at the *start* of the - // expression to first load the contents of the alloca before - // adjusting it with the expression. - if (Expr && Expr->isComplex()) - Expr = DIExpression::prepend(Expr, DIExpression::DerefBefore); - } auto &VMContext = DDI->getFunction()->getContext(); DDI->setOperand( 0, MetadataAsValue::get(VMContext, ValueAsMetadata::get(Storage))); DDI->setOperand(2, MetadataAsValue::get(VMContext, Expr)); - if (auto *InsertPt = dyn_cast_or_null(Storage)) - DDI->moveAfter(InsertPt); } void coro::buildCoroutineFrame(Function &F, Shape &Shape) { Index: llvm/lib/Transforms/Coroutines/CoroSplit.cpp =================================================================== --- llvm/lib/Transforms/Coroutines/CoroSplit.cpp +++ llvm/lib/Transforms/Coroutines/CoroSplit.cpp @@ -662,9 +662,24 @@ return BB->hasNPredecessors(0) && BB != &NewF->getEntryBlock(); }; for (DbgDeclareInst *DDI : Worklist) { - if (IsUnreachableBlock(DDI->getParent())) - DDI->eraseFromParent(); - else if (dyn_cast_or_null(DDI->getAddress())) { + auto* Address = DDI->getAddress(); + + if (isa(Address)) { + auto& Entry = NewF->getEntryBlock(); + auto* InsertPt = Entry.getFirstNonPHI(); + DDI->moveAfter(InsertPt); + continue; + } + + if (IsUnreachableBlock(DDI->getParent())) { + auto* Inst = dyn_cast_or_null(Address); + if (!Inst || IsUnreachableBlock(Inst->getParent())) { + DDI->eraseFromParent(); + continue; + } + + DDI->moveAfter(Inst); + } else if (dyn_cast_or_null(DDI->getAddress())) { // Count all non-debuginfo uses in reachable blocks. unsigned Uses = 0; for (auto *User : DDI->getAddress()->users()) Index: llvm/test/Transforms/Coroutines/coro-debug-frame-variable.ll =================================================================== --- llvm/test/Transforms/Coroutines/coro-debug-frame-variable.ll +++ llvm/test/Transforms/Coroutines/coro-debug-frame-variable.ll @@ -41,14 +41,11 @@ ; ; CHECK-LABEL: define internal fastcc void @f.resume({{.*}}) { ; CHECK: entry.resume: -; CHECK-NEXT: %[[DBG_PTR:.*]] = alloca %f.Frame* -; CHECK-NEXT: call void @llvm.dbg.declare(metadata %f.Frame** %[[DBG_PTR]], metadata ![[XVAR_RESUME:[0-9]+]], metadata !DIExpression(DW_OP_deref, DW_OP_plus_uconst, 32)), !dbg -; CHECK-NEXT: call void @llvm.dbg.declare(metadata %f.Frame** %[[DBG_PTR]], metadata ![[IVAR_RESUME:[0-9]+]], metadata !DIExpression(DW_OP_deref, DW_OP_plus_uconst, 20)), !dbg ![[IDBGLOC_RESUME:[0-9]+]] -; CHECK-NEXT: store %f.Frame* {{.*}}, %f.Frame** %[[DBG_PTR]] +; CHECK: call void @llvm.dbg.declare(metadata %f.Frame* %FramePtr, metadata ![[XVAR_RESUME:[0-9]+]], metadata !DIExpression(DW_OP_plus_uconst, 32)), !dbg +; CHECK-NEXT: call void @llvm.dbg.declare(metadata %f.Frame* %FramePtr, metadata ![[IVAR_RESUME:[0-9]+]], metadata !DIExpression(DW_OP_plus_uconst, 20)), !dbg ![[IDBGLOC_RESUME:[0-9]+]] ; CHECK: %[[J:.*]] = alloca i32, align 4 -; CHECK-NEXT: call void @llvm.dbg.declare(metadata i32* %[[J]], metadata ![[JVAR_RESUME:[0-9]+]], metadata !DIExpression()), !dbg ![[JDBGLOC_RESUME:[0-9]+]] -; CHECK: init.ready: ; CHECK: await.ready: +; CHECK: call void @llvm.dbg.declare(metadata i32* %[[J]], metadata ![[JVAR_RESUME:[0-9]+]], metadata !DIExpression()), !dbg ![[JDBGLOC_RESUME:[0-9]+]] ; ; CHECK: ![[IVAR]] = !DILocalVariable(name: "i" ; CHECK: ![[SCOPE:[0-9]+]] = distinct !DILexicalBlock(scope: !8, file: !1, line: 23, column: 12) Index: llvm/test/Transforms/Coroutines/coro-debug.ll =================================================================== --- llvm/test/Transforms/Coroutines/coro-debug.ll +++ llvm/test/Transforms/Coroutines/coro-debug.ll @@ -140,14 +140,12 @@ ; CHECK: define i8* @f(i32 %x) #0 !dbg ![[ORIG:[0-9]+]] ; CHECK: define internal fastcc void @f.resume(%f.Frame* noalias nonnull align 8 dereferenceable(32) %FramePtr) #0 !dbg ![[RESUME:[0-9]+]] ; CHECK: entry.resume: -; CHECK: %[[DBG_PTR:.*]] = alloca %f.Frame* -; CHECK: call void @llvm.dbg.declare(metadata %f.Frame** %[[DBG_PTR]], metadata ![[RESUME_COROHDL:[0-9]+]], metadata !DIExpression(DW_OP_deref, DW_OP_plus_uconst, -; CHECK: call void @llvm.dbg.declare(metadata %f.Frame** %[[DBG_PTR]], metadata ![[RESUME_X:[0-9]+]], metadata !DIExpression(DW_OP_deref, DW_OP_plus_uconst, [[EXPR_TAIL:.*]]) -; CHECK: call void @llvm.dbg.declare(metadata %f.Frame** %[[DBG_PTR]], metadata ![[RESUME_DIRECT:[0-9]+]], metadata !DIExpression(DW_OP_deref, DW_OP_plus_uconst, [[EXPR_TAIL]]) -; CHECK: store %f.Frame* {{.*}}, %f.Frame** %[[DBG_PTR]] +; CHECK: call void @llvm.dbg.declare(metadata %f.Frame* %FramePtr, metadata ![[RESUME_COROHDL:[0-9]+]], metadata !DIExpression(DW_OP_plus_uconst, +; CHECK: call void @llvm.dbg.declare(metadata %f.Frame* %FramePtr, metadata ![[RESUME_X:[0-9]+]], metadata !DIExpression(DW_OP_plus_uconst, [[EXPR_TAIL:.*]]) +; CHECK: call void @llvm.dbg.declare(metadata %f.Frame* %FramePtr, metadata ![[RESUME_DIRECT:[0-9]+]], metadata !DIExpression(DW_OP_plus_uconst, [[EXPR_TAIL]]) ; CHECK-NOT: alloca %struct.test* -; CHECK: call void @llvm.dbg.declare(metadata i32 0, metadata ![[RESUME_CONST:[0-9]+]], metadata !DIExpression()) ; CHECK: call void @coro.devirt.trigger(i8* null) +; CHECK: call void @llvm.dbg.declare(metadata i32 0, metadata ![[RESUME_CONST:[0-9]+]], metadata !DIExpression()) ; CHECK: define internal fastcc void @f.destroy(%f.Frame* noalias nonnull align 8 dereferenceable(32) %FramePtr) #0 !dbg ![[DESTROY:[0-9]+]] ; CHECK: define internal fastcc void @f.cleanup(%f.Frame* noalias nonnull align 8 dereferenceable(32) %FramePtr) #0 !dbg ![[CLEANUP:[0-9]+]]