Code Optimization
Compiler Code Optimizations Introduction Optimized code Executes faster efficient memory usage yielding better performance. Compilers can be designed to provide code optimization. Users should only focus on optimizations not provided by the compiler such as choosing a faster and/or less memory intensive algorithm.
Topics Machine-independent optimizations Code motion Reduction in strength Common subexpression sharing Tuning: Identifying performance bottlenecks Machine-dependent optimizations Pointer code Loop unrolling Enabling instruction-level parallelism Understanding processor optimization Translation of instructions into operations Out-of-order execution Branches Caches and Blocking Advice
Great Reality There’s more to performance than asymptotic complexity Constant factors matter too! Easily see 10:1 performance range depending on how code is written Must optimize at multiple levels: Algorithm, data representations, procedures, and loops Must understand system to optimize performance How programs are compiled and executed How to measure program performance and identify bottlenecks How to improve performance without destroying code modularity, generality, readability
Speed and optimization Programmer Choice of algorithm Intelligent coding Compiler Choice of instructions Moving code Reordering code Strength reduction Must be faithful to original program Processor Pipelining Multiple execution units Memory accesses Branches Caches Rest of system Uncontrollable
Optimizing Compilers Provide efficient mapping of program to machine Register allocation Code selection and ordering Eliminating minor inefficiencies Don’t (usually) improve asymptotic efficiency Up to programmer to select best overall algorithm Big-O savings are (often) more important than constant factors But constant factors also matter Have difficulty overcoming “optimization blockers” Potential memory aliasing Potential procedure side effects
Limitations of Optimizing Compilers Operate Under Fundamental Constraint Must not cause any change in program behavior under any possible condition Often prevents making optimizations that would only affect behavior under pathological conditions Behavior that may be obvious to the programmer can be obfuscated by languages and coding styles E.g., data ranges may be more limited than variable types suggest Most analysis is performed only within procedures Whole-program analysis is too expensive in most cases Most analysis is based only on static information Compiler has difficulty anticipating run-time inputs When in doubt, the compiler must be conservative
Basic Block BB is a sequence of consecutive statements in which the flow control enters at the beginning and leaves at the end w/o halt or possible branching except at the end
Limitations of Optimizing Compilers Operate Under Fundamental Constraint Must not cause any change in program behavior under any possible condition Often prevents making optimizations that would only affect behavior under pathological conditions Behavior that may be obvious to the programmer can be obfuscated by languages and coding styles E.g., data ranges may be more limited than variable types suggest Most analysis is performed only within procedures Whole-program analysis is too expensive in most cases Most analysis is based only on static information Compiler has difficulty anticipating run-time inputs When in doubt, the compiler must be conservative
Basic Block
Principle sources of optimization Local optimization: within a basic block Global optimization: otherwise Mixed
Function-Preserving Transformation Improving performance w/o changing fn. Techniques Common subexpression Elimination Copy Propagation Dead-code elimination Constant folding
Common subexpression Elimination An occurrence of an expression E is common subexpression if E was previously computed and the values of variables in E have not changed since.
Copy Propagation An idea behind this technique is to use g for f whenever possible after the copy of f := g before x := t3 a[t7] := t5 a[t10] := x Goto b2 After x := t3 a[t7] := t5 a[t10] := t3 Goto b2
Dead code elimination Remove unreachable code If (debug) print … Many times, debug := false
Loop optimizations Beyond basic block Three important techniques Code motion Induction-variable elimination Reduction in strength
Code motion after T = limit – 2 While ( I <= t) Move code outside the loop since there are potential many iterations Look for expressions that yeild the same result independent of the iterations. before While ( I <= limit – 2). after T = limit – 2 While ( I <= t)
Induction-variable elimination & Reduction in strength Look for induction variables for strength reductions E.g. a pattern of changes in a lock step B3: j = j - 1 t4 = 4 *j t5 = a [ t4] If t5 > v goto B3 B3: j = j - 1 t4 = t4 -4 t5 = a [ t4] If t5 > v goto B3
Others optimizations Optimizations for Basic blocks Reducible flow graph Global Data flow analysis Machine dependent Optimizations
Basic Blocks
DAG