Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 22 additions & 6 deletions compiler/stz-el.stanza
Original file line number Diff line number Diff line change
Expand Up @@ -2540,13 +2540,13 @@ 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<EObject|ENewObject> :
val table = IntListTable<EObject|ENewObject>()
defn binding-table (e:EBody) -> IntTable<ELItem> :
val table = IntListTable<ELItem>()
val remove-set = IntSet()
for i in ins(e) do :
match(i:EObject|ENewObject) : add(table, n(x(i)), i)
match(i:EObject|ENewObject|ETuple) : add(table, n(x(i)), i)
else : do(add{remove-set, n(_)}, varlocs(i))
to-inttable<EObject|ENewObject> $
to-inttable<ELItem> $
for entry in table seq? :
if remove-set[key(entry)] : None()
else if length(value(entry)) == 1 : One(key(entry) => head(value(entry)))
Expand All @@ -2563,7 +2563,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<EObject|ENewObject>) -> [EVarLoc, EImm] :
bindings:IntTable<ELItem>) -> [EVarLoc, EImm] :
val v = y(e) as? EVar
val o = get?(bindings, n(v)) as? ENewObject
val value = ys(o)[index(e)]
Expand All @@ -2575,7 +2575,7 @@ defn box-unbox-fold (epackage:EPackage, gvt:VarTable) -> EPackage :
;Calls fail() if not a match.
defn unbox-load (e:ELoad,
vt:VarTable,
bindings:IntTable<EObject|ENewObject>, ) -> [EVarLoc, EImm] :
bindings:IntTable<ELItem>, ) -> [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
Expand All @@ -2584,6 +2584,17 @@ defn box-unbox-fold (epackage:EPackage, gvt:VarTable) -> EPackage :
fail() when not immutable?(vt,value)
[x(e), value]

;If the given ETupleGet expression corresponds to a retrieval
;of a tuple element of a known tuple then return the destination and the field.
;Calls fail() if not a match.
defn unbox-tuple-get (e:ETupleGet,
vt:VarTable,
bindings:IntTable<ELItem>, ) -> [EVarLoc, EImm] :
val v = y(e) as? EVar
val t = get?(bindings, n(v)) as? ETuple
val value = ys(t)[index(e)]
[x(e), value]

;Perform unboxing folds in the given body.
;Assumes that all nested bodies have already been folded.
defn fold-in-body (e:EBody, vt:VarTable) -> EBody :
Expand All @@ -2603,6 +2614,11 @@ defn box-unbox-fold (epackage:EPackage, gvt:VarTable) -> EPackage :
val [x, v] = unbox-load(i, vt, bindings)
EDef(x, v, false)
else : i
(i:ETupleGet) :
attempt :
val [x, v] = unbox-tuple-get(i, vt, bindings)
EDef(x, v, false)
else : i
(i) : i

;Attempt to fold all instructions.
Expand Down