How does a compiler optimize a loop that traverses an array (e.g. summing it)?
It converts index-based access (A[i], recomputed each iteration) into a moving pointer that just increments by the element size.
* Strength reduction: index-based A[i] becomes a moving pointer *ap++ until ap reaches the end address. *
Recomputing A + i*4 every iteration wastes a multiply-and-add. The compiler instead keeps a running pointer and bumps it, comparing against a precomputed end address to stop:
Original C:
int A[N];
int sum(void) {
int i, sum = 0;
for (i = 0; i < N; i++) sum += A[i];
return sum;
}
What the compiler effectively produces:
int sum(void) {
int *ap = A;
int sum = 0;
do {
sum += *ap++; // dereference, then advance
} while (ap != A + 100); // stop at the one-past-the-end address
return sum;
}
The assembly advances the pointer with a single addq $4, %rdx and ends the loop with cmpq $A+400, %rdx (the address just past the last element). This optimization is called induction-variable / strength reduction — replacing repeated multiplication with cheap repeated addition.
Tip: Recognizing a add $4,%reg ; cmp $end,%reg ; jne pattern in disassembly is a strong sign of a pointer-walking array loop.
Go deeper:
Compiler Explorer (godbolt) — see induction-variable / strength reduction in real output.
Array data structure (Wikipedia) — arrays and contiguous element access.