<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Wed, Sep 6, 2017 at 10:50 AM Robinson, Paul <<a href="mailto:paul.robinson@sony.com">paul.robinson@sony.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">





<div lang="EN-US" link="blue" vlink="purple">
<div class="m_-1129212347092888653WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">It's worth remembering that there are two syntactically similar but semantically different kinds of "expression" in DWARF.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">A DWARF expression computes a value; if the available value is a pointer, you add DW_OP_deref to express the pointed-to value.  A DWARF location expression
 computes a location, and adds various operators to express locations that a (value) expression cannot, such as DW_OP_regx.  You also have DW_OP_stack_value to say "just kidding, this location expression is a value expression."<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">So, whether we want to start throwing around deref or stack_value or regx (implicit or explicit) really depends on whether we are going to be using value expressions
 or location expressions.  Let's not start mixing them up, it will just make the discussion more confusing.</span></p></div></div></blockquote><div><br>Where do non-location DWARF expressions appear?<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="purple"><div class="m_-1129212347092888653WordSection1"><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">--paulr<u></u><u></u></span></p>
<p class="MsoNormal"><a name="m_-1129212347092888653__MailEndCompose"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></a></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt">
<div>
<div style="border:none;border-top:solid #b5c4df 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">From:</span></b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif""> llvm-dev [mailto:<a href="mailto:llvm-dev-bounces@lists.llvm.org" target="_blank">llvm-dev-bounces@lists.llvm.org</a>]
<b>On Behalf Of </b>David Blaikie via llvm-dev<br>
<b>Sent:</b> Wednesday, September 06, 2017 10:02 AM<br>
<b>To:</b> Reid Kleckner; llvm-dev</span></p></div></div></div></div></div><div lang="EN-US" link="blue" vlink="purple"><div class="m_-1129212347092888653WordSection1"><div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt"><div><div style="border:none;border-top:solid #b5c4df 1.0pt;padding:3.0pt 0in 0in 0in"><p class="MsoNormal"><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif""><br>
<b>Subject:</b> Re: [llvm-dev] RFC: Introduce DW_OP_LLVM_memory to describe variables in memory with dbg.value<u></u><u></u></span></p></div></div></div></div></div><div lang="EN-US" link="blue" vlink="purple"><div class="m_-1129212347092888653WordSection1"><div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt"><div><div style="border:none;border-top:solid #b5c4df 1.0pt;padding:3.0pt 0in 0in 0in"><p class="MsoNormal"><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif""></span></p>
</div>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div>
<div>
<p class="MsoNormal">On Tue, Sep 5, 2017 at 1:00 PM Reid Kleckner via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<u></u><u></u></p>
</div></div></div></div></div></div><div lang="EN-US" link="blue" vlink="purple"><div class="m_-1129212347092888653WordSection1"><div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt"><div><div>
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<p class="MsoNormal">Debug info today handles two cases reasonably well:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">1. At -O0, dbg.declare does a good job describing variables that live at some known stack offset<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">2. With optimizations, variables promoted to SSA can be described with dbg.value<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">This leaves behind a large hole in our optimized debug info: variables that cannot be promoted, typically because they are address-taken. This is
<a href="https://llvm.org/pr34136" target="_blank">https://llvm.org/pr34136</a>, and this RFC is mostly about addressing that.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">The status today is that instcombine removes all dbg.declares and heuristically inserts dbg.values where it can identify the value of the variable in question. This prevents us from having misleading debug info, but it throws away information
 about the variable’s location in memory.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Part of the reason that instcombine discards dbg.declares is that we can’t mix and match dbg.value with dbg.declare. If the backend sees a dbg.declare, it accepts that information as more reliable and discards all DBG_VALUE instructions
 associated with that variable. So, we need something we can mix. We need a way to say, the variable lives in memory *at this program point*, and it might live somewhere else later on. I propose that we introduce DW_OP_LLVM_memory for this purpose, and then
 we transition from dbg.declare to dbg.value+DW_OP_LLVM_memory.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Initially I believed that DW_OP_deref was the way to say this with existing DWARF expression opcodes, but I implemented that in
<a href="https://reviews.llvm.org/D37311" target="_blank">https://reviews.llvm.org/D37311</a> and learned more about how DWARF expressions work. When a debugger begins evaluating a DWARF expression, it assumes that the resulting value will be a pointer to the
 variable in memory. For a debugger, this makes sense, because debug builds put things in memory and even after optimization many variables must be spilled. Only the special DW_OP_regN and DW_OP_stack_value expression opcodes change the location of the value
 from memory to register or stack value.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">LLVM SSA values obviously do not have an address that we can take and they don’t live in registers, so neither the default memory location model nor DW_OP_regN make sense for LLVM’s dbg.value. We could hypothetically repurpose DW_OP_stack_value
 to indicate that the SSA value passed to llvm.dbg.value *is* the variable’s value, and if the expression lacks DW_OP_stack_value, it must be a the address of the value. However, that is backwards incompatible and it seems like quite a stretch.<u></u><u></u></p>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
</div></div></div></div></div><div lang="EN-US" link="blue" vlink="purple"><div class="m_-1129212347092888653WordSection1"><div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt"><div>
<div>
<div>
<div>
<p class="MsoNormal">Seems like a stretch in what sense? The backwards incompatibility is certainly something to consider (though we went through that with DW_OP_bit_piece too), but this seems like the design I'd go to first so I'd like to better understand
 why it's not the path forward if there's some more detail about that aspect of the design choice here.<br>
<br>
I guess you described this already, but talking it through for myself/maybe others will find this useful:<br>
<br>
So since we don't have DW_OP_regN for LLVM registers, we could sort of assume the implicit first value on the stack is a pseudo-OP_regN of the LLVM SSA register.<br>
<br>
To support that, all existing uses would need no changes to match the DWARF model of registers being implicitly direct values.<br>
<br>
Code that wanted to describe the register as containing the memory address of the interesting thing would use DW_OP_stack_value to say "this location description that is a register is really an address you should follow to find the value, not a direct value
 itself"?<br>
<br>
But code that wanted to describe a variable as being 3 bytes ahead of a pointer in an LLVM SSA register would only have "plus 3" in the expression stack, since then it's no longer a direct value but is treated as a pointer to the value. I guess this is where
 the ambiguity would come in - currently how does "plus 3" get interpreted when seen in LLVM IR, I guess that's meant to describe reg value + 3 as being the immediate value of the variable? (so it's implicitly OP_stack_value? & OP_stack_value is added somewhere
 in the DWARF backend?)<br>
<br>
Thanks,<br>
- Dave<u></u><u></u></p>
</div>
</div>
</div>
<div>
<div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">DW_OP_LLVM_memory would be very similar to DW_OP_stack_value, though. It would only be valid at the end of a DIExpression. The backend will always remove it because the debugger will assume the variable lives in memory unless it is told
 otherwise.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">For the original problem of improving optimized debug info while avoiding inaccurate information in the presence of dead store elimination, consider this C example:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">  int x = 42;  // Can DSE<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">  dostuff(x); // Can propagate 42<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">  x = computation();  // Post-dominates `x = 42` store<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">  escape(&x);<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">We should be able to do this:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">  int x; // eliminate `x = 42` store<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">  dbg.value(!x, 42, !DIExpression()) // mark x as the constant 42 in debug info<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">  dostuff(42); // propagate 42<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">  dbg.value(!x, &x, !DIExpression(DW_OP_LLVM_memory)) // x is in memory again<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">  x = computation();<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">  escape(&x);<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Passes that delete stores would be responsible for checking if the store destination is part of an alloca with associated dbg.value instructions. They would emit a new dbg.value instruction for that variable with the stored value, and clone
 the dbg.value instruction that puts the variable back in memory before the killing store. If the store is dead because variable lifetime is ending, the second dbg.value is unnecessary.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">This will also allow us to fix debug info for px in this example:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> void __attribute__((optnone, noinline)) usevar(int *x) {}<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">  int main(int argc, char **argv) {<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">    int x = 42;<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">    int *px = &x;<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">    usevar(&x);<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">    if (argc) usevar(px);<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">  }<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Today, we emit a location for px like `DW_OP_breg7 RSP+12`, which gives it the incorrect value 42. This is because our DBG_VALUE instruction for px’s location uses a frame index, which we assume is in memory. This is not the case, px is
 not in memory, it’s value is a stack object pointer.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Please reply if you have any thoughts on this proposal. Adrian and I hashed this out over Bugzilla, IRC, and in person, so it shouldn’t be too surprising. Let me know if you want to be CC’d on the patches.<u></u><u></u></p>
</div>
</div>
<p class="MsoNormal">_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><u></u><u></u></p>
</blockquote>
</div>
</div>
</div></div></div></div></blockquote></div></div>