Sometimes loops can be transformed to different forms that are faster.
for i := 1 to 1000 do for j := 1 to 1000 do x[i,j] := y[i,j];This might be transformed to a single, linear loop:
for i := 1 to 1000000 do x[i] := y[i];Then it might be generated as a block-move instruction.
Code motion is moving code to a more favorable location, e.g., moving invariant code out of loops:
for i := 1 to 1000 do x[i] := y[i] * sqrt(a);The code sqrt(a) does not change within the loop, so it could be moved above the loop and its value reused.