# Constant Simplification

Constant simplification is one of the most basic optimization techniques — which is why much faster and much more compact code should not be expected. The name itself suggests the direction that optimization takes, but what does simplification actually achieve? The best way to answer this is by examining a short C example in which values are supplied to a number of variables.

Non-optimized assembler output looks like this:

.file "calc.c" .section .rodata

.globl main

.type main,@function

pushl %ebp movl %esp, %ebp subl \$40, %esp andl \$-16, %esp movl \$0, %eax subl %eax, %esp movl \$10, -4(%ebp)

movl -4(%ebp), %eax addl \$42, %eax movl %eax, -8(%ebp)

movl -8(%ebp), %edx movl %edx, %eax addl %eax, %eax addl %edx, %eax sall \$3, %eax subl %edx, %eax movl %eax, -12(%ebp)

call printf leave ret

.size main,.Lfe1-main

The value of the individual assignments is not clear at the outset but must first be computed (by means of addition and multiplication). The results achieved in the various program runs do not differ because the same initial values are always used. If optimization is switched off, the C code is compiled into assembler code in a relative straightforward way. Two computations are performed and three variables are supplied with values. If optimization is switched on, an additional constant appears in the assembler output: the exact result of the computation (which in this case is 119 6).

The optimized assembler code looks like this:

.file "calc.c"

.section .rodata.str1.1,"aMS",@progbits,1

 .text .p2align 4,,15 main .type main,@function pushl %ebp movl %esp, %ebp subl \$24, %esp andl \$-16, %esp movl \$1196, 12(%esp) movl \$52, 8(%esp) movl \$10, 4(%esp) movl \$.LC0, (%esp) call printf movl %ebp, %esp popl %ebp ret .size main,.Lfe1-main

The computation is no longer made at runtime because the results are already known. However, faster program execution6 is not the only benefit produced by this optimization step. The resulting code now uses only one variable (z) because the two temporary variables (x and y) are superfluous. This not only shortens execution time, but also saves storage space — a major consideration in large programs with a large number of variables.