-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mutable state using evidence #248
Conversation
@marzipankaiser I encountered an issue with boxed types while implementing this.
The generated core tree for above statements looks like this:
The var declaration uses |
Ah, sorry, I completely forgot about answering here. In principle, it should be easy enough to fix this in |
2232d74
to
e20d2b1
Compare
I special-cased references for now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very good job!
case Allocate(name, init, ev, rest) => | ||
toDoc(name.tpe) <+> name <> "<" <> ev <> ">" <+> "=" <+> init <> ";" <> line <> toDoc(rest) | ||
|
||
case Load(name, ref, rest) => | ||
name <+> "=" <+> "*" <> ref <> ";" <> line <> toDoc(rest) | ||
case Load(name, ref, ev, rest) => | ||
name <+> "=" <+> "*" <> ref <> "<" <> ev <> ">" <> ";" <> line <> toDoc(rest) | ||
|
||
case Store(ref, value, rest) => | ||
"*" <> ref <+> "=" <+> value <> ";" <> line <> toDoc(rest) | ||
case Store(ref, value, ev, rest) => | ||
"*" <> ref <> "<" <> ev <> ">" <+> "=" <+> value <> ";" <> line <> toDoc(rest) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would have used keywords like alloc
load
store
but this is fine.
; | Next | Size | Payload ... | | ||
; +---------------+--------------+ | ||
%State = type ptr | ||
%Region = type [ 3 x %Mem ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't quite like this solution and would prefer storing a sharer and an eraser with each object. But ok.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would become obsolete if we switch to monomorphic regions.
%regionval = load %RegionVal, %Region %region | ||
%oldstate = extractvalue %RegionVal %regionval, 0 | ||
%oldsize = extractvalue %RegionVal %regionval, 1 | ||
realloc: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Later we could perhaps move this reallocation into its own function.
} | ||
|
||
define ptr @getPtr(%Ref %ref, i64 %idx, i64 %evidence) alwaysinline { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The %idx
is for the 3 different kinds of values, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, perhaps it should be renamed to %kind
or something similar.
ret %Stk %newstk | ||
%objectsbase = extractvalue %Region %region, 1, 1 | ||
%objectssp = extractvalue %Region %region, 1, 0 | ||
call void @forEachObject(%Base %objectsbase, %Sp %objectssp, %Eraser @sharePositive) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! Higher-order functions in LLVM.
store %Stk %nextnew, ptr %newstkrest | ||
br label %loop | ||
|
||
closecycle: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I forgot why the meta stack is cyclic...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The meta-stack isn't cyclic but first-class stacks are.
This representation saves us a few operations on PushStack
/PopStack
, because we only have to swap the heads of the meta-stack and the first-class stack.
Here is an alternative implementation for mutable state in the LLVM backend that should work with #244. It doesn't refer to regions by name and instead uses evidence for allocation and access.
This comes with the cost of not having direct pointers as references anymore. On the other hand it makes memory management a lot simpler.