Does the compiler unroll for-in over constant ranges?

I was curious about the compiler behavior for code like this,

for i in 0..8 {
  ...
}

Regardless of opt-flags, since the compiler can see that the iteration is happening over a constant range, would it choose to always unroll the for-loop so that it can produce non-branching code. Or does it opt for something like while let Some(..) = _temp_iter.next() { .. } instead?

And it's possible my question is instead, is for-in treated as syntax sugar and will always de-sugar to the iterator pattern or is it compiled as a stand-alone loop construct?

Good chance something that simple unrolls, but....

...it's not a guaranteed optimization.

There are very few guaranteed optimizations.

3 Likes

Especially given the fact that LLVM has a reroll optimization.

2 Likes

You don't want that for 0..123456789.

So there are heuristic optimizations that sometimes happen, but nothing guaranteed.

4 Likes

It will unroll heuristically, because non-branching code is only an advantage if it's smaller than branching code - otherwise effects like instruction cache pressure and loop detection in CPUs result in the non-branching code being more expensive to run. The exact point at which it'll decide to unroll versus leaving it rolled up will vary over time and from CPU to CPU.

If you want to examine optimization choices on simple code, there's the Opt Pipeline tool in Godbolt's Compiler Explorer; this doesn't show you all optimizations (because it only looks at LLVM IR, and there are optimizations that take place inside the Rust compiler before it outputs LLVM IR), but it'll let you see the evolution of LLVM IR as LLVM's optimizer changes it; you can see, for example, that in the case of looping 8 times, LLVM fully unrolls the loop using the LoopFullUnrollPass.

2 Likes

Thanks for the detailed explanation!

(It’s interesting that the unroll only happens after opt-level 2, I figured it would still happen at 1 for such a short loop)

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.