0% found this document useful (0 votes)
2 views

lecture1

The document discusses control-flow graphs (CFG) and constant propagation in programming, detailing the structure of CFGs and the principles of data-flow analysis. It explains the use of lattices, flow functions, and the iterative data-flow analysis process to determine constant values in variables throughout program execution. Additionally, it highlights the benefits of constant propagation, such as dead code elimination and compile-time expression evaluation.

Uploaded by

Naruto Hinata
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

lecture1

The document discusses control-flow graphs (CFG) and constant propagation in programming, detailing the structure of CFGs and the principles of data-flow analysis. It explains the use of lattices, flow functions, and the iterative data-flow analysis process to determine constant values in variables throughout program execution. Additionally, it highlights the benefits of constant propagation, such as dead code elimination and compile-time expression evaluation.

Uploaded by

Naruto Hinata
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 22

Basics and Constant

Propagation
Control-Flow Graph
• A graph representation of intermediate code
• With nodes as basic- blocks and edges as the control-flow

• Basic blocks are maximal sequences of consecutive three-address


instructions with the properties that
• Flow of control can only enter the basic block through the first instruction in
the block (no jumps into the middle of the block)
• Control will leave the block without halting or branching except possibly at
the last instruction in the block
Example: CFG
x=0
int main() { n=0
int x = 0, n = 0; START
scanf(..)
scanf(“%d”, &x);
while (x != 1) { x != 1
if (x % 2) {
x = 3 * x + 1;
x%2
++n;
} else {
x /= 2; x=3*x+1 x /= 2
n = n+1; ++n n = n+1
}
}
printf(“%d\n”, n);
}
END printf(..)
Example with IR
Data-flow Analysis Preliminaries
• Lattice: Algebraic structure with elements on which a data-flow analysis is performed.

• Meet(⊓) and Join(⊔): Operations on elements of lattice L

• Unique elements of L: bottom (⊥), and top (⊤); ∀x ∈ L, x ⊓ ⊥ = ⊥ and x ⊔ ⊤ = ⊤.

• Flow Function: Abstracts the effect of a program construct to its effect on the corresponding lattice
elements.

• Monotonicity: A function f: L → L is a monotone, if for all x,y ∈ L, x ⊑ y ⇒ f(x) ⊑ f(y).

• Fixed Point: A fixed point of a function f: L → L is an element z ∈ L, such that f(z) = z.

• Termination: Finite lattice height combined with monotonicity of flow functions guarantee termination of
data-flow analysis algorithms
Constant Propagation: Example
• Aims at determining the variables that have constant values on all
executions of a program
1. a = 1;
•2. b = 4; 1. Is the value of ‘b’ constant at Line 8?
3. while (a > 0) {
4. if (a == 1) { 2. Is the value of ‘a’ constant at Line 4?
5. c = 9; 3. Is the value of ‘c’ constant at Line 11?
6. a = 4; 4. What is the output of the program?
7. } else {
8. c = b + 5;
9. a = a – b;
10. }
11. print c;
12. }
Uses of constant propagation
• Expressions can be evaluated at compile time (such expression in
loops save many evaluations at execution time)

• Dead code elimination: code that is never executed can be deleted

• Procedure integration or function inlining


Lattice for constant propagation
Constant Propagation: Lattice Meet Rules
• ⊥ = Constant value cannot be guaranteed
• ⊤ = May be a constant, not yet determined (init values)

• x ⊓ ⊤= x and x ⊓ ⊥ = ⊥, ∀x ∈ L

• c1 ⊓ c1 = c1 , c1 is a constant

• c2 ⊓ c1 = ⊥ , c1 and c2 are constants


Iterative Data-Flow Analysis
• Input:
• A flow graph G = (N,E) with entry and exit
• A lattice L

• Output:
• in(B) for each B ∈ N
• out(B) for each B ∈ N

• Computation: Solves the following data-flow equations iteratively

• ‘Init’ represents appropriate initial value for the data-flow information


Initialize worklist
and in() of all the
Iterative Data- nodes in CFG

Flow Analysis
(Kildall’s
worklist-based Apply flow function
algorithm)
Propagate data-flow
facts to successors
Constant Propagation: Statements of Interest
Assignment Statements:
• y = c, y ∈ Var, c ∈ Const
• y = 5;

• y = input(), y ∈ Var
• scanf(“%d”,&y);

• y = z, y ∈ Var, z ∈ Var

• y = e, y ∈ Var, e ∈ Expr
• ‘y = z + 5;’, ‘y = z * w;’, ‘y = y/z;’ etc.
IDFA Specific to Constant Propagation
• Assumption: one basic block per statement and start with the entry node

• Data flow values are given by a map m: Var → Vals (from Lattice L)

• Effect of a flow function fs for a statement s: mʹ = fs(m)

• Effect of a flow function on statements other than assignment statements


is: mʹ = m ⇒ fs is identity function

• At a merge point, get a meet of the flow maps


More on Flow Function fs

If s is an assignment statement to variable v, then fs (m) = mʹ, where:

• For all vʹ ≠ v, mʹ(vʹ) = m(vʹ)


• If the RHS of the statement is a constant c, then mʹ(v) = c
• If the RHS is an expression (say y op z),

m(y) op m(z), if m(y) and m(z) are constant values


mʹ(v) = " ⊥, if either of m(y) and m(z) is ⊥
⊤, Otherwise

• If the RHS is an expression that cannot be evaluated, then then mʹ(v) = ⊥


Working Example
Map
0. Entry x → T, y → T, z → T
1. x = 10;
1. x = 10; 2. y = 1;
2. y = 1;
3. z = 5;
3. z = 5;
4. if (cond) { 4. if (cond) {
5. y = y/x; 5. y = y/x;
6. x = x - 1;
6. x = x - 1;
7. z = z + 1;
8. } else { 7. z = z + 1;
9. z = z + y; 8. } else {
10. y = 0;
9. z = z + y;
11. }
12. print x + y + z; 10. y = 0;
12. print x + y + z;
Working Example
Map
0. Entry x → T, y → T, z → T
1. x = 10; x → 10, y → T, z → T
1. x = 10; 2. y = 1; x → 10, y → 1, z → T
2. y = 1;
3. z = 5; x → 10, y → 1, z → 5
3. z = 5;
4. if (cond) { 4. if (cond) { x → 10, y → 1, z → 5
5. y = y/x; 5. y = y/x;
6. x = x - 1;
6. x = x - 1;
7. z = z + 1;
8. } else { 7. z = z + 1;
9. z = z + y; 8. } else { x → 10, y → 1, z → 5
10. y = 0;
9. z = z + y;
11. }
12. print x + y + z; 10. y = 0;
12. print x + y + z;
Working Example
Map
0. Entry x → T, y → T, z → T
1. x = 10; x → 10, y → T, z → T
1. x = 10; 2. y = 1; x → 10, y → 1, z → T
2. y = 1;
3. z = 5; x → 10, y → 1, z → 5
3. z = 5;
4. if (cond) { 4. if (cond) { x → 10, y → 1, z → 5
5. y = y/x; 5. y = y/x; x → 10, y → 0, z → 5
6. x = x - 1;
6. x = x - 1; x → 9, y → 0, z → 5
7. z = z + 1;
8. } else { 7. z = z + 1; x → 9, y → 0, z → 6
9. z = z + y; 8. } else { x → 10, y → 1, z → 5
10. y = 0;
9. z = z + y;
11. }
12. print x + y + z; 10. y = 0;
12. print x + y + z;
Working Example
Map
0. Entry x → T, y → T, z → T
1. x = 10; x → 10, y → T, z → T
1. x = 10; 2. y = 1; x → 10, y → 1, z → T
2. y = 1;
3. z = 5; x → 10, y → 1, z → 5
3. z = 5;
4. if (cond) { 4. if (cond) { x → 10, y → 1, z → 5
5. y = y/x; 5. y = y/x; x → 10, y → 0, z → 5
6. x = x - 1;
6. x = x - 1; x → 9, y → 0, z → 5
7. z = z + 1;
8. } else { 7. z = z + 1; x → 9, y → 0, z → 6
9. z = z + y; 8. } else { x → 10, y → 1, z → 5
10. y = 0;
9. z = z + y; x → 10, y → 1, z → 6
11. }
12. print x + y + z; 10. y = 0; x → 10, y → 0, z → 6
12. print x + y + z;
Working Example
Map
0. Entry x → T, y → T, z → T
1. x = 10; x → 10, y → T, z → T
1. x = 10; 2. y = 1; x → 10, y → 1, z → T
2. y = 1;
3. z = 5; x → 10, y → 1, z → 5
3. z = 5;
4. if (cond) { 4. if (cond) { x → 10, y → 1, z → 5
5. y = y/x; 5. y = y/x; x → 10, y → 0, z → 5
6. x = x - 1;
6. x = x - 1; x → 9, y → 0, z → 5
7. z = z + 1;
8. } else { 7. z = z + 1; x → 9, y → 0, z → 6
9. z = z + y; 8. } else { x → 10, y → 1, z → 5
10. y = 0;
9. z = z + y; x → 10, y → 1, z → 6
11. }
12. print x + y + z; 10. y = 0; x → 10, y → 0, z → 6
12. print x + y + z; [x → 9, y → 0, z → 6] ⊓
[x → 10, y → 0, z → 6]
= [x → ⊥, y → 0, z → 6]
Example for you to try

Iteration1 Iteration2 Iteration3


Entry x → T, y → T, z → T, p → T {T, T, T, T} {T, T, T, T}
1. x = 10; x = 10; {10, T, T, T} {10, T, T, T} {10, T, T, T}
2. y = 1; y = 1; {10, 1, T, T} {10, 1, T, T} {10, 1, T, T}
3. z = 1;
4. while (x > 1) { z = 1; {10, 1, 1, T} {10, 1, 1, T} {10, 1, 1, T}
5 y = x * y; while (x > 1) {10, 1, 1, T} {10, 1, 1, T} ⊓ {9, 10, 1, T} {⊥, ⊥, 1, T}
6. x = x – 1; { = {⊥, ⊥, 1, T}
7. z = z * z; } y = x * y; {10, 10, 1, T} {⊥, ⊥, 1, T} {⊥, ⊥, 1, T}
8. p = x + y + z;
x = x – 1; {9, 10, 1, T} {⊥, ⊥, 1, T} {⊥, ⊥, 1, T}
z = z * z; } {9, 10, 1, T} {⊥, ⊥, 1, T} {⊥, ⊥, 1, T}
p = x + y + z; {10, 1, 1, 12} {⊥, ⊥, 1, ⊥} {⊥, ⊥, 1, ⊥}
Distributive property
[u → 1, v → 2, w → T] ⊓ [u → 2, v → 1, w → T] =
[u → ⊥, v → ⊥, w → T]

Effect f4 ⇒ [u → ⊥, v → ⊥, w → ⊥]
cond

Effect f4: [u → 1, v → 2, w → T] ⇒ [u → 1, v → 2, w → 3],


Effect f4: [u → 2, v → 1, w → T] ⇒ [u → 2, v → 1, w → 3]

[u → 1, v → 2, w → 3] ⊓ [u → 2, v → 1, w → 3] =
[u → ⊥, v → ⊥, w → 3]

f4(f2(m1) ⊓ f3(m1)) ⊑ f4(f2(m1)) ⊓ f4(f3(m1))


Conditional Constant Propagation
Idea: Process a block only if it is found executable.

• Mark the “entry” node executable.

x = 1; • If a node has only one successor, then mark the


successor “executable”.

if (x == 1) { • If a conditional branch node has more than one
y = 1; successor: evaluate the condition (based on the
} else { abstract values) and appropriately mark the
y = 10; successors as executable or not.
}
print x + y ; • Iterate till there is no change (in the flow maps and
the list of executable nodes).

You might also like