From 52b1ac4ea335d9763376f988199ce75cda09ba38 Mon Sep 17 00:00:00 2001 From: jackbackrack Date: Tue, 14 Sep 2021 22:47:41 -0700 Subject: [PATCH] fold literal unbox --- compiler/stz-el.stanza | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/compiler/stz-el.stanza b/compiler/stz-el.stanza index 14ee622bf..9e640bfa2 100644 --- a/compiler/stz-el.stanza +++ b/compiler/stz-el.stanza @@ -2845,14 +2845,22 @@ defn box-unbox-fold (epackage:EPackage, gvt:VarTable) -> EPackage : ;Compute binding table. ;Every entry in the binding table, x => e, indicates that - ;x is defined exactly once by the EObject or ENewObject instruction. - defn binding-table (e:EBody) -> IntTable : - val table = IntListTable() + ;x is defined exactly once by the + ;EObject, ENewObject, or EDef instruction. + defn binding-table (e:EBody) -> IntTable : + val table = IntListTable() val remove-set = IntSet() + defn remove-varloc-vars (i:EIns) : + do(add{remove-set, n(_)}, varlocs(i)) for i in ins(e) do : - match(i:EObject|ENewObject) : add(table, n(x(i)), i) - else : do(add{remove-set, n(_)}, varlocs(i)) - to-inttable $ + match(i) : + (i:EObject|ENewObject) : add(table, n(x(i)), i) + (i:EDef) : + match(x(i), y(i)) : + (x:EVarLoc, y:ELiteral) : add(table, n(x), y) + (x, y) : remove-varloc-vars(i) + (i) : remove-varloc-vars(i) + to-inttable $ for entry in table seq? : if remove-set[key(entry)] : None() else if length(value(entry)) == 1 : One(key(entry) => head(value(entry))) @@ -2869,7 +2877,7 @@ defn box-unbox-fold (epackage:EPackage, gvt:VarTable) -> EPackage : ;field. Calls fail() if not a match. defn unbox-object-get (e:EObjectGet, vt:VarTable, - bindings:IntTable) -> [EVarLoc, EImm] : + bindings:IntTable) -> [EVarLoc, EImm] : val v = y(e) as? EVar val o = get?(bindings, n(v)) as? ENewObject val value = ys(o)[index(e)] @@ -2877,18 +2885,24 @@ defn box-unbox-fold (epackage:EPackage, gvt:VarTable) -> EPackage : [x(e), value] ;If the given ELoad expression corresponds to a retrieval - ;of a known object field then return the destination and the field. + ;of a known object field or literal value then + ;return the destination and the field or value. ;Calls fail() if not a match. defn unbox-load (e:ELoad, vt:VarTable, - bindings:IntTable, ) -> [EVarLoc, EImm] : + bindings:IntTable, ) -> [EVarLoc, EImm] : val field = loc(e) as? EField val v = y(loc(field) as? EDeref) as? EVar - val o = get?(bindings, n(v)) as? EObject - fail() when mutable-field?(defstruct-table, n(o), index(field)) - val value = ys(o)[index(field)] - fail() when not immutable?(vt,value) - [x(e), value] + match(get?(bindings, n(v))) : + (o:EObject) : + fail() when mutable-field?(defstruct-table, n(o), index(field)) + val value = ys(o)[index(field)] + fail() when not immutable?(vt,value) + [x(e), value] + (o:ELiteral) : + fail() when (index(field) != 0 or value(o) is-not Byte|Int|Long|Float|Double) + [x(e), ELSLiteral(value(o))] + (o) : fail() ;Perform unboxing folds in the given body. ;Assumes that all nested bodies have already been folded.