Optimization Techniques Code Optimizations High-Level Optimizations Intermediate Code Optimizations
Total Page:16
File Type:pdf, Size:1020Kb
Optimization Techniques Code Optimizations z The most complex component of modern compilers 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 • Strength reduction • 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 compile time, 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 • Register allocation the loop's iteration outside the loop. • Instruction Scheduling for pipelined machines. for (i=0; i<N; i++) { => for (i=0; i<N; i++) { • loop unrolling for (j=0; j<N; i++) { base = a + (i * dim1); • instruction reordering ... a[i][j] ... for (j=0; j<N; i++) { ... (base + j) ... • delay slot filling • Utilizing features of specialized components, e.g., floating-point units. • Branch Prediction 7 8 2 Peephole Optimization Profile-based Optimization • Optimizations that examine small code sections at a time, • A compiler 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 constant folding to handle assignments of the form x = y • Dead code elimination • Loop optimizations • Code motion • Strength reduction • Induction variable 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 Debugging/Bug-finding program transformation • “Enhanced” type checking C ⇔ 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 Live Variable Analysis 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.