<html><head><meta http-equiv="Content-Type" content="text/html; charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Sep 11, 2020, at 11:12 AM, Tozer, Stephen <<a href="mailto:stephen.tozer@sony.com" class="">stephen.tozer@sony.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta charset="UTF-8" class=""><div style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">> Can you elaborate what "direct" means? I'm having trouble understanding what the opposite (a non-exact value) would be.</div><div style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><br class=""></div><div style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">Apologies, "exact" was a misleading/incorrect term. By direct, I mean that the expression computes the value of the variable, as opposed to its memory address, or the value that it points to. </div></div></blockquote><div><br class=""></div><div>That sounds to me to be the same concept that I am calling rvalue vs. lvalue. Do you agree, or is there some subtlety that I am missing?</div><br class=""><blockquote type="cite" class=""><div class=""><div style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">Within LLVM, where we don't have DW_OP_reg/DW_OP_breg but instead simply refer to a generic SSA value, this could mean either a register location or stack value.<br class=""></div><div style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><br class=""></div><div style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">> At the moment we don't make the lvalue/rvalue distinction in LLVM at all. We make an educated guess in AsmPrinter. But that's wrong and something we should strive to fix during this redesigning.</div><div style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><br class=""></div><div style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">I think the opposite; I don't believe there's any reason we need to make the explicit lvalue/rvalue distinction until we're writing DWARF. </div></div></blockquote><div><br class=""></div><div>Here is an example of why I think that an optimization pass must have the ability to downgrade an lvalue to an rvalue:</div><div><br class=""></div><div>; BEFORE</div><div>%foo = i32 ...</div><div>%mem = alloca i32</div><div>call %llvm.dbg.declare(%mem, !DILocalVariable("x"))</div><div>store i32* %mem, i32 %foo</div><div>...</div><div><div>store i32* %mem, i32 0</div></div><div><div>...</div></div><div>store i32* %mem, i32 %foo</div><div>...</div><div><br class=""></div><div>; AFTER</div><div><div>%foo = i32 ...</div></div><div>%mem = alloca i32</div><div>call %llvm.dbg.value(%mem, !DILocalVariable("x"), !DIExpression(DW_OP_deref))</div><div>store i32* %mem, i32 %foo</div><div>; optimization eliminated the store of 0 to %mem and replaced all loads of %mem with "i32 0".</div><div>call %llvm.dbg.value(%mem, !DILocalVariable("x"), !DIExpression(DW_OP_constu 0, DW_OP_stack_value))</div><div>...</div><div>call %llvm.dbg.value(%mem, !DILocalVariable("x"), !DIExpression(DW_OP_deref))</div><div>...</div><div><br class=""></div><div>The optimization eliminated the store of constant 0 to %mem and replaced all loads of %mem in the subsequent block with a constant "i32 0". This means that we need mark the first dbg.value (that would otherwise look like an lvalue) as an rvalue, because writing a new value to %mem there would not affect the code that is now hardcoded to use a constant 0 value for "x".</div><div><br class=""></div><div>what do you think?</div><div><br class=""></div><div>-- adrian</div><div><br class=""></div><blockquote type="cite" class=""><div class=""><div style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">To put it in more general terms, I think that the IR/MIR debug value instructions should only care about how the variable's value can be computed. Whether the result of that computation is an lvalue is unimportant within LLVM itself as far as I can tell, and is redundant when it can be computed from just the DIExpression and location operands.<br class=""></div><div style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><br class=""></div><div style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">>As stated above, I don't think we can trivially determine this, because (at least for dbg.values) this info was lost already in LLVM IR. Unless we say the dbg.declare / dbg.value distinction is what determines lvalues vs. rvalues.</div><div style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><br class=""></div><div style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">With the proposed operator, it would be trivial to determine lvalue vs rvalue debug values with a set of rules (ignoring any fragment operator, which may appear at the end but does not affect the location type):</div><div style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><br class=""></div><div style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">  1. If the expression is empty, or any location arguments are<span class="Apple-converted-space"> </span><span style="font-family: Consolas, Courier, monospace;" class="">$noreg<span class="Apple-converted-space"> </span></span>=> Empty<br class="">  2. If the expression ends with<span class="Apple-converted-space"> </span><span style="font-family: Consolas, Courier, monospace;" class="">DW_OP_implicit_ptr</span><span class="Apple-converted-space"> </span>=> Implicit pointer (rvalue)<br class="">  3. If the expression ends with<span class="Apple-converted-space"> </span><span style="font-family: Consolas, Courier, monospace;" class="">DW_OP_stack_value</span><span class="Apple-converted-space"> </span>=>Stack value (rvalue)  // LLVM should produce LLVM_direct instead.<br class="">  4. If the expression ends with<span class="Apple-converted-space"> </span><span style="font-family: Consolas, Courier, monospace;" class="">DW_OP_LLVM_direct</span>, then...<br class="">    4a. If the preceding expression is just<span class="Apple-converted-space"> </span><span style="font-family: Consolas, Courier, monospace;" class="">DW_OP_LLVM_arg, 0</span><span class="Apple-converted-space"> </span>and the only location operand is a register => Register location (lvalue)<br class="">    4b. Otherwise => Stack value (rvalue)<br class=""><div class="">  5. Otherwise => Memory location (lvalue)</div><div class=""><br class=""></div></div><div style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class="">This covers all the expected cases without ambiguity or almost any reduced expressiveness. I believe that the only expression that LLVM will not be able to produce like this is<span class="Apple-converted-space"> </span><span style="font-family: Consolas, Courier, monospace;" class="">DW_OP_bregN, DW_OP_stack_value<span class="Apple-converted-space"> </span></span>due to fact that when DW_OP_LLVM_direct is used, this would be written as a register location instead of a stack value. I don't think there are any cases where we would choose to emit a stack value location when we're able to produce a register location instead, so this shouldn't be a problem.</div></div></blockquote></div><br class=""></body></html>