Loops & Memory Optimization
Where the time actually goes: hoisting, unrolling, interchange, vectorization — and the aliasing and escape questions that decide whether any of it is allowed.
Move a computation whose result never changes out of the loop — but only if it is invariant AND either cannot trap or is guaranteed to execute at least once. That second condition is the one that turns a hoist into a fault the original program never had.
Duplicate the body so one iteration of the new loop does the work of several. It removes branches and exposes instruction-level parallelism, and it pays for both in code size and instruction-cache pressure — a trade whose sign depends on the trip count and the machine.
Four restructurings that leave the computation identical and change the order in which memory is touched. Each buys a specific thing — fewer traversals, better vectorizability, unit-stride access, a working set that fits in cache — and each is legal only when it preserves every dependence in the original.
Turn a loop over scalars into a loop over vectors, doing several elements per instruction. It is legal only when no dependence is violated by processing elements together, and profitable only when the memory access pattern suits it — and the list of things that make a vectorizer give up is longer than the list of things that make it succeed.
Can these two references point to the same memory? Almost every optimization over memory is gated on that question, the honest answer is usually "maybe", and "maybe" means no. Aliasing is the single biggest limiter on what a compiler is allowed to do.
Does this object outlive the scope that created it? If the compiler can prove it does not, the object can live on the stack, or be broken into registers and not exist at all — and the aliasing questions about it disappear with it.
A memory-safe language checks every array index. Removing the checks it can prove redundant is what makes safe languages fast — and it is why a loop written over a whole array is faster than the same loop written with index arithmetic the compiler cannot follow.