Basic Blocks Aslan Askarov aslan@cs.au.dk Revised from slides by E. - - PowerPoint PPT Presentation

basic blocks
SMART_READER_LITE
LIVE PREVIEW

Basic Blocks Aslan Askarov aslan@cs.au.dk Revised from slides by E. - - PowerPoint PPT Presentation

Compilation 2014 Basic Blocks Aslan Askarov aslan@cs.au.dk Revised from slides by E. Ernst IR = Intermediate IR does not match either end perfectly Source: Translation non-trivial, e.g., using the static link


slide-1
SLIDE 1

Compilation 2014

Basic Blocks

Aslan Askarov aslan@cs.au.dk
 
 
 Revised from slides by E. Ernst

slide-2
SLIDE 2

IR = Intermediate …

  • IR does not match either end perfectly
  • Source:
  • Translation non-trivial, e.g., using the static link
  • Target:
  • ESEQ & CALL enable side-effects in expressions
  • CJUMP has 2 targets, machine instructions fall through
  • CALL puts returned value in specific register (RV)
  • Why not just drop them?
  • CALL in expression: needed for function
  • ESEQ: very convenient
  • Strategy: Remove ESEQ, move CALL
slide-3
SLIDE 3

Idea: Require ‘well-formed’ IR Trees

Type Correct

MOVE(TEMP t, ESEQ…) MOVE(BINOP…, TEMP s)

Satisfies Constraints

MOVE(MEM…,CALL…) ESEQ(MOVE…, TEMP t) SEQ(MEM…,SEQ(…,SEQ…))

Only a subset of type correct terms used

slide-4
SLIDE 4

Canonical IR Trees

  • Just ordinary IR trees, but well-formed
  • Requirements:
  • SEQ only topmost (will be removed using exp list)
  • ESEQ never used
  • Parent of CALL is EXP(…) or MOVE(TEMP t, …)
  • Created in module ‘Canon’

signature CANON = sig val linearize: stm -> stm list val basicBlocks: stm list -> (stm list list * Temp.label) val traceSchedule: stm list list Temp.label -> stm list end structure Canon: CANON = struct ... end

slide-5
SLIDE 5

Technique: Rewriting

  • Goal of linearize achieved by repeated rewrite
  • Rewriting rules:
  • Specify a ‘from’ pattern, to be matched
  • Specify a ‘to’ pattern, to construct from match
  • Correctness requirement:
  • Every possible rewrite preserves the semantics
  • ne

tree IR will be replaced by another tree IR

slide-6
SLIDE 6

Rewriting 1

  • Purpose: Eliminate one ESEQ node
  • Matching: For given IR tree matching concrete

nodes, bind subtrees to metavariables

  • Construction: replace metavariables by their values

ESEQ ESEQ s1 s2 e ESEQ SEQ e s2 s1

slide-7
SLIDE 7

Rewriting 2

  • Purpose: Move ESEQ up

BINOP ESEQ e2 s e1 ESEQ BINOP s e2

  • p
  • p

e1 MEM(ESEQ(s,e1)) ESEQ(s,MEM(e1)) JUMP(ESEQ(s,e1)) ESEQ(s,JUMP(e1)) CJUMP(op,ESEQ(s,e1) ,e2,l1,l2) SEQ(s,CJUMP(op,e1,e2 ,l1,l2))

slide-8
SLIDE 8

Rewriting 3

  • Purpose: Pull ESEQ over operand

BINOP ESEQ e1 s e2

  • p

ESEQ BINOP MOVE e2

  • p

TEMP TEMP t e1 t ESEQ s CJUMP(op,e1 ,ESEQ(s,e2) ,l1,l2) SEQ(MOVE(TEMP t,e1) ,SEQ(s ,CJUMP(op,TEMP t ,e2,l1,l2)

slide-9
SLIDE 9

Rewriting 4

  • Purpose: Pull ESEQ over operand for free!

BINOP ESEQ e1 s e2

  • p

BINOP e2

  • p

e1 ESEQ s CJUMP(op,e1 ,ESEQ(s,e2) ,l1,l2) SEQ(s,CJUMP(op,e1,e2 ,l1,l2)) s,e1 commute s,e1 commute

slide-10
SLIDE 10

Algorithm Doing the Rewriting

  • Functions do… handle deconstruct/reconstruct
  • Functions reorder… perform subtree transforms

val reorderStm: exp list * (exp list -> stm) -> stm val reorderExp: exp list * (exp list -> exp) -> (stm*exp) fun doStm (T.JUMP(e,labs)) = reorderStm ([e], fn [e] => T.JUMP(e,labs)) | doStm (T.CJUMP(p,a,b,t,f)) = reorderStm ([a,b], fn [a,b] => T.CJUMP(p,a,b,t,f)) | doStm (T.MOVE(T.TEMP t, b)) = reorderStm ([b], fn [b] => T.MOVE(T.TEMP t, b)) ... and doExp (T.BINOP(p,a,b)) = reorderExp ([a,b], fn [a,b] => T.BINOP(p,a,b)) | doExp (T.MEM(a)) = reorderExp ([a], fn [a] => T.MEM(a)) ...

slide-11
SLIDE 11

On CALL

  • Problem: A CALL returns result in register RV
  • Why does CALL(f, CALL(…),CALL(…)) not work?
  • (unless we are careful)
  • Why does this solve the problem?

CALL(f,args)) ESEQ(MOVE(TEMP t ,CALL(f,args)) ,TEMP t)

slide-12
SLIDE 12

After Rewriting 1-4 Stabilizes

  • Eliminate SEQ:
  • First rewrite SEQ to enforce list structure
  • Then replace SEQ by list constructor

SEQ(SEQ(a,b),c)) SEQ(a,SEQ(b,c)) a::(b::c) SEQ(a,SEQ(b,c))

fun linearize (stm0: stm): stm list = let definitions of reorderExp, reorderStm, doExp, … fun linear (T.SEQ(a,b),l) = linear(a,linear(b,l)) | linear (s,l) = s::l in linear(doStm stm0, nil) end

slide-13
SLIDE 13

Basic Blocks

  • Control flow: Studying program behavior with no regard to

values, just “movement” (*JUMP , step)

  • Basic block: Sequence of instructions w/o JUMP
  • First statement: LABEL
  • Last statement: [C]JUMP
  • No other LABELs or [C]JUMPs
  • Simple algorithm:
  • at [C]JUMP: end current block; at LABEL: start new block
  • fixup: add ‘blocks’ label at very beginning, JUMP to

‘done’ label at very end

  • Result: basic blocks can be freely reordered
slide-14
SLIDE 14

Traces

  • Trace: instruction sequence that could be executed

consecutively (choice: CJUMP)

  • We reorder such that CJUMP is followed by its

‘false’ label, thus enabling fall through

  • Pseudo-code algorithm:

Put all blocks of the program into a list Q. while Q is not empty Start a new (empty) trace, call it T Remove the head element b from Q. while b is not marked Mark b; append b to the end of the current trace T. Examine the successors of b; if there is any unmarked successor c b := c end current trace T.

slide-15
SLIDE 15

Traces May be Optimized

  • All these are correct tracings for the same function
  • Count instructions for the loop!
  • Optimal traces: not this compiler

prologue statements JUMP (NAME test) LABEL test CJUMP (>,i,N,done,body) LABEL body loop body statements JUMP(NAME test) LABEL done epilogue statements prologue statements JUMP (NAME test) LABEL test CJUMP(<=,i,N,done,body) LABEL done epilogue statements LABEL body loop body statements JUMP(NAME test) prologue statements JUMP (NAME test) LABEL body loop body statements JUMP(NAME test) LABEL test CJUMP (>,i,N,done,body) LABEL done epilogue statements

slide-16
SLIDE 16

Implementation

  • File ‘canon.sml’ available, fully implemented
  • Has signature CANON (including linearize,

basicBlocks, traceSchedule)

  • Note warnings during compilation:
  • Not a problem! ;-) Caused by using well-formed

subset of type correct trees, carefully..

canon.sml:81.30-81.54 Warning: match nonexhaustive e :: nil => ... canon.sml:83.32-83.62 Warning: match nonexhaustive a :: b :: nil => ...

slide-17
SLIDE 17

Summary

  • IR trees really intermediate: Not a perfect fit for

source, nor for target

  • For target: Eliminate ESEQ & SEQ, move CALL,

ensure parent EXP(…) or MOVE(TEMP t, …)

  • Transformations: Move ESEQ up, eliminate an

ESEQ, pull ESEQ over expression, ditto for free

  • Tricky algorithm: note deconstruct/reconstruct
  • Protect register RV: Transform CALL
  • Move CALL up to EXP/MOVE
  • Basic blocks: find, then reorder into traces