<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<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);">
> That makes sense, and I think for "direct" values in your definition it is true that all direct values are r-values.</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
> Why do we need DW_OP_LLVM_direct when we already have DW_OP_LLVM_stack_value? Can you give an example of something that is definitely not a stack value, but direct?<br>
</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);">
The difference in definition is the intention: DW_OP_LLVM_direct means "we'd like this to be an l-value if possible", DW_OP_stack_value means "this should never be an l-value". Because of this, an expression ending with DW_OP_LLVM_direct can be emitted as an
l-value in any case where the value of the preceding expression is equal to an l-value. So for example:</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);">
<span style="font-family: Consolas, Courier, monospace;"> DBG_VALUE $rsp, !"x", !DIExpression(DW_OP_LLVM_direct) => DW_OP_reg7 RSP</span>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt">
<span style="font-family: Consolas, Courier, monospace;"> DBG_VALUE $rsp, !"x", !DIExpression(DW_OP_deref, DW_OP_LLVM_direct) => DW_OP_breg7 RSP+0</span>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt">
<span style="font-family: Consolas, Courier, monospace;"> DBG_VALUE $rsp, !"x", !DIExpression(DW_OP_plus_uconst, 4, DW_OP_LLVM_direct) => DW_OP_breg7 RSP+4, DW_OP_stack_value</span><br>
</div>
</div>
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Your point about the semantics of variable assignments in the debugger is useful, that clears up my misunderstandings. I believe that even with that in mind, LLVM_direct (or whatever name it takes) would be appropriate. If we recognize that a variable must
be read-only to preserve those semantics, then we can use DW_OP_stack_value to ensure that it is always an r-value. If we don't have any reason to make a variable read-only other than that we can't *currently* find an l-value location for it, then we would
use DW_OP_LLVM_direct. Right now we use DW_OP_stack_value whenever we make a complex expression, but that doesn't need to be the case.<br>
</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);">
The code below is an example program where we may eventually be able to generate a valid l-value for the variable "a" in foo(), but can't without an alternative to DW_OP_stack_value. At the end of the example, "a" is an r-value, but doesn't need to be: there
is a single register that holds its exact value, and an assignment to that register would have the same semantics as an equivalent assignment to "a" in the source. The optimizations taking place in this code are analogous to if we had "a = bar() + 4 - 4;",
but because we don't figure out that "a = bar()" in a single pass, we pre-emptively assume that "a" must be an r-value.<br>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt">
To be able to emit an l-value we would first need the ability to optimize/simplify DIExpressions so that the expression becomes just (DW_OP_stack_value) - this wouldn't be particularly difficult to implement for simple arithmetic. Even with this improvement,
the definition of DW_OP_stack_value explicitly forbids the expression from being a register location. If we instead used DW_OP_LLVM_direct, then we would be free to emit the register location
<span style="font-family: Consolas, Courier, monospace">(</span><span style="font-family: Consolas, Courier, monospace">DW_OP_reg0 RAX)</span><span style="font-family: "Segoe UI", "Helvetica Neue", sans-serif;">.</span></div>
</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);">
<span style="font-family: Consolas, Courier, monospace;"> // Compile with clang -O2 -g<br>
</span></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<span style="font-family: Consolas, Courier, monospace;"> int baz();</span>
<div><span style="font-family: Consolas, Courier, monospace;"> int bar2(int arg) {</span></div>
<div><span style="font-family: Consolas, Courier, monospace;"> return arg * 4;</span></div>
<div><span style="font-family: Consolas, Courier, monospace;"> }</span></div>
<div><span style="font-family: Consolas, Courier, monospace;"> int bar() {</span></div>
<div><span style="font-family: Consolas, Courier, monospace;"> return bar2(1);</span></div>
<span style="font-family: Consolas, Courier, monospace;"> }</span><br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<span style="font-family: Consolas, Courier, monospace;"> int foo() {</span><span style="font-family: Consolas, Courier, monospace;">
<div><span style="font-family: Consolas, Courier, monospace;"> int a = baz() + bar() - 4;</span></div>
<div> return a * 2;</div>
}</span></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<span style="font-family: Consolas, Courier, monospace;"><br>
</span></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<span style="font-family: Consolas, Courier, monospace;">; Eventually becomes the IR...</span></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<span style="font-family: Consolas, Courier, monospace;"> %call = call i32 @_Z3bazv(), !dbg !25</span>
<div><span style="font-family: Consolas, Courier, monospace;"> %call1 = call i32 @_Z3barv(), !dbg !26</span></div>
<div><span style="font-family: Consolas, Courier, monospace;"> %add = add nsw i32 %call, %call1, !dbg !27</span></div>
<div><span style="font-family: Consolas, Courier, monospace;"> %sub = sub nsw i32 %add, 4, !dbg !28</span></div>
<span style="font-family: Consolas, Courier, monospace;"> call void @llvm.dbg.value(metadata i32 %sub, metadata !24, metadata !DIExpression()), !dbg !29<br>
<div> %mul = mul nsw i32 %sub, 2, !dbg !30</div>
ret i32 %mul, !dbg !31</span></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<span style="font-family: Consolas, Courier, monospace;"><br>
</span></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<span style="font-family: Consolas, Courier, monospace;">; Combine redundant instructions, "a" is salvaged...</span></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<span style="font-family: Consolas, Courier, monospace;"> %call = call i32 @_Z3bazv(), !dbg !25
<div> %call1 = call i32 @_Z3barv(), !dbg !26</div>
<div> %add = add nsw i32 %call, %call1, !dbg !27</div>
call void @llvm.dbg.value(metadata i32 %add, metadata !24, metadata !DIExpression(DW_OP_constu, 4, DW_OP_minus, DW_OP_stack_value)), !dbg !28<br>
<div> %sub = shl i32 %add, 1, !dbg !29</div>
<div> %mul = add i32 %sub, -8, !dbg !29</div>
ret i32 %mul, !dbg !30</span></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<span style="font-family: Consolas, Courier, monospace;"> <br>
</span></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<span style="font-family: Consolas, Courier, monospace;">; bar() is found to always return 4<br>
<div> %call = call i32 @_Z3bazv(), !dbg !14</div>
<div> %add = add nsw i32 %call, 4, !dbg !15</div>
<div> call void @llvm.dbg.value(metadata i32 %add, metadata !13, metadata !DIExpression(DW_OP_constu, 4, DW_OP_minus, DW_OP_stack_value)), !dbg !16</div>
<div> %sub = shl i32 %add, 1, !dbg !17</div>
<div> %mul = add i32 %sub, -8, !dbg !17</div>
ret i32 %mul, !dbg !18
<div></div>
<div><br>
</div>
<div>; %add is unused, optimize out and salvage...</div>
<div></div>
%call = call i32 @_Z3bazv(), !dbg !24
<div> call void @llvm.dbg.value(metadata i32 %call, metadata !23, metadata !DIExpression(DW_OP_plus_uconst, 4, DW_OP_constu, 4, DW_OP_minus, DW_OP_stack_value)), !dbg !25</div>
<div> %add = shl i32 %call, 1, !dbg !26</div>
<div> ret i32 %add, !dbg !27</div>
<div><br>
</div>
<div> ; Final DWARF location for "a":</div>
<div> DW_AT_location (0x00000000:<br>
</div>
<div> [0x0000000000000029, 0x000000000000002b): DW_OP_breg0 RAX+4, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_lit4, DW_OP_minus, DW_OP_stack_value)<br>
</div>
<br>
</span></div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<span style="font-family: Consolas, Courier, monospace"></span><span style="font-family: Consolas, Courier, monospace;"></span><br>
</div>
<div id="appendonsend"></div>
</body>
</html>