module Futhark.Internalise.TypesValues
  ( -- * Internalising types
    internaliseReturnType,
    internaliseLambdaReturnType,
    internaliseEntryReturnType,
    internaliseType,
    internaliseParamTypes,
    internaliseLoopParamType,
    internalisePrimType,
    internalisedTypeSize,
    internaliseSumType,

    -- * Internalising values
    internalisePrimValue,
  )
where

import Control.Monad.State
import Data.Bitraversable (bitraverse)
import Data.List (delete, find, foldl')
import Data.Map.Strict qualified as M
import Data.Maybe
import Futhark.IR.SOACS as I
import Futhark.Internalise.Monad
import Language.Futhark qualified as E

internaliseUniqueness :: E.Uniqueness -> I.Uniqueness
internaliseUniqueness :: Uniqueness -> Uniqueness
internaliseUniqueness Uniqueness
E.Nonunique = Uniqueness
I.Nonunique
internaliseUniqueness Uniqueness
E.Unique = Uniqueness
I.Unique

newtype TypeState = TypeState {TypeState -> Int
typeCounter :: Int}

newtype InternaliseTypeM a
  = InternaliseTypeM (State TypeState a)
  deriving (forall a b. a -> InternaliseTypeM b -> InternaliseTypeM a
forall a b. (a -> b) -> InternaliseTypeM a -> InternaliseTypeM b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> InternaliseTypeM b -> InternaliseTypeM a
$c<$ :: forall a b. a -> InternaliseTypeM b -> InternaliseTypeM a
fmap :: forall a b. (a -> b) -> InternaliseTypeM a -> InternaliseTypeM b
$cfmap :: forall a b. (a -> b) -> InternaliseTypeM a -> InternaliseTypeM b
Functor, Functor InternaliseTypeM
forall a. a -> InternaliseTypeM a
forall a b.
InternaliseTypeM a -> InternaliseTypeM b -> InternaliseTypeM a
forall a b.
InternaliseTypeM a -> InternaliseTypeM b -> InternaliseTypeM b
forall a b.
InternaliseTypeM (a -> b)
-> InternaliseTypeM a -> InternaliseTypeM b
forall a b c.
(a -> b -> c)
-> InternaliseTypeM a -> InternaliseTypeM b -> InternaliseTypeM c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: forall a b.
InternaliseTypeM a -> InternaliseTypeM b -> InternaliseTypeM a
$c<* :: forall a b.
InternaliseTypeM a -> InternaliseTypeM b -> InternaliseTypeM a
*> :: forall a b.
InternaliseTypeM a -> InternaliseTypeM b -> InternaliseTypeM b
$c*> :: forall a b.
InternaliseTypeM a -> InternaliseTypeM b -> InternaliseTypeM b
liftA2 :: forall a b c.
(a -> b -> c)
-> InternaliseTypeM a -> InternaliseTypeM b -> InternaliseTypeM c
$cliftA2 :: forall a b c.
(a -> b -> c)
-> InternaliseTypeM a -> InternaliseTypeM b -> InternaliseTypeM c
<*> :: forall a b.
InternaliseTypeM (a -> b)
-> InternaliseTypeM a -> InternaliseTypeM b
$c<*> :: forall a b.
InternaliseTypeM (a -> b)
-> InternaliseTypeM a -> InternaliseTypeM b
pure :: forall a. a -> InternaliseTypeM a
$cpure :: forall a. a -> InternaliseTypeM a
Applicative, Applicative InternaliseTypeM
forall a. a -> InternaliseTypeM a
forall a b.
InternaliseTypeM a -> InternaliseTypeM b -> InternaliseTypeM b
forall a b.
InternaliseTypeM a
-> (a -> InternaliseTypeM b) -> InternaliseTypeM b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: forall a. a -> InternaliseTypeM a
$creturn :: forall a. a -> InternaliseTypeM a
>> :: forall a b.
InternaliseTypeM a -> InternaliseTypeM b -> InternaliseTypeM b
$c>> :: forall a b.
InternaliseTypeM a -> InternaliseTypeM b -> InternaliseTypeM b
>>= :: forall a b.
InternaliseTypeM a
-> (a -> InternaliseTypeM b) -> InternaliseTypeM b
$c>>= :: forall a b.
InternaliseTypeM a
-> (a -> InternaliseTypeM b) -> InternaliseTypeM b
Monad, MonadState TypeState)

runInternaliseTypeM :: InternaliseTypeM a -> a
runInternaliseTypeM :: forall a. InternaliseTypeM a -> a
runInternaliseTypeM = forall a. [VName] -> InternaliseTypeM a -> a
runInternaliseTypeM' forall a. Monoid a => a
mempty

runInternaliseTypeM' :: [VName] -> InternaliseTypeM a -> a
runInternaliseTypeM' :: forall a. [VName] -> InternaliseTypeM a -> a
runInternaliseTypeM' [VName]
exts (InternaliseTypeM State TypeState a
m) = forall s a. State s a -> s -> a
evalState State TypeState a
m forall a b. (a -> b) -> a -> b
$ Int -> TypeState
TypeState (forall (t :: * -> *) a. Foldable t => t a -> Int
length [VName]
exts)

internaliseParamTypes ::
  [E.TypeBase E.Size ()] ->
  InternaliseM [[I.TypeBase Shape Uniqueness]]
internaliseParamTypes :: [StructType] -> InternaliseM [[TypeBase Shape Uniqueness]]
internaliseParamTypes [StructType]
ts =
  forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall shape u. TypeBase shape u -> InternaliseM (TypeBase shape u)
mkAccCerts) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. InternaliseTypeM a -> a
runInternaliseTypeM forall a b. (a -> b) -> a -> b
$
    forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a b. (a -> b) -> [a] -> [b]
map forall {u}. TypeBase ExtShape u -> TypeBase Shape u
onType) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map VName Int
-> StructType -> InternaliseTypeM [TypeBase ExtShape Uniqueness]
internaliseTypeM forall a. Monoid a => a
mempty) [StructType]
ts
  where
    onType :: TypeBase ExtShape u -> TypeBase Shape u
onType = forall a. a -> Maybe a -> a
fromMaybe forall {a}. a
bad forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall u. TypeBase ExtShape u -> Maybe (TypeBase Shape u)
hasStaticShape
    bad :: a
bad = forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"internaliseParamTypes: " forall a. [a] -> [a] -> [a]
++ forall a. Pretty a => a -> String
prettyString [StructType]
ts

-- We need to fix up the arrays for any Acc return values or loop
-- parameters.  We look at the concrete types for this, since the Acc
-- parameter name in the second list will just be something we made up.
fixupKnownTypes :: [TypeBase shape1 u1] -> [TypeBase shape2 u2] -> [TypeBase shape2 u2]
fixupKnownTypes :: forall shape1 u1 shape2 u2.
[TypeBase shape1 u1]
-> [TypeBase shape2 u2] -> [TypeBase shape2 u2]
fixupKnownTypes = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall {shape} {u} {shape} {u}.
TypeBase shape u -> TypeBase shape u -> TypeBase shape u
fixup
  where
    fixup :: TypeBase shape u -> TypeBase shape u -> TypeBase shape u
fixup (Acc VName
acc Shape
ispace [Type]
ts u
_) (Acc VName
_ Shape
_ [Type]
_ u
u2) = forall shape u. VName -> Shape -> [Type] -> u -> TypeBase shape u
Acc VName
acc Shape
ispace [Type]
ts u
u2
    fixup TypeBase shape u
_ TypeBase shape u
t = TypeBase shape u
t

-- Generate proper certificates for the placeholder accumulator
-- certificates produced by internaliseType (identified with tag 0).
-- Only needed when we cannot use 'fixupKnownTypes'.
mkAccCerts :: TypeBase shape u -> InternaliseM (TypeBase shape u)
mkAccCerts :: forall shape u. TypeBase shape u -> InternaliseM (TypeBase shape u)
mkAccCerts (Array PrimType
pt shape
shape u
u) =
  forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall shape u. PrimType -> shape -> u -> TypeBase shape u
Array PrimType
pt shape
shape u
u
mkAccCerts (Acc VName
c Shape
shape [Type]
ts u
u) =
  forall shape u. VName -> Shape -> [Type] -> u -> TypeBase shape u
Acc forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> InternaliseM VName
c' forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (f :: * -> *) a. Applicative f => a -> f a
pure Shape
shape forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (f :: * -> *) a. Applicative f => a -> f a
pure [Type]
ts forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (f :: * -> *) a. Applicative f => a -> f a
pure u
u
  where
    c' :: InternaliseM VName
c'
      | VName -> Int
baseTag VName
c forall a. Eq a => a -> a -> Bool
== Int
0 = forall (m :: * -> *). MonadFreshNames m => String -> m VName
newVName String
"acc_cert"
      | Bool
otherwise = forall (f :: * -> *) a. Applicative f => a -> f a
pure VName
c
mkAccCerts TypeBase shape u
t = forall (f :: * -> *) a. Applicative f => a -> f a
pure TypeBase shape u
t

internaliseLoopParamType ::
  E.TypeBase E.Size () ->
  [TypeBase shape u] ->
  InternaliseM [I.TypeBase Shape Uniqueness]
internaliseLoopParamType :: forall shape u.
StructType
-> [TypeBase shape u] -> InternaliseM [TypeBase Shape Uniqueness]
internaliseLoopParamType StructType
et [TypeBase shape u]
ts =
  forall shape1 u1 shape2 u2.
[TypeBase shape1 u1]
-> [TypeBase shape2 u2] -> [TypeBase shape2 u2]
fixupKnownTypes [TypeBase shape u]
ts forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [StructType] -> InternaliseM [[TypeBase Shape Uniqueness]]
internaliseParamTypes [StructType
et]

internaliseReturnType ::
  E.StructRetType ->
  [TypeBase shape u] ->
  [I.TypeBase ExtShape Uniqueness]
internaliseReturnType :: forall shape u.
StructRetType
-> [TypeBase shape u] -> [TypeBase ExtShape Uniqueness]
internaliseReturnType (E.RetType [VName]
dims StructType
et) [TypeBase shape u]
ts =
  forall shape1 u1 shape2 u2.
[TypeBase shape1 u1]
-> [TypeBase shape2 u2] -> [TypeBase shape2 u2]
fixupKnownTypes [TypeBase shape u]
ts forall a b. (a -> b) -> a -> b
$ forall a. [VName] -> InternaliseTypeM a -> a
runInternaliseTypeM' [VName]
dims (Map VName Int
-> StructType -> InternaliseTypeM [TypeBase ExtShape Uniqueness]
internaliseTypeM Map VName Int
exts StructType
et)
  where
    exts :: Map VName Int
exts = forall k a. Ord k => [(k, a)] -> Map k a
M.fromList forall a b. (a -> b) -> a -> b
$ forall a b. [a] -> [b] -> [(a, b)]
zip [VName]
dims [Int
0 ..]

internaliseLambdaReturnType ::
  E.TypeBase E.Size () ->
  [TypeBase shape u] ->
  InternaliseM [I.TypeBase Shape NoUniqueness]
internaliseLambdaReturnType :: forall shape u.
StructType -> [TypeBase shape u] -> InternaliseM [Type]
internaliseLambdaReturnType StructType
et [TypeBase shape u]
ts =
  forall a b. (a -> b) -> [a] -> [b]
map forall shape.
TypeBase shape Uniqueness -> TypeBase shape NoUniqueness
fromDecl forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall shape u.
StructType
-> [TypeBase shape u] -> InternaliseM [TypeBase Shape Uniqueness]
internaliseLoopParamType StructType
et [TypeBase shape u]
ts

-- | As 'internaliseReturnType', but returns components of a top-level
-- tuple type piecemeal.
internaliseEntryReturnType ::
  E.StructRetType ->
  [[I.TypeBase ExtShape Uniqueness]]
internaliseEntryReturnType :: StructRetType -> [[TypeBase ExtShape Uniqueness]]
internaliseEntryReturnType (E.RetType [VName]
dims StructType
et) =
  forall a. [VName] -> InternaliseTypeM a -> a
runInternaliseTypeM' [VName]
dims forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Map VName Int
-> StructType -> InternaliseTypeM [TypeBase ExtShape Uniqueness]
internaliseTypeM Map VName Int
exts) forall a b. (a -> b) -> a -> b
$
    case forall dim as. TypeBase dim as -> Maybe [TypeBase dim as]
E.isTupleRecord StructType
et of
      Just [StructType]
ets | Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Bool
null [StructType]
ets -> [StructType]
ets
      Maybe [StructType]
_ -> [StructType
et]
  where
    exts :: Map VName Int
exts = forall k a. Ord k => [(k, a)] -> Map k a
M.fromList forall a b. (a -> b) -> a -> b
$ forall a b. [a] -> [b] -> [(a, b)]
zip [VName]
dims [Int
0 ..]

internaliseType ::
  E.TypeBase E.Size () ->
  [I.TypeBase I.ExtShape Uniqueness]
internaliseType :: StructType -> [TypeBase ExtShape Uniqueness]
internaliseType = forall a. InternaliseTypeM a -> a
runInternaliseTypeM forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map VName Int
-> StructType -> InternaliseTypeM [TypeBase ExtShape Uniqueness]
internaliseTypeM forall a. Monoid a => a
mempty

newId :: InternaliseTypeM Int
newId :: InternaliseTypeM Int
newId = do
  Int
i <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets TypeState -> Int
typeCounter
  forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \TypeState
s -> TypeState
s {typeCounter :: Int
typeCounter = Int
i forall a. Num a => a -> a -> a
+ Int
1}
  forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
i

internaliseDim ::
  M.Map VName Int ->
  E.Size ->
  InternaliseTypeM ExtSize
internaliseDim :: Map VName Int -> Size -> InternaliseTypeM (Ext SubExp)
internaliseDim Map VName Int
exts Size
d =
  case Size
d of
    E.AnySize Maybe VName
_ -> forall a. Int -> Ext a
Ext forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> InternaliseTypeM Int
newId
    E.ConstSize Int
n -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. a -> Ext a
Free forall a b. (a -> b) -> a -> b
$ IntType -> Integer -> SubExp
intConst IntType
I.Int64 forall a b. (a -> b) -> a -> b
$ forall a. Integral a => a -> Integer
toInteger Int
n
    E.NamedSize QualName VName
name -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ QualName VName -> Ext SubExp
namedDim QualName VName
name
  where
    namedDim :: QualName VName -> Ext SubExp
namedDim (E.QualName [VName]
_ VName
name)
      | Just Int
x <- VName
name forall k a. Ord k => k -> Map k a -> Maybe a
`M.lookup` Map VName Int
exts = forall a. Int -> Ext a
I.Ext Int
x
      | Bool
otherwise = forall a. a -> Ext a
I.Free forall a b. (a -> b) -> a -> b
$ VName -> SubExp
I.Var VName
name

internaliseTypeM ::
  M.Map VName Int ->
  E.StructType ->
  InternaliseTypeM [I.TypeBase ExtShape Uniqueness]
internaliseTypeM :: Map VName Int
-> StructType -> InternaliseTypeM [TypeBase ExtShape Uniqueness]
internaliseTypeM Map VName Int
exts StructType
orig_t =
  case StructType
orig_t of
    E.Array ()
_ Uniqueness
u Shape Size
shape ScalarTypeBase Size ()
et -> do
      [Ext SubExp]
dims <- Shape Size -> InternaliseTypeM [Ext SubExp]
internaliseShape Shape Size
shape
      [TypeBase ExtShape Uniqueness]
ets <- Map VName Int
-> StructType -> InternaliseTypeM [TypeBase ExtShape Uniqueness]
internaliseTypeM Map VName Int
exts forall a b. (a -> b) -> a -> b
$ forall dim as. ScalarTypeBase dim as -> TypeBase dim as
E.Scalar ScalarTypeBase Size ()
et
      forall (f :: * -> *) a. Applicative f => a -> f a
pure [forall shape u_unused u.
ArrayShape shape =>
TypeBase shape u_unused -> shape -> u -> TypeBase shape u
I.arrayOf TypeBase ExtShape Uniqueness
et' (forall d. [d] -> ShapeBase d
Shape [Ext SubExp]
dims) forall a b. (a -> b) -> a -> b
$ Uniqueness -> Uniqueness
internaliseUniqueness Uniqueness
u | TypeBase ExtShape Uniqueness
et' <- [TypeBase ExtShape Uniqueness]
ets]
    E.Scalar (E.Prim PrimType
bt) ->
      forall (f :: * -> *) a. Applicative f => a -> f a
pure [forall shape u. PrimType -> TypeBase shape u
I.Prim forall a b. (a -> b) -> a -> b
$ PrimType -> PrimType
internalisePrimType PrimType
bt]
    E.Scalar (E.Record Map Name StructType
ets)
      -- XXX: we map empty records to units, because otherwise
      -- arrays of unit will lose their sizes.
      | forall (t :: * -> *) a. Foldable t => t a -> Bool
null Map Name StructType
ets -> forall (f :: * -> *) a. Applicative f => a -> f a
pure [forall shape u. PrimType -> TypeBase shape u
I.Prim PrimType
I.Unit]
      | Bool
otherwise ->
          forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Map VName Int
-> StructType -> InternaliseTypeM [TypeBase ExtShape Uniqueness]
internaliseTypeM Map VName Int
exts forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd) (forall a. Map Name a -> [(Name, a)]
E.sortFields Map Name StructType
ets)
    E.Scalar (E.TypeVar ()
_ Uniqueness
u QualName VName
tn [E.TypeArgType StructType
arr_t SrcLoc
_])
      | VName -> Int
baseTag (forall vn. QualName vn -> vn
E.qualLeaf QualName VName
tn) forall a. Ord a => a -> a -> Bool
<= Int
E.maxIntrinsicTag,
        VName -> String
baseString (forall vn. QualName vn -> vn
E.qualLeaf QualName VName
tn) forall a. Eq a => a -> a -> Bool
== String
"acc" -> do
          [Type]
ts <- forall a b. (a -> b) -> [a] -> [b]
map (forall shape.
TypeBase shape Uniqueness -> TypeBase shape NoUniqueness
fromDecl forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {u}. TypeBase ExtShape u -> TypeBase Shape u
onAccType) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map VName Int
-> StructType -> InternaliseTypeM [TypeBase ExtShape Uniqueness]
internaliseTypeM Map VName Int
exts StructType
arr_t
          let acc_param :: VName
acc_param = Name -> Int -> VName
VName Name
"PLACEHOLDER" Int
0 -- See mkAccCerts.
              acc_t :: TypeBase shape Uniqueness
acc_t = forall shape u. VName -> Shape -> [Type] -> u -> TypeBase shape u
Acc VName
acc_param (forall d. [d] -> ShapeBase d
Shape [forall u. Int -> [TypeBase Shape u] -> SubExp
arraysSize Int
0 [Type]
ts]) (forall a b. (a -> b) -> [a] -> [b]
map forall u. TypeBase Shape u -> TypeBase Shape u
rowType [Type]
ts) forall a b. (a -> b) -> a -> b
$ Uniqueness -> Uniqueness
internaliseUniqueness Uniqueness
u
          forall (f :: * -> *) a. Applicative f => a -> f a
pure [forall {shape}. TypeBase shape Uniqueness
acc_t]
    E.Scalar E.TypeVar {} ->
      forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"internaliseTypeM: cannot handle type variable: " forall a. [a] -> [a] -> [a]
++ forall a. Pretty a => a -> String
prettyString StructType
orig_t
    E.Scalar E.Arrow {} ->
      forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"internaliseTypeM: cannot handle function type: " forall a. [a] -> [a] -> [a]
++ forall a. Pretty a => a -> String
prettyString StructType
orig_t
    E.Scalar (E.Sum Map Name [StructType]
cs) -> do
      ([TypeBase ExtShape Uniqueness]
ts, Map Name (Int, [Int])
_) <-
        Map Name [TypeBase ExtShape Uniqueness]
-> ([TypeBase ExtShape Uniqueness], Map Name (Int, [Int]))
internaliseConstructors
          forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Map VName Int
-> StructType -> InternaliseTypeM [TypeBase ExtShape Uniqueness]
internaliseTypeM Map VName Int
exts)) Map Name [StructType]
cs
      forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall shape u. PrimType -> TypeBase shape u
I.Prim (IntType -> PrimType
I.IntType IntType
I.Int8) forall a. a -> [a] -> [a]
: [TypeBase ExtShape Uniqueness]
ts
  where
    internaliseShape :: Shape Size -> InternaliseTypeM [Ext SubExp]
internaliseShape = forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Map VName Int -> Size -> InternaliseTypeM (Ext SubExp)
internaliseDim Map VName Int
exts) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall dim. Shape dim -> [dim]
E.shapeDims

    onAccType :: TypeBase ExtShape u -> TypeBase Shape u
onAccType = forall a. a -> Maybe a -> a
fromMaybe forall {a}. a
bad forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall u. TypeBase ExtShape u -> Maybe (TypeBase Shape u)
hasStaticShape
    bad :: a
bad = forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"internaliseTypeM Acc: " forall a. [a] -> [a] -> [a]
++ forall a. Pretty a => a -> String
prettyString StructType
orig_t

internaliseConstructors ::
  M.Map Name [I.TypeBase ExtShape Uniqueness] ->
  ( [I.TypeBase ExtShape Uniqueness],
    M.Map Name (Int, [Int])
  )
internaliseConstructors :: Map Name [TypeBase ExtShape Uniqueness]
-> ([TypeBase ExtShape Uniqueness], Map Name (Int, [Int]))
internaliseConstructors Map Name [TypeBase ExtShape Uniqueness]
cs =
  forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' forall {k} {t :: * -> *} {shape} {a}.
(Ord k, Foldable t, Eq shape) =>
([TypeBase shape Uniqueness], Map k (a, [Int]))
-> ((k, t (TypeBase shape Uniqueness)), a)
-> ([TypeBase shape Uniqueness], Map k (a, [Int]))
onConstructor forall a. Monoid a => a
mempty forall a b. (a -> b) -> a -> b
$ forall a b. [a] -> [b] -> [(a, b)]
zip (forall a. Map Name a -> [(Name, a)]
E.sortConstrs Map Name [TypeBase ExtShape Uniqueness]
cs) [Int
0 ..]
  where
    onConstructor :: ([TypeBase shape Uniqueness], Map k (a, [Int]))
-> ((k, t (TypeBase shape Uniqueness)), a)
-> ([TypeBase shape Uniqueness], Map k (a, [Int]))
onConstructor ([TypeBase shape Uniqueness]
ts, Map k (a, [Int])
mapping) ((k
c, t (TypeBase shape Uniqueness)
c_ts), a
i) =
      let ([(TypeBase shape NoUniqueness, Int)]
_, [Int]
js, [TypeBase shape Uniqueness]
new_ts) =
            forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' forall {shape}.
Eq shape =>
([(TypeBase shape NoUniqueness, Int)], [Int],
 [TypeBase shape Uniqueness])
-> TypeBase shape Uniqueness
-> ([(TypeBase shape NoUniqueness, Int)], [Int],
    [TypeBase shape Uniqueness])
f (forall a b. [a] -> [b] -> [(a, b)]
zip (forall a b. (a -> b) -> [a] -> [b]
map forall shape.
TypeBase shape Uniqueness -> TypeBase shape NoUniqueness
fromDecl [TypeBase shape Uniqueness]
ts) [Int
0 ..], forall a. Monoid a => a
mempty, forall a. Monoid a => a
mempty) t (TypeBase shape Uniqueness)
c_ts
       in ([TypeBase shape Uniqueness]
ts forall a. [a] -> [a] -> [a]
++ [TypeBase shape Uniqueness]
new_ts, forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert k
c (a
i, [Int]
js) Map k (a, [Int])
mapping)
      where
        f :: ([(TypeBase shape NoUniqueness, Int)], [Int],
 [TypeBase shape Uniqueness])
-> TypeBase shape Uniqueness
-> ([(TypeBase shape NoUniqueness, Int)], [Int],
    [TypeBase shape Uniqueness])
f ([(TypeBase shape NoUniqueness, Int)]
ts', [Int]
js, [TypeBase shape Uniqueness]
new_ts) TypeBase shape Uniqueness
t
          | Just (TypeBase shape NoUniqueness
_, Int
j) <- forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find ((forall a. Eq a => a -> a -> Bool
== forall shape.
TypeBase shape Uniqueness -> TypeBase shape NoUniqueness
fromDecl TypeBase shape Uniqueness
t) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) [(TypeBase shape NoUniqueness, Int)]
ts' =
              ( forall a. Eq a => a -> [a] -> [a]
delete (forall shape.
TypeBase shape Uniqueness -> TypeBase shape NoUniqueness
fromDecl TypeBase shape Uniqueness
t, Int
j) [(TypeBase shape NoUniqueness, Int)]
ts',
                [Int]
js forall a. [a] -> [a] -> [a]
++ [Int
j],
                [TypeBase shape Uniqueness]
new_ts
              )
          | Bool
otherwise =
              ( [(TypeBase shape NoUniqueness, Int)]
ts',
                [Int]
js forall a. [a] -> [a] -> [a]
++ [forall (t :: * -> *) a. Foldable t => t a -> Int
length [TypeBase shape Uniqueness]
ts forall a. Num a => a -> a -> a
+ forall (t :: * -> *) a. Foldable t => t a -> Int
length [TypeBase shape Uniqueness]
new_ts],
                [TypeBase shape Uniqueness]
new_ts forall a. [a] -> [a] -> [a]
++ [TypeBase shape Uniqueness
t]
              )

internaliseSumType ::
  M.Map Name [E.StructType] ->
  InternaliseM
    ( [I.TypeBase ExtShape Uniqueness],
      M.Map Name (Int, [Int])
    )
internaliseSumType :: Map Name [StructType]
-> InternaliseM
     ([TypeBase ExtShape Uniqueness], Map Name (Int, [Int]))
internaliseSumType Map Name [StructType]
cs =
  forall (t :: * -> * -> *) (f :: * -> *) a c b d.
(Bitraversable t, Applicative f) =>
(a -> f c) -> (b -> f d) -> t a b -> f (t c d)
bitraverse (forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall shape u. TypeBase shape u -> InternaliseM (TypeBase shape u)
mkAccCerts) forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. InternaliseTypeM a -> a
runInternaliseTypeM forall a b. (a -> b) -> a -> b
$
    Map Name [TypeBase ExtShape Uniqueness]
-> ([TypeBase ExtShape Uniqueness], Map Name (Int, [Int]))
internaliseConstructors
      forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Map VName Int
-> StructType -> InternaliseTypeM [TypeBase ExtShape Uniqueness]
internaliseTypeM forall a. Monoid a => a
mempty)) Map Name [StructType]
cs

-- | How many core language values are needed to represent one source
-- language value of the given type?
internalisedTypeSize :: E.TypeBase E.Size als -> Int
-- A few special cases for performance.
internalisedTypeSize :: forall als. TypeBase Size als -> Int
internalisedTypeSize (E.Scalar (E.Prim PrimType
_)) = Int
1
internalisedTypeSize (E.Array als
_ Uniqueness
_ Shape Size
_ (E.Prim PrimType
_)) = Int
1
internalisedTypeSize TypeBase Size als
t = forall (t :: * -> *) a. Foldable t => t a -> Int
length forall a b. (a -> b) -> a -> b
$ StructType -> [TypeBase ExtShape Uniqueness]
internaliseType (TypeBase Size als
t forall dim asf ast. TypeBase dim asf -> ast -> TypeBase dim ast
`E.setAliases` ())

-- | Convert an external primitive to an internal primitive.
internalisePrimType :: E.PrimType -> I.PrimType
internalisePrimType :: PrimType -> PrimType
internalisePrimType (E.Signed IntType
t) = IntType -> PrimType
I.IntType IntType
t
internalisePrimType (E.Unsigned IntType
t) = IntType -> PrimType
I.IntType IntType
t
internalisePrimType (E.FloatType FloatType
t) = FloatType -> PrimType
I.FloatType FloatType
t
internalisePrimType PrimType
E.Bool = PrimType
I.Bool

-- | Convert an external primitive value to an internal primitive value.
internalisePrimValue :: E.PrimValue -> I.PrimValue
internalisePrimValue :: PrimValue -> PrimValue
internalisePrimValue (E.SignedValue IntValue
v) = IntValue -> PrimValue
I.IntValue IntValue
v
internalisePrimValue (E.UnsignedValue IntValue
v) = IntValue -> PrimValue
I.IntValue IntValue
v
internalisePrimValue (E.FloatValue FloatValue
v) = FloatValue -> PrimValue
I.FloatValue FloatValue
v
internalisePrimValue (E.BoolValue Bool
b) = Bool -> PrimValue
I.BoolValue Bool
b