Download presentation
Presentation is loading. Please wait.
1
Cse322, Programming Languages and Compilers 1 6/14/2015 Lecture #3, April 11, 2007 Boolean expressions Positional encoding Short circuit evaluation Conditional move Array expressions
2
Cse322, Programming Languages and Compilers 2 6/14/2015 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.
3
Cse322, Programming Languages and Compilers 3 6/14/2015 Boolean Expressions Boolean expressions can be treated just like arithmetic expressions. –Need to represent True and False, some possibilities »False = 0000 n True = 0001 n »False = 0000 n True = 1111 n 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.
4
Cse322, Programming Languages and Compilers 4 6/14/2015 By example We will illustrate this by example 1.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.Approaches 1.Numerical encoding 1.Register based boolean operators 1.cmp_LT rx,ry => ra 2.Conditional Branches and condition codes 1.Comp rx,ry => cc1 2.Positional Encoding 3.Short Circuit evaluation
5
Cse322, Programming Languages and Compilers 5 6/14/2015 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)
6
Cse322, Programming Languages and Compilers 6 6/14/2015 Register based boolean encodings fun 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
7
Cse322, Programming Languages and Compilers 7 6/14/2015 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;
8
Cse322, Programming Languages and Compilers 8 6/14/2015 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;
9
Cse322, Programming Languages and Compilers 9 6/14/2015 Managing Labels We 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
10
Cse322, Programming Languages and Compilers 10 6/14/2015 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
11
Cse322, Programming Languages and Compilers 11 6/14/2015 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;
12
Cse322, Programming Languages and Compilers 12 6/14/2015 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
13
Cse322, Programming Languages and Compilers 13 6/14/2015 | 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,L2 L1: loadI true => r5 jumpI -> L3 L2: loadI false => r5 jumpI -> L3 L3: nop
14
Cse322, Programming Languages and Compilers 14 6/14/2015 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
15
Cse322, Programming Languages and Compilers 15 6/14/2015 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,L2 L1: loadI true => r5 jumpI -> L3 L2: loadI false => r5 jumpI -> L3 L3: 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,L5 L4: loadI true => r10 jumpI -> L6 L5: loadI false => r10 jumpI -> L6 L6: 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,L8 L7: loadI true => r15 jumpI -> L9 L8: loadI false => r15 jumpI -> L9 L9: nop And r10,r15 => r16 Or r5,r16 => r17 a<b or c<d and e<f
16
Cse322, Programming Languages and Compilers 16 6/14/2015 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
17
Cse322, Programming Languages and Compilers 17 6/14/2015 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
18
Cse322, Programming Languages and Compilers 18 6/14/2015 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
19
Cse322, Programming Languages and Compilers 19 6/14/2015 compare & fillRelSlots fun 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;
20
Cse322, Programming Languages and Compilers 20 6/14/2015 Short Circuit Evaluation loadI @a => r2 loadAO rA,r2 => r3 loadI @b => r4 loadAO rA,r4 => r5 L1: comp r3,r5 => cc1 cbr_Lt cc1 -> L2,L5 L5: loadI @c => r6 loadAO rA,r6 => r7 loadI @d => r8 loadAO rA,r8 => r9 comp r7,r9 => cc2 cbr_Lt cc2 -> L6,L3 L6: loadI @e => r10 loadAO rA,r10 => r11 loadI @f => r12 loadAO rA,r12 => r13 comp r11,r13 => cc3 cbr_Lt cc3 -> L2,L3 L2: loadI true => r1 jumpI -> L4 L3: loadI false => r1 jumpI -> L4 L4: nop a<b or c<d and e<f
21
Cse322, Programming Languages and Compilers 21 6/14/2015 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
22
Cse322, Programming Languages and Compilers 22 6/14/2015 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;
23
Cse322, Programming Languages and Compilers 23 6/14/2015 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
24
Cse322, Programming Languages and Compilers 24 6/14/2015 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)
25
Cse322, Programming Languages and Compilers 25 6/14/2015 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] 231422 X = 2341 X[0] = 2341 x[3] = 2341 + 3
26
Cse322, Programming Languages and Compilers 26 6/14/2015 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
27
Cse322, Programming Languages and Compilers 27 6/14/2015 1 dimensional Non zero indexing Array [ low.. High ] Address x[y] = address x + y - low
28
Cse322, Programming Languages and Compilers 28 6/14/2015 1 dimensional non unit size Array [ 0.. n ] of Float // where float = size bytes Address x[y] = address x + y * size
29
Cse322, Programming Languages and Compilers 29 6/14/2015 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
30
Cse322, Programming Languages and Compilers 30 6/14/2015 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)
31
Cse322, Programming Languages and Compilers 31 6/14/2015 Lets work out the formula Array[ l1..h1; l2..h2 ]
32
Cse322, Programming Languages and Compilers 32 6/14/2015 Assignment #2 CS322 Prog Lang & Compilers Prog Assignment #2 Assigned 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.
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.