{-# LANGUAGE TypeFamilies #-}

-- | A sequential representation.
module Futhark.IR.Seq
  ( Seq,

    -- * Simplification
    simplifyProg,

    -- * Module re-exports
    module Futhark.IR.Prop,
    module Futhark.IR.Traversals,
    module Futhark.IR.Pretty,
    module Futhark.IR.Syntax,
  )
where

import Futhark.Builder
import Futhark.Construct
import Futhark.IR.Pretty
import Futhark.IR.Prop
import Futhark.IR.Syntax
import Futhark.IR.Traversals
import Futhark.IR.TypeCheck qualified as TC
import Futhark.Optimise.Simplify qualified as Simplify
import Futhark.Optimise.Simplify.Engine qualified as Engine
import Futhark.Optimise.Simplify.Rules
import Futhark.Pass

-- | The phantom type for the Seq representation.
data Seq

instance RepTypes Seq

instance ASTRep Seq where
  expTypesFromPat :: forall (m :: * -> *).
(HasScope Seq m, Monad m) =>
Pat (LetDec Seq) -> m [BranchType Seq]
expTypesFromPat = [ExtType] -> m [ExtType]
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([ExtType] -> m [ExtType])
-> (Pat Type -> [ExtType]) -> Pat Type -> m [ExtType]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pat Type -> [ExtType]
forall dec. Typed dec => Pat dec -> [ExtType]
expExtTypesFromPat

instance TC.Checkable Seq where
  checkOp :: Op (Aliases Seq) -> TypeM Seq ()
checkOp Op (Aliases Seq)
NoOp (Aliases Seq)
NoOp = () -> TypeM Seq ()
forall a. a -> TypeM Seq a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

instance Buildable Seq where
  mkBody :: Stms Seq -> Result -> Body Seq
mkBody = BodyDec Seq -> Stms Seq -> Result -> Body Seq
forall rep. BodyDec rep -> Stms rep -> Result -> Body rep
Body ()
  mkExpPat :: [Ident] -> Exp Seq -> Pat (LetDec Seq)
mkExpPat [Ident]
idents Exp Seq
_ = [Ident] -> Pat Type
basicPat [Ident]
idents
  mkExpDec :: Pat (LetDec Seq) -> Exp Seq -> ExpDec Seq
mkExpDec Pat (LetDec Seq)
_ Exp Seq
_ = ()
  mkLetNames :: forall (m :: * -> *).
(MonadFreshNames m, HasScope Seq m) =>
[VName] -> Exp Seq -> m (Stm Seq)
mkLetNames = [VName] -> Exp Seq -> m (Stm Seq)
forall rep (m :: * -> *).
(ExpDec rep ~ (), LetDec rep ~ Type, MonadFreshNames m,
 TypedOp (Op rep), HasScope rep m) =>
[VName] -> Exp rep -> m (Stm rep)
simpleMkLetNames

instance BuilderOps Seq

instance TraverseOpStms Seq where
  traverseOpStms :: forall (m :: * -> *). Monad m => OpStmsTraverser m (Op Seq) Seq
traverseOpStms Scope Seq -> Stms Seq -> m (Stms Seq)
_ = Op Seq -> m (Op Seq)
NoOp Seq -> m (NoOp Seq)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure

instance PrettyRep Seq

instance BuilderOps (Engine.Wise Seq)

instance TraverseOpStms (Engine.Wise Seq) where
  traverseOpStms :: forall (m :: * -> *).
Monad m =>
OpStmsTraverser m (Op (Wise Seq)) (Wise Seq)
traverseOpStms Scope (Wise Seq) -> Stms (Wise Seq) -> m (Stms (Wise Seq))
_ = Op (Wise Seq) -> m (Op (Wise Seq))
NoOp (Wise Seq) -> m (NoOp (Wise Seq))
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure

simpleSeq :: Simplify.SimpleOps Seq
simpleSeq :: SimpleOps Seq
simpleSeq = SimplifyOp Seq (Op (Wise Seq)) -> SimpleOps Seq
forall rep.
(SimplifiableRep rep, Buildable rep) =>
SimplifyOp rep (Op (Wise rep)) -> SimpleOps rep
Simplify.bindableSimpleOps (SimpleM Seq (Op (Wise Seq), Stms (Wise Seq))
-> SimplifyOp Seq (Op (Wise Seq))
forall a b. a -> b -> a
const (SimpleM Seq (Op (Wise Seq), Stms (Wise Seq))
 -> SimplifyOp Seq (Op (Wise Seq)))
-> SimpleM Seq (Op (Wise Seq), Stms (Wise Seq))
-> SimplifyOp Seq (Op (Wise Seq))
forall a b. (a -> b) -> a -> b
$ (NoOp (Wise Seq), Stms (Wise Seq))
-> SimpleM Seq (NoOp (Wise Seq), Stms (Wise Seq))
forall a. a -> SimpleM Seq a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NoOp (Wise Seq)
forall {k} (rep :: k). NoOp rep
NoOp, Stms (Wise Seq)
forall a. Monoid a => a
mempty))

-- | Simplify a sequential program.
simplifyProg :: Prog Seq -> PassM (Prog Seq)
simplifyProg :: Prog Seq -> PassM (Prog Seq)
simplifyProg = SimpleOps Seq
-> RuleBook (Wise Seq)
-> HoistBlockers Seq
-> Prog Seq
-> PassM (Prog Seq)
forall rep.
SimplifiableRep rep =>
SimpleOps rep
-> RuleBook (Wise rep)
-> HoistBlockers rep
-> Prog rep
-> PassM (Prog rep)
Simplify.simplifyProg SimpleOps Seq
simpleSeq RuleBook (Wise Seq)
forall rep. (BuilderOps rep, TraverseOpStms rep) => RuleBook rep
standardRules HoistBlockers Seq
forall {k} {rep :: k}. HoistBlockers rep
blockers
  where
    blockers :: HoistBlockers rep
blockers = HoistBlockers rep
forall {k} {rep :: k}. HoistBlockers rep
Engine.noExtraHoistBlockers