{-# LANGUAGE FlexibleInstances #-}
module Gibbon.Passes.CalculateBounds ( inferRegSize ) where

import           Gibbon.Common
import qualified Data.Map                      as M
import           Gibbon.L2.Syntax
import qualified Data.List as L
import           Debug.Trace
import           Control.Monad

type LocationRegionMapping = M.Map LocVar Var
type LocationOffsetMapping = M.Map LocVar RegionSize
type VarSizeMapping = M.Map Var RegionSize
type VarLocMapping = M.Map Var LocVar
type RegionSizeMapping = M.Map Var RegionSize
type RegionTypeMapping = M.Map Var RegionType

inferRegSize :: Prog2 -> PassM Prog2
inferRegSize :: Prog2 -> PassM Prog2
inferRegSize = Prog2 -> PassM Prog2
calculateBounds

calculateBounds :: Prog2 -> PassM Prog2
calculateBounds :: Prog2 -> PassM Prog2
calculateBounds Prog { DDefs (TyOf Exp2)
ddefs :: DDefs (TyOf Exp2)
ddefs :: forall ex. Prog ex -> DDefs (TyOf ex)
ddefs, FunDefs Exp2
fundefs :: FunDefs Exp2
fundefs :: forall ex. Prog ex -> FunDefs ex
fundefs, Maybe (Exp2, TyOf Exp2)
mainExp :: Maybe (Exp2, TyOf Exp2)
mainExp :: forall ex. Prog ex -> Maybe (ex, TyOf ex)
mainExp } = do
  let env2 :: Env2 Ty2
env2 = TyEnv Ty2 -> TyEnv (ArrowTy Ty2) -> Env2 Ty2
forall a. TyEnv a -> TyEnv (ArrowTy a) -> Env2 a
Env2 TyEnv Ty2
forall k a. Map k a
M.empty (FunDefs Exp2 -> TyEnv (ArrowTy (TyOf Exp2))
forall a. FunDefs a -> TyEnv (ArrowTy (TyOf a))
initFunEnv FunDefs Exp2
fundefs)
  FunDefs Exp2
fundefs' <- (FunDef2 -> PassM FunDef2) -> FunDefs Exp2 -> PassM (FunDefs Exp2)
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) -> Map Var a -> m (Map Var b)
mapM (DDefs Ty2 -> Env2 Ty2 -> VarSizeMapping -> FunDef2 -> PassM FunDef2
calculateBoundsFun DDefs (TyOf Exp2)
DDefs Ty2
ddefs Env2 Ty2
env2 VarSizeMapping
forall k a. Map k a
M.empty) FunDefs Exp2
fundefs
  Maybe (Exp2, Ty2)
mainExp' <- case Maybe (Exp2, TyOf Exp2)
mainExp of
    Maybe (Exp2, TyOf Exp2)
Nothing       -> Maybe (Exp2, Ty2) -> PassM (Maybe (Exp2, Ty2))
forall a. a -> PassM a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Exp2, Ty2)
forall a. Maybe a
Nothing
    Just (Exp2
mn, TyOf Exp2
ty) -> (Exp2, Ty2) -> Maybe (Exp2, Ty2)
forall a. a -> Maybe a
Just ((Exp2, Ty2) -> Maybe (Exp2, Ty2))
-> ((Exp2, VarSizeMapping, RegionTypeMapping) -> (Exp2, Ty2))
-> (Exp2, VarSizeMapping, RegionTypeMapping)
-> Maybe (Exp2, Ty2)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (, TyOf Exp2
Ty2
ty) (Exp2 -> (Exp2, Ty2))
-> ((Exp2, VarSizeMapping, RegionTypeMapping) -> Exp2)
-> (Exp2, VarSizeMapping, RegionTypeMapping)
-> (Exp2, Ty2)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Exp2, VarSizeMapping, RegionTypeMapping) -> Exp2
forall a b c. (a, b, c) -> a
fst3 ((Exp2, VarSizeMapping, RegionTypeMapping) -> Maybe (Exp2, Ty2))
-> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
-> PassM (Maybe (Exp2, Ty2))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DDefs Ty2
-> Env2 Ty2
-> VarSizeMapping
-> VarLocMapping
-> VarLocMapping
-> VarSizeMapping
-> VarSizeMapping
-> RegionTypeMapping
-> Exp2
-> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
calculateBoundsExp DDefs (TyOf Exp2)
DDefs Ty2
ddefs Env2 Ty2
env2 VarSizeMapping
forall k a. Map k a
M.empty VarLocMapping
forall k a. Map k a
M.empty VarLocMapping
forall k a. Map k a
M.empty VarSizeMapping
forall k a. Map k a
M.empty VarSizeMapping
forall k a. Map k a
M.empty RegionTypeMapping
forall k a. Map k a
M.empty Exp2
mn
  Prog2 -> PassM Prog2
forall a. a -> PassM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Prog2 -> PassM Prog2) -> Prog2 -> PassM Prog2
forall a b. (a -> b) -> a -> b
$ DDefs (TyOf Exp2)
-> FunDefs Exp2 -> Maybe (Exp2, TyOf Exp2) -> Prog2
forall ex.
DDefs (TyOf ex) -> FunDefs ex -> Maybe (ex, TyOf ex) -> Prog ex
Prog DDefs (TyOf Exp2)
ddefs FunDefs Exp2
fundefs' Maybe (Exp2, TyOf Exp2)
Maybe (Exp2, Ty2)
mainExp'


calculateBoundsFun :: DDefs Ty2 -> Env2 Ty2 -> VarSizeMapping -> FunDef2 -> PassM FunDef2
calculateBoundsFun :: DDefs Ty2 -> Env2 Ty2 -> VarSizeMapping -> FunDef2 -> PassM FunDef2
calculateBoundsFun DDefs Ty2
ddefs Env2 Ty2
env2 VarSizeMapping
varSzEnv f :: FunDef2
f@FunDef { Var
funName :: Var
funName :: forall ex. FunDef ex -> Var
funName, Exp2
funBody :: Exp2
funBody :: forall ex. FunDef ex -> ex
funBody, ArrowTy (TyOf Exp2)
funTy :: ArrowTy (TyOf Exp2)
funTy :: forall ex. FunDef ex -> ArrowTy (TyOf ex)
funTy, [Var]
funArgs :: [Var]
funArgs :: forall ex. FunDef ex -> [Var]
funArgs } = do
  if [Char]
"_" [Char] -> [Char] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`L.isPrefixOf` Var -> [Char]
fromVar Var
funName
    then FunDef2 -> PassM FunDef2
forall a. a -> PassM a
forall (m :: * -> *) a. Monad m => a -> m a
return FunDef2
f
    else do
      let locRegEnv :: VarLocMapping
locRegEnv = [(Var, Var)] -> VarLocMapping
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([(Var, Var)] -> VarLocMapping) -> [(Var, Var)] -> VarLocMapping
forall a b. (a -> b) -> a -> b
$ (LRM -> (Var, Var)) -> [LRM] -> [(Var, Var)]
forall a b. (a -> b) -> [a] -> [b]
map (\LRM
lv -> (LRM -> Var
lrmLoc LRM
lv, Region -> Var
regionToVar (Region -> Var) -> Region -> Var
forall a b. (a -> b) -> a -> b
$ LRM -> Region
lrmReg LRM
lv)) (ArrowTy2 Ty2 -> [LRM]
forall ty2. ArrowTy2 ty2 -> [LRM]
locVars ArrowTy (TyOf Exp2)
ArrowTy2 Ty2
funTy)
      let locTyEnv :: VarSizeMapping
locTyEnv  = (Var -> RegionSize) -> VarLocMapping -> VarSizeMapping
forall a b k. (a -> b) -> Map k a -> Map k b
M.map (RegionSize -> Var -> RegionSize
forall a b. a -> b -> a
const (RegionSize -> Var -> RegionSize)
-> RegionSize -> Var -> RegionSize
forall a b. (a -> b) -> a -> b
$ Int -> RegionSize
BoundedSize Int
0) VarLocMapping
locRegEnv
      let argTys :: TyEnv Ty2
argTys    = [(Var, Ty2)] -> TyEnv Ty2
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([(Var, Ty2)] -> TyEnv Ty2) -> [(Var, Ty2)] -> TyEnv Ty2
forall a b. (a -> b) -> a -> b
$ [Var] -> [Ty2] -> [(Var, Ty2)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Var]
funArgs (ArrowTy2 Ty2 -> [Ty2]
forall ty2. ArrowTy2 ty2 -> [ty2]
arrIns ArrowTy (TyOf Exp2)
ArrowTy2 Ty2
funTy)
      let env2' :: Env2 Ty2
env2'     = Env2 Ty2
env2 { vEnv :: TyEnv Ty2
vEnv = TyEnv Ty2
argTys }
      Exp2
funBody' <- (Exp2, VarSizeMapping, RegionTypeMapping) -> Exp2
forall a b c. (a, b, c) -> a
fst3 ((Exp2, VarSizeMapping, RegionTypeMapping) -> Exp2)
-> PassM (Exp2, VarSizeMapping, RegionTypeMapping) -> PassM Exp2
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DDefs Ty2
-> Env2 Ty2
-> VarSizeMapping
-> VarLocMapping
-> VarLocMapping
-> VarSizeMapping
-> VarSizeMapping
-> RegionTypeMapping
-> Exp2
-> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
calculateBoundsExp DDefs Ty2
ddefs Env2 Ty2
env2' VarSizeMapping
varSzEnv VarLocMapping
forall k a. Map k a
M.empty VarLocMapping
locRegEnv VarSizeMapping
locTyEnv VarSizeMapping
forall k a. Map k a
M.empty RegionTypeMapping
forall k a. Map k a
M.empty Exp2
funBody
      FunDef2 -> PassM FunDef2
forall a. a -> PassM a
forall (m :: * -> *) a. Monad m => a -> m a
return (FunDef2 -> PassM FunDef2) -> FunDef2 -> PassM FunDef2
forall a b. (a -> b) -> a -> b
$ FunDef2
f { funBody :: Exp2
funBody = Exp2
funBody' }

{-
  * We recurse using three mappings (variable => size, location => region and region => size)
  * 1. the variable => size mapping is inferred using type of the variable
  * 2. the location => region mapping is inferred using threading location initializations
  *     using LocVars
  * 3. the region => size mapping is calculated by adding up the incremental offsets from
  *     previous location in the same reigon and then adding the size of the last location/variable
  *     size in the region
  *
  * While recursing we return the
  * 1. the updated expression (i.e. possibly attaching the size of the regions in the expression)
  * 2. the region to size mapping in the expression (which can be used to find maximum size
  *     from all the branches)
  * 3. the region to type mapping in the expression -> based on indirections
  *
  * NOTE: since input and output regions are not created inside the function,
  * we will not update the region size inside that function .
-}
calculateBoundsExp
  :: DDefs Ty2 -- ^ Data Definitions
  -> Env2 Ty2 -- ^ Type Environment (Variables + Functions)
  -> VarSizeMapping -- ^ var => size
  -> VarLocMapping -- ^ var => location
  -> LocationRegionMapping -- ^ location => region
  -> LocationOffsetMapping -- ^ location => offset
  -> RegionSizeMapping -- ^ region => size
  -> RegionTypeMapping -- ^ region => type
  -> Exp2 -- ^ expression
  -> PassM (Exp2, RegionSizeMapping, RegionTypeMapping)
calculateBoundsExp :: DDefs Ty2
-> Env2 Ty2
-> VarSizeMapping
-> VarLocMapping
-> VarLocMapping
-> VarSizeMapping
-> VarSizeMapping
-> RegionTypeMapping
-> Exp2
-> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
calculateBoundsExp DDefs Ty2
ddefs Env2 Ty2
env2 VarSizeMapping
varSzEnv VarLocMapping
varLocEnv VarLocMapping
locRegEnv VarSizeMapping
locOffEnv VarSizeMapping
regSzEnv RegionTypeMapping
regTyEnv Exp2
ex = case Exp2
ex of
  Ext (BoundsCheck{}) -> (Exp2, VarSizeMapping, RegionTypeMapping)
-> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a. a -> PassM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Exp2
ex, VarSizeMapping
regSzEnv, RegionTypeMapping
regTyEnv)
  Ext (IndirectionE [Char]
_tycon [Char]
_dcon (Var
fromLoc, Var
_fromvar) (Var
toLoc, Var
_tovar) Exp2
_exp) -> do
    let fromReg :: Var
fromReg = VarLocMapping
locRegEnv VarLocMapping -> Var -> Var
forall a b.
(Ord a, Out a, Out b, Show a, HasCallStack) =>
Map a b -> a -> b
# Var
fromLoc
    let fromOff :: RegionSize
fromOff = VarSizeMapping
locOffEnv VarSizeMapping -> Var -> RegionSize
forall a b.
(Ord a, Out a, Out b, Show a, HasCallStack) =>
Map a b -> a -> b
# Var
fromLoc
    let toOff :: RegionSize
toOff   = VarSizeMapping
locOffEnv VarSizeMapping -> Var -> RegionSize
forall a b.
(Ord a, Out a, Out b, Show a, HasCallStack) =>
Map a b -> a -> b
# Var
toLoc
    let regTy :: RegionType
regTy = RegionType -> Var -> RegionTypeMapping -> RegionType
forall k a. Ord k => a -> k -> Map k a -> a
M.findWithDefault RegionType
IndirectionFree Var
fromReg RegionTypeMapping
regTyEnv RegionType -> RegionType -> RegionType
forall a. Semigroup a => a -> a -> a
<> if RegionSize
toOff RegionSize -> RegionSize -> Bool
forall a. Ord a => a -> a -> Bool
>= RegionSize
fromOff then RegionType
RightwardLocalIndirections else RegionType
LocalIndirections
    let regSz :: RegionSize
regSz   = RegionSize
fromOff RegionSize -> RegionSize -> RegionSize
forall a. Semigroup a => a -> a -> a
<> Int -> RegionSize
BoundedSize Int
9
    (Exp2, VarSizeMapping, RegionTypeMapping)
-> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a. a -> PassM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Exp2
ex, Var -> RegionSize -> VarSizeMapping -> VarSizeMapping
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert Var
fromReg RegionSize
regSz VarSizeMapping
regSzEnv, Var -> RegionType -> RegionTypeMapping -> RegionTypeMapping
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert Var
fromReg RegionType
regTy RegionTypeMapping
regTyEnv)
  VarE Var
_ -> (Exp2, VarSizeMapping, RegionTypeMapping)
-> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a. a -> PassM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Exp2
ex, VarSizeMapping
regSzEnv, RegionTypeMapping
regTyEnv)
  Exp2
_ ->
    let ty :: TyOf Exp2
ty   = DDefs (TyOf Exp2) -> Env2 (TyOf Exp2) -> Exp2 -> TyOf Exp2
forall e.
Typeable e =>
DDefs (TyOf e) -> Env2 (TyOf e) -> e -> TyOf e
gRecoverType DDefs (TyOf Exp2)
DDefs Ty2
ddefs Env2 (TyOf Exp2)
Env2 Ty2
env2 Exp2
ex
        go :: Exp2 -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
go   = DDefs Ty2
-> Env2 Ty2
-> VarSizeMapping
-> VarLocMapping
-> VarLocMapping
-> VarSizeMapping
-> VarSizeMapping
-> RegionTypeMapping
-> Exp2
-> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
calculateBoundsExp DDefs Ty2
ddefs Env2 Ty2
env2 VarSizeMapping
varSzEnv VarLocMapping
varLocEnv VarLocMapping
locRegEnv VarSizeMapping
locOffEnv VarSizeMapping
regSzEnv RegionTypeMapping
regTyEnv
        err :: a
err  = [Char] -> a
forall a. HasCallStack => [Char] -> a
error [Char]
"Should have been covered by sizeOfTy"
        pass :: PassM (Exp2, VarSizeMapping, RegionTypeMapping)
pass = (Exp2, VarSizeMapping, RegionTypeMapping)
-> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a. a -> PassM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Exp2
ex, VarSizeMapping
regSzEnv, RegionTypeMapping
regTyEnv)
    in  case Ty2 -> Maybe Int
forall a. UrTy a -> Maybe Int
sizeOfTy TyOf Exp2
Ty2
ty of
          Just Int
_ -> (Exp2, VarSizeMapping, RegionTypeMapping)
-> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a. a -> PassM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Exp2
ex, VarSizeMapping
regSzEnv, RegionTypeMapping
regTyEnv)
          Maybe Int
_      -> case Exp2
ex of
            LitE    Int
_           -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall {a}. a
err
            CharE   Char
_           -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall {a}. a
err
            FloatE  Double
_           -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall {a}. a
err
            LitSymE Var
_           -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall {a}. a
err
            ProjE{}             -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
pass
            TimeIt{}            -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
pass
            WithArenaE{}        -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
pass
            SpawnE{}            -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
pass
            SyncE{}             -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
pass
            MapE{}              -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
pass
            FoldE{}             -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
pass
            AppE Var
_v [Var]
_locs [Exp2]
_args -> do
              -- TODO traversals
              (Exp2, VarSizeMapping, RegionTypeMapping)
-> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a. a -> PassM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Exp2
ex, VarSizeMapping
regSzEnv, RegionTypeMapping
regTyEnv)
            PrimAppE{}             -> (Exp2, VarSizeMapping, RegionTypeMapping)
-> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a. a -> PassM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Exp2
ex, VarSizeMapping
regSzEnv, RegionTypeMapping
regTyEnv)
            DataConE Var
loc [Char]
dcon [Exp2]
args -> do
              ([Exp2]
_, [VarSizeMapping]
res, [RegionTypeMapping]
rts) <- [(Exp2, VarSizeMapping, RegionTypeMapping)]
-> ([Exp2], [VarSizeMapping], [RegionTypeMapping])
forall a b c. [(a, b, c)] -> ([a], [b], [c])
unzip3 ([(Exp2, VarSizeMapping, RegionTypeMapping)]
 -> ([Exp2], [VarSizeMapping], [RegionTypeMapping]))
-> PassM [(Exp2, VarSizeMapping, RegionTypeMapping)]
-> PassM ([Exp2], [VarSizeMapping], [RegionTypeMapping])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Exp2 -> PassM (Exp2, VarSizeMapping, RegionTypeMapping))
-> [Exp2] -> PassM [(Exp2, VarSizeMapping, RegionTypeMapping)]
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 Exp2 -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
go [Exp2]
args
              (Exp2, VarSizeMapping, RegionTypeMapping)
-> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a. a -> PassM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Var -> [Char] -> [Exp2] -> Exp2
forall (ext :: * -> * -> *) loc dec.
loc -> [Char] -> [PreExp ext loc dec] -> PreExp ext loc dec
DataConE Var
loc [Char]
dcon [Exp2]
args, [VarSizeMapping] -> VarSizeMapping
forall a. Monoid a => [a] -> a
mconcat [VarSizeMapping]
res, [RegionTypeMapping] -> RegionTypeMapping
forall a. Monoid a => [a] -> a
mconcat [RegionTypeMapping]
rts)
            IfE Exp2
cond Exp2
bod1 Exp2
bod2 -> do
              (Exp2
bod1', VarSizeMapping
regSzEnv1, RegionTypeMapping
regTyEnv1) <- Exp2 -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
go Exp2
bod1
              (Exp2
bod2', VarSizeMapping
regSzEnv2, RegionTypeMapping
regTyEnv2) <- Exp2 -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
go Exp2
bod2
              (Exp2, VarSizeMapping, RegionTypeMapping)
-> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a. a -> PassM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Exp2 -> Exp2 -> Exp2 -> Exp2
forall (ext :: * -> * -> *) loc dec.
PreExp ext loc dec
-> PreExp ext loc dec -> PreExp ext loc dec -> PreExp ext loc dec
IfE Exp2
cond Exp2
bod1' Exp2
bod2', (RegionSize -> RegionSize -> RegionSize)
-> VarSizeMapping -> VarSizeMapping -> VarSizeMapping
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
M.unionWith RegionSize -> RegionSize -> RegionSize
forall a. Ord a => a -> a -> a
max VarSizeMapping
regSzEnv1 VarSizeMapping
regSzEnv2, RegionTypeMapping
regTyEnv1 RegionTypeMapping -> RegionTypeMapping -> RegionTypeMapping
forall a. Semigroup a => a -> a -> a
<> RegionTypeMapping
regTyEnv2)
            MkProdE [Exp2]
ls -> do
              ([Exp2]
ls', [VarSizeMapping]
regSzEnvs, [RegionTypeMapping]
regTyEnvs) <- [(Exp2, VarSizeMapping, RegionTypeMapping)]
-> ([Exp2], [VarSizeMapping], [RegionTypeMapping])
forall a b c. [(a, b, c)] -> ([a], [b], [c])
unzip3 ([(Exp2, VarSizeMapping, RegionTypeMapping)]
 -> ([Exp2], [VarSizeMapping], [RegionTypeMapping]))
-> PassM [(Exp2, VarSizeMapping, RegionTypeMapping)]
-> PassM ([Exp2], [VarSizeMapping], [RegionTypeMapping])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Exp2 -> PassM (Exp2, VarSizeMapping, RegionTypeMapping))
-> [Exp2] -> PassM [(Exp2, VarSizeMapping, RegionTypeMapping)]
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 Exp2 -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
go [Exp2]
ls
              (Exp2, VarSizeMapping, RegionTypeMapping)
-> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a. a -> PassM a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Exp2] -> Exp2
forall (ext :: * -> * -> *) loc dec.
[PreExp ext loc dec] -> PreExp ext loc dec
MkProdE [Exp2]
ls', (RegionSize -> RegionSize -> RegionSize)
-> [VarSizeMapping] -> VarSizeMapping
forall (f :: * -> *) k a.
(Foldable f, Ord k) =>
(a -> a -> a) -> f (Map k a) -> Map k a
M.unionsWith RegionSize -> RegionSize -> RegionSize
forall a. Ord a => a -> a -> a
max [VarSizeMapping]
regSzEnvs, [RegionTypeMapping] -> RegionTypeMapping
forall (f :: * -> *) k a.
(Foldable f, Ord k) =>
f (Map k a) -> Map k a
M.unions [RegionTypeMapping]
regTyEnvs)
            LetE (Var
v, [Var]
locs, Ty2
ty0, Exp2
bind) Exp2
bod -> do
              (Exp2
bind', VarSizeMapping
regSzEnv', RegionTypeMapping
regTyEnv') <- Exp2 -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
go Exp2
bind
              let venv' :: TyEnv Ty2
venv' = Var -> Ty2 -> TyEnv Ty2 -> TyEnv Ty2
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert Var
v Ty2
ty0 (Env2 Ty2 -> TyEnv Ty2
forall a. Env2 a -> TyEnv a
vEnv Env2 Ty2
env2)
              let vle :: VarLocMapping
vle = case Ty2
ty0 of
                    PackedTy [Char]
_tag Var
loc -> Var -> Var -> VarLocMapping -> VarLocMapping
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert Var
v Var
loc VarLocMapping
varLocEnv
                    Ty2
_                 -> VarLocMapping
varLocEnv
              (Exp2
bod', VarSizeMapping
regSzEnv'', RegionTypeMapping
regTyEnv'') <- DDefs Ty2
-> Env2 Ty2
-> VarSizeMapping
-> VarLocMapping
-> VarLocMapping
-> VarSizeMapping
-> VarSizeMapping
-> RegionTypeMapping
-> Exp2
-> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
calculateBoundsExp DDefs Ty2
ddefs (Env2 Ty2
env2 { vEnv :: TyEnv Ty2
vEnv = TyEnv Ty2
venv' }) VarSizeMapping
varSzEnv VarLocMapping
vle VarLocMapping
locRegEnv VarSizeMapping
locOffEnv VarSizeMapping
regSzEnv RegionTypeMapping
regTyEnv Exp2
bod
              let regSzEnv3 :: VarSizeMapping
regSzEnv3 = (RegionSize -> RegionSize -> RegionSize)
-> VarSizeMapping -> VarSizeMapping -> VarSizeMapping
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
M.unionWith RegionSize -> RegionSize -> RegionSize
forall a. Ord a => a -> a -> a
max VarSizeMapping
regSzEnv' VarSizeMapping
regSzEnv''
              let regSzEnv4 :: VarSizeMapping
regSzEnv4 = case Ty2
ty0 of
                    -- TODO sizeofTy ty0 is incalculable? -> assume as 0 to give preference to analysis in other locations
                    PackedTy [Char]
_tag Var
loc ->
                      -- Make the chunk at least 32 bytes.
                      let sz :: RegionSize
sz = case (VarSizeMapping
locOffEnv VarSizeMapping -> Var -> RegionSize
forall a b.
(Ord a, Out a, Out b, Show a, HasCallStack) =>
Map a b -> a -> b
# Var
loc RegionSize -> RegionSize -> RegionSize
forall a. Semigroup a => a -> a -> a
<> (RegionSize -> (Int -> RegionSize) -> Maybe Int -> RegionSize
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Int -> RegionSize
BoundedSize Int
0) Int -> RegionSize
BoundedSize (Maybe Int -> RegionSize)
-> (Ty2 -> Maybe Int) -> Ty2 -> RegionSize
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ty2 -> Maybe Int
forall a. UrTy a -> Maybe Int
sizeOfTy) Ty2
ty0) of
                                 BoundedSize Int
i -> Int -> RegionSize
BoundedSize (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
i Int
32)
                                 RegionSize
Undefined -> RegionSize
Undefined
                      in (RegionSize -> RegionSize -> RegionSize)
-> Var -> RegionSize -> VarSizeMapping -> VarSizeMapping
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
M.insertWith RegionSize -> RegionSize -> RegionSize
forall a. Ord a => a -> a -> a
max (VarLocMapping
locRegEnv VarLocMapping -> Var -> Var
forall a b.
(Ord a, Out a, Out b, Show a, HasCallStack) =>
Map a b -> a -> b
# Var
loc) RegionSize
sz VarSizeMapping
regSzEnv3
                    Ty2
_ -> VarSizeMapping
regSzEnv3
              (Exp2, VarSizeMapping, RegionTypeMapping)
-> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a. a -> PassM a
forall (m :: * -> *) a. Monad m => a -> m a
return ((Var, [Var], Ty2, Exp2) -> Exp2 -> Exp2
forall (ext :: * -> * -> *) loc dec.
(Var, [loc], dec, PreExp ext loc dec)
-> PreExp ext loc dec -> PreExp ext loc dec
LetE (Var
v, [Var]
locs, Ty2
ty0, Exp2
bind') Exp2
bod', VarSizeMapping
regSzEnv4, RegionTypeMapping -> RegionTypeMapping -> RegionTypeMapping
forall k a. Ord k => Map k a -> Map k a -> Map k a
M.union RegionTypeMapping
regTyEnv' RegionTypeMapping
regTyEnv'')
            CaseE Exp2
ex2 [([Char], [(Var, Var)], Exp2)]
cases -> do
              ([([Char], [(Var, Var)], Exp2)]
cases', [VarSizeMapping]
res, [RegionTypeMapping]
rts) <-
                [(([Char], [(Var, Var)], Exp2), VarSizeMapping, RegionTypeMapping)]
-> ([([Char], [(Var, Var)], Exp2)], [VarSizeMapping],
    [RegionTypeMapping])
forall a b c. [(a, b, c)] -> ([a], [b], [c])
unzip3
                  ([(([Char], [(Var, Var)], Exp2), VarSizeMapping,
   RegionTypeMapping)]
 -> ([([Char], [(Var, Var)], Exp2)], [VarSizeMapping],
     [RegionTypeMapping]))
-> PassM
     [(([Char], [(Var, Var)], Exp2), VarSizeMapping, RegionTypeMapping)]
-> PassM
     ([([Char], [(Var, Var)], Exp2)], [VarSizeMapping],
      [RegionTypeMapping])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (([Char], [(Var, Var)], Exp2)
 -> PassM
      (([Char], [(Var, Var)], Exp2), VarSizeMapping, RegionTypeMapping))
-> [([Char], [(Var, Var)], Exp2)]
-> PassM
     [(([Char], [(Var, Var)], Exp2), VarSizeMapping, RegionTypeMapping)]
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
                        (\([Char]
dcon :: DataCon, [(Var, Var)]
vlocs :: [(Var, LocVar)], Exp2
bod :: Exp2) -> do
                          -- TODO use for traversal somewhere down the line?
                          -- let offsets =
                          --       M.fromList
                          --         . tail -- remove tag
                          --         . scanl1 (\(_, s1) (v2, s2) -> (v2, s1 <> s2)) -- accumulate offsets
                          --         . ((undefined, BoundedSize 1) :)  -- add size for tag
                          --         . zip (map snd vlocs) -- take locations
                          --         . map (maybe Undefined BoundedSize . sizeOfTy) -- map to our region size type
                          --         $ lookupDataCon ddefs dcon -- find ddef)
                          let venv' :: TyEnv Ty2
venv' = TyEnv Ty2 -> TyEnv Ty2 -> TyEnv Ty2
forall k a. Ord k => Map k a -> Map k a -> Map k a
M.union ([(Var, Ty2)] -> TyEnv Ty2
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([(Var, Ty2)] -> TyEnv Ty2) -> [(Var, Ty2)] -> TyEnv Ty2
forall a b. (a -> b) -> a -> b
$ [Var] -> [Ty2] -> [(Var, Ty2)]
forall a b. [a] -> [b] -> [(a, b)]
zip (((Var, Var) -> Var) -> [(Var, Var)] -> [Var]
forall a b. (a -> b) -> [a] -> [b]
map (Var, Var) -> Var
forall a b. (a, b) -> a
fst [(Var, Var)]
vlocs) (DDefs Ty2 -> [Char] -> [Ty2]
forall a. Out a => DDefs a -> [Char] -> [a]
lookupDataCon DDefs Ty2
ddefs [Char]
dcon)) (Env2 Ty2 -> TyEnv Ty2
forall a. Env2 a -> TyEnv a
vEnv Env2 Ty2
env2)
                              varLocEnv' :: VarLocMapping
varLocEnv' = [(Var, Var)] -> VarLocMapping
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList [(Var, Var)]
vlocs VarLocMapping -> VarLocMapping -> VarLocMapping
forall k a. Ord k => Map k a -> Map k a -> Map k a
`M.union` VarLocMapping
varLocEnv
                              ([Var]
_vars,[Var]
locs) = [(Var, Var)] -> ([Var], [Var])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Var, Var)]
vlocs
                              locOffEnv' :: VarSizeMapping
locOffEnv' = ([(Var, RegionSize)] -> VarSizeMapping
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([Var] -> [RegionSize] -> [(Var, RegionSize)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Var]
locs (RegionSize -> [RegionSize]
forall a. a -> [a]
repeat RegionSize
Undefined))) VarSizeMapping -> VarSizeMapping -> VarSizeMapping
forall k a. Ord k => Map k a -> Map k a -> Map k a
`M.union` VarSizeMapping
locOffEnv
                          (Exp2
bod', VarSizeMapping
re, RegionTypeMapping
rt) <- DDefs Ty2
-> Env2 Ty2
-> VarSizeMapping
-> VarLocMapping
-> VarLocMapping
-> VarSizeMapping
-> VarSizeMapping
-> RegionTypeMapping
-> Exp2
-> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
calculateBoundsExp DDefs Ty2
ddefs (Env2 Ty2
env2 { vEnv :: TyEnv Ty2
vEnv = TyEnv Ty2
venv'}) VarSizeMapping
varSzEnv VarLocMapping
varLocEnv' VarLocMapping
locRegEnv VarSizeMapping
locOffEnv' VarSizeMapping
regSzEnv RegionTypeMapping
regTyEnv Exp2
bod
                          (([Char], [(Var, Var)], Exp2), VarSizeMapping, RegionTypeMapping)
-> PassM
     (([Char], [(Var, Var)], Exp2), VarSizeMapping, RegionTypeMapping)
forall a. a -> PassM a
forall (m :: * -> *) a. Monad m => a -> m a
return (([Char]
dcon, [(Var, Var)]
vlocs, Exp2
bod'), VarSizeMapping
re, RegionTypeMapping
rt)
                        )
                        [([Char], [(Var, Var)], Exp2)]
cases
              (Exp2, VarSizeMapping, RegionTypeMapping)
-> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a. a -> PassM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Exp2 -> [([Char], [(Var, Var)], Exp2)] -> Exp2
forall (ext :: * -> * -> *) loc dec.
PreExp ext loc dec
-> [([Char], [(Var, loc)], PreExp ext loc dec)]
-> PreExp ext loc dec
CaseE Exp2
ex2 [([Char], [(Var, Var)], Exp2)]
cases', (RegionSize -> RegionSize -> RegionSize)
-> [VarSizeMapping] -> VarSizeMapping
forall (f :: * -> *) k a.
(Foldable f, Ord k) =>
(a -> a -> a) -> f (Map k a) -> Map k a
M.unionsWith RegionSize -> RegionSize -> RegionSize
forall a. Ord a => a -> a -> a
max [VarSizeMapping]
res, [RegionTypeMapping] -> RegionTypeMapping
forall (f :: * -> *) k a.
(Foldable f, Ord k) =>
f (Map k a) -> Map k a
M.unions [RegionTypeMapping]
rts)
            Ext E2Ext Var Ty2
ext -> case E2Ext Var Ty2
ext of
              LetRegionE Region
reg RegionSize
_ Maybe RegionType
_ Exp2
bod -> do
                (Exp2
bod', VarSizeMapping
re, RegionTypeMapping
rt) <- Exp2 -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
go Exp2
bod
                let regVar :: Var
regVar = Region -> Var
regionToVar Region
reg
                let regSz :: RegionSize
regSz  = VarSizeMapping
re VarSizeMapping -> Var -> RegionSize
forall a b.
(Ord a, Out a, Out b, Show a, HasCallStack) =>
Map a b -> a -> b
# Var
regVar
                let regTy :: Maybe RegionType
regTy = RegionType -> Maybe RegionType
forall a. a -> Maybe a
Just (RegionType -> Maybe RegionType) -> RegionType -> Maybe RegionType
forall a b. (a -> b) -> a -> b
$ RegionType -> Var -> RegionTypeMapping -> RegionType
forall k a. Ord k => a -> k -> Map k a -> a
M.findWithDefault RegionType
IndirectionFree Var
regVar RegionTypeMapping
rt
                Bool -> PassM () -> PassM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
dbgLvl Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
4) (PassM () -> PassM ()) -> PassM () -> PassM ()
forall a b. (a -> b) -> a -> b
$ [Char] -> PassM ()
forall (f :: * -> *). Applicative f => [Char] -> f ()
traceM ([Char] -> PassM ()) -> [Char] -> PassM ()
forall a b. (a -> b) -> a -> b
$ [Char]
">> Region: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Region -> [Char]
forall a. Show a => a -> [Char]
show Region
reg [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" -> " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ RegionSize -> [Char]
forall a. Show a => a -> [Char]
show RegionSize
regSz [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" : " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Maybe RegionType -> [Char]
forall a. Show a => a -> [Char]
show Maybe RegionType
regTy
                (Exp2, VarSizeMapping, RegionTypeMapping)
-> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a. a -> PassM a
forall (m :: * -> *) a. Monad m => a -> m a
return (E2Ext Var Ty2 -> Exp2
forall (ext :: * -> * -> *) loc dec.
ext loc dec -> PreExp ext loc dec
Ext (E2Ext Var Ty2 -> Exp2) -> E2Ext Var Ty2 -> Exp2
forall a b. (a -> b) -> a -> b
$ Region -> RegionSize -> Maybe RegionType -> Exp2 -> E2Ext Var Ty2
forall loc dec.
Region
-> RegionSize -> Maybe RegionType -> E2 loc dec -> E2Ext loc dec
LetRegionE Region
reg RegionSize
regSz Maybe RegionType
regTy Exp2
bod', VarSizeMapping
re, RegionTypeMapping
rt)
              LetParRegionE Region
reg RegionSize
_ Maybe RegionType
_ Exp2
bod -> do
                (Exp2
bod', VarSizeMapping
re, RegionTypeMapping
rt) <- Exp2 -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
go Exp2
bod
                let regVar :: Var
regVar = Region -> Var
regionToVar Region
reg
                let regSz :: RegionSize
regSz  = VarSizeMapping
re VarSizeMapping -> Var -> RegionSize
forall a b.
(Ord a, Out a, Out b, Show a, HasCallStack) =>
Map a b -> a -> b
# Var
regVar
                let regTy :: Maybe RegionType
regTy = RegionType -> Maybe RegionType
forall a. a -> Maybe a
Just (RegionType -> Maybe RegionType) -> RegionType -> Maybe RegionType
forall a b. (a -> b) -> a -> b
$ RegionType -> Var -> RegionTypeMapping -> RegionType
forall k a. Ord k => a -> k -> Map k a -> a
M.findWithDefault RegionType
IndirectionFree Var
regVar RegionTypeMapping
rt
                Bool -> PassM () -> PassM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
dbgLvl Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
4) (PassM () -> PassM ()) -> PassM () -> PassM ()
forall a b. (a -> b) -> a -> b
$ [Char] -> PassM ()
forall (f :: * -> *). Applicative f => [Char] -> f ()
traceM ([Char] -> PassM ()) -> [Char] -> PassM ()
forall a b. (a -> b) -> a -> b
$ [Char]
">> Region: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Region -> [Char]
forall a. Show a => a -> [Char]
show Region
reg [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" -> " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ RegionSize -> [Char]
forall a. Show a => a -> [Char]
show RegionSize
regSz [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" : " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Maybe RegionType -> [Char]
forall a. Show a => a -> [Char]
show Maybe RegionType
regTy
                (Exp2, VarSizeMapping, RegionTypeMapping)
-> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a. a -> PassM a
forall (m :: * -> *) a. Monad m => a -> m a
return (E2Ext Var Ty2 -> Exp2
forall (ext :: * -> * -> *) loc dec.
ext loc dec -> PreExp ext loc dec
Ext (E2Ext Var Ty2 -> Exp2) -> E2Ext Var Ty2 -> Exp2
forall a b. (a -> b) -> a -> b
$ Region -> RegionSize -> Maybe RegionType -> Exp2 -> E2Ext Var Ty2
forall loc dec.
Region
-> RegionSize -> Maybe RegionType -> E2 loc dec -> E2Ext loc dec
LetParRegionE Region
reg RegionSize
regSz Maybe RegionType
regTy Exp2
bod', VarSizeMapping
re, RegionTypeMapping
rt)
              LetLocE Var
loc PreLocExp Var
locExp Exp2
ex1 -> do
                -- * NOTE: jumps are only necessary for route ends, skipping them.
                if [Char]
"jump_" [Char] -> [Char] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`L.isPrefixOf` Var -> [Char]
fromVar Var
loc
                  then do
                    (Exp2
ex1', VarSizeMapping
re', RegionTypeMapping
rt') <- Exp2 -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
go Exp2
ex1
                    (Exp2, VarSizeMapping, RegionTypeMapping)
-> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a. a -> PassM a
forall (m :: * -> *) a. Monad m => a -> m a
return (E2Ext Var Ty2 -> Exp2
forall (ext :: * -> * -> *) loc dec.
ext loc dec -> PreExp ext loc dec
Ext (E2Ext Var Ty2 -> Exp2) -> E2Ext Var Ty2 -> Exp2
forall a b. (a -> b) -> a -> b
$ Var -> PreLocExp Var -> Exp2 -> E2Ext Var Ty2
forall loc dec. Var -> PreLocExp loc -> E2 loc dec -> E2Ext loc dec
LetLocE Var
loc PreLocExp Var
locExp Exp2
ex1', VarSizeMapping
re', RegionTypeMapping
rt')
                  else do
                    let (Var
re, RegionSize
off) = case PreLocExp Var
locExp of
                          (StartOfRegionLE Region
r          ) -> (Region -> Var
regionToVar Region
r, Int -> RegionSize
BoundedSize Int
0)
                          (AfterConstantLE Int
n Var
l  ) -> (VarLocMapping
locRegEnv VarLocMapping -> Var -> Var
forall a b.
(Ord a, Out a, Out b, Show a, HasCallStack) =>
Map a b -> a -> b
# Var
l, VarSizeMapping
locOffEnv VarSizeMapping -> Var -> RegionSize
forall a b.
(Ord a, Out a, Out b, Show a, HasCallStack) =>
Map a b -> a -> b
# Var
l RegionSize -> RegionSize -> RegionSize
forall a. Semigroup a => a -> a -> a
<> Int -> RegionSize
BoundedSize Int
n)
                          -- [2022.12.26] CSK: the lookup in varSzEnv always fails since the
                          -- pass never inserts anything into it. Disabling it for now.
                          (AfterVariableLE Var
v Var
l Bool
_) -> (VarLocMapping
locRegEnv VarLocMapping -> Var -> Var
forall a b.
(Ord a, Out a, Out b, Show a, HasCallStack) =>
Map a b -> a -> b
# Var
l, VarSizeMapping
locOffEnv VarSizeMapping -> Var -> RegionSize
forall a b.
(Ord a, Out a, Out b, Show a, HasCallStack) =>
Map a b -> a -> b
# (VarLocMapping
varLocEnv VarLocMapping -> Var -> Var
forall a b.
(Ord a, Out a, Out b, Show a, HasCallStack) =>
Map a b -> a -> b
# Var
v)) -- <> varSzEnv # v
                          (InRegionLE Region
r         ) -> (Region -> Var
regionToVar Region
r, RegionSize
Undefined)
                          (FromEndLE  Var
l         ) -> (VarLocMapping
locRegEnv VarLocMapping -> Var -> Var
forall a b.
(Ord a, Out a, Out b, Show a, HasCallStack) =>
Map a b -> a -> b
# Var
l, RegionSize
Undefined)
                          PreLocExp Var
FreeLE                  -> (Var, RegionSize)
forall a. HasCallStack => a
undefined
                    let lre :: VarLocMapping
lre = Var -> Var -> VarLocMapping -> VarLocMapping
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert Var
loc Var
re VarLocMapping
locRegEnv
                    let loe :: VarSizeMapping
loe = Var -> RegionSize -> VarSizeMapping -> VarSizeMapping
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert Var
loc RegionSize
off VarSizeMapping
locOffEnv
                    (Exp2
ex1', VarSizeMapping
re', RegionTypeMapping
rt') <- DDefs Ty2
-> Env2 Ty2
-> VarSizeMapping
-> VarLocMapping
-> VarLocMapping
-> VarSizeMapping
-> VarSizeMapping
-> RegionTypeMapping
-> Exp2
-> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
calculateBoundsExp DDefs Ty2
ddefs Env2 Ty2
env2 VarSizeMapping
varSzEnv VarLocMapping
varLocEnv VarLocMapping
lre VarSizeMapping
loe VarSizeMapping
regSzEnv RegionTypeMapping
regTyEnv Exp2
ex1
                    (Exp2, VarSizeMapping, RegionTypeMapping)
-> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a. a -> PassM a
forall (m :: * -> *) a. Monad m => a -> m a
return (E2Ext Var Ty2 -> Exp2
forall (ext :: * -> * -> *) loc dec.
ext loc dec -> PreExp ext loc dec
Ext (E2Ext Var Ty2 -> Exp2) -> E2Ext Var Ty2 -> Exp2
forall a b. (a -> b) -> a -> b
$ Var -> PreLocExp Var -> Exp2 -> E2Ext Var Ty2
forall loc dec. Var -> PreLocExp loc -> E2 loc dec -> E2Ext loc dec
LetLocE Var
loc PreLocExp Var
locExp Exp2
ex1', VarSizeMapping
re', RegionTypeMapping
rt')
              RetE [Var]
_locs Var
v -> do
                (Exp2
_, VarSizeMapping
re, RegionTypeMapping
rt) <- Exp2 -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
go (Var -> Exp2
forall (ext :: * -> * -> *) loc dec. Var -> PreExp ext loc dec
VarE Var
v)
                (Exp2, VarSizeMapping, RegionTypeMapping)
-> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a. a -> PassM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Exp2
ex, VarSizeMapping
re, RegionTypeMapping
rt)
              FromEndE{}         -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
pass
              AddFixed{}         -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
pass
              GetCilkWorkerNum{} -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
pass
              LetAvail [Var]
vs Exp2
e      -> do
                (Exp2
e', VarSizeMapping
re', RegionTypeMapping
rt') <- Exp2 -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
go Exp2
e
                (Exp2, VarSizeMapping, RegionTypeMapping)
-> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a. a -> PassM a
forall (m :: * -> *) a. Monad m => a -> m a
return (E2Ext Var Ty2 -> Exp2
forall (ext :: * -> * -> *) loc dec.
ext loc dec -> PreExp ext loc dec
Ext (E2Ext Var Ty2 -> Exp2) -> E2Ext Var Ty2 -> Exp2
forall a b. (a -> b) -> a -> b
$ [Var] -> Exp2 -> E2Ext Var Ty2
forall loc dec. [Var] -> E2 loc dec -> E2Ext loc dec
LetAvail [Var]
vs Exp2
e', VarSizeMapping
re', RegionTypeMapping
rt')
              StartOfPkdCursor{}    -> [Char] -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a. HasCallStack => [Char] -> a
error ([Char] -> PassM (Exp2, VarSizeMapping, RegionTypeMapping))
-> [Char] -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a b. (a -> b) -> a -> b
$ [Char]
"todo: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Exp2 -> [Char]
forall a. Out a => a -> [Char]
sdoc Exp2
ex
              TagCursor{}           -> [Char] -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a. HasCallStack => [Char] -> a
error ([Char] -> PassM (Exp2, VarSizeMapping, RegionTypeMapping))
-> [Char] -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a b. (a -> b) -> a -> b
$ [Char]
"todo: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Exp2 -> [Char]
forall a. Out a => a -> [Char]
sdoc Exp2
ex
              AllocateTagHere{}     -> [Char] -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a. HasCallStack => [Char] -> a
error ([Char] -> PassM (Exp2, VarSizeMapping, RegionTypeMapping))
-> [Char] -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a b. (a -> b) -> a -> b
$ [Char]
"todo: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Exp2 -> [Char]
forall a. Out a => a -> [Char]
sdoc Exp2
ex
              AllocateScalarsHere{} -> [Char] -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a. HasCallStack => [Char] -> a
error ([Char] -> PassM (Exp2, VarSizeMapping, RegionTypeMapping))
-> [Char] -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a b. (a -> b) -> a -> b
$ [Char]
"todo: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Exp2 -> [Char]
forall a. Out a => a -> [Char]
sdoc Exp2
ex
              SSPush{}              -> [Char] -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a. HasCallStack => [Char] -> a
error ([Char] -> PassM (Exp2, VarSizeMapping, RegionTypeMapping))
-> [Char] -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a b. (a -> b) -> a -> b
$ [Char]
"todo: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Exp2 -> [Char]
forall a. Out a => a -> [Char]
sdoc Exp2
ex
              SSPop{}               -> [Char] -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a. HasCallStack => [Char] -> a
error ([Char] -> PassM (Exp2, VarSizeMapping, RegionTypeMapping))
-> [Char] -> PassM (Exp2, VarSizeMapping, RegionTypeMapping)
forall a b. (a -> b) -> a -> b
$ [Char]
"todo: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Exp2 -> [Char]
forall a. Out a => a -> [Char]
sdoc Exp2
ex