<div dir="ltr">I'm reading/following along - discussion so far sounds reasonable to me.<br><br>Only minor note: if dbg.value/declare can be narrowed down to one (I think you mentioned in your original proposal that it seemed like everything could be just dbg.value?) that'd be a good step, regardless - possibly ahead of/while this conversation is underway. Or is it the case that the proposed enhanced semantics are required before that transition (because currently dbg.value only goes to the end of the BB? if I recall correctly, whereas dbg.declare is the whole function)? In the latter case, perhaps it'd be a good first step/goal/transition to do as cleanup/generalization anyway.<br><br>- Dave</div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jan 6, 2016 at 2:02 PM, Vivek Sarkar via llvm-dev <span dir="ltr"><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I will be out of the office on January 7th and will return on January 19th. I will not have access to email during this time. Please contact Karen Lavelle at <a href="mailto:klavelle@rice.edu">klavelle@rice.edu</a> or <a href="tel:713-348-2062" value="+17133482062">713-348-2062</a> if you have any questions or concerns.<br>
<br>
Best regards,<br>
Annepha<br>
<div><div class="h5"><br>
On Jan 6, 2016, at 3:58 PM, Adrian Prantl via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> wrote:<br>
<br>
><br>
> On Jan 5, 2016, at 10:37 AM, Keno Fischer <<a href="mailto:kfischer@college.harvard.edu">kfischer@college.harvard.edu</a>> wrote:<br>
> On Tue, Jan 5, 2016 at 6:59 PM, Adrian Prantl <<a href="mailto:aprantl@apple.com">aprantl@apple.com</a>> wrote:<br>
> Thanks for the clarification, Paul!<br>
> Keno, just a few more questions for my understanding:<br>
><br>
> > - Indicating that a value changed at source level (e.g. because an<br>
> > assignment occurred)<br>
><br>
> This is done by a key call.<br>
><br>
> Correct<br>
> <br>
> > - Indicating that the same value is now available in a new location<br>
><br>
> Additional, alternative locations with identical contents are added by passing in the token from a key call.<br>
><br>
> Correct<br>
> <br>
> > - Indicating that a value is no longer available in some location<br>
><br>
> This is done by another key call (possibly with an %undef location).<br>
><br>
> Not quite. Another key call could be used if all locations are now invalid. However, to just remove a single value, I was proposing<br>
><br>
> ; This is the key call<br>
> %first = call token @llvm.dbg.value(token undef, %someloc,<br>
> metadata !var, metadata !())<br>
><br>
> ; This adds a location<br>
> %second = call token @llvm.dbg.value(token %second, %someotherloc,<br>
> metadata !var, metadata !())<br>
><br>
> ; This removes the (%second) location<br>
> %third = call token @llvm.dbg.value(token %second, metadata token undef,<br>
> metadata !var, metadata !())<br>
><br>
> 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<br>
><br>
</div></div><span class="">> Makes sense. If I understand your comment correctly, the following snippet:<br>
><br>
> %1 = ...<br>
> %token = call llvm.dbg.value(token %undef, %1, !var, !())<br>
> %2 = ...<br>
> call llvm.dbg.value(token %token, %undef, !var, !())<br>
> call llvm.dbg.value(token %undef, %2, !var, !())<br>
><br>
> is equivalent to<br>
><br>
> %1 = ...<br>
> call llvm.dbg.value(token %undef, %1, !var, !())<br>
> %2 = ...<br>
> call llvm.dbg.value(token %undef, %2, !var, !())<br>
><br>
> and both are legal.<br>
><br>
> > > ><br>
</span><div><div class="h5">> > > > - 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>
> > > > %second =3D call token @llvm.dbg.value(token %first, metadata<br>
> > > %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>
> 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>
><br>
> Yeah, this is true. We could potentially extend the semantics by allowing separate key calls for pieces, i.e.<br>
> <br>
> %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>
><br>
> ; This now only invalidates the .j part<br>
> %tok2 = call llvm.dbg.value(token %undef, %j, !Struct, !DIExpression(DW_OP_bit_piece(32, 32)))<br>
><br>
> 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.<br>
><br>
> This way all non-key-call additional locations are describing alternative locations for (a subset of) the bits described the key-call location. Makes sense, and again would simplify the backend’s work.<br>
><br>
><br>
</div></div><span class="">> 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>
><br>
> 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.<br>
><br>
> Right. Determining whether two locations have equivalent contents is not generally decidable.<br>
><br>
> 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>
><br>
> -- adrian<br>
><br>
><br>
</span><span class="">> One thing I’m wondering about is whether we couldn’t design a friendlier (assembler) syntax for the three different use-cases:<br>
> %tok1 = call llvm.dbg.value(token %undef, %1, !var, !())<br>
> %tok2 = call llvm.dbg.value(token %token, %2, !var, !())<br>
> %tok3 = call llvm.dbg.value(token %tok1, %undef, !var, !())<br>
><br>
> Could be written as e.g.:<br>
><br>
> %tok1 = call llvm.dbg.value.new(%1, !var, !())<br>
> %tok2 = call llvm.dbg.value.add(token %token, %2, !var, !())<br>
> %tok3 = call llvm.dbg.value.delete(token %tok1, !var, !())<br>
><br>
</span>> -- adrian<br>
> _______________________________________________<br>
> LLVM Developers mailing list<br>
> <a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
<br>_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
<br></blockquote></div><br></div>