On 23/06/14 12:46 AM, comex wrote: > On Mon, Jun 23, 2014 at 12:35 AM, Daniel Micay <danielmi...@gmail.com> wrote: >> An operation that can unwind isn't pure. It impedes code motion such as >> hoisting operations out of a loop, which is very important for easing >> the performance issues caused by indexing bounds checks. LLVM doesn't >> model the `nounwind` effect on functions simply for fun. > > No it doesn't! Or maybe it does today, but an unwindable operation is > guaranteed to be repeatable without consequence, which I'd like to > think can account for most cases where operations are hoisted out of > loops (again, could be wrong :), and not to modify any memory (unless > it traps, but in Rust at that point you are guaranteed to be exiting > the function immediately).
The call we make to perform unwinding isn't a pure function though, it's aware of the context causing it to unwind. As long as we're supporting stuff like backtraces outside of a debugger, that's going to be the case. If it was pure beyond not being `nounwind` then LLVM would have more freedom to move it around, but it would still cause more problems than using `llvm.trap` (abort). > In particular, the only reason I can see why an impure operation would > require repeating a bounds check is if the compiler thinks it could > modify the size of the array, or the index, or something else in > memory. But it cannot. > > Yeah, yeah, Rust is designed for 2014 not 2024, and I admit "LLVM > cannot do this right now" is a perfectly good reason in this context. > But I want to differentiate the different arguments being made here. > >> Unwinding is a stateful effect, and any code that would be otherwise >> pure is no longer pure if it has the potential to unwind. It's not >> simply a matter of unwinding or not unwinding, the compiler needs to >> ensure that the source of the unwinding is the same. > > Only if it crosses initialization of objects with destructors. It > doesn't matter if the stack trace is off. > >> I provided an example demonstrating the cost with `clang`. > > First of all, that's including actual bounds checks as opposed to > merely assuming impurity/unwinding, no? Again, simply to > differentiate the arguments... It's just a measurement of the overflow checks on signed/unsigned integers. It does introduce a form of impurity since it's aborting in branches, but it's a simpler form of impurity than unwinding where the code continues running based on the context where it was thrown. > Second of all, it may be possible to do the checks more efficiently. > I should look at clang's assembly output. LLVM actually has intrinsics for checked arithmetic to avoid screwups in code generation. I don't think it's going to get any better on x86 at a code generation level.
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev