Loop Unwinding

When a loop needs to run for a small, but definite number of iterations, it is often better to unwind the loop in order to reduce the number of jump instructions performed, and in many cases prevent the processor’s branch predictor from failing. Consider the following C loop, which calls the function MyFunction() 5 times:

for(x = 0; x < 5; x++)
{
  MyFunction();
}

Converting to assembly, we see that this becomes, roughly:

mov eax, 0
loop_top:
cmp eax, 5
jge loop_end
call _MyFunction
inc eax
jmp loop_top

Each loop iteration requires the following operations to be performed:

  1. Compare the value in eax (the variable “x”) to 5, and jump to the end if greater then or equal
  2. Increment eax
  3. Jump back to the top of the loop.

Notice that we remove all these instructions if we manually repeat our call to MyFunction():

call _MyFunction
call _MyFunction
call _MyFunction
call _MyFunction
call _MyFunction

This new version not only takes up less disk space because it uses fewer instructions, but also runs faster because fewer instructions are executed. This process is called Loop Unwinding.