{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE TypeFamilies #-}

-- | This pass attempts to lift allocations as far towards the top in their body
-- as possible. It does not try to hoist allocations outside across body
-- boundaries.
module Futhark.Pass.LiftAllocations
  ( liftAllocationsSeqMem,
    liftAllocationsGPUMem,
    liftAllocationsMCMem,
  )
where

import Control.Monad.Reader
import Data.Sequence (Seq (..))
import Futhark.IR.GPUMem
import Futhark.IR.MCMem
import Futhark.IR.SeqMem
import Futhark.Pass (Pass (..))

liftAllocationsSeqMem :: Pass SeqMem SeqMem
liftAllocationsSeqMem :: Pass SeqMem SeqMem
liftAllocationsSeqMem =
  forall {k} {k1} (fromrep :: k) (torep :: k1).
String
-> String
-> (Prog fromrep -> PassM (Prog torep))
-> Pass fromrep torep
Pass String
"lift allocations" String
"lift allocations" forall a b. (a -> b) -> a -> b
$ \prog :: Prog SeqMem
prog@Prog {[FunDef SeqMem]
progFuns :: forall {k} (rep :: k). Prog rep -> [FunDef rep]
progFuns :: [FunDef SeqMem]
progFuns} ->
    forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$
      Prog SeqMem
prog
        { progFuns :: [FunDef SeqMem]
progFuns =
            forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
              ( \f :: FunDef SeqMem
f@FunDef {Body SeqMem
funDefBody :: forall {k} (rep :: k). FunDef rep -> Body rep
funDefBody :: Body SeqMem
funDefBody} ->
                  FunDef SeqMem
f {funDefBody :: Body SeqMem
funDefBody = forall r a. Reader r a -> r -> a
runReader (forall {k} (rep :: k) inner.
(Mem rep inner, LetDec rep ~ LetDecMem) =>
Body rep -> LiftM inner (Body rep)
liftAllocationsInBody Body SeqMem
funDefBody) (forall inner. (inner -> LiftM inner inner) -> Env inner
Env forall (f :: * -> *) a. Applicative f => a -> f a
pure)}
              )
              [FunDef SeqMem]
progFuns
        }

liftAllocationsGPUMem :: Pass GPUMem GPUMem
liftAllocationsGPUMem :: Pass GPUMem GPUMem
liftAllocationsGPUMem =
  forall {k} {k1} (fromrep :: k) (torep :: k1).
String
-> String
-> (Prog fromrep -> PassM (Prog torep))
-> Pass fromrep torep
Pass String
"lift allocations gpu" String
"lift allocations gpu" forall a b. (a -> b) -> a -> b
$ \prog :: Prog GPUMem
prog@Prog {[FunDef GPUMem]
progFuns :: [FunDef GPUMem]
progFuns :: forall {k} (rep :: k). Prog rep -> [FunDef rep]
progFuns} ->
    forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$
      Prog GPUMem
prog
        { progFuns :: [FunDef GPUMem]
progFuns =
            forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
              ( \f :: FunDef GPUMem
f@FunDef {Body GPUMem
funDefBody :: Body GPUMem
funDefBody :: forall {k} (rep :: k). FunDef rep -> Body rep
funDefBody} ->
                  FunDef GPUMem
f {funDefBody :: Body GPUMem
funDefBody = forall r a. Reader r a -> r -> a
runReader (forall {k} (rep :: k) inner.
(Mem rep inner, LetDec rep ~ LetDecMem) =>
Body rep -> LiftM inner (Body rep)
liftAllocationsInBody Body GPUMem
funDefBody) (forall inner. (inner -> LiftM inner inner) -> Env inner
Env HostOp GPUMem () -> LiftM (HostOp GPUMem ()) (HostOp GPUMem ())
liftAllocationsInHostOp)}
              )
              [FunDef GPUMem]
progFuns
        }

liftAllocationsMCMem :: Pass MCMem MCMem
liftAllocationsMCMem :: Pass MCMem MCMem
liftAllocationsMCMem =
  forall {k} {k1} (fromrep :: k) (torep :: k1).
String
-> String
-> (Prog fromrep -> PassM (Prog torep))
-> Pass fromrep torep
Pass String
"lift allocations mc" String
"lift allocations mc" forall a b. (a -> b) -> a -> b
$ \prog :: Prog MCMem
prog@Prog {[FunDef MCMem]
progFuns :: [FunDef MCMem]
progFuns :: forall {k} (rep :: k). Prog rep -> [FunDef rep]
progFuns} ->
    forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$
      Prog MCMem
prog
        { progFuns :: [FunDef MCMem]
progFuns =
            forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
              ( \f :: FunDef MCMem
f@FunDef {Body MCMem
funDefBody :: Body MCMem
funDefBody :: forall {k} (rep :: k). FunDef rep -> Body rep
funDefBody} ->
                  FunDef MCMem
f {funDefBody :: Body MCMem
funDefBody = forall r a. Reader r a -> r -> a
runReader (forall {k} (rep :: k) inner.
(Mem rep inner, LetDec rep ~ LetDecMem) =>
Body rep -> LiftM inner (Body rep)
liftAllocationsInBody Body MCMem
funDefBody) (forall inner. (inner -> LiftM inner inner) -> Env inner
Env MCOp MCMem () -> LiftM (MCOp MCMem ()) (MCOp MCMem ())
liftAllocationsInMCOp)}
              )
              [FunDef MCMem]
progFuns
        }

newtype Env inner = Env
  {forall inner. Env inner -> inner -> LiftM inner inner
onInner :: inner -> LiftM inner inner}

type LiftM inner a = Reader (Env inner) a

liftAllocationsInBody :: (Mem rep inner, LetDec rep ~ LetDecMem) => Body rep -> LiftM inner (Body rep)
liftAllocationsInBody :: forall {k} (rep :: k) inner.
(Mem rep inner, LetDec rep ~ LetDecMem) =>
Body rep -> LiftM inner (Body rep)
liftAllocationsInBody Body rep
body = do
  Stms rep
stms <- forall {k} (rep :: k) inner.
(Mem rep inner, LetDec rep ~ LetDecMem) =>
Stms rep -> Stms rep -> Stms rep -> Names -> LiftM inner (Stms rep)
liftAllocationsInStms (forall {k} (rep :: k). Body rep -> Stms rep
bodyStms Body rep
body) forall a. Monoid a => a
mempty forall a. Monoid a => a
mempty forall a. Monoid a => a
mempty
  forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Body rep
body {bodyStms :: Stms rep
bodyStms = Stms rep
stms}

liftAllocationsInStms ::
  (Mem rep inner, LetDec rep ~ LetDecMem) =>
  -- | The input stms
  Stms rep ->
  -- | The lifted allocations and associated statements
  Stms rep ->
  -- | The other statements processed so far
  Stms rep ->
  -- | Names we need to lift
  Names ->
  LiftM inner (Stms rep)
liftAllocationsInStms :: forall {k} (rep :: k) inner.
(Mem rep inner, LetDec rep ~ LetDecMem) =>
Stms rep -> Stms rep -> Stms rep -> Names -> LiftM inner (Stms rep)
liftAllocationsInStms Stms rep
Empty Stms rep
lifted Stms rep
acc Names
_ = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Stms rep
lifted forall a. Semigroup a => a -> a -> a
<> Stms rep
acc
liftAllocationsInStms (Stms rep
stms :|> stm :: Stm rep
stm@(Let (Pat [PatElem VName
vname LetDec rep
_]) StmAux (ExpDec rep)
_ (Op (Alloc SubExp
_ Space
_)))) Stms rep
lifted Stms rep
acc Names
to_lift =
  forall {k} (rep :: k) inner.
(Mem rep inner, LetDec rep ~ LetDecMem) =>
Stms rep -> Stms rep -> Stms rep -> Names -> LiftM inner (Stms rep)
liftAllocationsInStms Stms rep
stms (Stm rep
stm forall a. a -> Seq a -> Seq a
:<| Stms rep
lifted) Stms rep
acc ((forall a. FreeIn a => a -> Names
freeIn Stm rep
stm forall a. Semigroup a => a -> a -> a
<> Names
to_lift) Names -> Names -> Names
`namesSubtract` VName -> Names
oneName VName
vname)
liftAllocationsInStms (Stms rep
stms :|> stm :: Stm rep
stm@(Let Pat (LetDec rep)
pat StmAux (ExpDec rep)
_ (Op (Inner inner
inner)))) Stms rep
lifted Stms rep
acc Names
to_lift = do
  inner -> LiftM inner inner
on_inner <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall inner. Env inner -> inner -> LiftM inner inner
onInner
  inner
inner' <- inner -> LiftM inner inner
on_inner inner
inner
  let stm' :: Stm rep
stm' = Stm rep
stm {stmExp :: Exp rep
stmExp = forall {k} (rep :: k). Op rep -> Exp rep
Op forall a b. (a -> b) -> a -> b
$ forall inner. inner -> MemOp inner
Inner inner
inner'}
      pat_names :: Names
pat_names = [VName] -> Names
namesFromList forall a b. (a -> b) -> a -> b
$ forall dec. Pat dec -> [VName]
patNames Pat (LetDec rep)
pat
  if Names
pat_names Names -> Names -> Bool
`namesIntersect` Names
to_lift
    then forall {k} (rep :: k) inner.
(Mem rep inner, LetDec rep ~ LetDecMem) =>
Stms rep -> Stms rep -> Stms rep -> Names -> LiftM inner (Stms rep)
liftAllocationsInStms Stms rep
stms (Stm rep
stm' forall a. a -> Seq a -> Seq a
:<| Stms rep
lifted) Stms rep
acc ((Names
to_lift Names -> Names -> Names
`namesSubtract` Names
pat_names) forall a. Semigroup a => a -> a -> a
<> forall a. FreeIn a => a -> Names
freeIn Stm rep
stm)
    else forall {k} (rep :: k) inner.
(Mem rep inner, LetDec rep ~ LetDecMem) =>
Stms rep -> Stms rep -> Stms rep -> Names -> LiftM inner (Stms rep)
liftAllocationsInStms Stms rep
stms Stms rep
lifted (Stm rep
stm' forall a. a -> Seq a -> Seq a
:<| Stms rep
acc) Names
to_lift
liftAllocationsInStms (Stms rep
stms :|> stm :: Stm rep
stm@(Let Pat (LetDec rep)
pat StmAux (ExpDec rep)
aux (Match [SubExp]
cond_ses [Case (Body rep)]
cases Body rep
body MatchDec (BranchType rep)
dec))) Stms rep
lifted Stms rep
acc Names
to_lift = do
  [Case (Body rep)]
cases' <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (\(Case [Maybe PrimValue]
p Body rep
b) -> forall body. [Maybe PrimValue] -> body -> Case body
Case [Maybe PrimValue]
p forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall {k} (rep :: k) inner.
(Mem rep inner, LetDec rep ~ LetDecMem) =>
Body rep -> LiftM inner (Body rep)
liftAllocationsInBody Body rep
b) [Case (Body rep)]
cases
  Body rep
body' <- forall {k} (rep :: k) inner.
(Mem rep inner, LetDec rep ~ LetDecMem) =>
Body rep -> LiftM inner (Body rep)
liftAllocationsInBody Body rep
body
  let stm' :: Stm rep
stm' = Stm rep
stm {stmExp :: Exp rep
stmExp = forall {k} (rep :: k).
[SubExp]
-> [Case (Body rep)]
-> Body rep
-> MatchDec (BranchType rep)
-> Exp rep
Match [SubExp]
cond_ses [Case (Body rep)]
cases' Body rep
body' MatchDec (BranchType rep)
dec}
      pat_names :: Names
pat_names = [VName] -> Names
namesFromList forall a b. (a -> b) -> a -> b
$ forall dec. Pat dec -> [VName]
patNames Pat (LetDec rep)
pat
  if Names
pat_names Names -> Names -> Bool
`namesIntersect` Names
to_lift
    then
      forall {k} (rep :: k) inner.
(Mem rep inner, LetDec rep ~ LetDecMem) =>
Stms rep -> Stms rep -> Stms rep -> Names -> LiftM inner (Stms rep)
liftAllocationsInStms
        Stms rep
stms
        (Stm rep
stm' forall a. a -> Seq a -> Seq a
:<| Stms rep
lifted)
        Stms rep
acc
        ( (Names
to_lift Names -> Names -> Names
`namesSubtract` Names
pat_names)
            forall a. Semigroup a => a -> a -> a
<> forall a. FreeIn a => a -> Names
freeIn [SubExp]
cond_ses
            forall a. Semigroup a => a -> a -> a
<> forall a. FreeIn a => a -> Names
freeIn [Case (Body rep)]
cases
            forall a. Semigroup a => a -> a -> a
<> forall a. FreeIn a => a -> Names
freeIn Body rep
body
            forall a. Semigroup a => a -> a -> a
<> forall a. FreeIn a => a -> Names
freeIn MatchDec (BranchType rep)
dec
            forall a. Semigroup a => a -> a -> a
<> forall a. FreeIn a => a -> Names
freeIn StmAux (ExpDec rep)
aux
        )
    else forall {k} (rep :: k) inner.
(Mem rep inner, LetDec rep ~ LetDecMem) =>
Stms rep -> Stms rep -> Stms rep -> Names -> LiftM inner (Stms rep)
liftAllocationsInStms Stms rep
stms Stms rep
lifted (Stm rep
stm' forall a. a -> Seq a -> Seq a
:<| Stms rep
acc) Names
to_lift
liftAllocationsInStms (Stms rep
stms :|> stm :: Stm rep
stm@(Let Pat (LetDec rep)
pat StmAux (ExpDec rep)
_ (DoLoop [(FParam rep, SubExp)]
params LoopForm rep
form Body rep
body))) Stms rep
lifted Stms rep
acc Names
to_lift = do
  Body rep
body' <- forall {k} (rep :: k) inner.
(Mem rep inner, LetDec rep ~ LetDecMem) =>
Body rep -> LiftM inner (Body rep)
liftAllocationsInBody Body rep
body
  let stm' :: Stm rep
stm' = Stm rep
stm {stmExp :: Exp rep
stmExp = forall {k} (rep :: k).
[(FParam rep, SubExp)] -> LoopForm rep -> Body rep -> Exp rep
DoLoop [(FParam rep, SubExp)]
params LoopForm rep
form Body rep
body'}
      pat_names :: Names
pat_names = [VName] -> Names
namesFromList forall a b. (a -> b) -> a -> b
$ forall dec. Pat dec -> [VName]
patNames Pat (LetDec rep)
pat
  if Names
pat_names Names -> Names -> Bool
`namesIntersect` Names
to_lift
    then forall {k} (rep :: k) inner.
(Mem rep inner, LetDec rep ~ LetDecMem) =>
Stms rep -> Stms rep -> Stms rep -> Names -> LiftM inner (Stms rep)
liftAllocationsInStms Stms rep
stms (Stm rep
stm' forall a. a -> Seq a -> Seq a
:<| Stms rep
lifted) Stms rep
acc ((Names
to_lift Names -> Names -> Names
`namesSubtract` Names
pat_names) forall a. Semigroup a => a -> a -> a
<> forall a. FreeIn a => a -> Names
freeIn Stm rep
stm)
    else forall {k} (rep :: k) inner.
(Mem rep inner, LetDec rep ~ LetDecMem) =>
Stms rep -> Stms rep -> Stms rep -> Names -> LiftM inner (Stms rep)
liftAllocationsInStms Stms rep
stms Stms rep
lifted (Stm rep
stm' forall a. a -> Seq a -> Seq a
:<| Stms rep
acc) Names
to_lift
liftAllocationsInStms (Stms rep
stms :|> stm :: Stm rep
stm@(Let Pat (LetDec rep)
pat StmAux (ExpDec rep)
_ Exp rep
_)) Stms rep
lifted Stms rep
acc Names
to_lift = do
  let pat_names :: Names
pat_names = [VName] -> Names
namesFromList (forall dec. Pat dec -> [VName]
patNames Pat (LetDec rep)
pat)
  if Names
pat_names Names -> Names -> Bool
`namesIntersect` Names
to_lift
    then forall {k} (rep :: k) inner.
(Mem rep inner, LetDec rep ~ LetDecMem) =>
Stms rep -> Stms rep -> Stms rep -> Names -> LiftM inner (Stms rep)
liftAllocationsInStms Stms rep
stms (Stm rep
stm forall a. a -> Seq a -> Seq a
:<| Stms rep
lifted) Stms rep
acc ((Names
to_lift Names -> Names -> Names
`namesSubtract` Names
pat_names) forall a. Semigroup a => a -> a -> a
<> forall a. FreeIn a => a -> Names
freeIn Stm rep
stm)
    else forall {k} (rep :: k) inner.
(Mem rep inner, LetDec rep ~ LetDecMem) =>
Stms rep -> Stms rep -> Stms rep -> Names -> LiftM inner (Stms rep)
liftAllocationsInStms Stms rep
stms Stms rep
lifted (Stm rep
stm forall a. a -> Seq a -> Seq a
:<| Stms rep
acc) Names
to_lift

liftAllocationsInSegOp ::
  (Mem rep inner, LetDec rep ~ LetDecMem) =>
  SegOp lvl rep ->
  LiftM inner (SegOp lvl rep)
liftAllocationsInSegOp :: forall {k} (rep :: k) inner lvl.
(Mem rep inner, LetDec rep ~ LetDecMem) =>
SegOp lvl rep -> LiftM inner (SegOp lvl rep)
liftAllocationsInSegOp (SegMap lvl
lvl SegSpace
sp [Type]
tps KernelBody rep
body) = do
  Stms rep
stms <- forall {k} (rep :: k) inner.
(Mem rep inner, LetDec rep ~ LetDecMem) =>
Stms rep -> Stms rep -> Stms rep -> Names -> LiftM inner (Stms rep)
liftAllocationsInStms (forall {k} (rep :: k). KernelBody rep -> Stms rep
kernelBodyStms KernelBody rep
body) forall a. Monoid a => a
mempty forall a. Monoid a => a
mempty forall a. Monoid a => a
mempty
  forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall {k} lvl (rep :: k).
lvl -> SegSpace -> [Type] -> KernelBody rep -> SegOp lvl rep
SegMap lvl
lvl SegSpace
sp [Type]
tps forall a b. (a -> b) -> a -> b
$ KernelBody rep
body {kernelBodyStms :: Stms rep
kernelBodyStms = Stms rep
stms}
liftAllocationsInSegOp (SegRed lvl
lvl SegSpace
sp [SegBinOp rep]
binops [Type]
tps KernelBody rep
body) = do
  Stms rep
stms <- forall {k} (rep :: k) inner.
(Mem rep inner, LetDec rep ~ LetDecMem) =>
Stms rep -> Stms rep -> Stms rep -> Names -> LiftM inner (Stms rep)
liftAllocationsInStms (forall {k} (rep :: k). KernelBody rep -> Stms rep
kernelBodyStms KernelBody rep
body) forall a. Monoid a => a
mempty forall a. Monoid a => a
mempty forall a. Monoid a => a
mempty
  forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall {k} lvl (rep :: k).
lvl
-> SegSpace
-> [SegBinOp rep]
-> [Type]
-> KernelBody rep
-> SegOp lvl rep
SegRed lvl
lvl SegSpace
sp [SegBinOp rep]
binops [Type]
tps forall a b. (a -> b) -> a -> b
$ KernelBody rep
body {kernelBodyStms :: Stms rep
kernelBodyStms = Stms rep
stms}
liftAllocationsInSegOp (SegScan lvl
lvl SegSpace
sp [SegBinOp rep]
binops [Type]
tps KernelBody rep
body) = do
  Stms rep
stms <- forall {k} (rep :: k) inner.
(Mem rep inner, LetDec rep ~ LetDecMem) =>
Stms rep -> Stms rep -> Stms rep -> Names -> LiftM inner (Stms rep)
liftAllocationsInStms (forall {k} (rep :: k). KernelBody rep -> Stms rep
kernelBodyStms KernelBody rep
body) forall a. Monoid a => a
mempty forall a. Monoid a => a
mempty forall a. Monoid a => a
mempty
  forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall {k} lvl (rep :: k).
lvl
-> SegSpace
-> [SegBinOp rep]
-> [Type]
-> KernelBody rep
-> SegOp lvl rep
SegScan lvl
lvl SegSpace
sp [SegBinOp rep]
binops [Type]
tps forall a b. (a -> b) -> a -> b
$ KernelBody rep
body {kernelBodyStms :: Stms rep
kernelBodyStms = Stms rep
stms}
liftAllocationsInSegOp (SegHist lvl
lvl SegSpace
sp [HistOp rep]
histops [Type]
tps KernelBody rep
body) = do
  Stms rep
stms <- forall {k} (rep :: k) inner.
(Mem rep inner, LetDec rep ~ LetDecMem) =>
Stms rep -> Stms rep -> Stms rep -> Names -> LiftM inner (Stms rep)
liftAllocationsInStms (forall {k} (rep :: k). KernelBody rep -> Stms rep
kernelBodyStms KernelBody rep
body) forall a. Monoid a => a
mempty forall a. Monoid a => a
mempty forall a. Monoid a => a
mempty
  forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall {k} lvl (rep :: k).
lvl
-> SegSpace
-> [HistOp rep]
-> [Type]
-> KernelBody rep
-> SegOp lvl rep
SegHist lvl
lvl SegSpace
sp [HistOp rep]
histops [Type]
tps forall a b. (a -> b) -> a -> b
$ KernelBody rep
body {kernelBodyStms :: Stms rep
kernelBodyStms = Stms rep
stms}

liftAllocationsInHostOp :: HostOp GPUMem () -> LiftM (HostOp GPUMem ()) (HostOp GPUMem ())
liftAllocationsInHostOp :: HostOp GPUMem () -> LiftM (HostOp GPUMem ()) (HostOp GPUMem ())
liftAllocationsInHostOp (SegOp SegOp SegLevel GPUMem
op) = forall {k} (rep :: k) op. SegOp SegLevel rep -> HostOp rep op
SegOp forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall {k} (rep :: k) inner lvl.
(Mem rep inner, LetDec rep ~ LetDecMem) =>
SegOp lvl rep -> LiftM inner (SegOp lvl rep)
liftAllocationsInSegOp SegOp SegLevel GPUMem
op
liftAllocationsInHostOp HostOp GPUMem ()
op = forall (f :: * -> *) a. Applicative f => a -> f a
pure HostOp GPUMem ()
op

liftAllocationsInMCOp :: MCOp MCMem () -> LiftM (MCOp MCMem ()) (MCOp MCMem ())
liftAllocationsInMCOp :: MCOp MCMem () -> LiftM (MCOp MCMem ()) (MCOp MCMem ())
liftAllocationsInMCOp (ParOp Maybe (SegOp () MCMem)
par SegOp () MCMem
op) =
  forall {k} (rep :: k) op.
Maybe (SegOp () rep) -> SegOp () rep -> MCOp rep op
ParOp 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 {k} (rep :: k) inner lvl.
(Mem rep inner, LetDec rep ~ LetDecMem) =>
SegOp lvl rep -> LiftM inner (SegOp lvl rep)
liftAllocationsInSegOp Maybe (SegOp () MCMem)
par forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall {k} (rep :: k) inner lvl.
(Mem rep inner, LetDec rep ~ LetDecMem) =>
SegOp lvl rep -> LiftM inner (SegOp lvl rep)
liftAllocationsInSegOp SegOp () MCMem
op
liftAllocationsInMCOp MCOp MCMem ()
op = forall (f :: * -> *) a. Applicative f => a -> f a
pure MCOp MCMem ()
op