-
Notifications
You must be signed in to change notification settings - Fork 0
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
Add tuple return values for par exprs in codegen #157
base: main
Are you sure you want to change the base?
Conversation
-- given a list of par return vals and their types, wrap the return vals in a tuple | ||
genParRetVal :: [C.Exp] -> [I.Type] -> GenFn (C.Exp, [C.BlockItem]) | ||
genParRetVal [] _ = fail "par should have 2 or more return values" | ||
genParRetVal [_] _ = fail "par should have 2 or more return values" | ||
genParRetVal rets@(ret0 : ret1 : _) retTys = do | ||
-- TODO: given n ret vals, return an n-ary tuple | ||
when (length rets /= length retTys) $ do fail "lists of return vals and types must be same length" | ||
let dcon = I.tempTupleId (length rets) | ||
let dty = I.tempTuple retTys | ||
onHeap <- getsDCon dconOnHeap dcon | ||
unless onHeap $ do | ||
fail $ "Cannot handle packed fields yet, for: " ++ show dcon | ||
construct <- getsDCon dconConstruct dcon | ||
destruct <- getsDCon dconDestruct dcon | ||
tmp <- genTmp dty | ||
let alloc = [[citem|$exp:tmp = $exp:construct;|]] | ||
initField y i = [citem|$exp:(destruct i tmp) = $exp:y;|] | ||
initFields = zipWith initField [ret0, ret1] [0 ..] -- puts first two return vals in a 2-tuple for now | ||
return (tmp, alloc ++ initFields) |
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.
creates a 2-tuple with the first two ret vals of par as its arguments
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.
Here's a quick review! But I have the following questions:
- Why isn't codegen for more than 2 tuples supported? It doesn't seem like the logic is any different from regular tuples.
- Why do we need to define
type Pair2 a b
in the source code, and why is it written as that (instead of(a, b)
)?
Otherwise, the code looks really good, but those questions need to be answered/addressed before we can merge this in.
@@ -1,3 +1,6 @@ | |||
type Pair2 a b |
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.
Why was this not there before? And is it being used?
import Control.Monad (foldM, unless) | ||
import Control.Monad (foldM, unless, when) | ||
|
||
-- import Control.Monad (foldM, unless) |
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.
Remove the commented-out import
@@ -809,12 +811,31 @@ genPrim I.Par procs _ = do | |||
return (ret, fnStms ++ argStms, appStms) | |||
apply (e, _) = do | |||
fail $ "Cannot compile par with non-application expression: " ++ show e | |||
-- given a list of par return vals and their types, wrap the return vals in a tuple | |||
genParRetVal :: [C.Exp] -> [I.Type] -> GenFn (C.Exp, [C.BlockItem]) | |||
genParRetVal [] _ = fail "par should have 2 or more return values" |
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.
nit: You can just put this as a _
wildcard case after the rets@(ret0:ret1:_)
case, to consolidate them
genParRetVal [_] _ = fail "par should have 2 or more return values" | ||
genParRetVal rets@(ret0 : ret1 : _) retTys = do | ||
-- TODO: given n ret vals, return an n-ary tuple | ||
when (length rets /= length retTys) $ do fail "lists of return vals and types must be same length" |
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.
Put the fail
statement on the line after the do
, i.e.,
when (length rets /= length retTys) $ do
fail "lists of return vals and types must be same length"
-- TODO: given n ret vals, return an n-ary tuple | ||
when (length rets /= length retTys) $ do fail "lists of return vals and types must be same length" | ||
let dcon = I.tempTupleId (length rets) | ||
let dty = I.tempTuple retTys |
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.
Remove the redundant let
here, should just be:
let dcon = ...
dty = ...
tmp <- genTmp dty | ||
let alloc = [[citem|$exp:tmp = $exp:construct;|]] | ||
initField y i = [citem|$exp:(destruct i tmp) = $exp:y;|] | ||
initFields = zipWith initField [ret0, ret1] [0 ..] -- puts first two return vals in a 2-tuple 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.
Why only the first two values? Why not zipWith initField rets [0..]
?
FYI 8d50b53 merged in support for tuples without having to define the |
This PR modifies code generation so that the return values of par expressions are saved in a 2-tuple.