Spring 2011 CSCI 565 - Compiler Design
Spring 2011 CSCI 565 - Compiler Design
Spring 2011 CSCI 565 - Compiler Design
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
Pedro Diniz<br />
pedro@isi.edu<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
Intermediate Code Generation<br />
Basic Approach and Application to<br />
Assignment and Expressions<br />
Array Expressions<br />
Boolean Expressions<br />
<strong>Spring</strong> <strong>2011</strong><br />
Copyright <strong>2011</strong>, Pedro C. Diniz, all rights reserved.<br />
Students enrolled in the <strong>Compiler</strong>s class at the University of Southern California<br />
have explicit permission to make copies of these materials for their personal use.
Pedro Diniz<br />
pedro@isi.edu<br />
O(n)<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
Structure of a <strong>Compiler</strong><br />
O(n)<br />
words IR<br />
Scanner Parser<br />
IR IR<br />
Intermediate<br />
Code Generation<br />
O(n)<br />
O(n log n)<br />
Analysis<br />
&<br />
Optimization<br />
Code<br />
Generation<br />
<strong>Spring</strong> <strong>2011</strong><br />
A compiler is a lot of fast stuff followed by some hard problems<br />
– The hard stuff is mostly in Code Generation and Optimization<br />
– For super-scalars, its Allocation & Scheduling that counts<br />
∞<br />
regs<br />
Very Fast or Very<br />
Hard NP Complete<br />
asm<br />
k<br />
regs
Pedro Diniz<br />
pedro@isi.edu<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
Intermediate Code Generation<br />
IR IR<br />
Parse tree<br />
AST<br />
Intermediate<br />
Code Generation<br />
O(n)<br />
Three-Address<br />
Instructions<br />
∞ regs<br />
• Direct Translation<br />
– Using SDT scheme<br />
– Parse tree to Three-Address Instructions<br />
– Can be done while parsing in a single pass<br />
– Needs to be able to deal with Syntactic Errors and Recovery<br />
• Indirect Translation<br />
– First validate parsing constructing of AST<br />
– Uses SDT scheme to build AST<br />
– Traverse the AST and generate Three Address Instructions<br />
This Lecture<br />
<strong>Spring</strong> <strong>2011</strong><br />
Same but Easier
Pedro Diniz<br />
pedro@isi.edu<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
Three-Address Instructions IR<br />
<strong>Spring</strong> <strong>2011</strong><br />
• High-level Constructs mapped to Three-Address Instructions<br />
– Register-based IR for Expression Evaluation<br />
– Infinite Number of Virtual Registers<br />
– Still Independent of Target Architecture<br />
– Parameter Passing Discipline either on Stack or via Registers<br />
• Addresses and Instructions<br />
– Symbolic Names are addresses of the corresponding source-level variable.<br />
– Various constants, such as numeric and offsets (known at compile time)<br />
• Generic Instruction Format:<br />
Label: x = y op z or if exp goto L<br />
– Statements can have Symbolic Labels<br />
– <strong>Compiler</strong> inserts Temporary Variables (any variable with t prefix)<br />
– Type and Conversions dealt in other Phases of the Code Generation
Pedro Diniz<br />
pedro@isi.edu<br />
• Assignments:<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
Three-Address Instructions<br />
– x = y op z (binary operator)<br />
– x = op y (unary)<br />
– x = y (copy)<br />
– x = y[i] and x[i] = y (array indexing assignments)<br />
<strong>Spring</strong> <strong>2011</strong><br />
– x = phi y z (Static Single Assignment instruction)<br />
• Memory Operations:<br />
– x = &y; x = *y and *x = y; for assignments via pointer variables.
Pedro Diniz<br />
pedro@isi.edu<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
Three-Address Instructions<br />
• Control Transfer and Function Calls:<br />
– goto L (unconditional);<br />
– if (a relop b) goto L (conditional) where relop is a relational<br />
operator consistent with the type of the variables a and b;<br />
<strong>Spring</strong> <strong>2011</strong><br />
– y = call p, n for a function or procedure call instruction to the name<br />
or variable p<br />
• p might be a variable holding a set of possible symbolic names (a function<br />
pointer)<br />
• the value n specifies that before this call there were n putparam instructions<br />
to load the values of the arguments.<br />
• the param x instruction specifies a specific value in reverse order (i.e, the<br />
param instruction closest to the call is the first argument value.<br />
• Later we will talk about parameter passing disciplines (Run-Time Env.)
Pedro Diniz<br />
pedro@isi.edu<br />
y = p(a, b+1)<br />
int p(x,z){<br />
}<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
Function Call Example<br />
Source Code Three Address Instructions<br />
return x+z;<br />
t1 = a<br />
t2 = b + 1<br />
putparam t1<br />
putparam t2<br />
y = call p, 2<br />
p: getparam z<br />
getparam x<br />
t3 = x + z<br />
return t3<br />
return<br />
<strong>Spring</strong> <strong>2011</strong>
Pedro Diniz<br />
pedro@isi.edu<br />
y = p(a, b+1)<br />
int p(x,z){<br />
}<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
Function Call Example<br />
Source Code Three Address Instructions<br />
return x+z;<br />
argument<br />
evaluation<br />
passing args<br />
on the stack<br />
getting values<br />
from the stack<br />
t1 = a<br />
t2 = b + 1<br />
putparam t1<br />
putparam t2<br />
y = call p, 2<br />
p: getparam z<br />
getparam x<br />
t3 = x + z<br />
return t3<br />
return<br />
<strong>Spring</strong> <strong>2011</strong>
Pedro Diniz<br />
pedro@isi.edu<br />
do<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
Loop Example<br />
Source Code Three Address Instructions<br />
i = i + 1;<br />
while (a[i] < v);<br />
L: t1 = i + 1<br />
i = t1<br />
t2 = i * 8<br />
t3 = a[t2]<br />
if t3 < v goto L<br />
<strong>Spring</strong> <strong>2011</strong>
Pedro Diniz<br />
pedro@isi.edu<br />
do<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
Loop Example<br />
Source Code Three Address Instructions<br />
i = i + 1;<br />
while (a[i] < v);<br />
Where did this<br />
come from ?<br />
L: t1 = i + 1<br />
i = t1<br />
t2 = i * 8<br />
t3 = a[t2]<br />
if t3 < v goto L<br />
<strong>Spring</strong> <strong>2011</strong>
Pedro Diniz<br />
pedro@isi.edu<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
SDT to Three Address Code<br />
<strong>Spring</strong> <strong>2011</strong><br />
• Attributes for the Non-Terminals, E and S<br />
– Location (in terms of temporary variable) of the value of an expression: E.place<br />
– The Code that Evaluates the Expressions or Statement: E.code<br />
– Markers for beginning and end of sections of the code S.begin, S.end<br />
• Semantic Actions in Productions of the Grammar<br />
– Functions to create temporaries newtemp, and labels newlabel<br />
– Auxiliary functions to enter symbols and consult types corresponding to<br />
declarations in a symbol table.<br />
– Generate the code we use the emit function gen which creates a list of<br />
instructions to be emitted later and can generate symbolic labels corresponding<br />
to next instruction of a list.<br />
– Use of append function on lists of instructions.<br />
– Synthesized and Inherited Attributes
Pedro Diniz<br />
pedro@isi.edu<br />
x = a * b + c * d - e * f;<br />
S<br />
id =<br />
x<br />
*<br />
E E<br />
id<br />
a<br />
id<br />
b<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
Assignment: Example<br />
E<br />
E<br />
*<br />
E E<br />
id<br />
c<br />
E<br />
+<br />
id<br />
d<br />
E<br />
-<br />
E<br />
*<br />
E E<br />
id<br />
e<br />
id<br />
f<br />
<strong>Spring</strong> <strong>2011</strong>
Pedro Diniz<br />
pedro@isi.edu<br />
x = a * b + c * d - e * f;<br />
S<br />
id =<br />
x<br />
*<br />
E E<br />
id<br />
a<br />
id<br />
b<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
Assignment: Example<br />
E<br />
E<br />
*<br />
E E<br />
id<br />
c<br />
E<br />
+<br />
id<br />
d<br />
E<br />
-<br />
Production:<br />
E<br />
*<br />
E E<br />
id<br />
e<br />
id<br />
f<br />
<strong>Spring</strong> <strong>2011</strong><br />
E → id { p = lookup(id.name);<br />
}<br />
if (p != NULL)<br />
else<br />
E.place = p;<br />
error;<br />
E.code = null list;
Pedro Diniz<br />
pedro@isi.edu<br />
x = a * b + c * d - e * f;<br />
S<br />
id =<br />
x<br />
*<br />
E E<br />
id<br />
a<br />
id<br />
b<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
Assignment: Example<br />
E<br />
E<br />
*<br />
E E<br />
id<br />
c<br />
E<br />
+<br />
id<br />
d<br />
E<br />
-<br />
Production:<br />
E<br />
*<br />
E place = loc(e) E place = loc(f)<br />
id<br />
e<br />
id<br />
f<br />
<strong>Spring</strong> <strong>2011</strong><br />
E → id { p = lookup(id.name);<br />
code = null<br />
}<br />
if (p != NULL)<br />
else<br />
E.place = p;<br />
error;<br />
E.code = null list;<br />
code = null
Pedro Diniz<br />
pedro@isi.edu<br />
x = a * b + c * d - e * f;<br />
S<br />
id =<br />
x<br />
E * E<br />
id<br />
a<br />
id<br />
b<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
Assignment: Example<br />
E<br />
id<br />
c<br />
E<br />
E + E<br />
E<br />
*<br />
id<br />
d<br />
E<br />
-<br />
E<br />
E * E<br />
id<br />
e<br />
id<br />
f<br />
t1 = e * f;<br />
t2 = c * d;<br />
t3 = t2 - t1;<br />
t4 = a * b;<br />
t5 = t4 + t3;<br />
x = t5;<br />
<strong>Spring</strong> <strong>2011</strong>
Pedro Diniz<br />
pedro@isi.edu<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
Reusing Temporary Variables<br />
• Temporary Variables<br />
– Short lived<br />
– Used for Evaluation of Expressions<br />
– Clutter the Symbol Table<br />
• Change the newtemp Function<br />
– Keep track of when a value created in a temporary is used<br />
– Use a counter to keep track of the number of active temporaries<br />
– When a temporary is used in an expression decrement counter<br />
– When a temporary is generated by newtemp increment counter<br />
– Initialize counter to zero (0)<br />
• Alternatively, can be done as a post-processing pass…<br />
<strong>Spring</strong> <strong>2011</strong>
Pedro Diniz<br />
pedro@isi.edu<br />
x = a * b + c * d - e * f;<br />
S<br />
id =<br />
x<br />
E * E<br />
id<br />
a<br />
id<br />
b<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
Assignment: Example<br />
E<br />
id<br />
c<br />
E<br />
E + E<br />
E<br />
*<br />
id<br />
d<br />
E<br />
-<br />
E<br />
E * E<br />
id<br />
e<br />
id<br />
f<br />
<strong>Spring</strong> <strong>2011</strong><br />
// c = 0<br />
t1 = e * f; // c = 1<br />
t2 = c * d; // c = 2<br />
t1 = t2 - t1; // c = 1<br />
t2 = a * b; // c = 2<br />
t1 = t2 + t1; // c = 1<br />
x = t1; // c = 0<br />
• Only 2 Temporary Variables and<br />
hence only 2 registers are Needed
Pedro Diniz<br />
pedro@isi.edu<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
Code Generation for Array Accesses<br />
…<br />
x = A[y,z];<br />
…<br />
id<br />
A<br />
S<br />
L = E<br />
id L<br />
x<br />
Elist<br />
[ E<br />
L<br />
id<br />
y<br />
Elist<br />
,<br />
E<br />
L<br />
id<br />
z<br />
]<br />
?<br />
• Questions:<br />
– What is the Base Type of A?<br />
– What are the Dimensions of A?<br />
• Answers:<br />
– Use Symbol Table<br />
– Check Array Layout<br />
t1 = y * 20<br />
t1 = t1 * z<br />
t2 = baseA - 84<br />
t3 = 4 * t1<br />
t4 = t2[t3]<br />
X = t4<br />
<strong>Spring</strong> <strong>2011</strong>
Pedro Diniz<br />
pedro@isi.edu<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
<strong>Spring</strong> <strong>2011</strong><br />
How does the <strong>Compiler</strong> Handle A[i,j] ?<br />
First, must agree on a storage scheme<br />
Row-major order (most languages)<br />
Lay out as a sequence of consecutive rows<br />
Rightmost subscript varies fastest<br />
A[1,1], A[1,2], A[1,3], A[2,1], A[2,2], A[2,3]<br />
Column-major order (Fortran)<br />
Lay out as a sequence of columns<br />
Leftmost subscript varies fastest<br />
A[1,1], A[2,1], A[1,2], A[2,2], A[1,3], A[2,3]<br />
Indirection vectors (Java)<br />
Vector of pointers to pointers to … to values<br />
Takes much more space, trades indirection for arithmetic<br />
Not amenable to analysis
Pedro Diniz<br />
pedro@isi.edu<br />
The Concept<br />
A<br />
Row-major order<br />
A<br />
Column-major order<br />
A<br />
Indirection vectors<br />
A<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
Laying Out Arrays<br />
1,1 1,2 1,3 1,4<br />
2,1 2,2 2,3 2,4<br />
1,1 1,2 1,3 1,4 2,1 2,2 2,3 2,4<br />
1,1 2,1 1,2 2,2 1,3 2,3 1,4 2,4<br />
1,1 1,2 1,3 1,4<br />
2,1 2,2 2,3 2,4<br />
<strong>Spring</strong> <strong>2011</strong><br />
These have distinct &<br />
different cache behavior
Pedro Diniz<br />
pedro@isi.edu<br />
A[ i ]<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
Computing an Array Address<br />
<strong>Spring</strong> <strong>2011</strong><br />
• baseA + ( i – low ) x sizeof(baseType(A))<br />
• In general: base(A) + ( i – low ) x sizeof(baseType(A))
Pedro Diniz<br />
pedro@isi.edu<br />
A[ i ]<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
Computing an Array Address<br />
<strong>Spring</strong> <strong>2011</strong><br />
• baseA + ( i – low ) x sizeof(baseType(A))<br />
• In general: base(A) + ( i – low ) x sizeof(baseType(A))<br />
Almost always a power of 2,<br />
known at compile-time and<br />
use a shift for speed<br />
int A[1:10] where low is 1; Make low 0<br />
for faster access (saves a – ) as in the C<br />
language
Pedro Diniz<br />
pedro@isi.edu<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
Computing an Array Address<br />
A[ i ]<br />
• baseA + ( i – low ) x sizeof(baseType(A))<br />
• In general: base(A) + ( i – low ) x sizeof(baseType(A))<br />
<strong>Spring</strong> <strong>2011</strong><br />
What about A[i1 ,i2 ] ?<br />
This stuff looks expensive!<br />
Lots of implicit +, -, x ops<br />
Row-major order, two dimensions<br />
baseA + (( i1 – low1 ) x (high2 – low2 + 1) + i2 – low2 ) x sizeof(baseType(A))<br />
Column-major order, two dimensions<br />
baseA + (( i 2 – low 2 ) x (high 1 – low 1 + 1) + i 1 – low 1 ) x sizeof(baseType(A))<br />
Indirection vectors, two dimensions<br />
*(A[i 1 ])[i 2 ] — where A[i 1 ] is, itself, a 1-d array reference
Pedro Diniz<br />
pedro@isi.edu<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
where w = sizeof(baseType(A))<br />
<strong>Spring</strong> <strong>2011</strong><br />
Optimizing Address Calculation for A[i,j]<br />
In row-major order<br />
baseA + (i–low 1 )(high 2 –low 2 +1) x w + (j – low 2 ) x w<br />
Which can be factored into<br />
baseA + i x (high 2 –low 2 +1) x w + j x w<br />
– (low 1 x (high 2 –low 2 +1) x w) + (low 2 x w)<br />
If low i , high i , and w are known, the last term is a constant<br />
Define baseA 0 as<br />
baseA – (low 1 x (high 2 –low 2 +1)) x w + low 2 x w<br />
and len 2 as (high 2 -low 2 +1)<br />
Then, the address expression becomes<br />
baseA 0 + (i x len 2 + j ) x w<br />
Compile-time constants
Pedro Diniz<br />
pedro@isi.edu<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
Address Calculation for A[i 1 ,i 2 ,…,i k ]<br />
• A[i 1 ,i 2 ,…,i k ]<br />
Addressing generalizes to<br />
((…((i 1 n 2 +i 2 )n 3 +i 3 )…)n k +i k ) x w +<br />
+baseA - ((…((low 1 n 2 +low 2 )n 3 +low 3 )…)m k +low k ) x w<br />
where n j = high j - low j + 1 and w = sizeof(baseType(A))<br />
First term can be computed using the recurrence<br />
e 1 = i 1<br />
e m = e m-1 x n m + i m<br />
at the end multiply by w and add compile-time constant term<br />
<strong>Spring</strong> <strong>2011</strong><br />
Compile-time constants
Pedro Diniz<br />
pedro@isi.edu<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
<strong>Spring</strong> <strong>2011</strong><br />
SDT for Addressing Arrays Elements<br />
• Three Attributes<br />
– place: just the name or base address of the array<br />
– offset: the index value into the array<br />
– ndim: the number of dimensions<br />
• Use the Recurrence to Compute Offset<br />
offset 1 = i 1<br />
offset m = offset m-1 x n m + i m<br />
– At the end multiply by w = sizeof(baseType(A))<br />
– Add the compile-time constant term<br />
– Keep track of which dimension at each level<br />
– Use the auxiliary function n m = numElem(A,m) as the number of<br />
elements along the m th dimension of A
Pedro Diniz<br />
pedro@isi.edu<br />
E → L { if (L.offset = NULL) then<br />
}<br />
else<br />
E.place = L.place;<br />
E.place = newtemp;<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
E.code = gen(E.place = L.place[L.offset]);<br />
S → L = E { if L.offset = NULL then<br />
}<br />
else<br />
E.code = gen(L.place = E.place);<br />
S.code = append(E.code,gen(L.place[L.offset] = E.place);<br />
L → id { L.place = id.place;<br />
}<br />
L.offset = null;<br />
<strong>Spring</strong> <strong>2011</strong><br />
SDT for Addressing Arrays Elements
Pedro Diniz<br />
pedro@isi.edu<br />
x = A[y,z];<br />
L<br />
x<br />
A<br />
S<br />
=<br />
Elist<br />
Elist , E<br />
[<br />
E<br />
L<br />
y<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
A is 10 x 20 array with low 1 = low 2 = 1<br />
sizeof(baseType(A)) = sizeof(int) = 4 bytes<br />
L<br />
z<br />
E<br />
L<br />
]<br />
<strong>Spring</strong> <strong>2011</strong><br />
SDT for Addressing Arrays Elements
Pedro Diniz<br />
pedro@isi.edu<br />
x = A[y,z];<br />
L.place = x<br />
L.offset = null<br />
x<br />
A<br />
S<br />
=<br />
Elist.place = y<br />
Elist.ndim = 1<br />
Elist.array = A<br />
[<br />
Elist.place = t1<br />
Elist.ndim = 2<br />
Elist.array = A<br />
E.place = y<br />
L.place = y<br />
y<br />
,<br />
L.offset = null<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
E.place = z<br />
L.place = z<br />
L.offset = null<br />
z<br />
E.place = t4<br />
L.place = t2<br />
L.offset = t3<br />
]<br />
<strong>Spring</strong> <strong>2011</strong><br />
SDT for Addressing Arrays Elements<br />
A is 10 x 20 array with low 1 = low 2 = 1<br />
sizeof(baseType(A)) = sizeof(int) = 4 bytes<br />
t1 = y * 20 // numElem(A,2) = 20<br />
t1 = t1 + z // E.place is z<br />
t2 = c // c = base(A) - (20+1)*4<br />
t3 = t1 * 4 // sizeof(int) = 4<br />
t4 = t2[t3]<br />
x = t4<br />
See page 383-384 of the textbook for an alternative approach
Pedro Diniz<br />
pedro@isi.edu<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
Array References<br />
What about arrays as actual parameters?<br />
Whole arrays, as call-by-reference parameters<br />
• Need dimension information ⇒ build a dope vector<br />
• Store the values in the calling sequence<br />
• Pass the address of the dope vector in the parameter slot<br />
• Generate complete address polynomial at each reference<br />
Some improvement is possible<br />
• Save len i and low i rather than low i and high i<br />
• Pre-compute the fixed terms in prologue sequence<br />
What about call-by-value?<br />
• Most call-by-value languages pass arrays by reference<br />
• This is a language design issue<br />
<strong>Spring</strong> <strong>2011</strong><br />
baseA<br />
low 1<br />
high 1<br />
low 2<br />
high 2
Pedro Diniz<br />
pedro@isi.edu<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
Array References<br />
What about Variable-Sized Arrays?<br />
Local arrays dimensioned by actual parameters<br />
• Same set of problems as parameter arrays<br />
• Requires dope vectors (or equivalent)<br />
– dope vector at fixed offset in activation record<br />
⇒ Different access costs for textually similar references<br />
This presents a lot of opportunity for a good optimizer<br />
• Common sub-expressions in the address polynomial<br />
• Contents of dope vector are fixed during each activation<br />
• Should be able to recover much of the lost ground<br />
⇒ Handle them like parameter arrays<br />
<strong>Spring</strong> <strong>2011</strong>
Pedro Diniz<br />
pedro@isi.edu<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
Array Address Calculations in a Loop<br />
DO J = 1, N<br />
A[I,J] = A[I,J] + B[I,J]<br />
END DO<br />
• Naïve: Perform the address calculation twice<br />
DO J = 1, N<br />
R1 = baseA 0 + (J x len 1 + I ) x floatsize<br />
R2 = baseB 0 + (J x len 1 + I ) x floatsize<br />
MEM(R1) = MEM(R1) + MEM(R2)<br />
END DO<br />
<strong>Spring</strong> <strong>2011</strong>
Pedro Diniz<br />
pedro@isi.edu<br />
DO J = 1, N<br />
A[I,J] = A[I,J] + B[I,J]<br />
END DO<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
• Sophisticated: Move common calculations out of loop<br />
R1 = I x floatsize<br />
c = len 1 x floatsize ! Compile-time constant<br />
R2 = baseA 0 + R1<br />
R3 = baseB 0 + R1<br />
DO J = 1, N<br />
a = J x c<br />
R4 = R2 + a<br />
R5 = R3 + a<br />
MEM(R4) = MEM(R4) + MEM(R5)<br />
END DO<br />
<strong>Spring</strong> <strong>2011</strong><br />
Array Address Calculations in a Loop
Pedro Diniz<br />
pedro@isi.edu<br />
DO J = 1, N<br />
A[I,J] = A[I,J] + B[I,J]<br />
END DO<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
• Very sophisticated: Convert multiply to add (Operator Strength Reduction)<br />
R1 = I x floatsize<br />
c = len 1 x floatsize ! Compile-time constant<br />
R2 = baseA 0 + R1 ; R3 = baseB 0 + R1<br />
DO J = 1, N<br />
R2 = R2 + c<br />
R3 = R3 + c<br />
MEM(R2) = MEM(R2) + MEM(R3)<br />
END DO<br />
<strong>Spring</strong> <strong>2011</strong><br />
Array Address Calculations in a Loop
Pedro Diniz<br />
pedro@isi.edu<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
<strong>Spring</strong> <strong>2011</strong><br />
Arithmetic Scheme: Grammar and Actions<br />
E → false ‖ E.place = newtemp()<br />
E.code = {gen(E.place = 0)}<br />
E.laststat = E.nextstat + 1<br />
E → true ‖ E.place = newtemp()<br />
E.code = {gen(E.place = 1)}<br />
E.laststat = E.nextstat + 1<br />
E → (E 1 ) ‖ E.place = E 1 .place;<br />
E.code = E 1 .code;<br />
E 1 .nextstat = E.nextstat<br />
E.laststat = E 1 .laststat<br />
E → not E 1 ‖ E.place = newtemp()<br />
E.code = append(E 1 .code,gen(E.place = not E 1 .place))<br />
E 1 .nextstat = E.nextstat<br />
E.laststat = E 1 .laststat + 1
Pedro Diniz<br />
pedro@isi.edu<br />
E → E 1 or E 2 ‖ E.place = newtemp()<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
<strong>Spring</strong> <strong>2011</strong><br />
Arithmetic Scheme: Grammar and Actions<br />
E.code = append(E 1 .code,E 2 .code,gen(E.place = E 1 .place or E 2 .place)<br />
E 1 .nextstat = E.nexstat<br />
E 2 .nextstat = E 1 .laststat<br />
E.laststat = E 2 .laststat + 1<br />
E → E 1 and E 2 ‖ E.place = newtemp()<br />
E.code = append(E 1 .code,E 2 .code,gen(E.place = E 1 .place and E 2 .place)<br />
E 1 .nextstat = E.nexstat<br />
E 2 .nextstat = E 1 .laststat<br />
E.laststat = E 2 .laststat + 1<br />
E → id 1 relop id 2 ‖ E.place = newtemp()<br />
E.code = gen(if id1.place relop id2.place goto E.nextstat+3)<br />
E.code = append(E.code,gen(E.place = 0))<br />
E.code = append(E.code,gen(goto E.nextstat+2))<br />
E.code = append(E.code,gen(E.place = 1))<br />
E.laststat = E.nextstat + 4
Pedro Diniz<br />
pedro@isi.edu<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
Boolean Expressions: Example<br />
a < b or c < d and e < f<br />
E<br />
id relop id<br />
a < b<br />
E<br />
or<br />
E<br />
id relop id<br />
E<br />
and<br />
E<br />
id relop id<br />
c < d e < f<br />
00: if a < b goto 03<br />
01: t1 = 0<br />
02: goto 04<br />
03: t1 = 1<br />
04: if c < d goto 07<br />
05: t2 = 0<br />
06: goto 08<br />
07: t2 = 1<br />
08: if e < f goto 11<br />
09: t3 = 0<br />
10: goto 12<br />
11: t3 = 1<br />
12: t4 = t2 and t3<br />
13: t5 = t1 or t4<br />
<strong>Spring</strong> <strong>2011</strong>
Pedro Diniz<br />
pedro@isi.edu<br />
<strong>CSCI</strong> <strong>565</strong> - <strong>Compiler</strong> <strong>Design</strong><br />
Summary<br />
• Intermediate Code Generation<br />
– Using Syntax-Directed Translation Schemes<br />
– Expressions and Assignments<br />
– Array Expressions and Array References<br />
– Boolean Expressions (Arithmetic Scheme)<br />
<strong>Spring</strong> <strong>2011</strong>