<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Hi Jeremy,</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Thanks for proposing that.</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
First of all, I think that all the dbg-instr-ref work can give us a lot of benefits (since handling of llvm.dbg.value() intrinsic is easier, indeed) when implemented/committed, so thanks for that.</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
I completely like the idea you have described, and there are a couple of questions/comments:</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<ol>
<li>The entry-values-as-"backups" could be used this way, but we firstly need to have the <span style="font-family: "Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif; font-size: 14.6667px; text-align: start; background-color: rgb(255, 255, 255); display: inline !important">DBG_INSTR_REF
 in use. I don't see an overlapping with the way I suggested for current "non-ref-dbg-values" at MIR. (?)</span></li><li>This will be an improvement of the <span style="font-family: "Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif; font-size: 14.6667px; text-align: start; background-color: rgb(255, 255, 255); display: inline !important;">DBG_INSTR_REF,
 since it needs the variadic form of the instruction; and we don't have it at the moment? <span style="font-family: "Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif; background-color: rgb(255, 255, 255); display: inline !important">As
 you have pointed out, by having the variadic form of the instruction, we can salvage "non-entry" values as well, I guess.</span><br>
</span></li></ol>
<div><span style="font-family: "Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif; font-size: 14.6667px; text-align: start; background-color: rgb(255, 255, 255); display: inline !important"><br>
</span></div>
<div><span style="font-family: "Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif; font-size: 14.6667px; text-align: start; background-color: rgb(255, 255, 255); display: inline !important">Best
 regards,</span></div>
<div><span style="font-family: "Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif; font-size: 14.6667px; text-align: start; background-color: rgb(255, 255, 255); display: inline !important">Djordje</span></div>
<div><span style="font-family: "Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif; font-size: 14.6667px; text-align: start; background-color: rgb(255, 255, 255); display: inline !important"><br>
</span></div>
</div>
<div id="appendonsend"></div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> Jeremy Morse <jeremy.morse.llvm@gmail.com><br>
<b>Sent:</b> Wednesday, September 9, 2020 5:19 PM<br>
<b>To:</b> Djordje Todorovic <Djordje.Todorovic@syrmia.com><br>
<b>Cc:</b> David Stenberg <david.stenberg@ericsson.com>; llvm-dev@lists.llvm.org <llvm-dev@lists.llvm.org>; Nikola Tesic <Nikola.Tesic@syrmia.com>; Petar Jovanovic <petar.jovanovic@syrmia.com>; ibaev@cisco.com <ibaev@cisco.com>; asowda@cisco.com <asowda@cisco.com><br>
<b>Subject:</b> Re: [llvm-dev] [RFC] [DebugInfo] Using DW_OP_entry_value within LLVM IR</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">Hi Djordje,<br>
<br>
On Wed, Sep 9, 2020 at 7:52 AM Djordje Todorovic<br>
<Djordje.Todorovic@syrmia.com> wrote:<br>
> Using entry-values ('callee' side of the feature) is not enough in any case. It is always connected to the call-site-param (function arguments but we call it call-site-params; 'caller' side of the feature) debug info. I believe that there are call-site-params
 that could be expressed in terms of DWARF for the cases we face within deadargelim. GCC does perform correct output for both caller and callee sides for unused params.<br>
<br>
Ah, that covers my concerns. This is definitely a worthy cause then --<br>
especially as parameters are usually considered more important to<br>
preserve than other variables.<br>
<br>
Djordje<br>
> Please share that work when you are ready.<br>
<br>
Sure, explanation below: note that I'm bringing this up now because I<br>
see producing entry-value "backup" locations as a technique to recover<br>
from the register allocator clobbering things, and I feel the below is<br>
a more general solution.<br>
<br>
I'd like to use this (contrived) code as an illustrative example:<br>
<br>
    void ext(long);<br>
    void foo(long *ptr, long bar, long baz) {<br>
      for (long i = 0; i < bar; ++i) {<br>
        long index = baz + i;<br>
        long *curptr = &ptr[index];<br>
        ext(*curptr);<br>
      }<br>
    }<br>
<br>
All it does is iterate over a loop, loading values from an offset into<br>
a pointer. I've compiled this at -O2, and then given it an additional<br>
run of -loop-reduce with opt [0]. During optimisation, LLVM rightly<br>
identifies that the 'baz' offset is loop-invariant, and that it can<br>
fold some of the offset calculation into the loop preheader. This then<br>
leads to both 'ptr' and 'baz' being out of liveness, and being<br>
clobbered in the body of the loop. In addition, the 'index' variable<br>
is optimised out too, and that's the variable I'd like to focus on.<br>
<br>
Today, we're not able to describe 'index' in the IR after<br>
-loop-reduce, but I'm confident that the variadic variable locations<br>
work will make that possible. I'm going to assume that we can describe<br>
such locations for the rest of this email.<br>
<br>
"index" could be described by using the entry value of 'baz' and<br>
adding it to 'i', which remains in liveness throughout. To produce a<br>
"backup" location though, we would have to guess that 'baz' would go<br>
out of liveness in advance, and speculatively produce the expression.<br>
I reckon that we can instead calculate the location at end of<br>
compilation by using the SSA-like information from instruction<br>
referencing. Here's the MIR for the reduced loop body, using<br>
instruction-referencing [1] and lightly edited to remove noise, with<br>
only variable locations for the 'i' variable. I've added some<br>
explanatory comments:<br>
<br>
    DBG_PHI $rbx, 2<br>
    DBG_INSTR_REF 2, 0, !16, !DIExpression(), debug-location !23<br>
    ;  This is the load from *curptr:<br>
    renamable $rdi = MOV64rm renamable $r15, 8, renamable $rbx<br>
    ; Call to ext,<br>
    CALL64pcrel32 @ext, csr_64, [implicit defs]<br>
    ; Loop increment:<br>
    renamable $rbx = nuw nsw ADD64ri8 killed renamable $rbx, 1,<br>
debug-instr-number 1<br>
    DBG_INSTR_REF 1, 0, !16, !DIExpression(), debug-location !23<br>
    CMP64rr renamable $r14, renamable $rbx, implicit-def $eflags<br>
    JCC_1 %bb.2, 5, implicit $eflags<br>
<br>
The label "debug-instr-number 1" on the ADD64ri8 identifies the ADD as<br>
corresponding to the loop increment, and the DBG_PHI for $rbx as the<br>
position where the loop PHI occurs. My key observation is that there<br>
is a one-to-one relationship between LLVM-IR Values and these<br>
end-of-compilation instruction numbers [2]. If we stored a mapping<br>
during instruction selection of Value <=> instruction reference, at<br>
the end of compilation we would be able to salvage variable locations<br>
that had gone out of liveness.<br>
<br>
Imagine for a moment that we described the "index" variable as a<br>
variadic variable location, possibly looking like this:<br>
<br>
    DBG_INSTR_REF {3, 0}, {2, 0}, !17, !DIExpression(DW_OP_LLVM_arg,<br>
0, DW_OP_LLVM_arg, 1, DW_OP_plus)<br>
<br>
Where the {3, 0} instruction number referred to the 'baz' argument,<br>
and {2, 0} the value of 'i' on entry to the loop body. The workflow<br>
for salvaging would look something like this, after LiveDebugValues<br>
has finished doing dataflow things:<br>
  1) Examine instruction reference {3, 0},<br>
  2) Observe that it's out of liveness in the current location (the loop body),<br>
  3) Look up the LLVM-IR Value that {3, 0} corresponds to, finding the<br>
Argument in LLVM-IR,<br>
  4) Because it's an Argument, replace DW_OP_LLVM_arg, 0 with the<br>
corresponding entry value expression,<br>
  5) Emit variable location.<br>
<br>
This is harder than just speculating how we might salvage the location<br>
earlier in compilation, but is more direct, and involves no<br>
un-necessary work. Additionally, it's not limited to entry values: for<br>
any value that goes out of liveness that was computed by a side-effect<br>
free instruction, we could:<br>
  4) For each operand of the corresponding LLVM-IR Instruction,<br>
  4.1) Identify the instruction number of this operand,<br>
  4.2) Confirm that that number is still in liveness (if not: abort),<br>
  5) Compute an expression that recomputes the Value using the<br>
locations of the operands,<br>
  6) Emit variable location.<br>
<br>
We could even go the other way and recover a value from other<br>
computations that used the value (if an inverse operation exists).<br>
<br>
~<br>
<br>
This may sound far-fetched, but I think a lot of the information<br>
necessary to do the above is becoming available. Doing this completely<br>
in general would involve putting instruction references on every<br>
LLVM-IR Value in the function being compiled, which could add an<br>
overhead. Whether that's worth it depends on how many variable<br>
locations could be recovered.<br>
<br>
Again, it hinges on not finding something fatal in the instruction<br>
referencing approach to variable locations. Tail duplication is being<br>
miserable, but hasn't thrown up anything fatal yet.<br>
<br>
Thanks for listening!<br>
<br>
[0] I'm not sure why -loop-reduce wasn't firing during -O2, but that's<br>
not important.<br>
[1] It's possible with all the patches I've uploaded for review so<br>
far; although I seem to have missed the patch to InstrEmitter.cpp that<br>
labels PHI instructions, I'll try to get that up soon.<br>
[2] Not necessarily true after tail-duplication runs; but I believe<br>
that can be addressed with some minor pain.<br>
<br>
--<br>
Thanks,<br>
Jeremy<br>
</div>
</span></font></div>
</body>
</html>