Code Generation Issues Aslan Askarov aslan@cs.au.dk Based on slides - - PowerPoint PPT Presentation

code generation issues
SMART_READER_LITE
LIVE PREVIEW

Code Generation Issues Aslan Askarov aslan@cs.au.dk Based on slides - - PowerPoint PPT Presentation

Compilation 2014 Code Generation Issues Aslan Askarov aslan@cs.au.dk Based on slides by E. Ernst Administrativia November 28 guest lecture by Filip Sieczkowski (AU) Memory Models December 12 guest lecture by Kevin


slide-1
SLIDE 1

Compilation 2014

Code Generation Issues

Aslan Askarov aslan@cs.au.dk
 
 
 Based on slides by E. Ernst

slide-2
SLIDE 2

Administrativia

  • November 28 – guest lecture by Filip Sieczkowski (AU)
  • Memory Models
  • December 12 – guest lecture by Kevin Millikin (G)
  • Register allocation in JIT compilers
  • The very last hand-in “Putting it all together” is due on

December 10

  • No new functional requirements, just fix your bugs

and resubmit

slide-3
SLIDE 3

Code generation issues

  • Until now we have discussed Tiger on an abstract platform
  • In reality, it needs to run on a concrete one
  • Need consider
  • Concrete assembly language
  • Calling conventions
  • Transformation from abstract assembly to concrete

assembly

  • Note: no textbook reference here, but check out linked

material on x86 assembly

slide-4
SLIDE 4

The x86 assembly language

  • Specifies machine instructions for a large family of CPUs – we

choose the 32 bit subfamily

  • Only very little abstraction
  • Symbolic addresses (crucial!)
  • Choice among jumps (please ignore)
  • Generation of meta/debug information (please ignore)
  • Checks several things
  • “This is actually a MOVE” (bit-pattern could mean anything)
  • “MUL is actually capable of operating on that register”
  • Syntax not standardized: we use AT&T syntax that is

compatible with gcc inline code

slide-5
SLIDE 5

The x86 assembly language

  • Example instruction: move $-42, 8(%ebp)
  • General format: <instr><S> <src>, <dst>
  • <S> ∈ {b,s,w,l,q,t} specifies size (l: 32 bit)
  • $ indicates literal number
  • % indicates register
  • o(%r1, %r2, n) means o + %r1 + %r2 * n
  • Example label: mylabel
  • gives the “current address” the name ‘mylabel’
  • Example directives:
  • .text .data .globl .ascii .asciz


.size .func .type .endfunc

slide-6
SLIDE 6

The x86 assembly language

  • Assembler produces object file that contains

segments (address ranges with a purpose)

  • Segments containing runnable code: .text
  • Segments containing initialized data: .data
  • Remember to specify segment to fit purpose
  • Specifying data:
  • .ascii .asciz
  • Metadata:
  • .func .type .endfunc .size .globl
  • For examples: check provided *.s
slide-7
SLIDE 7

The x86 assembly language

.text # PROCEDURE tigermain .globl tigermain .func tigermain .type tigermain, @function tigermain: # FRAME tigermain(1 formals, 10 locals) pushl %ebp movl %esp, %ebp subl $44, %esp # SP, FP, calleesaves, argregs have values L2_blocks: # x86gen:122 movl %ebp, -8(%ebp) # x86gen:246 x86frame:575 movl -8(%ebp), %ebx # x86gen:251 x86frame:367 addl $-4, %ebx # x86gen:251 x86frame:372 . . . movl -28(%ebp), %eax # x86gen:117 x86frame:582 jmp L1_block_done # x86gen:172 L1_block_done: # x86gen:122 # FP, SP, RV, calleesaves still live leave ret .size tigermain, .-tigermain .endfunc # END tigermain

.data L0_string: .long 13 .asciz "DefaultString"

slide-8
SLIDE 8

The x86 assembly language

  • A reasonable selection of instructions

addl $17, %esp addl %eax, %ebx call Label cltd cmpl $17, %ecx cmpl %eax, %edx idivl %ebx imull %eax je Label jg Label jge Label jl Label jle Label jmp Label jne Label leave movl $17, %eax movl $Label, %eax movl %eax, %ebx movl %eax, 17(%ebp) movl %esp, %ebp movl 17(%ebp), %eax negl %eax pushl %eax pushl %ebp ret subl $17, %esp subl %eax, %ebx

slide-9
SLIDE 9

Calling Convention (cdecl)

  • For practical reasons, gcc is used to do linking
  • includes startup symbols/code
  • easy integration with C (e.g., runtime.c, showstack.c)
  • convenient calling convention
  • Must use gcc -static .. to allow debugging
  • Avoid ‘smart’ options (-fomit-frame-pointer)
  • Conventions
  • all parameters passed on stack (‘push’)
  • last parameter pushed first, .., return address last
  • return value passed in %eax
  • caller cleans up stack
slide-10
SLIDE 10

Recall Tiger frame slots

saved_FP localVar_1 ... localVar_m temp_1 ... temp_p ... (args for next)

FP

SP

(prev.frame) ... arg_k ... arg_1 staticLink returnAddr

SP SP SP

  • ld FP

Memory[FP] Memory[FP-4*1] Memory[FP-who_cares] Memory[FP+4] Memory[saved_FP], Memory[FP+8] Memory[FP+4*(2+1)] Memory[FP+4*(2+k)] Memory[FP-4*m] Memory[FP-4*(m+1)] Memory[FP-4*(m+p)] Memory[staticLink]?

Top of frame: known early Bottom: known later

slide-11
SLIDE 11

Calling Conventions at Work

  • Consider an invocation of the function g(_) from the

function f(…)

  • Reverse-push parameters
  • Push static link
  • Call (clean up after return)
  • Callee sets up stack frame
  • ends by destructing it again

L33_f: . . . pushl %ebx pushl %ebp call L3_g addl $8, %esp . . . L3_g: pushl %ebp movl %esp, %ebp subl $44, %esp . . . leave ret

slide-12
SLIDE 12

From Abstract to Concrete Assembly

  • Maximal Munch will generate instructions, but

abstract

  • Abstract instructions: Like concrete ones, but

using an unlimited supply of ‘temporaries’

  • Register allocation: Reusing registers as much as

possible, then spill

  • We will just spill!
slide-13
SLIDE 13

Generated Code

  • Note dependencies: Each instruction uses some

temporaries and defines others (or the same)

  • In 2-op instr. (e.g. addl), first src is implicit dependency

. . . | munchStm (T.MOVE (T.TEMP t, T.CALL (T.NAME l, args))) = ( emit (A.OPER { assem = "\tcall " ^ S.name l , src = munchArgs args , dst = F.calldefs , jump = NONE , doc = "x86gen:68"}) ; emit (freeArgs (length args)) ; emit (moveInstr F.EAX t "70")) emit (A.OPER { assem = "\taddl `s1, `d0" , src = [r, munchExp e2] (* old-r used *) , dst = [r] , jump = NONE , doc = "x86gen:270"})

slide-14
SLIDE 14

From Abstract to Concrete Assembly

  • Actual source code examples:

tigermain: pushl %ebp movl %esp, %ebp subl $44, %esp L2_blocks: movl %ebp, t111 addl $-4, t111 movl t111, t110 movl $0, t112 pushl t112 movl $10, t113 pushl t113 call initArray . . . tigermain: pushl %ebp movl %esp, %ebp subl $44, %esp L2_blocks: movl %ebp, -8(%ebp) movl -8(%ebp), %ebx addl $-4, %ebx movl %ebx, -8(%ebp) movl -8(%ebp), %ebx movl %ebx, -20(%ebp) movl -12(%ebp), %ebx movl $0, %ebx movl %ebx, -12(%ebp) movl -12(%ebp), %ebx pushl %ebx movl -16(%ebp), %ebx movl $10, %ebx movl %ebx, -16(%ebp) movl -16(%ebp), %ebx pushl %ebx call initArray . . .

slide-15
SLIDE 15

Spilling: Basic Idea

  • Starting point: instruction using input/output
  • Use instead: same instruction, in/out via registers
  • Add instructions to move data to/from those

registers

bloopl

src dst

bloopl

src dst

move move

R1 R2

slide-16
SLIDE 16

Spilling: Implementation

  • Starting point: instruction i using [s0], []
  • Use instead: A.OPER variant
  • Add movl instruction to move data into

fun expand (A.OPER {src=s0::ss, jump = SOME (j::js), ...}) = raise Bug "Encountered OPER that uses temps and jumps" | expand (i as (A.OPER {src=[], dst=[], ...})) = [i] | expand (i as A.OPER {assem, src=[s0], dst=[], jump, doc}) = if isRegister s0 then [i] else (* s0 other temp *) [ A.OPER { assem = "\tmovl " ^ ofs s0 ^ "(%ebp), `d0" , src = [] , dst = [EBX] , jump = NONE , doc = doc ^ " x86frame:265"} , A.OPER { assem = assem , src = [EBX] , dst = [] , jump = jump , doc = doc ^ " x86frame:270"}] . . .

slide-17
SLIDE 17

Spilling: Implementation

  • Invariant maintained: Registers are initialized and

used locally in snippet of code for one abstract instruction — so there are no conflicts

  • Note special casing with registers

. . . | expand (i as A.OPER {assem, src=[s0], dst=[], jump, doc}) = if isRegister s0 then [i] else (* s0 other temp *) [ A.OPER { assem = "\tmovl " ^ ofs s0 ^ "(%ebp), `d0" , src = [] , dst = [EBX] , jump = NONE , doc = doc ^ " x86frame:265"} , A.OPER { assem = assem , src = [EBX] , dst = [] , jump = jump , doc = doc ^ " x86frame:270"}] . . .

slide-18
SLIDE 18

Summary

  • Abstract platform (Jouette) now dropped
  • Choice: x86, 32 bit
  • Assembly language: safer than machine code
  • Assembly instruction format, labels, directives
  • The notion of a segment
  • Actual assembly: check out test0?.s
  • An example required set of instructions
  • Calling conventions: cdecl
  • Transformation abstract/concrete assembly code
slide-19
SLIDE 19

References

  • Assembly directives: see ‘as’ manual
  • https://sourceware.org/binutils/docs/as/index.html
  • Sign extension (CTLD):
  • https://en.wikipedia.org/wiki/Sign_extension