What an optimizing compiler does
An optimizing compiler translates source code into machine instructions and then transforms that translation to make it faster. It removes work the program never needed, reshapes loops, and chooses instructions that do more per cycle. Optimization is selected in levels — commonly via command-line flags — where lower levels apply safe, quick transformations and higher levels attempt more aggressive ones at the cost of longer compile times.
Inlining and constant folding
Inlining replaces a procedure call with the procedure's body at the call site, which removes call overhead and — more importantly — lets other optimizations see through the call and specialize the code for the actual arguments. Constant folding evaluates expressions made only of constants at compile time, so x = 2.0 * 3.5 becomes a single stored value. Dead code elimination then removes computations whose results are never used. Each is small; together they clean up a program substantially.
Loop transformations
Loops dominate scientific runtimes, so compilers work hardest there. Unrolling replicates a loop body several times per iteration to cut loop-control overhead and expose independent operations. Fusion merges adjacent loops over the same data so the data is loaded once instead of twice. Exchange and blocking reorder loops to improve memory locality. All of them preserve the program's meaning while changing its shape.
Vectorization
Modern processors have vector instructions — single instruction, multiple data (SIMD) — that apply one operation to several numbers at once. Vectorization rewrites a loop so its body executes as vector operations. It works best on loops with no dependencies between iterations, which is exactly the shape of whole-array expressions in Fortran: a statement like y = a*x + b over arrays is an open invitation to vectorize.
Choosing an optimization level
The right level is a small experiment, not a theory: build with the default, build with higher levels, and compare measured runtime on representative input. Higher levels occasionally slow a program down or change floating-point behavior through reassociation, so the measurement-first habit from A Measurement-First Workflow applies here too.