Optimization Techniques Code Optimizations

z The most complex component of modern z High-level optimizations z Must always be sound, i.e., semantics-preserving • Operate at a level close to that of source-code • Need to pay attention to exception cases as well • Use a conservative approach: risk missing out optimization rather • Often language-dependent than changing semantics z Intermediate code optimizations z Reduce runtime resource requirements (most of the time)‏ • Usually, runtime, but there are memory optimizations as well • Most optimizations fall here • Runtime optimizations focus on frequently executed code • Typically, language-independent • How to determine what parts are frequently executed? • Assume: loops are executed frequently z Low-level optimizations • Alternative: profile-based optimizations • Some optimizations involve trade-offs, e.g., more memory for • Usually specific to each architecture faster execution z Cost-effective, i.e., benefits of optimization must be worth the effort of its implementation 1 2

High-level optimizations Intermediate code optimizations • Inlining • Common subexpression elimination •Replace function call with the function body • Constant propagation • Partial evaluation • Jump-threading •Statically evaluate those components of a • Loop-invariant code motion program that can be evaluated • Dead-code elimination • Tail recursion elimination • • Loop reordering • Array alignment, padding, layout

3 4

1 Constant Propagation Strength Reduction z Identify expressions that can be evaluated at •Replace expensive operations with equivalent , and replace them with their cheaper (more efficient) ones. values. y = 2; => y = 2; z x = 5; => x = 5; => x = 5; z = x^y; z = x*x; y = 2; y = 2; y = 2; ...... v = u + y; v = u + y; v = u + 2; •The underlying architecture may determine z = x * y; z = x * y; z = 10; which operations are cheaper and which w = v + z + 2; w = v + z + 2; w = v + 12; ones are more expensive......

5 6

Loop-Invariant Code Motion Low-level Optimizations •Move code whose effect is independent of • the loop's iteration outside the loop. • for pipelined machines. for (i=0; i for (i=0; i

7 8

2 Profile-based Optimization

• Optimizations that examine small code sections at a time, • A has difficulty in predicting: and transform them • likely outcome of branches • Peephole: a small, moving window in the target program • functions and/or loops that are most frequently • Much simpler to implement than global optimizations executed • Typically applied at machine code, and some times at • sizes of arrays intermediate code level as well • or more generally, any thing that depends on • Any optimization can be a peephole optimization, dynamic rogram behavior. provided it operates on the code within the peephole. • Runtime profiles can provide this missing information, • redundant instruction elimination making it easier for compilers to decide when certain • flow-of control optimizations • algebraic simplifications • ... 9 10

Example Program: Quicksort 3-address code for Quicksort

z Most optimizations opportunities arise in intermediate code • Several aspects of execution (e.g., address calculation for array access) aren’t exposed in source code z Explicit representations provide most opportunities for optimization z It is best for programmers to focus on writing readable code, leaving simple optimizations to a compiler

11 12

3 Organization of Optimizer Flow Graph for Quicksort

z B1,…,B6 are basic blocks • sequence of statements where control enters at beginning, with no branches in the middle z Possible optimizations • Common subexpression elimination (CSE)‏ • Copy propagation • Generalization of to handle assignments of the form x = y • • Loop optimizations • Code motion • Strength reduction • elimination

13 14

Common Subexpression Elimination Copy Propagation

z Expression z Consider x = y; previously z = x*u; computed w = y*u; Clearly, we can replace z Values of all assignment on w by variables in w = z z This requires recognition of expression have cases where multiple variables not changed. have same value (i.e., they are copies of each other)‏ z Based on z One optimization may expose available opportunities for another • Even the simplest expressions optimizations can pay off analysis • Need to iterate optimizations a few times 15 16

4 Induction Vars, Strength Reduction Dead Code Elimination and IV Elimination

z Dead variable: a z Induction Var: a variable whose value variable whose value is changes in lock-step with a loop index no longer used z If expensive operations are used for z Live variable: opposite of dead variable computing IV values, they can be replaced by less expensive operations z Dead code: a statement that assigns to a dead z When there are multiple IVs, some can be variable eliminated z Copy propagation turns copy statement into dead code.

17 18

Strength Reduction on IVs After IV Elimination …

19 20

5 Program Analysis Applications of Program Analysis

z Compiler optimization z Optimization is usually expressed as a z /Bug-finding program transformation • “Enhanced” type checking ⇔ C when property P holds • Use before assign 1 2 • Null pointer dereference z Whether property P holds is determined by a • Returning pointer to stack-allocated data z Vulnerability analysis/mitigation program analysis • Information flow analysis • Detect propagation of sensitive data, e.g., passwords z Most program properties are undecidable in • Detect use of untrustworthy data in security-critical context general • Find potential buffer overflows • Solution: Relax the problem so that the answer is z Testing – automatic generation of test cases z Verification: Show that program satisfies a specified an “yes” or “don’t know” property, e.g., no deadlocks • model-checking

21 22

Dataflow Analysis Dataflow Analysis zAnswers questions relating to how data flows z Equations typically of the form through a program out[S] = gen[S] ∪ (in[S] – kill[S]) • What can be asserted about the value of a variable (or where the definitions of out, gen, in and kill more generally, an expression) at a program point differ for different analysis zExamples z When statements have multiple • Reaching definitions: which assignments reach a program statement predecessors, the equations have to be • Available expressions modified accordingly • Live variables z Procedure calls, pointers and arrays require • Dead code careful treatment • …

23 24

6 Points and Paths Reaching Definitions

z A definition of a variable x is a statement that assigns to x • Ambiguous definition: In the presence of aliasing, a statement may define a variable, but it may be impossible to determine this for sure. z A definition d reaches a point p provided: • There is a path from d to p, and this definition is not “killed” along p • “Kill” means an unambiguous redefinition z Ambiguity Î approximation • Need to ensure that approximation is in the right direction, so that the analysis will be sound

25 26

DFA of Structured Programs DF Equations for Reaching Defns z S Æ id := E | S;S | if E then S else S | do S while E z E Æ E + E | id

27 28

7 DF Equations for Reaching Defns Direction of Approximation

z Actual kill is a superset of the set computed by the dataflow equations z Actual gen is a subset of the set computed by these equations z Are other choices possible? • Subset approximation of kill, superset approximation of gen • Subset approximation of both • Superset approximation of both z Which approximation is suitable depends on the intended use of analysis results

29 30

Solving Dataflow Equations Computing Fixpoints: Equation for Loop z Dataflow equations are recursive z Rewrite equations using more compact notation, with: J standing for in[S] and z Need to compute so-called fixpoints, to solve I, G, K, and O for in[S1], gen[S1], kill[S1] and out[S1]: I = J ∪ O, these equations O = G ∪ (I – K) z Fixpoint computations uses an interative z Letting I0 = O0 = φ, we have: I1 = J O1 = G ∪ (I0 – K) = G procedure I2 = J ∪ O1 = J ∪ G O2 = G ∪ (I1 – K) = G ∪ (J – K) out0 = φ I3 = J ∪ O2 O3 = G ∪ (I2 – K) • = J ∪ G ∪ (J – K)= G ∪ (J ∪ G – K) i = J ∪ G = I2 = G ∪ (J – K) = O2 • out is computed using the equations by (Note that for all sets A and B, A U (A-B) = A, and i-1 substituting out for occurrences of out on the rhs for all sets A, B and C, A U (A U C –B) = A U (C-B).) Thus, we have a fixpoint. • Fixpoint is a solution, i.e., outi = outi-1

31 32

8 Use-Definition Chains Available Expressions z Convenient way to represent reaching z An expression e is available at point p if definition information • every path to p evaluates e • none of the variables in e are assigned after last z ud-chain for a variable links each use of the computation of e variable to its reaching definitions z A block kills e if it assigns to some variable in e and does not recompute e. • One list for each use of a variable z A block generates e if it computes e and doesn’t subsequently assign to variables in e z Exercise: Set up data-flow equations for available expressions. Give an example use for which your equations are sound, and another example for which they aren’t

33 34

Available expressions -- Example

z A variable x is live at a program point p if the a := b+c value of x is used in some path from p z Otherwise, x is dead. z Storage allocated for dead variables can be b := a-d freed or reused for other purposes. z in[B] = use[B] ∪ (out[B] – def[B])‏ c := b+c z out[B] = ∪ in[S], for S a successor of B z Equation similar to reaching definitions, but d := a-d the role of in and out are interchanged

35 36

9 Def-Use Chains Optimizations and Related Analyses z du-chain links the definition of a variable with z Common subexpression elimination all its uses • Available expressions z Copy propagation Use of a definition of a variable x at a point p • • In every path that reaches a program point p, the variables implies that there is a path from this definition to p x and y have identical values in which there are no assignments to x z Detection of loop-invariant computation z du-chains can be computed using a dataflow • Any assignment x := e where the definition of every variable in e occurs outside the loop. analysis similar to that for live variables z Code reordering: A statement x := e can be moved • earlier before statements that (a) do not use x, (b) do not assign to variables in e • later after statements that (a) do not use , (b) do not assign to variables in e

37 38

Difficulties in Analysis Difficulties in Analysis z Procedure calls z Procedure calls • may modify global variables • potentially kill all available expressions involving global variables • modify reaching definitions on global variables z Aliasing z Aliasing • Create ambiguous definitions • a[i] = a[j] --- here, i and j may have same value, so assignment to a[i] can potentially kill a[j] • *p = q + r --- here, p could potentially point to q, r or any other variable • creates ambiguous redefinition for all variables in the program!

39 40

10