Chapter5 1 Merged
Chapter5 1 Merged
Syntax-Directed
Translation
outline
• the translation of languages guided by context-free
grammars.
• A syntax-directed definition specifies the values of
attributes by associating semantic rules with the
grammar productions.
We associate information with a language construct
by attaching attributes to the grammar symbol(s)
representing the construct,
outline
• a syntax-directed translation scheme embeds
program fragments called semantic actions
within production bodies.
E → El +T { print ' + ' }
The position of a semantic action in a production
body determines the order in which the action is
executed.
in general, semantic actions may occur at any
position in a production body.
outline
• The most general approach to syntax-
directed translation is to construct a parse
tree or a syntax tree, and then to compute
the values of attributes at the nodes of the
tree by visiting the nodes of the tree.
• a class of syntax-directed translations called
"L-attributed translations "
• a smaller class, called "S-attributed
translations" (S for synthesized )
5.1 Syntax-Directed Definitions
Figure 5.6: E. val is synthesized from El. val and E2. val
5.2.1 Dependency Graphs
• Example 5.5
Figure 5.7: Dependency graph for the annotated parse tree of Fig. 5.5
5.2.2 Ordering the Evaluation of Attributes
• the only allowable orders of evaluation are those
sequences of nodes Nl, N2,. . . , Nk such that if there is
an edge of the dependency graph from Ni to Nj; then i
< j.
• Such an ordering embeds a directed graph into a linear
order, and is called a topological sort of the graph.
•If there is any cycle in the graph, then there are no
topological sorts; that is,there is no way to evaluate the
SDD on this parse tree.
•If there are no cycles,however, then there is always at
least one topological sort.
5.2.3 S-Attributed Definitions
• An SDD is S-attributed if every attribute is
synthesized.
Example 5.7 : The SDD of Fig. 5.1 is an example of
an S-attributed definition. Each attribute, L.val, E.va1,
T.val, and F.val is synthesized.
Figure 5.14: Dependency graph for a - 4 + c, with the SDD of Fig. 5.13
5.3.2 The Structure of a Type
• Inherited attributes are useful when the structure of
the parse tree differs from the abstract syntax of the
input; attributes can then be used to carry
information from one part of the parse tree to another.
Example 5.13: In C, the type int [2][3] can be read
as, "array of 2 arrays of 3 integers." The corresponding
type expression array(2, array(3, integer)) is
represented by the tree in Fig. 5.15
Semester 2019-2020-II
CSE, IIT Kanpur
Content influenced by many excellent references, see References slide for acknowledgements.
An Overview of Compilation
source program target program
intermediate code
semantic analyzer
generator
rdArr() qsort(1,9)
global
main() variable main()
integer 𝑎[11] integer 𝑎[11]
main main
rdArr()
rdArr
integer 𝑖 local
variable
main
rdArr() qsort(1,9)
integer 𝑚, 𝑛
qsort(1,9)
integer 𝑖 local
variable
naming, allocation of
resources, addressability, postreturn
epilogue
and protection
epilogue
Control link
Caller’s responsibility
Links and saved status
responsibility
Control link
Links and saved status
Caller’s
top_stack
Temporaries and local data
Call sequence
• Caller evaluates the actual parameters
• Caller stores a return address and the old value of top_stack into
the callee's activation record
• Caller then increments top_stack past the caller's local data and
temporaries and the callee's parameters and status fields
• Callee saves the register values and other status information
• Callee initializes its local data and begins execution
Return Sequence
• Callee places the return value next to the parameters
• Callee restores top_stack and other registers
• Callee branches to the return address that the caller placed in the
status field
• Caller copies return value into its activation record
y=f(3);
y=f(3);
• Simple rules
• Global variables are in static storage
• Addresses are fixed and determined at compile time
• Any other name must be local to the activation at the top of the stack
Temporaries
d[1] d[1]
d[2] sort d[2] sort
qsort(1,9) qsort(1,9)
null null
… …
qsort(1,3)
saved d[2]
size
size
next
Level 0
null
Structure of the Symbol Table
Then we increase the block level and install
the keywords in the symbol table at level 1.
Level 1 Level 0
Hash table
of null
Keywords
Structure of the Symbol Table
Then we increase the block level and install
the globals at level 2.
class Bar {
int value;
void setValue(int c) {
value = c;
} scope of c scope of value
}
23
Symbol table example cont.
…
(Foo)
Symbol Kind Type Properties
(Test) (setValue)
Symbol Kind Type Properties Symbol Kind Type Properties
(block1)
Symbol Kind Type Properties
d var int …
24
Checking scope rules
(Foo)
Symbol Kind Type Properties
(Test) (setValue)
Symbol Kind Type Properties Symbol Kind Type Properties
(block1)
void setValue(int c) { lookup(value) Symbol Kind Type Properties
value = c; d var int …
{ int d = c;
c = c + d;
value = c;
}
25
}
Catching semantic errors
Error !
(Foo)
Symbol Kind Type Properties
(Test) (setValue)
Symbol Kind Type Properties Symbol Kind Type Properties
(block1)
void setValue(int c) { lookup(myValue) Symbol Kind Type Properties
value = c; d var int …
{ int d = c;
c = c + d;
myValue = c;
}
}
26
Hash Tables
A hash table is a list in which each member is
accessed through a key.
The key is used to determine where to store
the value in the table.
The function that produces a location from
the key is called the hash function.
For example, if it were a hash table of strings,
the hash function might compute the sum of
the ASCII values of the first 5 characters of
the string, modulo the size of the table.
Hash Tables
The numerical value of the hashed key gives
the location of the member.
Thus, there is no need to search for the
member; the hashed key tells where it is
located.
For example, if the string were "return",
then the key would be (114 + 101 + 116 +
117 + 114) % 100 = 62.
Thus, "return" would be located in position
62 of the hash table.
Clashes and Buckets
Clearly, there is the possibility of a clash: two
members have the same hashed key.
In that case, the hash table creates a list,
called a “bucket,” of those values in the table
with that same location.
When that location comes up, the list is
searched.
However, it is generally a very short list,
especially if the table size has been chosen
well.
Hash Table Efficiency
The two parameters that determine how
efficiently the hash table performs are
The capacity of the table, i.e., the total amount of
memory allocated.
The number of buckets, or equivalently, the size
of a bucket.
Clearly, the size of a bucket times the
number of buckets equals the capacity of the
table.
Hash Table Efficiency
For a given hash table capacity,
If there are too many buckets, then many buckets
will not be used, leading to space inefficiency.
If there are too few buckets, then there will be
many clashes, causing the searches to
degenerate into predominately sequential
searches, leading to time inefficiency.
End of Chapter # 13
CODE OPTIMIZATION
Presented By:
Amita das
Jayanti bhattacharya
Jaistha Upadhyay
Design Of a Compiler
S ource code
L exical A nalysis
S yntax A nalysis
Table Error
M gmt
Routine
Intermediate Code Generation Handling
Routine
Code Optimization
Code Generation
Object code
What is optimization?
In computing, optimization is the process of modifying a system to make
some aspect of it work more efficiently or use fewer resources. F or
instance, a computer program may be optimized so that it executes more
rapidly, or is capable of operating with less memory storage or other
resources, or draw less power. The system may be a single computer
program, a collection of computers or even an entire network such as the
internet.
Levels' of optimization
Optimization can occur at a number of 'levels':
Design level
A t the highest level, the design may be optimized to make best use
of the available resources. The implementation of this design will
benefit from the use of suitable efficient algorithms and the
implementation of these algorithms will benefit from writing good
quality code. The architectural design of a system overwhelmingly
affects its performance. The choice of algorithm affects efficiency
more than any other item of the design.
Compile level
A t the lowest level, writing code using an A ssembly language designed for
a particular hardware platform will normally produce the most efficient
code since the programmer can take advantage of the full repertoire of
machine instructions. The operating systems of most machines has been
traditionally written in A ssembler code for this reason.
Runtime
Source Code:
-A lgorithms transformations can produce spectacular improvements
-Profiling can be helpful to focus a programmer’s attention on important code.
Intermediate Code:
-Compiler can improve loops, procedure calls and address calculations
-Typically only optimizing compilers include this phase
Target Code:
-Compilers can use registers efficiently
-Peephole transformation can be applied
Types of Code optimization
a=b * c + g temp=b * c
a=temp + g
d=b * c * d
d=temp * d
Dead code Optimization:
Dead Code elimination is a compiler optimization that removes code that does not
affect a program. Removing such code has two benefits It shrinks program size, an
important consideration in some contexts. It lets the running program avoid
executing irrelevant operations, which reduces its running time.
If (a>b)
m=a If (a>b)
m=0 else
else m=0
m=-1
Redundant Code
Redundant Code is code that is executed but has
no effect on the output from a program
main(){
int a,b,c,r;
a=5;
b=6;
c=a + b;
Adding time & space complexity
r=2;
r++;
printf(“ %d” ,c);
}
Loop optimization
i =1 i =1
s= 0 s= 0
do{ a =5
s= s + i do{
a =5 s= s + i
i =i +1 i =i +1
{ {
B4
if i >= j goto B6
B1 Common Subexpression Elimination
i=m-1
j=n
t1 =4 * n
v = a[t1] B5 B6
B2 t6 = 4 * i t11 = 4 * i
B4
if i >= j goto B6
B1 Common Subexpression Elimination
i=m-1
j=n
t1 =4 * n
v = a[t1] B5 B6
B2 t6 = 4 * i t11 = 4 * i
i=i +1 x = a[t11]
x = a[t6]
t2 = 4 * i t12 = 4 * i
t8 = 4 * j
t3 = a[t2] t13 = 4 * n
t9 = a[t8]
if t3 < v goto B2
t14 = a[t13]
a[t6] = t9
B3 a[t12] = t14
t10 = 4 *
j=j–1
j t15 = 4 * n
t4 = 4 * j
a[t10] = x a[t15] = x
t5 = a[t4]
if t5 > v goto B3 goto B2
B4
if i >= j goto B6
B1 Common Subexpression Elimination
i=m-1
j=n
t1 =4 * n
v = a[t1] B5 B6
B2 t6 = 4 * i t11 = 4 *i
i=i +1 x = a[t11]
x = a[t6]
t2 = 4 * i t12 = 4 * i
t8 = 4 * j
t3 = a[t2] t13 = 4 * n
t9 = a[t8]
if t3 < v goto B2
t14 = a[t13]
a[t6] = t9
B3 a[t12] = t14
a[t8] = x
j=j–1
t15 = 4 * n
t4 = 4 * j goto B2
a[t15] = x
t5 = a[t4]
if t5 > v goto B3
B4
if i >= j goto B6
B1 Common Subexpression Elimination
i=m-1
j=n
t1 =4 * n
v = a[t1] B5 B6
B2 t6 = 4 * i t11 = 4 * i
i=i +1 x = a[t11]
x = a[t6]
t2 = 4 * i t12 = 4 * i
t8 = 4 * j
t3 = a[t2] t13 = 4 * n
t9 = a[t8]
if t3 < v goto B2
t14 = a[t13]
a[t6] = t9
B3 a[t12] = t14
a[t8] = x
j=j–1
t15 = 4 * n
t4 = 4 * j goto B2
a[t15] = x
t5 = a[t4]
if t5 > v goto B3
B4
if i >= j goto B6
B1 Common Subexpression Elimination
i=m-1
j=n
t1 =4 * n
v = a[t1] B5 B6
B2 t6 = 4 * i t11 = 4 * i
i=i +1 x = a[t11]
x = a[t6]
t2 = 4 * i t13 = 4 * n
t8 = 4 * j
t3 = a[t2] t14 = a[t13]
t9 = a[t8]
if t3 < v goto B2
a[t11] = t14
a[t6] = t9
B3 t15 = 4 * n
a[t8] = x
j=j–1
a[t15] = x
t4 = 4 * j goto B2
t5 = a[t4]
if t5 > v goto B3
B4
if i >= j goto B6
B1 Common Subexpression Elimination
i=m-1
j=n
t1 =4 * n
v = a[t1] B5 B6
B2 t6 = 4 * i
t11 = 4 * i
i=i +1 x = a[t11]
x = a[t6]
t2 = 4 * i
t8 = 4 * j t13 = 4 * n
t3 = a[t2]
t9 = a[t8] t14 = a[t13]
if t3 < v goto B2
a[t6] = t9 a[t11] = t14
B3
a[t8] = x a[t13] = x
j=j–1
t4 = 4 * j goto B2
t5 = a[t4]
if t5 > v goto B3
B4
if i >= j goto B6
B1 Common Subexpression Elimination
i=m-1
j=n
t1 =4 * n
v = a[t1] B5 B6
B2 t6 = 4 * i
t11 = 4 * i
i=i +1 x = a[t11]
x = a[t6]
t2 = 4 * i
t8 = 4 * j t13 = 4 * n
t3 = a[t2]
t9 = a[t8] t14 = a[t13]
if t3 < v goto B2
a[t6] = t9 a[t11] = t14
B3
a[t8] = x a[t13] = x
j=j–1
t4 = 4 * j goto B2
t5 = a[t4]
if t5 > v goto B3
B4
if i >= j goto B6
B1 Common Subexpression Elimination
i=m-1
j=n
t1 =4 * n
v = a[t1] B5 B6
B2 x = a[t2]
t11 = 4 * i
i=i +1 t8 = 4 * j
x = a[t11]
t2 = 4 * i t9 = a[t8]
t13 = 4 * n
t3 = a[t2] a[t2] = t9
t14 = a[t13]
if t3 < v goto B2 a[t8] = x
a[t11] = t14
B3 goto B2
a[t13] = x
j=j–1
t4 = 4 * j
t5 = a[t4]
if t5 > v goto B3
B4
if i >= j goto B6
B1 Common Subexpression Elimination
i=m-1
j=n
t1 =4 * n
v = a[t1] B5 B6
B2 x = t3
t11 = 4 * i
i=i +1 t8 = 4 * j
x = a[t11]
t2 = 4 * i t9 = a[t8]
t13 = 4 * n
t3 = a[t2] a[t2] = t9
t14 = a[t13]
if t3 < v goto B2 a[t8] = x
a[t11] = t14
B3 goto B2
a[t13] = x
j=j–1
t4 = 4 * j
t5 = a[t4]
if t5 > v goto B3
B4
if i >= j goto B6
B1 Common Subexpression Elimination
i=m-1
j=n
t1 =4 * n
v = a[t1] B5 B6
B2 x = t3
t11 = 4 * i
i=i +1 a[t2] = t5
x = a[t11]
t2 = 4 * i a[t4] = x
t13 = 4 * n
t3 = a[t2] goto B2
t14 = a[t13]
if t3 < v goto B2
a[t11] = t14
B3
a[t13] = x
j=j–1
t4 = 4 * j
t5 = a[t4]
if t5 > v goto B3
B4
if i >= j goto B6
B1 Common Subexpression Elimination
i=m-1
j=n
t1 =4 * n
v = a[t1] B5 B6
B2 x = t3
x = t3
i=i +1 a[t2] = t5
t14 = a[t1]
t2 = 4 * i a[t4] = x
a[t2] = t14
t3 = a[t2] goto B2
a[t1] = x
if t3 < v goto B2
B3
Similarly for B6
j=j–1
t4 = 4 * j
t5 = a[t4]
if t5 > v goto B3
B4
if i >= j goto B6
B1 Dead Code Elimination
i=m-1
j=n
t1 =4 * n
v = a[t1] B5 B6
B2 x = t3
x = t3
i=i +1 a[t2] = t5
t14 = a[t1]
t2 = 4 * i a[t4] = x
a[t2] = t14
t3 = a[t2] goto B2
a[t1] = x
if t3 < v goto B2
B3
j=j–1
t4 = 4 * j
t5 = a[t4]
if t5 > v goto B3
B4
if i >= j goto B6
B1 Dead Code Elimination
i=m-1
j=n
t1 =4 * n
v = a[t1] B5 B6
B2 a[t2] = t5 t14 = a[t1]
a[t4] = t3 a[t2] = t14
i=i +1
t2 = 4 * i goto B2 a[t1] = t3
t3 = a[t2]
if t3 < v goto B2
B3
j=j–1
t4 = 4 * j
t5 = a[t4]
if t5 > v goto B3
B4
if i >= j goto B6
B1 Reduction in Strength
i=m-1
j=n
t1 =4 * n
v = a[t1] B5 B6
B2 a[t2] = t5 t14 = a[t1]
a[t4] = t3 a[t2] = t14
i=i +1
t2 = 4 * i goto B2 a[t1] = t3
t3 = a[t2]
if t3 < v goto B2
B3
j=j–1
t4 = 4 * j
t5 = a[t4]
if t5 > v goto B3
B4
if i >= j goto B6
B1 Reduction in Strength
i=m-1
j=n
t1 =4 * n
v = a[t1] B5 B6
t2 = 4 * i
B2 a[t2] = t5 t14 = a[t1]
t4 = 4 * j
a[t4] = t3 a[t2] = t14
goto B2 a[t1] = t3
t2 = t2 + 4
t3 = a[t2]
B3 if t3 < v goto B2
t4 = t4 - 4
t5 = a[t4]
if t5 > v goto B3
B4
if i >= j goto B6