200 likes | 350 Views
Lecture 22 Code Generation. CSCE 531 Compiler Construction. Topics Arrays Code Generation Readings: 9. April 10, 2006. Overview. Last Time – Lec21 slides 1-15, 29-35 Array indexing Test 2 - review Test 2 - (7:15 PM 300Main B213) Today’s Lecture
E N D
Lecture 22 Code Generation CSCE 531 Compiler Construction • Topics • Arrays • Code Generation • Readings: 9 April 10, 2006
Overview • Last Time – Lec21 slides 1-15, 29-35 • Array indexing • Test 2 - review • Test 2 - (7:15 PM 300Main B213) • Today’s Lecture • Finishing touches on Arrays in expressions • Project 5 - Code Generation • References: Chapter 9
Optimization levels • man gcc • Page of optimization options • E.g. -funroll-loops • Optimization Levels • O1 – optimize to make code smaller and faster • O2 – optimize more • O3 – optimize even more • Optimizer rewrites code for inner loop to use pointers • gcc –O2 –S array.c -o array.O2.s
func: pushl %ebp movl %esp, %ebp pushl %edi pushl %esi pushl %ebx subl $92, %esp movl 12(%ebp), %edx movl $0, -92(%ebp) cmpl %edx, -92(%ebp) movl 16(%ebp), %ebx jge .L11 movl $0, -76(%ebp) .p2align 4,,15 .L9: xorl %ecx, %ecx cmpl %ebx, %ecx jge .L13 movl -76(%ebp), %esi Notes: Compiling using the optimizer Callee-save registers %edi, %esi, %ebx 92 bytes of local storage 12(%ebp) = arg 2 edx (outer loop limit) -92(%ebp) gcc –O2 –S array.c –o arrayO2.s
Notes %edx = %edi + %esi * 4 Inner loop %ecx contain for index “n” x movl 8(%ebp), %edi leal (%edi,%esi,4), %edx .p2align 4,,15 .L8: incl %ecx addl (%edx), %eax addl $4, %edx cmpl %ebx, %ecx jl .L8 .L13: incl -92(%ebp) movl 12(%ebp), %edx addl $7, -76(%ebp) cmpl %edx, -92(%ebp) jl .L9 .L11: arrayO2.s Page2
Notes Inner loop %ecx contain for index “n” x .L11: addl $92, %esp popl %ebx popl %esi popl %edi popl %ebp ret arrayO2.s Page2
Array references in Source Code • sum = sum + d[i][j]; • A right hand side value (rval) refers to the value in d[i][j] • a[i][j] = 32; • A left hand side value (lval) refers to the address of the memory location whose value should be updated by the assignment • Note the variable sum above has lval and an rval also.
Extending Grammar for Expressions • S L := E • E E * E | E + E | ( E ) • E L • L Elist ] • L id • Elist Elist , E • Elist id [ E
Generalizing the Array Address Indexing Formula to 3rd and Higher Dimensions • In this discussion of Addressing a[i1, i2, … im] let: • nk = the number of elements in the kth dimension • After factoring out width, the width of the element type • Address of a[i1, i2, … ip] is f * width • Dimension = 1 • i1 e1 = i1 ; • Dimension = 2 • (i1 * n2 + i2) e2 = e1 * n2 + i2; • Dimension = 3 • ((i1 * n2 + i2) * n3 + i3) e3 = e2 * n3 + i3 . . . • Dimension = p • (…((i1 * n2 + i2) … * np + ip) ep = ep-1 * np + ip
Attributes for Elist - Index Expr List • For Elist Elist , E • we need to be able to evaluate the recursion em = em-1 * nm + im ( • For Elist • Elist.array - pointer to the symbol table for the array • Elist.ndim - number of dimensions • Elist.place - place for offset calculation (pointer to the symbol table) • For L • L.place • L.offset - place for offset calculation
Elist – Semantic Actions • Elist id [ E { Elist.array = id.place; • Elist.place = E.place; • Elist.ndim = 1; • } • Elist Elist1 , E { t = newtemp(); • m = Elist1.ndim + 1; • emit(t := Elist1.place * numcols(Elist1.array, m); ); • emit(t := t + E.place;); • Elist.array = Elist1.array • Elist.place = t; • Elist.ndim = m; • }
L – Semantic Actions • L id { L.place = id.place; • L.offset = null; /* non-array */ • } • L Elist ‘]’ { L.offset = newtemp(); • L.offset = newtemp(); • emit(L.place := Elist.array->base; • emit(L.offset := Elist.place *width(Elist.array); • }
E L { • if L.offset = null then • E.place = L.place; • else{ • E.place = newtemp(); • emit(E.place := L.place[L/offset]); • } • }
One more thing about Arrays • I have been telling you that C started subscripts at zero for simplicity and efficiency. • Actually that is true but compilers can generate code that is just as efficient for more general array references. Its just more work on the compiler! • E.g. a[low1..high1][low2..high2][low3..high3] • Static (compile time) versus Dynamic (run time) • (…(( (i1 - low) * n2 + (i2 - low)) … * np + (ip - lowp)) + base • = (…((i1 * n2 + i2) … * np + ip) • - (…((low1 * n2 + low2) … * np + lowp) • + base • So what portion of this computation is dynamic(run-time) and what is static( compile-time)? Same dynamic computation (at run time) Static computation (at compile time)
Project 5 - Functions • Add Functions to core+ • Non-nested functions • FuncDefList inserted … • Parameters passed • By value for ugrads • By value or ref for grads • Symbol Tables • Current symbol table; current offset; no global variables • Allocate new table when parsing of function definition starts. • Types • int, float, level of indirection • Functions?
Functions as First Class Objects • Functions in C – pointer to the start of the code • You can pass pointers to functions as argument. • Pointer to a function returning an int • int (*currentRoundToInt) ( float); • ... • ival = *currentRoundToInt(f+2.3); • Signal handlers is one of the places that this is commonly used • #include <signal.h> • typedef void (*sighandler_t)(int); • sighandler_t signal(int signum, sighandler_t handler);
Code Generation • Chapter 9 • Issues in Code Generation • Input to code generator • Target programs • Memory management • Instruction selection • Register allocation
Target Machine Architecture • RISC vs CISC • Byte addressable, word addressable? • Byte order? Big Endian vs little • Address Modes supported by architecture • Absolute • Register • Indexed d(R) d + contents(R) • Indirect register *d(R) contents(d + contents(R)) • Cost of address modes in references to memory