Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
In compiler theory, peephole optimization is a kind of optimization performed over a very small set of instructions in a segment of generated code. The set is called a "peephole" or a "window". It works by recognising sets of instructions that don't actually do anything, or that can be replaced by a leaner set of instructions.
Constant folding - Evaluate constant subexpressions in advance. Replace a variable with constant which has been assigned to it earlier. Example: pi := 3.14286 area = pi * r ** 2 area = 3.14286 * r ** 2
Reducing Strength
Certain machine instructions are considered to be cheaper than others. Hence, if we replace expensive operations by equivalent cheaper ones on the target machine, then the efficiency will be better. For example, x2 is invariable cheaper to implement as x * x than as a call to an exponentiation routine. Similarly, fixed-point multiplication or division by a power of two is cheaper to implement as a shift.
Null sequences - Delete useless operations Combine Operations: Replace several operations with one equivalent. Algebraic Laws: Use algebraic laws to simplify or reorder instructions. Special Case Instructions: Use instructions designed for special operand cases. Address Mode Operations: Use address modes to simplify code.
There can, of course, be other types of peephole optimizations involving simplifying the target machine instructions, assuming that the target machine is known in advance.
EX.-
we can delete the second instruction if it an unlabeled instruction. This is because the first instruction ensures that the value of a is already in the register R. If it is labeled, there is no guarantee that step 1 will always be executed before step 2.
Algebraic Simplifications
If statements like:
are generated in the code, they can be eliminated, because zero is an additive identity, and one is a multiplicative identity.
Loop Optimization
Decrease the number if instruction in the inner loop Even if we increase no of instructions in the outer loop Techniques: Code motion
Induction variable elimination Strength reduction Peephole Optimization Redundant instruction Elimination: Use algebraic identities Flow of control optimization: removal of redundant jumps Use of machine idioms Redundant instruction elimination Redundant load/store: see if an obvious replacement is possible MOV R0, a MOV a, R0 Can eliminate the second instruction without needing any global knowledge of a Unreachable code: identify code which will never be executed: #define DEBUG 0 if( DEBUG) { if (0 != 1) goto L2 print debugging info
Worth recognizing single instructions with a constant operand: A*1=A A*0=0 A/1=A A*2=A+A More delicate with floating-point Strength reduction: A^2=A*A Three address code
In computer science, three-address code (often abbreviated to TAC or 3AC) is a form of representing intermediate code used by compilers to aid in the implementation of codeimproving transformations. Each instruction in three-address code can be described as a 4-tuple: (operator, operand1, operand2, result). Each statement has the general form of:
such as:
where x, y and z are variables, constants or temporary variables generated by the compiler. op represents any operator, e.g. an arithmetic operator. Expressions containing more than one fundamental operation, such as:
are not representable in three-address code as a single instruction. Instead, they are decomposed into an equivalent series of instructions, such as
The term three-address code is still used even if some instructions use more or fewer than two operands. The key features of three-address code are that every instruction implements exactly one fundamental operation, and that the source and destination may refer to any available register.