-
Notifications
You must be signed in to change notification settings - Fork 1
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
First steps hooking up to LLVM #2
Conversation
1. The current version isn't on hackage yet, see llvm-hs/llvm-hs#369 2. We needed to patch the version bounds to get this to build with our other dependencies; see llvm-hs/llvm-hs#389
This results in a bit more verbosity at the type level, but as I tried to add a doc comment explaining what this function did, I realized it was very semantically muddled and justifying it required too much appeal to compressing call sites; it's more clear this way.
Fixed the merge conflicts. |
@marcinjangrzybowski, I would welcome your review as well; for some reason the "request review" thing only lets me pick one person. |
I don't have many comments on the code in this PR itself, I mainly have questions about the I notice that the code in this PR ignores the For example: data Type
= -- | The type of a function pointer:
TFPtr FPtrType
| ...other variants...
data FPtrType = FPtrType
{ fptCaptures :: [Type],
fptFuncType :: FuncType
} why wouldn't it be data Type
= -- | The type of a function pointer with closure captures:
TFPtr [Type] FuncType
| ...other variants... so that the corresponding translation code could more naturally use pattern matching like translateType ty = case ty of
...other cases...
Ast.TFPtr captures fTy ->
...body... and avoid the field name accessors? |
For the specific example of Note that it is still possible to match this as:
...I suppose it's a question of style whether that scans better. I don't feel super strongly; if you do I could flip it. Wrt. the general case of "why introduce intermediate records?" I might be a little trigger happy about this, but I have often enough done things the other way and then been in the middle of building out something that used the type, and found myself wanting to pass the arguments to some ctor to a function as a unit, without having to handle the other cases. Re: |
Does that mean that effectful functions can't have non-unit return values, or that functions with non-unit return types must be pure? |
See the comment. Thanks to Alex K for spotting this.
-- If the function has side effects, that means it | ||
-- doesn't return a value at the LLVM level - instead we unwind | ||
-- the stack, commit the transaction, and our continuation gets | ||
-- the value in the next transaction. |
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 comment: does that mean the "effectful" distinction is actually a transaction-boundary distinction?
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, exactly. I have some scratch work where I'm cleaning up the LastLeg Ast and will probably make that more clear.
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.
Is "effectful" really the right word for this then? Plenty of effects don't need a transaction boundary, and a transaction boundary doesn't happen "after" an effect necessarily, it happens before the next participant's effect.
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.
Also I would have expected the transaction boundary distinction to be on the labels, not the function types.
At the LLVM level, yes, effectful functions don't actually return a value, and right now afaik all of our effectful functions (deposit, withdraw) happen to return unit anyway, but if we found a case where an effectful function could return some other value, we'd have to communicate it to the next transaction some way other than the LLVM-level return value (maybe storing next to the continuation when we checkpoint the state). Anyway, I made the change. |
Most of this no longer makes sense, since we're dropping the LastLeg IR (#10); all that is still relevant is just adding the llvm dependency/submodule. I don't have a strong opinion about whether we should merge that on its own; we'll probably want it at some point, but it feels a bit weird to me to have the dependency there before we're using it. |
Going to close this, since most of the diff is irrelevant now. We can pull in LLVM as a dependency later when we need it. |
Quoting Alex Knauth (2022-03-29 00:25:43)
Is "effectful" really the right word for this then? Plenty of effects
don't need a transaction boundary, and a transaction boundary doesn't
happen "after" an effect necessarily, it happens before the next
participant's effect.
It is definitely not the right word, you're correct. Maybe we should
punt this conversation until I've finished up the pass I'm doing
reworking the Ast here anyway? There's even a comment that says it's
half-baked :P
|
This pulls in
llvm-hs-pure
as a dependency, and kicks the tires on it by doing some translation of at least types in our last-leg IR to LLVM.I had to vendor the package to get this working; see llvm-hs/llvm-hs#389; when that is merged & released on hackage we can drop the submodule.
This is still a little bit WIP, but I fear if I wait until I've hit a clear milestone, the patch will be a large burden to review.