module Gibbon.Passes.FollowPtrs
  ( followPtrs )
  where

import qualified Data.Map as M
-- import qualified Data.Set as S
import qualified Data.List as L
-- import           Data.Foldable ( foldrM )
import           Data.Maybe ( fromJust )

import           Gibbon.Common
import           Gibbon.Language
import           Gibbon.L2.Syntax as L2

--------------------------------------------------------------------------------

-- | Generate code for indirection and redirection pointer branches in the case expression.
followPtrs :: Prog2 -> PassM Prog2
followPtrs :: Prog2 -> PassM Prog2
followPtrs (Prog DDefs (TyOf (PreExp E2Ext Var (UrTy Var)))
ddefs FunDefs (PreExp E2Ext Var (UrTy Var))
fundefs Maybe
  (PreExp E2Ext Var (UrTy Var), TyOf (PreExp E2Ext Var (UrTy Var)))
mainExp) = do
    [FunDef2]
fds' <- (FunDef2 -> PassM FunDef2) -> [FunDef2] -> PassM [FunDef2]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM FunDef2 -> PassM FunDef2
gofun (FunDefs (PreExp E2Ext Var (UrTy Var)) -> [FunDef2]
forall k a. Map k a -> [a]
M.elems FunDefs (PreExp E2Ext Var (UrTy Var))
fundefs)
    let fundefs' :: FunDefs (PreExp E2Ext Var (UrTy Var))
fundefs' = [(Var, FunDef2)] -> FunDefs (PreExp E2Ext Var (UrTy Var))
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([(Var, FunDef2)] -> FunDefs (PreExp E2Ext Var (UrTy Var)))
-> [(Var, FunDef2)] -> FunDefs (PreExp E2Ext Var (UrTy Var))
forall a b. (a -> b) -> a -> b
$ (FunDef2 -> (Var, FunDef2)) -> [FunDef2] -> [(Var, FunDef2)]
forall a b. (a -> b) -> [a] -> [b]
map (\FunDef2
f -> (FunDef2 -> Var
forall ex. FunDef ex -> Var
funName FunDef2
f,FunDef2
f)) [FunDef2]
fds'
    Prog2 -> PassM Prog2
forall a. a -> PassM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Prog2 -> PassM Prog2) -> Prog2 -> PassM Prog2
forall a b. (a -> b) -> a -> b
$ DDefs (TyOf (PreExp E2Ext Var (UrTy Var)))
-> FunDefs (PreExp E2Ext Var (UrTy Var))
-> Maybe
     (PreExp E2Ext Var (UrTy Var), TyOf (PreExp E2Ext Var (UrTy Var)))
-> Prog2
forall ex.
DDefs (TyOf ex) -> FunDefs ex -> Maybe (ex, TyOf ex) -> Prog ex
Prog DDefs (TyOf (PreExp E2Ext Var (UrTy Var)))
ddefs FunDefs (PreExp E2Ext Var (UrTy Var))
fundefs' Maybe
  (PreExp E2Ext Var (UrTy Var), TyOf (PreExp E2Ext Var (UrTy Var)))
mainExp
  where
    gofun :: FunDef2 -> PassM FunDef2
    gofun :: FunDef2 -> PassM FunDef2
gofun f :: FunDef2
f@FunDef{Var
funName :: forall ex. FunDef ex -> Var
funName :: Var
funName,[Var]
funArgs :: [Var]
funArgs :: forall ex. FunDef ex -> [Var]
funArgs,PreExp E2Ext Var (UrTy Var)
funBody :: PreExp E2Ext Var (UrTy Var)
funBody :: forall ex. FunDef ex -> ex
funBody,ArrowTy (TyOf (PreExp E2Ext Var (UrTy Var)))
funTy :: ArrowTy (TyOf (PreExp E2Ext Var (UrTy Var)))
funTy :: forall ex. FunDef ex -> ArrowTy (TyOf ex)
funTy} = do
      let in_tys :: [UrTy Var]
in_tys = ArrowTy2 (UrTy Var) -> [UrTy Var]
forall ty2. ArrowTy2 ty2 -> [ty2]
arrIns ArrowTy (TyOf (PreExp E2Ext Var (UrTy Var)))
ArrowTy2 (UrTy Var)
funTy
      let out_ty :: UrTy Var
out_ty = ArrowTy2 (UrTy Var) -> UrTy Var
forall ty2. ArrowTy2 ty2 -> ty2
arrOut ArrowTy (TyOf (PreExp E2Ext Var (UrTy Var)))
ArrowTy2 (UrTy Var)
funTy
      PreExp E2Ext Var (UrTy Var)
funBody' <- Map Var (UrTy Var)
-> UrTy Var
-> Var
-> [Var]
-> ArrowTy2 (UrTy Var)
-> PreExp E2Ext Var (UrTy Var)
-> PassM (PreExp E2Ext Var (UrTy Var))
go ([(Var, UrTy Var)] -> Map Var (UrTy Var)
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([Var] -> [UrTy Var] -> [(Var, UrTy Var)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Var]
funArgs [UrTy Var]
in_tys)) UrTy Var
out_ty Var
funName [Var]
funArgs ArrowTy (TyOf (PreExp E2Ext Var (UrTy Var)))
ArrowTy2 (UrTy Var)
funTy PreExp E2Ext Var (UrTy Var)
funBody
      FunDef2 -> PassM FunDef2
forall a. a -> PassM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (FunDef2 -> PassM FunDef2) -> FunDef2 -> PassM FunDef2
forall a b. (a -> b) -> a -> b
$ FunDef2
f { funBody :: PreExp E2Ext Var (UrTy Var)
funBody = PreExp E2Ext Var (UrTy Var)
funBody' }

    go :: Map Var (UrTy Var)
-> UrTy Var
-> Var
-> [Var]
-> ArrowTy2 (UrTy Var)
-> PreExp E2Ext Var (UrTy Var)
-> PassM (PreExp E2Ext Var (UrTy Var))
go Map Var (UrTy Var)
env  UrTy Var
out_ty Var
funName [Var]
funArgs ArrowTy2 (UrTy Var)
funTy PreExp E2Ext Var (UrTy Var)
e =
      case PreExp E2Ext Var (UrTy Var)
e of
          CaseE PreExp E2Ext Var (UrTy Var)
scrt [(DataCon, [(Var, Var)], PreExp E2Ext Var (UrTy Var))]
brs -> do
            let VarE Var
scrtv = PreExp E2Ext Var (UrTy Var)
scrt
                PackedTy DataCon
tycon Var
scrt_loc = Map Var (UrTy Var)
env Map Var (UrTy Var) -> Var -> UrTy Var
forall a b.
(Ord a, Out a, Out b, Show a, HasCallStack) =>
Map a b -> a -> b
# Var
scrtv
                DDef{[(DataCon, [(IsBoxed, UrTy Var)])]
dataCons :: [(DataCon, [(IsBoxed, UrTy Var)])]
dataCons :: forall a. DDef a -> [(DataCon, [(IsBoxed, a)])]
dataCons} = DDefs (UrTy Var) -> DataCon -> DDef (UrTy Var)
forall a. Out a => DDefs a -> DataCon -> DDef a
lookupDDef DDefs (TyOf (PreExp E2Ext Var (UrTy Var)))
DDefs (UrTy Var)
ddefs DataCon
tycon

            Var
indir_ptrv <- Var -> PassM Var
forall (m :: * -> *). MonadState Int m => Var -> m Var
gensym Var
"indr"
            Var
indir_ptrloc <- Var -> PassM Var
forall (m :: * -> *). MonadState Int m => Var -> m Var
gensym Var
"case"
            Var
jump <- Var -> PassM Var
forall (m :: * -> *). MonadState Int m => Var -> m Var
gensym Var
"jump"
            Var
callv <- Var -> PassM Var
forall (m :: * -> *). MonadState Int m => Var -> m Var
gensym Var
"call"
            let _effs :: Set Effect
_effs = ArrowTy2 (UrTy Var) -> Set Effect
forall ty2. ArrowTy2 ty2 -> Set Effect
arrEffs ArrowTy2 (UrTy Var)
funTy
            [Var]
endofs <- (LocRet -> PassM Var) -> [LocRet] -> PassM [Var]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (\LocRet
_ -> Var -> PassM Var
forall (m :: * -> *). MonadState Int m => Var -> m Var
gensym Var
"endof") (ArrowTy2 (UrTy Var) -> [LocRet]
forall ty2. ArrowTy2 ty2 -> [LocRet]
locRets ArrowTy2 (UrTy Var)
funTy)
            let ret_endofs :: [Var]
ret_endofs = ((Var, LocRet) -> [Var] -> [Var])
-> [Var] -> [(Var, LocRet)] -> [Var]
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\(Var
end, (EndOf (LRM Var
loc Region
_ Modality
_))) [Var]
acc ->
                                      if Var
loc Var -> Var -> IsBoxed
forall a. Eq a => a -> a -> IsBoxed
== Var
scrt_loc
                                      then Var
jump Var -> [Var] -> [Var]
forall a. a -> [a] -> [a]
: [Var]
acc
                                      else Var
end Var -> [Var] -> [Var]
forall a. a -> [a] -> [a]
: [Var]
acc)
                             []
                             ([Var] -> [LocRet] -> [(Var, LocRet)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Var]
endofs (ArrowTy2 (UrTy Var) -> [LocRet]
forall ty2. ArrowTy2 ty2 -> [LocRet]
locRets ArrowTy2 (UrTy Var)
funTy))
            let args :: [PreExp E2Ext Var (UrTy Var)]
args = (Var
 -> [PreExp E2Ext Var (UrTy Var)] -> [PreExp E2Ext Var (UrTy Var)])
-> [PreExp E2Ext Var (UrTy Var)]
-> [Var]
-> [PreExp E2Ext Var (UrTy Var)]
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\Var
v [PreExp E2Ext Var (UrTy Var)]
acc -> if Var
v Var -> Var -> IsBoxed
forall a. Eq a => a -> a -> IsBoxed
== Var
scrtv
                                        then ((Var -> PreExp E2Ext Var (UrTy Var)
forall (ext :: * -> * -> *) loc dec. Var -> PreExp ext loc dec
VarE Var
indir_ptrv) PreExp E2Ext Var (UrTy Var)
-> [PreExp E2Ext Var (UrTy Var)] -> [PreExp E2Ext Var (UrTy Var)]
forall a. a -> [a] -> [a]
: [PreExp E2Ext Var (UrTy Var)]
acc)
                                        else (Var -> PreExp E2Ext Var (UrTy Var)
forall (ext :: * -> * -> *) loc dec. Var -> PreExp ext loc dec
VarE Var
v PreExp E2Ext Var (UrTy Var)
-> [PreExp E2Ext Var (UrTy Var)] -> [PreExp E2Ext Var (UrTy Var)]
forall a. a -> [a] -> [a]
: [PreExp E2Ext Var (UrTy Var)]
acc))
                             [] [Var]
funArgs
            let in_locs :: [Var]
in_locs = (Var -> [Var] -> [Var]) -> [Var] -> [Var] -> [Var]
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\Var
loc [Var]
acc -> if Var
loc Var -> Var -> IsBoxed
forall a. Eq a => a -> a -> IsBoxed
==  Var
scrt_loc then (Var
indir_ptrv Var -> [Var] -> [Var]
forall a. a -> [a] -> [a]
: [Var]
acc) else (Var
loc Var -> [Var] -> [Var]
forall a. a -> [a] -> [a]
: [Var]
acc)) [] (ArrowTy2 (UrTy Var) -> [Var]
forall ty2. ArrowTy2 ty2 -> [Var]
inLocVars ArrowTy2 (UrTy Var)
funTy)
            let out_locs :: [Var]
out_locs = ArrowTy2 (UrTy Var) -> [Var]
forall ty2. ArrowTy2 ty2 -> [Var]
outLocVars ArrowTy2 (UrTy Var)
funTy
            Var
wc <- Var -> PassM Var
forall (m :: * -> *). MonadState Int m => Var -> m Var
gensym Var
"wildcard"
            let indir_bod :: PreExp E2Ext Var (UrTy Var)
indir_bod = E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var)
forall (ext :: * -> * -> *) loc dec.
ext loc dec -> PreExp ext loc dec
Ext (E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var))
-> E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var)
forall a b. (a -> b) -> a -> b
$ Var
-> PreLocExp Var
-> PreExp E2Ext Var (UrTy Var)
-> E2Ext Var (UrTy Var)
forall loc dec. Var -> PreLocExp loc -> E2 loc dec -> E2Ext loc dec
LetLocE Var
jump (Int -> Var -> PreLocExp Var
forall loc. Int -> loc -> PreLocExp loc
AfterConstantLE Int
8 Var
indir_ptrloc) (PreExp E2Ext Var (UrTy Var) -> E2Ext Var (UrTy Var))
-> PreExp E2Ext Var (UrTy Var) -> E2Ext Var (UrTy Var)
forall a b. (a -> b) -> a -> b
$
                            (if Var -> IsBoxed
isPrinterName Var
funName then (Var, [Var], UrTy Var, PreExp E2Ext Var (UrTy Var))
-> PreExp E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var)
forall (ext :: * -> * -> *) loc dec.
(Var, [loc], dec, PreExp ext loc dec)
-> PreExp ext loc dec -> PreExp ext loc dec
LetE (Var
wc,[],[UrTy Var] -> UrTy Var
forall loc. [UrTy loc] -> UrTy loc
ProdTy[],Prim (UrTy Var)
-> [PreExp E2Ext Var (UrTy Var)] -> PreExp E2Ext Var (UrTy Var)
forall (ext :: * -> * -> *) loc dec.
Prim dec -> [PreExp ext loc dec] -> PreExp ext loc dec
PrimAppE Prim (UrTy Var)
forall ty. Prim ty
PrintSym [Var -> PreExp E2Ext Var (UrTy Var)
forall (ext :: * -> * -> *) loc dec. Var -> PreExp ext loc dec
LitSymE (DataCon -> Var
toVar DataCon
" ->i ")]) else PreExp E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var)
forall a. a -> a
id) (PreExp E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var))
-> PreExp E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var)
forall a b. (a -> b) -> a -> b
$
                            (Var, [Var], UrTy Var, PreExp E2Ext Var (UrTy Var))
-> PreExp E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var)
forall (ext :: * -> * -> *) loc dec.
(Var, [loc], dec, PreExp ext loc dec)
-> PreExp ext loc dec -> PreExp ext loc dec
LetE (Var
callv,[Var]
endofs,UrTy Var
out_ty,Var
-> [Var]
-> [PreExp E2Ext Var (UrTy Var)]
-> PreExp E2Ext Var (UrTy Var)
forall (ext :: * -> * -> *) loc dec.
Var -> [loc] -> [PreExp ext loc dec] -> PreExp ext loc dec
AppE Var
funName ([Var]
in_locs [Var] -> [Var] -> [Var]
forall a. [a] -> [a] -> [a]
++ [Var]
out_locs) [PreExp E2Ext Var (UrTy Var)]
args) (PreExp E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var))
-> PreExp E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var)
forall a b. (a -> b) -> a -> b
$
                            E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var)
forall (ext :: * -> * -> *) loc dec.
ext loc dec -> PreExp ext loc dec
Ext ([Var] -> Var -> E2Ext Var (UrTy Var)
forall loc dec. [loc] -> Var -> E2Ext loc dec
RetE [Var]
ret_endofs Var
callv)
            let indir_dcon :: DataCon
indir_dcon = (DataCon, [(IsBoxed, UrTy Var)]) -> DataCon
forall a b. (a, b) -> a
fst ((DataCon, [(IsBoxed, UrTy Var)]) -> DataCon)
-> (DataCon, [(IsBoxed, UrTy Var)]) -> DataCon
forall a b. (a -> b) -> a -> b
$ Maybe (DataCon, [(IsBoxed, UrTy Var)])
-> (DataCon, [(IsBoxed, UrTy Var)])
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe (DataCon, [(IsBoxed, UrTy Var)])
 -> (DataCon, [(IsBoxed, UrTy Var)]))
-> Maybe (DataCon, [(IsBoxed, UrTy Var)])
-> (DataCon, [(IsBoxed, UrTy Var)])
forall a b. (a -> b) -> a -> b
$ ((DataCon, [(IsBoxed, UrTy Var)]) -> IsBoxed)
-> [(DataCon, [(IsBoxed, UrTy Var)])]
-> Maybe (DataCon, [(IsBoxed, UrTy Var)])
forall (t :: * -> *) a.
Foldable t =>
(a -> IsBoxed) -> t a -> Maybe a
L.find (DataCon -> IsBoxed
isIndirectionTag (DataCon -> IsBoxed)
-> ((DataCon, [(IsBoxed, UrTy Var)]) -> DataCon)
-> (DataCon, [(IsBoxed, UrTy Var)])
-> IsBoxed
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (DataCon, [(IsBoxed, UrTy Var)]) -> DataCon
forall a b. (a, b) -> a
fst) [(DataCon, [(IsBoxed, UrTy Var)])]
dataCons
            let indir_br :: (DataCon, [(Var, Var)], PreExp E2Ext Var (UrTy Var))
indir_br = (DataCon
indir_dcon,[(Var
indir_ptrv,Var
indir_ptrloc)],PreExp E2Ext Var (UrTy Var)
indir_bod)
            ----------------------------------------
            let redir_dcon :: DataCon
redir_dcon = (DataCon, [(IsBoxed, UrTy Var)]) -> DataCon
forall a b. (a, b) -> a
fst ((DataCon, [(IsBoxed, UrTy Var)]) -> DataCon)
-> (DataCon, [(IsBoxed, UrTy Var)]) -> DataCon
forall a b. (a -> b) -> a -> b
$ Maybe (DataCon, [(IsBoxed, UrTy Var)])
-> (DataCon, [(IsBoxed, UrTy Var)])
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe (DataCon, [(IsBoxed, UrTy Var)])
 -> (DataCon, [(IsBoxed, UrTy Var)]))
-> Maybe (DataCon, [(IsBoxed, UrTy Var)])
-> (DataCon, [(IsBoxed, UrTy Var)])
forall a b. (a -> b) -> a -> b
$ ((DataCon, [(IsBoxed, UrTy Var)]) -> IsBoxed)
-> [(DataCon, [(IsBoxed, UrTy Var)])]
-> Maybe (DataCon, [(IsBoxed, UrTy Var)])
forall (t :: * -> *) a.
Foldable t =>
(a -> IsBoxed) -> t a -> Maybe a
L.find (DataCon -> IsBoxed
isRedirectionTag (DataCon -> IsBoxed)
-> ((DataCon, [(IsBoxed, UrTy Var)]) -> DataCon)
-> (DataCon, [(IsBoxed, UrTy Var)])
-> IsBoxed
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (DataCon, [(IsBoxed, UrTy Var)]) -> DataCon
forall a b. (a, b) -> a
fst) [(DataCon, [(IsBoxed, UrTy Var)])]
dataCons
            let redir_bod :: PreExp E2Ext Var (UrTy Var)
redir_bod = (if Var -> IsBoxed
isPrinterName Var
funName then (Var, [Var], UrTy Var, PreExp E2Ext Var (UrTy Var))
-> PreExp E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var)
forall (ext :: * -> * -> *) loc dec.
(Var, [loc], dec, PreExp ext loc dec)
-> PreExp ext loc dec -> PreExp ext loc dec
LetE (Var
wc,[],[UrTy Var] -> UrTy Var
forall loc. [UrTy loc] -> UrTy loc
ProdTy[],Prim (UrTy Var)
-> [PreExp E2Ext Var (UrTy Var)] -> PreExp E2Ext Var (UrTy Var)
forall (ext :: * -> * -> *) loc dec.
Prim dec -> [PreExp ext loc dec] -> PreExp ext loc dec
PrimAppE Prim (UrTy Var)
forall ty. Prim ty
PrintSym [Var -> PreExp E2Ext Var (UrTy Var)
forall (ext :: * -> * -> *) loc dec. Var -> PreExp ext loc dec
LitSymE (DataCon -> Var
toVar DataCon
" ->r ")]) else PreExp E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var)
forall a. a -> a
id) (PreExp E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var))
-> PreExp E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var)
forall a b. (a -> b) -> a -> b
$
                            (Var, [Var], UrTy Var, PreExp E2Ext Var (UrTy Var))
-> PreExp E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var)
forall (ext :: * -> * -> *) loc dec.
(Var, [loc], dec, PreExp ext loc dec)
-> PreExp ext loc dec -> PreExp ext loc dec
LetE (Var
callv,[Var]
endofs,UrTy Var
out_ty,Var
-> [Var]
-> [PreExp E2Ext Var (UrTy Var)]
-> PreExp E2Ext Var (UrTy Var)
forall (ext :: * -> * -> *) loc dec.
Var -> [loc] -> [PreExp ext loc dec] -> PreExp ext loc dec
AppE Var
funName ([Var]
in_locs [Var] -> [Var] -> [Var]
forall a. [a] -> [a] -> [a]
++ [Var]
out_locs) [PreExp E2Ext Var (UrTy Var)]
args) (PreExp E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var))
-> PreExp E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var)
forall a b. (a -> b) -> a -> b
$
                            E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var)
forall (ext :: * -> * -> *) loc dec.
ext loc dec -> PreExp ext loc dec
Ext ([Var] -> Var -> E2Ext Var (UrTy Var)
forall loc dec. [loc] -> Var -> E2Ext loc dec
RetE [Var]
endofs Var
callv)
            let redir_br :: (DataCon, [(Var, Var)], PreExp E2Ext Var (UrTy Var))
redir_br = (DataCon
redir_dcon,[(Var
indir_ptrv,Var
indir_ptrloc)],PreExp E2Ext Var (UrTy Var)
redir_bod)
            ----------------------------------------
            (PreExp E2Ext Var (UrTy Var) -> PassM (PreExp E2Ext Var (UrTy Var))
forall a. a -> PassM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreExp E2Ext Var (UrTy Var)
-> [(DataCon, [(Var, Var)], PreExp E2Ext Var (UrTy Var))]
-> PreExp E2Ext Var (UrTy Var)
forall (ext :: * -> * -> *) loc dec.
PreExp ext loc dec
-> [(DataCon, [(Var, loc)], PreExp ext loc dec)]
-> PreExp ext loc dec
CaseE PreExp E2Ext Var (UrTy Var)
scrt ([(DataCon, [(Var, Var)], PreExp E2Ext Var (UrTy Var))]
brs [(DataCon, [(Var, Var)], PreExp E2Ext Var (UrTy Var))]
-> [(DataCon, [(Var, Var)], PreExp E2Ext Var (UrTy Var))]
-> [(DataCon, [(Var, Var)], PreExp E2Ext Var (UrTy Var))]
forall a. [a] -> [a] -> [a]
++ [(DataCon, [(Var, Var)], PreExp E2Ext Var (UrTy Var))
indir_br,(DataCon, [(Var, Var)], PreExp E2Ext Var (UrTy Var))
redir_br])))
          IfE PreExp E2Ext Var (UrTy Var)
a PreExp E2Ext Var (UrTy Var)
b PreExp E2Ext Var (UrTy Var)
c -> do
            PreExp E2Ext Var (UrTy Var)
a' <- Map Var (UrTy Var)
-> UrTy Var
-> Var
-> [Var]
-> ArrowTy2 (UrTy Var)
-> PreExp E2Ext Var (UrTy Var)
-> PassM (PreExp E2Ext Var (UrTy Var))
go Map Var (UrTy Var)
env  UrTy Var
out_ty Var
funName [Var]
funArgs ArrowTy2 (UrTy Var)
funTy PreExp E2Ext Var (UrTy Var)
a
            PreExp E2Ext Var (UrTy Var)
b' <- Map Var (UrTy Var)
-> UrTy Var
-> Var
-> [Var]
-> ArrowTy2 (UrTy Var)
-> PreExp E2Ext Var (UrTy Var)
-> PassM (PreExp E2Ext Var (UrTy Var))
go Map Var (UrTy Var)
env  UrTy Var
out_ty Var
funName [Var]
funArgs ArrowTy2 (UrTy Var)
funTy PreExp E2Ext Var (UrTy Var)
b
            PreExp E2Ext Var (UrTy Var)
c' <- Map Var (UrTy Var)
-> UrTy Var
-> Var
-> [Var]
-> ArrowTy2 (UrTy Var)
-> PreExp E2Ext Var (UrTy Var)
-> PassM (PreExp E2Ext Var (UrTy Var))
go Map Var (UrTy Var)
env  UrTy Var
out_ty Var
funName [Var]
funArgs ArrowTy2 (UrTy Var)
funTy PreExp E2Ext Var (UrTy Var)
c
            PreExp E2Ext Var (UrTy Var) -> PassM (PreExp E2Ext Var (UrTy Var))
forall a. a -> PassM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PreExp E2Ext Var (UrTy Var)
 -> PassM (PreExp E2Ext Var (UrTy Var)))
-> PreExp E2Ext Var (UrTy Var)
-> PassM (PreExp E2Ext Var (UrTy Var))
forall a b. (a -> b) -> a -> b
$ PreExp E2Ext Var (UrTy Var)
-> PreExp E2Ext Var (UrTy Var)
-> PreExp E2Ext Var (UrTy Var)
-> PreExp E2Ext Var (UrTy Var)
forall (ext :: * -> * -> *) loc dec.
PreExp ext loc dec
-> PreExp ext loc dec -> PreExp ext loc dec -> PreExp ext loc dec
IfE PreExp E2Ext Var (UrTy Var)
a' PreExp E2Ext Var (UrTy Var)
b' PreExp E2Ext Var (UrTy Var)
c'

          WithArenaE Var
v PreExp E2Ext Var (UrTy Var)
bod -> (Var -> PreExp E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var)
forall (ext :: * -> * -> *) loc dec.
Var -> PreExp ext loc dec -> PreExp ext loc dec
WithArenaE Var
v) (PreExp E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var))
-> PassM (PreExp E2Ext Var (UrTy Var))
-> PassM (PreExp E2Ext Var (UrTy Var))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map Var (UrTy Var)
-> UrTy Var
-> Var
-> [Var]
-> ArrowTy2 (UrTy Var)
-> PreExp E2Ext Var (UrTy Var)
-> PassM (PreExp E2Ext Var (UrTy Var))
go Map Var (UrTy Var)
env  UrTy Var
out_ty Var
funName [Var]
funArgs ArrowTy2 (UrTy Var)
funTy PreExp E2Ext Var (UrTy Var)
bod

          LetE (Var
v,[Var]
locs,UrTy Var
ty,PreExp E2Ext Var (UrTy Var)
rhs) PreExp E2Ext Var (UrTy Var)
bod ->
            (Var, [Var], UrTy Var, PreExp E2Ext Var (UrTy Var))
-> PreExp E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var)
forall (ext :: * -> * -> *) loc dec.
(Var, [loc], dec, PreExp ext loc dec)
-> PreExp ext loc dec -> PreExp ext loc dec
LetE (Var
v,[Var]
locs,UrTy Var
ty,PreExp E2Ext Var (UrTy Var)
rhs) (PreExp E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var))
-> PassM (PreExp E2Ext Var (UrTy Var))
-> PassM (PreExp E2Ext Var (UrTy Var))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map Var (UrTy Var)
-> UrTy Var
-> Var
-> [Var]
-> ArrowTy2 (UrTy Var)
-> PreExp E2Ext Var (UrTy Var)
-> PassM (PreExp E2Ext Var (UrTy Var))
go (Var -> UrTy Var -> Map Var (UrTy Var) -> Map Var (UrTy Var)
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert Var
v UrTy Var
ty Map Var (UrTy Var)
env)  UrTy Var
out_ty Var
funName [Var]
funArgs ArrowTy2 (UrTy Var)
funTy  PreExp E2Ext Var (UrTy Var)
bod

          Ext (LetLocE Var
loc PreLocExp Var
rhs PreExp E2Ext Var (UrTy Var)
bod) ->
            E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var)
forall (ext :: * -> * -> *) loc dec.
ext loc dec -> PreExp ext loc dec
Ext (E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var))
-> (PreExp E2Ext Var (UrTy Var) -> E2Ext Var (UrTy Var))
-> PreExp E2Ext Var (UrTy Var)
-> PreExp E2Ext Var (UrTy Var)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Var
-> PreLocExp Var
-> PreExp E2Ext Var (UrTy Var)
-> E2Ext Var (UrTy Var)
forall loc dec. Var -> PreLocExp loc -> E2 loc dec -> E2Ext loc dec
LetLocE Var
loc PreLocExp Var
rhs) (PreExp E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var))
-> PassM (PreExp E2Ext Var (UrTy Var))
-> PassM (PreExp E2Ext Var (UrTy Var))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map Var (UrTy Var)
-> UrTy Var
-> Var
-> [Var]
-> ArrowTy2 (UrTy Var)
-> PreExp E2Ext Var (UrTy Var)
-> PassM (PreExp E2Ext Var (UrTy Var))
go Map Var (UrTy Var)
env  UrTy Var
out_ty Var
funName [Var]
funArgs ArrowTy2 (UrTy Var)
funTy  PreExp E2Ext Var (UrTy Var)
bod

          Ext (LetRegionE Region
reg RegionSize
sz Maybe RegionType
ty PreExp E2Ext Var (UrTy Var)
bod) ->
            E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var)
forall (ext :: * -> * -> *) loc dec.
ext loc dec -> PreExp ext loc dec
Ext (E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var))
-> (PreExp E2Ext Var (UrTy Var) -> E2Ext Var (UrTy Var))
-> PreExp E2Ext Var (UrTy Var)
-> PreExp E2Ext Var (UrTy Var)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Region
-> RegionSize
-> Maybe RegionType
-> PreExp E2Ext Var (UrTy Var)
-> E2Ext Var (UrTy Var)
forall loc dec.
Region
-> RegionSize -> Maybe RegionType -> E2 loc dec -> E2Ext loc dec
LetRegionE Region
reg RegionSize
sz Maybe RegionType
ty) (PreExp E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var))
-> PassM (PreExp E2Ext Var (UrTy Var))
-> PassM (PreExp E2Ext Var (UrTy Var))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map Var (UrTy Var)
-> UrTy Var
-> Var
-> [Var]
-> ArrowTy2 (UrTy Var)
-> PreExp E2Ext Var (UrTy Var)
-> PassM (PreExp E2Ext Var (UrTy Var))
go Map Var (UrTy Var)
env  UrTy Var
out_ty Var
funName [Var]
funArgs ArrowTy2 (UrTy Var)
funTy  PreExp E2Ext Var (UrTy Var)
bod

          Ext (LetParRegionE Region
reg RegionSize
sz Maybe RegionType
ty PreExp E2Ext Var (UrTy Var)
bod) ->
            E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var)
forall (ext :: * -> * -> *) loc dec.
ext loc dec -> PreExp ext loc dec
Ext (E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var))
-> (PreExp E2Ext Var (UrTy Var) -> E2Ext Var (UrTy Var))
-> PreExp E2Ext Var (UrTy Var)
-> PreExp E2Ext Var (UrTy Var)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Region
-> RegionSize
-> Maybe RegionType
-> PreExp E2Ext Var (UrTy Var)
-> E2Ext Var (UrTy Var)
forall loc dec.
Region
-> RegionSize -> Maybe RegionType -> E2 loc dec -> E2Ext loc dec
LetParRegionE Region
reg RegionSize
sz Maybe RegionType
ty) (PreExp E2Ext Var (UrTy Var) -> PreExp E2Ext Var (UrTy Var))
-> PassM (PreExp E2Ext Var (UrTy Var))
-> PassM (PreExp E2Ext Var (UrTy Var))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map Var (UrTy Var)
-> UrTy Var
-> Var
-> [Var]
-> ArrowTy2 (UrTy Var)
-> PreExp E2Ext Var (UrTy Var)
-> PassM (PreExp E2Ext Var (UrTy Var))
go Map Var (UrTy Var)
env  UrTy Var
out_ty Var
funName [Var]
funArgs ArrowTy2 (UrTy Var)
funTy  PreExp E2Ext Var (UrTy Var)
bod

          PreExp E2Ext Var (UrTy Var)
_ -> PreExp E2Ext Var (UrTy Var) -> PassM (PreExp E2Ext Var (UrTy Var))
forall a. a -> PassM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PreExp E2Ext Var (UrTy Var)
e