Array Code Generation 1. Array code generation 2. Surprises in - - PowerPoint PPT Presentation

array code generation
SMART_READER_LITE
LIVE PREVIEW

Array Code Generation 1. Array code generation 2. Surprises in - - PowerPoint PPT Presentation

Array Code Generation 1. Array code generation 2. Surprises in memory access 3. Lessons learned Array Code Gen Model-Driven VAR i, k, x : INTEGER; A : ARRAY 17 OF INTEGER; ... BEGIN Arrays dont know offset at compile time


slide-1
SLIDE 1

Array Code Generation

  • 1. Array code generation
  • 2. Surprises in memory access
  • 3. Lessons learned
slide-2
SLIDE 2

Array Code Gen – Model-Driven

VAR i, k, x : INTEGER; A : ARRAY 17 OF INTEGER; ... BEGIN x := A[i A[i]; ]; ... A[k A[k] ] := 2 * x; Des ::= ID | Des ‘[‘ E ‘]’ E ::= Des S ::= Des ‘:=‘ E

  • Arrays – don’t know offset at compile time
  • what is the value of i or k?
  • Is there a base + offset formulation?
  • Arrays – don’t know offset at compile time
  • what is the value of i

i or k k?

  • Is there a base + offset formulation?
slide-3
SLIDE 3

Base + Offset for Arrays

Array A has its own base and offset

&A = base(A) + offset(A)

But k dictates an offset inside A

&(A[k]) = base(A) + offset(A) + ((k - lowerbound(A lowerbound(A) )) * size(elemtype(A))) &(A[k]) = base(A) + offset(A) + ((k - 0 0) * size(elemtype(A))) &(A[k]) = base(A) + offset(A) + (k * size(elemtype(A)))

Base+offset method motivated by assembler syntax

arraybase = base(A) + offset(A) &(A[k]) = arraybase + (k * size(elemtype(A)))

Two-stage base + offset! Multi-dimensional case is really nasty

slide-4
SLIDE 4

Assembly – Store Case: A[k] := 2 * x;

ld [gp+4], r1 ! k ; D ::= D [E1] mul r1, 4, r2 ! k * intSize st r2, [gp+80] ! T2 <T3 := 2 * x> ! gp+88 ; E2 ::= E * E add gp, 12, r3 ! addr of A ; S ::= D := E2 ld [gp+80], r2 ! T2 add r3, r2, r4 ! &A[k] r4 ld [gp+84], r0 ! T3 st r0, [r4] ! A[k] := T3

Des ::= ID | Des ‘[‘ E1 ‘]’ E ::= Des S ::= Des ‘:=‘ E2 Des ::= ID | Des ‘[‘ E1 ‘]’ E ::= Des S ::= Des ‘:=‘ E2

slide-5
SLIDE 5

Assembly – Store Case: A[k] := 2 * x;

ld [gp+4], r1 ! k ; D ::= D [E1] mul r1, 4, r2 ! k * intSize st r2, [gp+80] ! T2 <T3 := 2 * x> ! gp+88 ; E2 ::= E * E add gp, 12, r3 ! addr of A ; S ::= D := E2 ld [gp+80], r2 ! T2 add r3, r2, r4 ! &A[k] r4 ld [gp+84], r0 ! T3 st r0, [r4] ! A[k] := T3

Des ::= ID | Des ‘[‘ E1 ‘]’ E ::= Des S ::= Des ‘:=‘ E2 Des ::= ID | Des ‘[‘ E1 ‘]’ E ::= Des S ::= Des ‘:=‘ E2

slide-6
SLIDE 6

Assembly – Store Case: A[k] := 2 * x;

ld [gp+4] r1 ! D ::= D [ E1 ] mul r1, 4, r2 add gp, 12, r3 add gp, 12, r3 add r3, r2, r4 add r3, r2, r4 st r4, [gp+80] <T3 = 2 * x> ! E2 ::= E * E ld [gp+84], r0 ! S ::= D := E2 ld [gp+80], r4 ! r4 holds an address! st r0, [r4]

slide-7
SLIDE 7

Array Code Gen

void emit(VarSTO t, STO a, STO e) { // ArrayRef String indexReg = Machine.getReg(); String addrReg = Machine.getReg(); String resReg = Machine.getReg(); Machine.emitLoad(e, indexReg); // see next section eprint("mul %R, %D, %R", indexReg, a.elemSize(), indexReg); Machine.emitLoadAddress(a, addrReg); // ld addr, not 1st val eprint("add %R, %R, %R", addrReg, indexReg, resReg); Machine.emitStore(resReg, t); // see next section // free registers }

ld [gp+4] r1 ! load index mul r1, 4, r2 add gp, 12, r3 ! “load” &A add r3, r2, r4 st r4, [fp+80] ld [gp+4] r1 ! load index mul r1, 4, r2 add gp, 12, r3 ! “load” &A add r3, r2, r4 st r4, [fp+80]

slide-8
SLIDE 8

Two “Strange” Memory Manipulations

ld [gp+4] r1 mul r1, 4, r2 add gp, 12, r3 add gp, 12, r3 ! ! load isn load isn’ ’t a load, var addr t a load, var addr add r3, r2, r4 st r4, [gp+80] ! ! stores an stores an address address <T3 = 2 * x> ld [gp+84], r0 ld [gp+80], r1 ld [gp+80], r1 ! r1 holds a var r1 holds a var address! address! st r0, [r1] [r1] ! double indirection ! double indirection ! emitStore doesn ! emitStore doesn’ ’t work t work ! this way ! this way

slide-9
SLIDE 9

Two “Strange” Memory Manipulations

ld [gp+4] r1 mul r1, 4, r2 add gp, 12, r3 add gp, 12, r3 ! ! load isn load isn’ ’t a load, var addr t a load, var addr add r3, r2, r4 st r4, [gp+80] ! ! stores an stores an address address <T3 = 2 * x> ld [gp+84], r0 ld [gp+80], r1 ld [gp+80], r1 ! r1 holds a var r1 holds a var address! address! st r0, [r1] [r1] ! double indirection ! double indirection ! emitStore doesn ! emitStore doesn’ ’t work t work ! this way ! this way

void emitLoadAddress(VarSTO var, Register reg) { if (var.isReference()) // array elem, class field ref emitLoad(var, reg); // get addr out of memory else if (var.isVariable()) // for arrays & VAR args eprint("add %R, %D, %R", var.base(), var.offset(), reg); else /* error */ } // Have to rewrite emitStore to store // to reg, b+o already done

slide-10
SLIDE 10

Extended emitLoad (EmitLoadValue)

void emitLoadValue(STO var, Register reg) { // was emitLoad if (var.isConstant()) // Constants are a "mode", too. eprint("set %D, %R", var.value(), reg); // value() has toString() else if (var.isReference()) { String r = getReg(); emitLoad(var, r); // load addr eprint("ld [%R], %R", r, reg); // deref freeReg(r); } else if (var.isVariable()) emitLoad(var, reg); else /* error */ }

Requires replacing existing emitLoad calls with emitLoadValue Requires replacing existing emitLoad calls with emitLoadValue

slide-11
SLIDE 11

Lessons Learned

  • Several problems with our “rules”
  • base + offset challenged
  • single-STO per-rule challenged
  • load/store storage model challenged
  • Generalized rules from new domain insights
  • double base + offset
  • introduced notion of “address” STO
  • generalized value load/store for addresses and

constants

  • Kept our rules by generalizing them to

conform to realities of domain

  • “bend but don’t break”, refactor code