<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Tue, Jan 5, 2016 at 6:59 PM, Adrian Prantl <span dir="ltr"><<a href="mailto:aprantl@apple.com" target="_blank">aprantl@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Thanks for the clarification, Paul!<br>
Keno, just a few more questions for my understanding:<br>
<span class=""><br>
>     - Indicating that a value changed at source level (e.g. because an<br>
>       assignment occurred)<br>
<br>
</span>This is done by a key call.</blockquote><div><br></div><div>Correct</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">
>     - Indicating that the same value is now available in a new location<br>
<br>
</span>Additional, alternative locations with identical contents are added by passing in the token from a key call.</blockquote><div><br></div><div>Correct</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">
>     - Indicating that a value is no longer available in some location<br><br>
</span>This is done by another key call (possibly with an %undef location).</blockquote><div><br></div><div>Not quite. Another key call could be used if all locations are now invalid. However, to just remove a single value, I was proposing</div><div><br></div><div>; This is the key call</div><div><div style="font-size:12.8px">%first = call token @llvm.dbg.value(token undef, %someloc,</div><div style="font-size:12.8px">                                  metadata !var, metadata !())</div></div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">; This adds a location</div><div style="font-size:12.8px"><div style="font-size:12.8px">%second = call token @llvm.dbg.value(token %second, %someotherloc,</div><div style="font-size:12.8px">                                  metadata !var, metadata !())</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">; This removes the (%second) location</div><div style="font-size:12.8px">%third = <span style="font-size:12.8px">call token @llvm.dbg.value(token %second, metadata token undef,</span></div><div style="font-size:12.8px">                                  metadata !var, metadata !())</div></div><div><br></div><div>Thus, to remove a location you always pass in the token of the call that added the location. This is also the reason why I'm requiring the second argument to be `token undef` because no valid location can be of type token, and I wanted to avoid the situation in which a location gets replaced by undef everywhere, accidentally turning into a removal of the location specified by the key call.</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">
> > ><br>
> > >     - To add a location with the same value for the same variable, you<br>
> > pass the<br>
> > >       token of the FIRST llvm.dbg.value, as this llvm.dbg.value's first<br>
> > argument<br>
> > >       E.g. to add another location for the variable above:<br>
> > ><br>
</span>> > >         %second =3D call token @llvm.dbg.value(token %first, metadata<br>
<span class="">> > %val2,<br>
> > >                                             metadata !var, metadata<br>
> > !expr2)<br>
> ><br>
> > Does this invalidate the first location, or does this add an additional<br>
> > location<br>
> > to the set of locations for var at this point? If I want to add a third<br>
> > location,<br>
> > which token do I pass in? Can you explain a bit more what information the<br>
> > token<br>
> > allows us to express that is currently not possible?<br>
> ><br>
><br>
> It adds a second location. If you want to add a third location you pass in<br>
> the first token again.<br>
> Thus the first call (key call) indicates a change of values, and all<br>
> locations that have the same value should use the key call's token.<br>
><br>
<br>
</span>Ok. Looks like this is going to be somewhat verbose for partial updates of SROA’ed aggregates as in the following example:<br>
<br>
// struct s { int i, j };<br>
// void foo(struct s) { s.j = 0; ... }<br>
<br>
define void @foo(i32 %i, i32 %j) {<br>
  %token = call llvm.dbg.value(token %undef, %i, !Struct, !DIExpression(DW_OP_bit_piece(0, 32)))<br>
           call llvm.dbg.value(token %token, %j, !Struct, !DIExpression(DW_OP_bit_piece(32, 32)))<br>
  ...<br>
<br>
  ; have to repeat %i here:<br>
  %tok2 = call llvm.dbg.value(token %undef, %i, !Struct, !DIExpression(DW_OP_bit_piece(0, 32)))<br>
          call llvm.dbg.value(token %tok2, metadata i32 0, !Struct, !DIExpression(DW_OP_bit_piece(32, 32)))<br>
<br>
On the upside, having all this information explicit could simplify the code in DwarfDebug::buildLocationList().<br></blockquote><div><br></div><div>Yeah, this is true. We could potentially extend the semantics by allowing separate key calls for pieces, i.e.</div><div> </div><div>%token = call llvm.dbg.value(token %undef, %i, !Struct, !DIExpression(DW_OP_bit_piece(0, 32)))<br>           call llvm.dbg.value(token undef, %j, !Struct, !DIExpression(DW_OP_bit_piece(32, 32)))<br></div><div><br></div><div>; This now only invalidates the .j part</div><div>%tok2 = call llvm.dbg.value(token %undef, %j, !Struct, !DIExpression(DW_OP_bit_piece(32, 32)))<br></div><div><br></div><div>In that case we would probably have to require that all DW_OP_bit_pieces in non-key-call expressions are a subrange of those in the associated key call.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
Is there any information in the tokens that could not be recovered by a static analysis of the debug intrinsics?<br>
Note that having redundant information available explicitly is not necessarily a bad thing.<br></blockquote><div><br></div><div>I am not entirely sure what you are proposing. You somehow need to be able to encode which dbg.values invalidate previous locations and which do not. Since we're describing front-end variables this will generally depend on front-end semantics, so I'm not sure what a generic analysis pass can do here without requiring language-specific analysis.</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
The one difference I noticed so far is that alternative locations allow earlier locations to outlive locations that are dominated by them:<br>
  %loc = dbg.value(%undef, var, ...)<br>
  ...<br>
  %alt = dbg.value(%loc, var, ...)<br>
  ...<br>
  ; alt becomes unavailable<br>
  ...<br>
  ; %loc is still available here.<br>
<br>
Any other advantages that I missed?<br>
<span class=""><font color="#888888"><br>
-- adrian</font></span></blockquote></div><br></div></div>