Compiler Design
105601Module 4: Intermediate Code Generation, Code Improvement (optimization)
Q1d. Three-address code involves (i) Exactly 3 address (ii) At most 3 addresses (iii) No unary operator (iv) None20232m
Module 4: Intermediate Code Generation, Code Improvement (optimization)
View this question on its own page →Three-address code involves
(i) Exactly 3 address
(ii) At most 3 addresses
(iii) No unary operator
(iv) NoneWorked SolutionAnswer: (ii) At most 3 addresses
Explanation
A three-address code is an intermediate-code statement of the general form:
Each statement contains at most three operands/addresses: the destination plus at most two source operands. The name comes from the fact that a single 3-address statement involves at most three addresses.
- It is not exactly 3 addresses — a statement like
t = aort = -ahas fewer than three addresses. - It can contain a unary operation (e.g.
t = -x), so saying "no unary operator" is wrong. - Therefore "Exactly 3 address" (i), "No unary operator" (iii), and "None" (iv) are incorrect.
The correct statement is:
- It is not exactly 3 addresses — a statement like
Q1g. Which optimization eliminates repeated computation of the same expression? (i) Loop interchange (ii) Dead-code elimination only (iii) Common subexpression elimination (iv) Register allocation20262m
Module 4: Intermediate Code Generation, Code Improvement (optimization)
View this question on its own page →Which optimization eliminates repeated computation of the same expression?
(i) Loop interchange
(ii) Dead-code elimination only
(iii) Common subexpression elimination
(iv) Register allocationWorked SolutionAnswer: (iii) Common subexpression elimination
Explanation
Common subexpression elimination (CSE) detects an expression that was already computed and whose operands have not changed since, and reuses the earlier result instead of recomputing it.
Before:
x = a * b + c y = a * b + dAfter CSE:
t = a * b x = t + c y = t + dThe other options: loop interchange changes loop order (cache behaviour); dead-code elimination removes useless code; register allocation maps variables to registers.
Q1i. The method which merges the bodies of two loops is (i) Loop rolling (ii) Loop Jamming (iii) Constant folding (iv) None of the above20232m
Module 4: Intermediate Code Generation, Code Improvement (optimization)
View this question on its own page →The method which merges the bodies of two loops is
(i) Loop rolling
(ii) Loop Jamming
(iii) Constant folding
(iv) None of the aboveWorked SolutionAnswer: (ii) Loop Jamming (loop jamming)
Explanation
- Loop jamming / loop fusion (jamming) is the compiler optimization that merges the bodies of two adjacent loops that have the same range of traversal, into a single loop, so the loop control overhead runs only once.
- Loop rolling is not a standard optimization.
- Constant folding folds expressions with only constants at compile time, evaluating them at compile time (e.g.
x = 3+4→x = 7), unrelated to merging loops. - "None of the above" is therefore wrong.
Hence the method which merges the bodies of two loops is:
Q6a. Generate the three-address code for the following expression. Then represent the generated code using quadruple, triple, and indirect-triple representations. x = a * (b + c) - d / e20267m
Module 4: Intermediate Code Generation, Code Improvement (optimization)
View this question on its own page →Generate the three-address code for the following expression. Then represent the generated code using quadruple, triple, and indirect-triple representations.
Worked SolutionExpression:
Operator precedence and parentheses give the evaluation order: first, then , then , then the subtraction, then the assignment.
Three-address code
t1 = b + c t2 = a * t1 t3 = d / e t4 = t2 - t3 x = t4Syntax tree of the expression (each internal node becomes one three-address instruction, bottom-up)
MermaidDiagramRendering diagram…(i) Quadruples (op, arg1, arg2, result)
# op arg1 arg2 result 0 +b c t1 1 *a t1 t2 2 /d e t3 3 -t2 t3 t4 4 =t4 x (ii) Triples (op, arg1, arg2): there is no result field; a result is referred to by the number of the triple that computed it.
# op arg1 arg2 (0) +b c (1) *a (0) (2) /d e (3) -(1) (2) (4) =x (3) (iii) Indirect triples: the triples are the same as above, but a separate instruction list holds pointers to them. The order of execution can then be changed by reordering the pointers without touching the triples.
Instruction list Points to 100 (0) 101 (1) 102 (2) 103 (3) 104 (4) Triple # op arg1 arg2 (0) +b c (1) *a (0) (2) /d e (3) -(1) (2) (4) =x (3) Comparison
Form Temporaries in symbol table Easy to reorder for optimization Quadruples Yes (explicit result names) Yes Triples No No (numbers refer to positions) Indirect triples No Yes (reorder the pointer list) Q6b. Explain the construction of basic blocks and control-flow graphs (CFGs) in compiler design using a suitable three-address code example.20267m
Module 4: Intermediate Code Generation, Code Improvement (optimization)
View this question on its own page →Explain the construction of basic blocks and control-flow graphs (CFGs) in compiler design using a suitable three-address code example.
Worked SolutionBasic block
A basic block is a maximal sequence of consecutive three-address instructions with one entry point (only the first instruction can be reached from outside) and one exit point (control leaves only at the last instruction, with no jumps into or out of the middle).
Algorithm to find basic blocks
- Find the leaders (first instructions of blocks):
- the first instruction of the program;
- the target of any conditional or unconditional jump;
- the instruction immediately after a jump (conditional or unconditional).
- For each leader, the basic block consists of the leader and all instructions up to (but not including) the next leader or the end of the program.
Example three-address code
1 sum = 0 2 i = 1 3 if i > 10 goto 8 4 t1 = i * 2 5 sum = sum + t1 6 i = i + 1 7 goto 3 8 print sumLeaders: instruction 1 (first), 3 (target of the jump at 7), 4 (follows the conditional jump at 3), 8 (target of the jump at 3 and follows the jump at 7). So the leaders are .
Block Instructions 1-2 3 4-7 8 Control-flow graph (CFG)
A CFG has the basic blocks as nodes. There is an edge if control can pass from the end of to the start of : either by a jump from the last instruction of to the leader of , or because follows in program order and does not end in an unconditional jump.
MermaidDiagramRendering diagram…Uses: the CFG exposes loops (here ), and is the basis for data-flow analysis, local optimizations inside a block, and global optimizations such as code motion and dead-code elimination.
- Find the leaders (first instructions of blocks):
Q8b. Translate the expression a = (a + b) * (c + d) + (a + b + c) into (i) Quadruple (ii) Triple (iii) Indirect triple20239m
Module 4: Intermediate Code Generation, Code Improvement (optimization)
View this question on its own page →Translate the expression into
(i) Quadruple
(ii) Triple
(iii) Indirect tripleWorked SolutionThree-address code for
Start from the natural statement sequence:
t1 = a + b t2 = c + d t3 = t1 * t2 t4 = a + b (or reuse t1) t5 = t4 + c → computes (a+b) + c t6 = t3 + t5 a = t6(i) Quadruples
Form (op, arg1, arg2, result):
No op arg1 arg2 result 1 + a b t1 2 + c d t2 3 * t1 t2 t3 4 + a b t4 5 + t4 c t5 6 + t3 t5 t6 7 = t6 (empty) a (ii) Triples
Three fields (op, arg1, arg2); a result value is referenced by its triple index
(k).# op arg1 arg2 1 + a b 2 + c d 3 * (1) (2) 4 + a b 5 + (4) c 6 + (3) (5) 7 = (6) a (iii) Indirect triples
List of triples plus a separate indirect table that holds the execution-order pointers to the triples; changing an instruction (e.g. removing a common subexpression) is done by redirecting a pointer, no renumbering needed.
Triples:
# op arg1 arg2 1 + a b 2 + c d 3 * (1) (2) 4 + (1) c 5 + (3) (4) 6 = (5) a Indirect table (execution order):
(1) → triple 1 (2) → triple 2 (3) → triple 3 (4) → triple 4 (5) → triple 5 (6) → triple 6 → assigns into aSince triple 4 reuses triple 1 (
a+b), the (a+b) subexpression appears once; that is exactly how the indirection layer makes common-subexpression elimination and code motion easy.Summary
- Quadruple: explicit result names — easiest to manipulate, most commonly used in optimizers.
- Triple: compact (no temporaries), but moving/deleting statements requires renumbering.
- Indirect triple: triples + index vector — easy CSE/code motion at the price of one extra level of indirection.