Where does LLVM do that? LLVM does hoist of invariant code out of loops in the Loop Invariant Code Motion and Loop Strength Reduction phases.[1] But that's not enough. This isn't an invariant situation. Consider a matrix multiply, the most common operation in number-crunching. You're indexing through three 2D matrices along both axes. The indices are usually controlled by FOR statements, so the compiler knows the range the indices can take. If the compiler knows about multidimensional arrays, it's easy to make those checks once at FOR loop entry.
But if those checks are in asserts, it's tougher. Is LLVM allowed to fail an assert early? If the array is 0..999, and the index is 0..1000, a subscript out of range condition will occur on iteration 1001. For best performance, you want to detect the subscript out of range condition at the point it becomes inevitable, rather than checking on every iteration and failing on iteration 1001. (Although technically you could generate a special case.)
But that requires special treatment of "assert". In Rust, "assert!" is just a macro. The compiler can't optimize it that aggressively and fail early. Especially since you can now catch assertion failures during unwinding.
If all those optimizations really exist, why is there code like this (at
https://github.com/SiegeLord/RustAlgebloat/blob/master/algeb...)?
MatrixMul
{ unsafe fn raw_get(&self, r: usize, c: usize) -> f64
{ let mut ret = 0.0;
for z in 0..self.lhs.ncol()
{ ret += self.lhs.raw_get(r, z) * self.rhs.raw_get(z, c); }
ret
}
}
If what you say is true, all that unsafe stuff is unnecessary.
[1] http://llvm.org/docs/Passes.html