This commit is contained in:
Nilstrieb 2022-07-22 14:14:02 +00:00
parent 852cd64f73
commit df08ff65e1
12 changed files with 59 additions and 33 deletions

View file

@ -50,14 +50,20 @@ well here. But what allows it to make this optimization? Taking a look at the ge
reveals the solution: (severely shortened to only show the relevant parts)</p>
<pre tabindex="0"><code class="language-llvmir" data-lang="llvmir">define void @takes_box_and_ptr_to_it(i8* noalias %0, i8* %ptr) {
</code></pre><p>See the little attribute on the first parameter called <code>noalias</code>? That’s what’s doing the magic here.
<code>noalias</code> is quite complex, but for our case here, it says that no other pointers point to (alias) the same location.
This allows the optimizer to assume that writing to the box pointer doesn’t affect the other pointer - they are
not allowed to alias (it’s like if they used <code>restrict</code> in C).</p>
<code>noalias</code> is an LLVM attribute on pointers that allows for various optimizations. If there are two pointers,
and at least one of them is <code>noalias</code>, there are some restrictions around the two:</p>
<ul>
<li>If one of them writes, they must not point to the same value (alias each other)</li>
<li>If neither of them writes, they can alias just fine.
Therefore, we also apply <code>noalias</code> to <code>&mut T</code> and <code>&T</code> (if it doesn’t contain interior mutability through
<code>UnsafeCell<T></code>, since they uphold these rules.</li>
</ul>
<p>This might sound familiar to you if you’re a viewer of <a href="https://twitter.com/jonhoo">Jon Gjengset</a>’s content (which I can highly recommend). Jon has made an entire video about this before, since his crate <code>left-right</code>
was affected by this (<a href="https://youtu.be/EY7Wi9fV5bk)">https://youtu.be/EY7Wi9fV5bk)</a>.</p>
<p>If you’re looking for <em>any</em> hint that using box emits <code>noalias</code>, you have to look no further than the documentation
for <a href="https://doc.rust-lang.org/nightly/std/boxed/index.html#considerations-for-unsafe-code"><code>std::boxed</code></a>. Well, the nightly or beta docs, because I only added this section very recently. For years, this behaviour was not really documented, and you had to
belong to the arcane circles of the select few who were aware of it. So lots of code was written thinking that box was “just a RAII pointer” (a pointer that allocates the value in the constructor, and deallocates it in the destructor on drop) for all
belong to the arcane circles of the select few who were aware of it. So lots of code was written thinking that box was “just an
RAII pointer” (a pointer that allocates the value in the constructor, and deallocates it in the destructor on drop) for all
pointers are concerned.</p>
<h1 id="stacked-borrows-and-miri">Stacked Borrows and Miri</h1>
<p><a href="https://github.com/rust-lang/miri">Miri</a> is an interpreter for Rust code with the goal of finding undefinde behaviour.