Thanks all, especially Jeremy, for your help. > On Thu, Feb 6, 2020 at 11:04 AM Jeremy Morse <jeremy.morse.l...@gmail.com> > wrote: >> Everything in the IR appears correct to my eyes, although I know next >> to nothing about coroutines and might have missed something.
Yes, good point. I think a better explanation of the coroutine passes is in order. The coro-split pass first uses 'llvm::LowerDbgDeclare' to replace all llvm.dbg.declare for %i with llvm.dbg.value, and then replaces all uses of the '%i = alloca i32' instruction with a getelementptr instruction like this one: %i.reload.addr63 = getelementptr inbounds %_Z3foov.Frame, %_Z3foov.Frame* %FramePtr, i32 0, i32 7, !dbg !651 In other words, the value of %i is stored on the frame object, on the heap, at an offset of 7 into the frame. I'm beginning to think a fundamental fix for this issue would be to stop replacing llvm.dbg.declare with llvm.dbg.value, and instead replace the llvm.dbg.declare with llvm.dbg.addr that points the debugger to the %i variable's new permanent location as an offset into the coroutine frame object. Does this approach make sense to people on this mailing list, who probably know more about how these intrinsics work than I do? >> If whatever's producing the coroutine IR has guarantees about where >> and when variables are loaded/stored from/to memory, it should be >> possible to put more information into the IR, so that the rest of LLVM >> doesn't have to guess. For example, this portion of IR: >> >> %15 = load i32, i32* %i.reload.addr62, align 4, !dbg !670 >> call void @llvm.dbg.value(metadata i32 %15, metadata !659, metadata >> !DIExpression()), !dbg !661 >> %inc19 = add nsw i32 %15, 1, !dbg !670 >> call void @llvm.dbg.value(metadata i32 %inc19, metadata !659, >> metadata !DIExpression()), !dbg !661 >> store i32 %inc19, i32* %i.reload.addr62, align 4, !dbg !670 >> >> Could have a call to llvm.dbg.addr(metadata i32 *%i.reload.addr66, >> ...) inserted after the store, indicating that the variable is located >> in memory. I tried multiple approaches to manually inserting an llvm.dbg.addr after the store instruction, as per your suggestion, Jeremy. I used llc to compile the IR into an object file that I then linked, and inspected the DWARF generated for the file. Unfortunately, inserting dbg.addr that operated on the reloaded values didn't lead to any change in the DWARF that was produced -- specifically, this didn't make a difference: call void @llvm.dbg.addr(metadata i32* %i.reload.addr62, metadata !873, metadata !DIExpression()), !dbg !884 I also tried adding a dbg.addr that attempted to point the debugger to the %i variable's location at its offset on the coroutine frame: call void @llvm.dbg.addr(metadata %_Z3foov.Frame* %FramePtr, metadata !873, metadata !DIExpression(DW_OP_plus, 28)), !dbg !884 This changed the live ranges for %i in the DWARF that was output, but not in a way that made the %i variable visible to the debugger. Again, I wonder if maybe the correct path forward here is to, instead of attempting to expand the live ranges in the DWARF for %i, to instead signal in the debug info that the value of %i is always available to read from the 7 offset into the coroutine frame. If this makes sense, then I need to learn how to convey that via the llvm.dbg intrinsics -- llvm.dbg.addr sounds like what I want, doesn't it? Again, thanks for all the help on this list. (PS: I've also been enjoying reading the proposals you sent, Jeremy, for post-ISel debug info salvaging!) Please let me know if my thinking above sounds right or misguided in any way -- thanks! - Brian Gesiak _______________________________________________ lldb-dev mailing list lldb-dev@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev