20.04.2013 Views

Spring 2011 CSCI 565 - Compiler Design

Spring 2011 CSCI 565 - Compiler Design

Spring 2011 CSCI 565 - Compiler Design

SHOW MORE
SHOW LESS

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>

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!