array code generation
play

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


  1. Array Code Generation 1. Array code generation 2. Surprises in memory access 3. Lessons learned

  2. Array Code Gen – Model-Driven VAR i, k, x : INTEGER; A : ARRAY 17 OF INTEGER; ... BEGIN • Arrays – don’t know offset at compile time • Arrays – don’t know offset at compile time x := A[i A[i]; ]; - what is the value of i i or k k? - what is the value of i or k? • Is there a base + offset formulation? ... • Is there a base + offset formulation? A[k] ] := 2 * x; A[k Des ::= ID | Des ‘[‘ E ‘]’ E ::= Des S ::= Des ‘:=‘ E

  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

  4. Assembly – Store Case: A[k] := 2 * x; ld [gp+4], r1 ! k ; D ::= D [E 1 ] mul r1, 4, r2 ! k * intSize st r2, [gp+80] ! T2 <T3 := 2 * x> ! gp+88 ; E 2 ::= E * E add gp, 12, r3 ! addr of A ; S ::= D := E 2 ld [gp+80], r2 ! T2 add r3, r2, r4 ! &A[k] � r4 ld [gp+84], r0 ! T3 Des ::= ID | Des ‘[‘ E 1 ‘]’ Des ::= ID | Des ‘[‘ E 1 ‘]’ E ::= Des st r0, [r4] ! A[k] := T3 E ::= Des S ::= Des ‘:=‘ E 2 S ::= Des ‘:=‘ E 2

  5. Assembly – Store Case: A[k] := 2 * x; ld [gp+4], r1 ! k ; D ::= D [E 1 ] mul r1, 4, r2 ! k * intSize st r2, [gp+80] ! T2 <T3 := 2 * x> ! gp+88 ; E 2 ::= E * E add gp, 12, r3 ! addr of A ; S ::= D := E 2 ld [gp+80], r2 ! T2 add r3, r2, r4 ! &A[k] � r4 ld [gp+84], r0 ! T3 Des ::= ID | Des ‘[‘ E 1 ‘]’ Des ::= ID | Des ‘[‘ E 1 ‘]’ E ::= Des st r0, [r4] ! A[k] := T3 E ::= Des S ::= Des ‘:=‘ E 2 S ::= Des ‘:=‘ E 2

  6. Assembly – Store Case: A[k] := 2 * x; ld [gp+4] r1 ! D ::= D [ E 1 ] 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> ! E 2 ::= E * E ld [gp+84], r0 ! S ::= D := E 2 ld [gp+80], r4 ! r4 holds an address! st r0, [r4]

  7. Array Code Gen void emit(VarSTO t, STO a, STO e) { // ArrayRef String indexReg = Machine.getReg(); ld [gp+4] r1 ! load index ld [gp+4] r1 ! load index String addrReg = Machine.getReg(); mul r1, 4, r2 mul r1, 4, r2 add gp, 12, r3 ! “load” &A add gp, 12, r3 ! “load” &A String resReg = Machine.getReg(); add r3, r2, r4 add r3, r2, r4 st r4, [fp+80] st r4, [fp+80] 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 }

  8. Two “Strange” Memory Manipulations ld [gp+4] r1 mul r1, 4, r2 add gp, 12, r3 ! load isn load isn’ ’t a load, var addr t a load, var addr add gp, 12, r3 ! 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 ! r1 holds a var r1 holds a var address! address! ld [gp+80], r1 st r0, [r1] [r1] ! double indirection ! double indirection ! emitStore doesn’ ’t work t work ! emitStore doesn ! this way ! this way

  9. Two “Strange” Memory Manipulations ld [gp+4] r1 void emitLoadAddress (VarSTO var, Register reg) { mul r1, 4, r2 if (var.isReference()) // array elem, class field ref emitLoad(var, reg); // get addr out of memory add gp, 12, r3 ! load isn load isn’ ’t a load, var addr t a load, var addr add gp, 12, r3 ! else if (var.isVariable()) // for arrays & VAR args eprint("add %R, %D, %R", add r3, r2, r4 var.base(), var.offset(), reg); st r4, [gp+80] ! stores an stores an address address ! else /* error */ } // Have to rewrite emitStore to store <T3 = 2 * x> // to reg, b+o already done ld [gp+84], r0 ld [gp+80], r1 ! r1 holds a var r1 holds a var address! address! ld [gp+80], r1 st r0, [r1] [r1] ! double indirection ! double indirection ! emitStore doesn’ ’t work t work ! emitStore doesn ! this way ! this way

  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()) Requires replacing existing emitLoad emitLoad(var, reg); Requires replacing existing emitLoad calls with emitLoadValue else /* error */ calls with emitLoadValue }

  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

Recommend


More recommend