cse322, programming languages and compilers 1 6/14/2015 lecture #3, april 11, 2007 boolean...
Post on 19-Dec-2015
228 views
TRANSCRIPT
Cse322, Programming Languages and Compilers
104/18/23
Lecture #3, April 11, 2007• Boolean expressions•Positional encoding•Short circuit evaluation•Conditional move•Array expressions
Cse322, Programming Languages and Compilers
204/18/23
Assignments
• Reading– Read chapter 7 sections 7.6 7.7 and 7.8
– Possible Quiz Wednesday on the reading.
• Programming assignment #2 is now available on the class website under the assignments link.
•
Cse322, Programming Languages and Compilers
304/18/23
Boolean Expressions• Boolean expressions can be treated just like
arithmetic expressions.– Need to represent True and False, some possibilities
» False = 0000n True = 0001n
» False = 0000n True = 1111n for a n-bit representations
• Some machines have special instructions for manipulating booleans in addition to boolean operations– Special hardware called the condition code
» One to several bits (pattern encodes the conditions LT, GT etc)
» Set by arithmetic and boolean operations» Special instructions that interrogate the condition code
• Some compilers use an implicit representation using the location of the program counter to encode True or False.
Cse322, Programming Languages and Compilers
404/18/23
By example
• We will illustrate this by example1. Add new instructions to our IR
2. Translate code from CS321 expressions into the new IR instructions
3. Illustrate the approaches by defining a different translation for each approach.
1. Approaches1. Numerical encoding
1. Register based boolean operators1. cmp_LT rx,ry => ra
2. Conditional Branches and condition codes1. Comp rx,ry => cc1
2. Positional Encoding
3. Short Circuit evaluation
Cse322, Programming Languages and Compilers
504/18/23
New IR instruction
type Reg = int;
type Label = int;
type CC = int;
datatype IR
= LoadI of (string * Reg)
| LoadAO of (Reg * Reg * Reg)
| Arith of (BINOP * Reg * Reg * Reg)
| Comp of (Reg * Reg * CC)
Cse322, Programming Languages and Compilers
604/18/23
Register based boolean encodingsfun expr dict node =
case node of
| Binop(m,x,y) =>
let val t1 = expr dict x
val t2 = expr dict y
val result = NextRegister()
in emit (Arith(m,t1,t2,result));
result
end
| Relop(m,x,y) =>
let val rx = expr dict x
val ry = expr dict y
val r2 = NextRegister()
in emit (Cmp(m,rx,ry,r2))
Notice the similarity between arithmetic and
relational operators, Depends upon machine
operations that leave boolean values in
registers
Cse322, Programming Languages and Compilers
704/18/23
New Concepts
1. Condition codes– type CC = int;– fun showCC n = "cc"^Int.toString n;
2. Labels– type Label = int;– fun showLab n = "L"^Int.toString n;
Cse322, Programming Languages and Compilers
804/18/23
Managing Condition Codes
val firstCC = 1;
val CCCount = ref firstCC;
fun resetCC () = CCCount := firstCC;
fun NextCC() =
let val n = !CCCount
in (CCCount := n+1; n) end;
Cse322, Programming Languages and Compilers
904/18/23
Managing LabelsWe often generate multiple labels all at once.
val firstLabel = 1;
val LabelCount = ref firstLabel;
fun resetLabel () = LabelCount := firstLabel;
fun NextLabel m =
let val n = !LabelCount
fun f n 0 = []
| f n m = n :: (f (n+1) (m-1))
in (LabelCount := n+m; f n m) end;
- NextLabel 4;val it = [10,11,12,13] : int list
Cse322, Programming Languages and Compilers
1004/18/23
Emitting labeled code• fun emitAt l x = emit(Lab(l,x));
emit (Comp(rx,ry,cc));
emit (Cbr(LT,cc,l1,l2);
emitAt l1 (LoadI("true",r2));
emit (JumpI l3);
emitAt l2 (LoadI("false",r2));
emit (JumpI l3);
emitAt l3 Nop
Cse322, Programming Languages and Compilers
1104/18/23
Additions to the IR
datatype IR
= LoadI of (string * Reg)
| LoadAO of (Reg * Reg * Reg)
| Arith of (Op * Reg * Reg * Reg)
| Cmp of (Op * Reg * Reg * Reg)
| Comp of (Reg * Reg * CC)
| Neg of (Reg * Reg)
| Cbr of ( RELOP * CC * Label * Label)
| JumpI of Label
| Lab of (Label * IR)
| Nop;
Cse322, Programming Languages and Compilers
1204/18/23
Condition codes• Operations set special hardware called condition
codes.• Some operations depend upon condition codes.
loadI @x => r1
loadAO rA,r1 => r2
loadI @y => r3
loadAO rA,r3 => r4
comp r2,r4 => cc1
cbr_Lt cc1 -> L1,L2
L1: loadI true => r5
jumpI -> L3
L2: loadI false => r5
jumpI -> L3
L3: nop
Conditional branch.L1 and L2 are labels
Cse322, Programming Languages and Compilers
1304/18/23
| Relop(m,x,y) => let val rx = expr dict x val ry = expr dict y val r2 = NextRegister() val cc = NextCC() val [l1,l2,l3] = NextLabel 3 in emit (Comp(rx,ry,cc)); emit (Cbr(m,cc,l1,l2)); emitAt l1 (LoadI("true",r2)); emit (JumpI l3); emitAt l2 (LoadI("false",r2)); emit (JumpI l3); emitAt l3 Nop r2 end
loadI @x => r1 loadAO rA,r1 => r2 loadI @y => r3 loadAO rA,r3 => r4 comp r2,r4 => cc1 cbr_Lt cc1 -> L1,L2L1: loadI true => r5 jumpI -> L3L2: loadI false => r5 jumpI -> L3L3: nop
Cse322, Programming Languages and Compilers
1404/18/23
Choosing between a style| Relop(m,x,y) => let val rx = expr dict x val ry = expr dict y val r2 = NextRegister() in (case !style of Numerical => emit (Cmp(m,rx,ry,r2)) | CondCode => let val cc = NextCC() val [l1,l2,l3] = NextLabel 3 in emit (Comp(rx,ry,cc)); emit (Cbr(m,cc,l1,l2)); emitAt l1 (LoadI("true",r2)); emit (JumpI l3); emitAt l2 (LoadI("false",r2)); emit (JumpI l3); emitAt l3 Nop end); r2 end
Cse322, Programming Languages and Compilers
1504/18/23
loadI @a => r1 loadAO rA,r1 => r2 // r2=a loadI @b => r3 loadAO rA,r3 => r4 // r4=b comp r2,r4 => cc1 // a<b cbr_Lt cc1 -> L1,L2L1: loadI true => r5 jumpI -> L3L2: loadI false => r5 jumpI -> L3L3: nop loadI @c => r6 loadAO rA,r6 => r7 // r7=c loadI @d => r8 loadAO rA,r8 => r9 // r9=d comp r7,r9 => cc2 // c<d cbr_Lt cc2 -> L4,L5L4: loadI true => r10 jumpI -> L6L5: loadI false => r10 jumpI -> L6L6: nop loadI @e => r11 loadAO rA,r11 => r12 // r11=e loadI @f => r13 loadAO rA,r13 => r14 // r14=f comp r12,r14 => cc3 // e<f cbr_Lt cc3 -> L7,L8L7: loadI true => r15 jumpI -> L9L8: loadI false => r15 jumpI -> L9L9: nop And r10,r15 => r16 Or r5,r16 => r17
a<b or
c<d and
e<f
Cse322, Programming Languages and Compilers
1604/18/23
Positional Rather than load a boolean into a register use the position in the
code to indicate the result of the test.
loadI @x => r1
loadAO rA,r1 => r2
loadI @y => r3
loadAO rA,r3 => r4
comp r2,r4 => cc1
cbr_Lt cc1 -> L1,L2
L1: ____cc1 is true here__
jumpI -> L3
L2: ___cc1 is false here__
jumpI -> L3
L3: nop
Cse322, Programming Languages and Compilers
1704/18/23
Use functions as parameters
• Suppose we were translating– if x<y then z := 0 else z := z+1
loadI @x => r1 loadAO rA,r1 => r2
loadI @y => r3
loadAO rA,r3 => r4
comp r2,r4 => cc1
cbr_Lt cc1 -> L1,L2
L1: ____ z := 0 here__ jumpI -> L3
L2: ___ z := z+1 here__ jumpI -> L3
L3: nop
Cse322, Programming Languages and Compilers
1804/18/23
Break translation into 2 parts| Relop(m,x,y) => let val rx = expr dict x val ry = expr dict y val r2 = NextRegister() in (case !style of Positional => let val [trueL,falseL] = NextLabel 2 in compare m rx ry trueL falseL; fillRelSlot trueL (fn () => emit (LoadI("true",r2))) falseL (fn () => emit (LoadI("false",r2))) end );
emits comparison
code
Cse322, Programming Languages and Compilers
1904/18/23
compare & fillRelSlotsfun compare oper rx ry trueL falseL = let val cc = NextCC() in emit (Comp(rx,ry,cc)); emit (Cbr(oper,cc,trueL,falseL)) end;
fun fillRelSlot trueL truef falseL falsef = let val [resultL] = NextLabel 1 in tag trueL truef; emit (JumpI resultL); tag falseL falsef; emit (JumpI resultL); emitAt resultL Nop end;
Cse322, Programming Languages and Compilers
2004/18/23
Short Circuit Evaluation loadI @a => r2 loadAO rA,r2 => r3 loadI @b => r4 loadAO rA,r4 => r5L1: comp r3,r5 => cc1 cbr_Lt cc1 -> L2,L5L5: loadI @c => r6 loadAO rA,r6 => r7 loadI @d => r8 loadAO rA,r8 => r9 comp r7,r9 => cc2 cbr_Lt cc2 -> L6,L3L6: loadI @e => r10 loadAO rA,r10 => r11 loadI @f => r12 loadAO rA,r12 => r13 comp r11,r13 => cc3 cbr_Lt cc3 -> L2,L3L2: loadI true => r1 jumpI -> L4L3: loadI false => r1 jumpI -> L4L4: nop
a<b or
c<d and
e<f
Cse322, Programming Languages and Compilers
2104/18/23
Coding it up
fun short dict (Relop(m,x,y)) start trueL falseL = let val _ = emitAt start Nop val rx = expr dict x val ry = expr dict y val cc = NextCC() in emit (Comp(rx,ry,cc)); emit (Cbr(m,cc,trueL,falseL)) end | short dict (Binop(AND,r1,r2)) start trueL falseL = let val [start2] = NextLabel 1 in short dict r1 start start2 falseL; short dict r2 start2 trueL falseL end | short dict (Binop(OR,r1,r2)) start trueL falseL = let val [start2] = NextLabel 1 in short dict r1 start trueL start2; short dict r2 start2 trueL falseL end
Cse322, Programming Languages and Compilers
2204/18/23
Driving short
fun shortCircuit dict exp =
let val [start,l1,l2,l3] = NextLabel 4
val r2 = NextRegister()
in short dict exp start l1 l2;
emitAt l1 (LoadI("true",r2));
emit (JumpI l3);
emitAt l2 (LoadI("false",r2));
emit (JumpI l3);
emitAt l3 Nop;
r2
end;
Cse322, Programming Languages and Compilers
2304/18/23
Incorporation into expr
fun expr dict node =
case node of
Binop(AND,_,_) => shortCircuit dict node
| Binop(OR,_,_) => shortCircuit dict node
| Binop(m,x,y) =>
let val t1 = expr dict x
val t2 = expr dict y
val result = NextRegister()
in emit (Arith(m,t1,t2,result));
result
end
Cse322, Programming Languages and Compilers
2404/18/23
Conditional Move
• Some machines have conditional move instructions– Mov_GT cc,r1,r2, => r3
• Mostly we use these to avoid branching or jumps– if x<y then a <- c+d else a <- e+f
– comp rx,ry => cc1– add rc,rd => r1– add re,rf => r2– mov_LT cc1,r1,r2 => ra
• Note the speculative evaluation (we need only one of the branches)
Cse322, Programming Languages and Compilers
2504/18/23
Array Access
• Arrays addresses have two components– Base
– Offset
• For 1-dimensional, zero-based arrays, with elements of 1 byte things are straight forward.
• X[3]
23 14 2 2
X = 2341
X[0] = 2341 x[3] = 2341 + 3
Cse322, Programming Languages and Compilers
2604/18/23
1 dimensional address calculation
• X[y]
• Address of x[y] = address of x + y
loadI @y => r1
loadA0 ra,r1 => r1
loadI @x => r2
add r1,r2 => r3
load r3 => r4
Cse322, Programming Languages and Compilers
2704/18/23
1 dimensional Non zero indexing
• Array [ low .. High ]
• Address x[y] = address x + y - low
Cse322, Programming Languages and Compilers
2804/18/23
1 dimensional non unit size
• Array [ 0 .. n ] of Float // where float = size bytes
• Address x[y] = address x + y * size
Cse322, Programming Languages and Compilers
2904/18/23
Combined
• Array [ low .. High ] of Float // where float = size bytes
• Address x[y] = address x + (y – low) * size
• Optimization
• Address x[y] = address x + (y * size) – (low * size)
• Address x[y] = address x – (low * size) + (y * size) Perhaps this is known
at compile-time?
Performed with a shift if size is a power of 2
Cse322, Programming Languages and Compilers
3004/18/23
2 dimensional arrays
• Array[1..2; 2..3]
• Row major
• Column major
(1,2) (1,3) (2,2) (2,3)
(1,2) (2,2) (1,3) (2,3)
(1,2) (1,3)
(2,2) (2,3)
Cse322, Programming Languages and Compilers
3104/18/23
Lets work out the formula
• Array[ l1..h1; l2..h2 ]
Cse322, Programming Languages and Compilers
3204/18/23
Assignment #2CS322 Prog Lang & Compilers Prog Assignment #2Assigned Monday April 10, 2006. Due Wednesday, April 12, 2006
• This assignment is to extend the expr program discussed in class• (and available for download) so that it can translate array
accesses, where the array is a variable: i.e. x[34+j]
• fun expr dict (ArrayElm(Var(loc,nm),index,SOME typ)) = . . .
• See the assignment directory for for details.