<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jan 5, 2016, at 10:37 AM, Keno Fischer <<a href="mailto:kfischer@college.harvard.edu" class="">kfischer@college.harvard.edu</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote">On Tue, Jan 5, 2016 at 6:59 PM, Adrian Prantl<span class="Apple-converted-space"> </span><span dir="ltr" class=""><<a href="mailto:aprantl@apple.com" target="_blank" class="">aprantl@apple.com</a>></span><span class="Apple-converted-space"> </span>wrote:<br class=""><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 class="">Keno, just a few more questions for my understanding:<br class=""><span class=""><br class="">> - Indicating that a value changed at source level (e.g. because an<br class="">> assignment occurred)<br class=""><br class=""></span>This is done by a key call.</blockquote><div class=""><br class=""></div><div class="">Correct</div><div class=""> </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 class=""><br class=""></span>Additional, alternative locations with identical contents are added by passing in the token from a key call.</blockquote><div class=""><br class=""></div><div class="">Correct</div><div class=""> </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 class=""><br class=""></span>This is done by another key call (possibly with an %undef location).</blockquote><div class=""><br class=""></div><div class="">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 class=""><br class=""></div><div class="">; This is the key call</div><div class=""><div style="font-size: 12.8px;" class="">%first = call token @llvm.dbg.value(token undef, %someloc,</div><div style="font-size: 12.8px;" class=""> metadata !var, metadata !())</div></div><div style="font-size: 12.8px;" class=""><br class=""></div><div style="font-size: 12.8px;" class="">; This adds a location</div><div style="font-size: 12.8px;" class=""><div style="font-size: 12.8px;" class="">%second = call token @llvm.dbg.value(token %second, %someotherloc,</div><div style="font-size: 12.8px;" class=""> metadata !var, metadata !())</div><div style="font-size: 12.8px;" class=""><br class=""></div><div style="font-size: 12.8px;" class="">; This removes the (%second) location</div><div style="font-size: 12.8px;" class="">%third = <span style="font-size: 12.8px;" class="">call token @llvm.dbg.value(token %second, metadata token undef,</span></div><div style="font-size: 12.8px;" class=""> metadata !var, metadata !())</div></div><div class=""><br class=""></div></div></div></div></div></blockquote><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote"><div class="">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></div></div></div></blockquote><div><br class=""></div>Makes sense. If I understand your comment correctly, the following snippet:</div><div><br class=""></div><div>%1 = ...</div><div>%token = call llvm.dbg.value(token %undef, %1, !var, !())</div><div>%2 = ...</div><div>call llvm.dbg.value(token %token, %undef, !var, !())</div><div>call llvm.dbg.value(token %undef, %2, !var, !())</div><div><br class=""></div><div>is equivalent to</div><div><br class=""></div><div><div>%1 = ...</div><div>call llvm.dbg.value(token %undef, %1, !var, !())</div><div>%2 = ...</div><div>call llvm.dbg.value(token %undef, %2, !var, !())</div><div class=""><br class=""></div></div><div>and both are legal.<br class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote"><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 class="">> > > - To add a location with the same value for the same variable, you<br class="">> > pass the<br class="">> > > token of the FIRST llvm.dbg.value, as this llvm.dbg.value's first<br class="">> > argument<br class="">> > > E.g. to add another location for the variable above:<br class="">> > ><br class=""></span>> > > %second =3D call token @llvm.dbg.value(token %first, metadata<br class=""><span class="">> > %val2,<br class="">> > > metadata !var, metadata<br class="">> > !expr2)<br class="">> ><br class="">> > Does this invalidate the first location, or does this add an additional<br class="">> > location<br class="">> > to the set of locations for var at this point? If I want to add a third<br class="">> > location,<br class="">> > which token do I pass in? Can you explain a bit more what information the<br class="">> > token<br class="">> > allows us to express that is currently not possible?<br class="">> ><br class="">><br class="">> It adds a second location. If you want to add a third location you pass in<br class="">> the first token again.<br class="">> Thus the first call (key call) indicates a change of values, and all<br class="">> locations that have the same value should use the key call's token.<br class="">><br class=""><br class=""></span>Ok. Looks like this is going to be somewhat verbose for partial updates of SROA’ed aggregates as in the following example:<br class=""><br class="">// struct s { int i, j };<br class="">// void foo(struct s) { s.j = 0; ... }<br class=""><br class="">define void @foo(i32 %i, i32 %j) {<br class=""> <span class="Apple-converted-space"> </span>%token = call llvm.dbg.value(token %undef, %i, !Struct, !DIExpression(DW_OP_bit_piece(0, 32)))<br class=""> call llvm.dbg.value(token %token, %j, !Struct, !DIExpression(DW_OP_bit_piece(32, 32)))<br class=""> <span class="Apple-converted-space"> </span>...<br class=""><br class=""> <span class="Apple-converted-space"> </span>; have to repeat %i here:<br class=""> <span class="Apple-converted-space"> </span>%tok2 = call llvm.dbg.value(token %undef, %i, !Struct, !DIExpression(DW_OP_bit_piece(0, 32)))<br class=""> <span class="Apple-converted-space"> </span>call llvm.dbg.value(token %tok2, metadata i32 0, !Struct, !DIExpression(DW_OP_bit_piece(32, 32)))<br class=""><br class="">On the upside, having all this information explicit could simplify the code in DwarfDebug::buildLocationList().<br class=""></blockquote><div class=""><br class=""></div><div class="">Yeah, this is true. We could potentially extend the semantics by allowing separate key calls for pieces, i.e.</div><div class=""> </div><div class="">%token = call llvm.dbg.value(token %undef, %i, !Struct, !DIExpression(DW_OP_bit_piece(0, 32)))<br class=""> call llvm.dbg.value(token undef, %j, !Struct, !DIExpression(DW_OP_bit_piece(32, 32)))<br class=""></div><div class=""><br class=""></div><div class="">; This now only invalidates the .j part</div><div class="">%tok2 = call llvm.dbg.value(token %undef, %j, !Struct, !DIExpression(DW_OP_bit_piece(32, 32)))<br class=""></div><div class=""><br class=""></div><div class="">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></div></div></div></blockquote><div><br class=""></div><div>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.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></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 class="">Note that having redundant information available explicitly is not necessarily a bad thing.<br class=""></blockquote><div class=""><br class=""></div><div class="">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></div></div></div></blockquote><div><br class=""></div>Right. Determining whether two locations have equivalent contents is not generally decidable.<br class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote"><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 class=""> <span class="Apple-converted-space"> </span>%loc = dbg.value(%undef, var, ...)<br class=""> <span class="Apple-converted-space"> </span>...<br class=""> <span class="Apple-converted-space"> </span>%alt = dbg.value(%loc, var, ...)<br class=""> <span class="Apple-converted-space"> </span>...<br class=""> <span class="Apple-converted-space"> </span>; alt becomes unavailable<br class=""> <span class="Apple-converted-space"> </span>...<br class=""> <span class="Apple-converted-space"> </span>; %loc is still available here.<br class=""><br class="">Any other advantages that I missed?<br class=""><span class=""><font color="#888888" class=""><br class="">-- adrian</font></span></blockquote></div></div></div></div></blockquote><br class=""></div><div><br class=""></div><div>One thing I’m wondering about is whether we couldn’t design a friendlier (assembler) syntax for the three different use-cases:</div><div> %tok1 = call llvm.dbg.value(token %undef, %1, !var, !())</div> %tok2 = call llvm.dbg.value(token %token, %2, !var, !())<div class=""> %tok3 = call llvm.dbg.value(token %tok1, %undef, !var, !())</div><div class=""><br class=""></div><div class="">Could be written as e.g.:</div><div class=""><br class=""></div><div class=""><div> %tok1 = call llvm.dbg.value.new(%1, !var, !())</div> %tok2 = call llvm.dbg.value.add(token %token, %2, !var, !())<div class=""> %tok3 = call llvm.dbg.value.delete(token %tok1, !var, !())</div></div><div class=""><br class=""></div><div class="">-- adrian</div></body></html>