<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 29, 2017 at 9:59 AM, Ariel Ben-Yehuda 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:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi,<br>
<br>
I have a question about the meaning of the nocapture attribute:<br>
<br>
In Rust, safe code can use pointers as, say, HashMap keys (by<br>
reference equality) without regard to their lifetimes - of course, a<br>
dead pointer might be reference-equal to other pointers, but users<br>
should not face any other trouble with that (of course, dead pointers<br>
can't be dereferenced).<br>
<br>
Rust also has "anonymous &T" arguments, which are pointers that can't<br>
be dereferenced after the function returns. </blockquote><div><br></div><div>Do you mean "dereferenced in the called function"?</div><div>or dereferenced in the callee?<br> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">However, because pointers<br>
can be used as HashMap keys without regard to their lifetimes, their<br>
identity can be inserted into an HashMap.<br>
<br>
Now, we want to transfer this information to LLVM, which is quite<br>
similar to the `nocapture` attribute.<br>
<br>
However, according to the documentation for `nocapture`, "This<br>
indicates that the callee does not make any copies of the pointer that<br>
outlive the callee itself.".<br></blockquote><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
This might mean that the pointer becomes some sort of indeterminate<br>
value after the function returns - aka using it as a HashMap key would<br>
be trouble.</blockquote><div>No, because that would not be a copy becoming indeterminate, since this is SSA.</div><div>Remember this is SSA, so the original value passed to the function can only have been assigned once. </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Or it could just mean that the pointer can't be<br>
dereferenced after the function returns, which is the Rust semantics.<br></blockquote><div>No, it doesn't mean that either.</div><div>The semantics are  precisely:<br></div><div>"the *called* function does not store this pointer in a place that, after function return, it may be accessed by the called function or any other function that the called function used"</div><div><br></div><div>To be concrete, if this is the entire function:</div><div>declare func(nocapture i8*);</div><div><br></div><div>define bar() {</div><div>a_1 = pointer to foo</div><div>call func(a_1) </div><div>*a_1 = 5</div><div>}</div><div>is legal.<br></div><div><br>Additionally</div><div><div><br class="gmail-Apple-interchange-newline">define bar() {</div><div>a_1 = pointer to foo</div><div>call func(a_1) </div><div>call func2() </div><div>}</div></div><div>func2 cannot access a_1</div><div><br></div><div>Note:</div><div><div><br class="gmail-Apple-interchange-newline">define bar() {</div><div>a_1 = pointer to foo</div><div>call func(a_1) </div><div>a_1 = different thing</div><div> }</div></div><div><br></div><div>is impossible, because a_1 is an ssa value</div><div><br></div><div>it would be:<br><div><div>define bar() {</div><div>a_1 = pointer to foo</div><div>call func(a_1) </div><div>a_2 = different thing</div><div> }</div></div></div><div><br></div><div>and a_2 is a different pointer than a_1.</div><div><br></div><div>Note, if our first example was:</div><div><div>declare func(nocapture i8*);</div></div><div><br></div><div>define bar(i8* a_1 ) {</div><div>call func(a_1) <br></div><div>}<br></div><div><br></div><div>bar would also be nocapture of a_1, and could be marked as such.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
Does `nocapture` have Rust-compatible semantics, and if not, is there<br>
some other way to emulate these semantics?<br></blockquote><div><br></div><div>If your semantic is that, after the call to func, a_1 is actually *dead*, the way to emulate that semantic would be to use llvm.lifetime.end on it.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
Thanks,<br>
 - Ariel<br>
______________________________<wbr>_________________<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/<wbr>mailman/listinfo/llvm-dev</a><br>
</blockquote></div><br></div></div>