{-# LANGUAGE TypeFamilies #-}

-- | A representation for multicore CPU parallelism.
module Futhark.IR.MC
  ( MC,

    -- * Simplification
    simplifyProg,

    -- * Module re-exports
    module Futhark.IR.Prop,
    module Futhark.IR.Traversals,
    module Futhark.IR.Pretty,
    module Futhark.IR.Syntax,
    module Futhark.IR.SegOp,
    module Futhark.IR.SOACS.SOAC,
    module Futhark.IR.MC.Op,
  )
where

import Futhark.Builder
import Futhark.Construct
import Futhark.IR.MC.Op
import Futhark.IR.Pretty
import Futhark.IR.Prop
import Futhark.IR.SOACS.SOAC hiding (HistOp (..))
import Futhark.IR.SOACS.Simplify qualified as SOAC
import Futhark.IR.SegOp
import Futhark.IR.Syntax
import Futhark.IR.Traversals
import Futhark.IR.TypeCheck qualified as TypeCheck
import Futhark.Optimise.Simplify qualified as Simplify
import Futhark.Optimise.Simplify.Engine qualified as Engine
import Futhark.Optimise.Simplify.Rules
import Futhark.Pass

data MC

instance RepTypes MC where
  type OpC MC = MCOp SOAC

instance ASTRep MC where
  expTypesFromPat :: forall (m :: * -> *).
(HasScope MC m, Monad m) =>
Pat (LetDec MC) -> m [BranchType MC]
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 TypeCheck.Checkable MC where
  checkOp :: Op (Aliases MC) -> TypeM MC ()
checkOp = (SOAC (Aliases MC) -> TypeM MC ())
-> MCOp SOAC (Aliases MC) -> TypeM MC ()
forall rep (op :: * -> *).
Checkable rep =>
(op (Aliases rep) -> TypeM rep ())
-> MCOp op (Aliases rep) -> TypeM rep ()
typeCheckMCOp SOAC (Aliases MC) -> TypeM MC ()
forall rep. Checkable rep => SOAC (Aliases rep) -> TypeM rep ()
typeCheckSOAC

instance Buildable MC where
  mkBody :: Stms MC -> Result -> Body MC
mkBody = BodyDec MC -> Stms MC -> Result -> Body MC
forall rep. BodyDec rep -> Stms rep -> Result -> Body rep
Body ()
  mkExpPat :: [Ident] -> Exp MC -> Pat (LetDec MC)
mkExpPat [Ident]
idents Exp MC
_ = [Ident] -> Pat Type
basicPat [Ident]
idents
  mkExpDec :: Pat (LetDec MC) -> Exp MC -> ExpDec MC
mkExpDec Pat (LetDec MC)
_ Exp MC
_ = ()
  mkLetNames :: forall (m :: * -> *).
(MonadFreshNames m, HasScope MC m) =>
[VName] -> Exp MC -> m (Stm MC)
mkLetNames = [VName] -> Exp MC -> m (Stm MC)
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 MC

instance BuilderOps (Engine.Wise MC)

instance PrettyRep MC

instance TraverseOpStms (Engine.Wise MC) where
  traverseOpStms :: forall (m :: * -> *).
Monad m =>
OpStmsTraverser m (Op (Wise MC)) (Wise MC)
traverseOpStms = OpStmsTraverser m (SOAC (Wise MC)) (Wise MC)
-> OpStmsTraverser m (MCOp SOAC (Wise MC)) (Wise MC)
forall (m :: * -> *) (op :: * -> *) rep.
Monad m =>
OpStmsTraverser m (op rep) rep
-> OpStmsTraverser m (MCOp op rep) rep
traverseMCOpStms OpStmsTraverser m (SOAC (Wise MC)) (Wise MC)
forall (m :: * -> *) rep.
Monad m =>
OpStmsTraverser m (SOAC rep) rep
traverseSOACStms

simpleMC :: Simplify.SimpleOps MC
simpleMC :: SimpleOps MC
simpleMC = SimplifyOp MC (Op (Wise MC)) -> SimpleOps MC
forall rep.
(SimplifiableRep rep, Buildable rep) =>
SimplifyOp rep (Op (Wise rep)) -> SimpleOps rep
Simplify.bindableSimpleOps (SimplifyOp MC (Op (Wise MC)) -> SimpleOps MC)
-> SimplifyOp MC (Op (Wise MC)) -> SimpleOps MC
forall a b. (a -> b) -> a -> b
$ SimplifyOp MC (SOAC (Wise MC))
-> MCOp SOAC (Wise MC)
-> SimpleM MC (MCOp SOAC (Wise MC), Stms (Wise MC))
forall rep (op :: * -> *).
(SimplifiableRep rep, BodyDec rep ~ ()) =>
SimplifyOp rep (op (Wise rep))
-> MCOp op (Wise rep)
-> SimpleM rep (MCOp op (Wise rep), Stms (Wise rep))
simplifyMCOp SimplifyOp MC (SOAC (Wise MC))
forall rep. SimplifiableRep rep => SimplifyOp rep (SOAC (Wise rep))
SOAC.simplifySOAC

simplifyProg :: Prog MC -> PassM (Prog MC)
simplifyProg :: Prog MC -> PassM (Prog MC)
simplifyProg = SimpleOps MC
-> RuleBook (Wise MC)
-> HoistBlockers MC
-> Prog MC
-> PassM (Prog MC)
forall rep.
SimplifiableRep rep =>
SimpleOps rep
-> RuleBook (Wise rep)
-> HoistBlockers rep
-> Prog rep
-> PassM (Prog rep)
Simplify.simplifyProg SimpleOps MC
simpleMC RuleBook (Wise MC)
rules HoistBlockers MC
forall {k} {rep :: k}. HoistBlockers rep
blockers
  where
    blockers :: HoistBlockers rep
blockers = HoistBlockers rep
forall {k} {rep :: k}. HoistBlockers rep
Engine.noExtraHoistBlockers
    rules :: RuleBook (Wise MC)
rules = RuleBook (Wise MC)
forall rep. (BuilderOps rep, TraverseOpStms rep) => RuleBook rep
standardRules RuleBook (Wise MC) -> RuleBook (Wise MC) -> RuleBook (Wise MC)
forall a. Semigroup a => a -> a -> a
<> RuleBook (Wise MC)
forall rep.
(HasSegOp rep, BuilderOps rep, Buildable rep, Aliased rep) =>
RuleBook rep
segOpRules

instance HasSegOp MC where
  type SegOpLevel MC = ()
  asSegOp :: Op MC -> Maybe (SegOp (SegOpLevel MC) MC)
asSegOp = Maybe (SegOp () MC) -> MCOp SOAC MC -> Maybe (SegOp () MC)
forall a b. a -> b -> a
const Maybe (SegOp () MC)
forall a. Maybe a
Nothing
  segOp :: SegOp (SegOpLevel MC) MC -> Op MC
segOp = Maybe (SegOp () MC) -> SegOp () MC -> MCOp SOAC MC
forall (op :: * -> *) rep.
Maybe (SegOp () rep) -> SegOp () rep -> MCOp op rep
ParOp Maybe (SegOp () MC)
forall a. Maybe a
Nothing

instance HasSegOp (Engine.Wise MC) where
  type SegOpLevel (Engine.Wise MC) = ()
  asSegOp :: Op (Wise MC) -> Maybe (SegOp (SegOpLevel (Wise MC)) (Wise MC))
asSegOp = Maybe (SegOp () (Wise MC))
-> MCOp SOAC (Wise MC) -> Maybe (SegOp () (Wise MC))
forall a b. a -> b -> a
const Maybe (SegOp () (Wise MC))
forall a. Maybe a
Nothing
  segOp :: SegOp (SegOpLevel (Wise MC)) (Wise MC) -> Op (Wise MC)
segOp = Maybe (SegOp () (Wise MC))
-> SegOp () (Wise MC) -> MCOp SOAC (Wise MC)
forall (op :: * -> *) rep.
Maybe (SegOp () rep) -> SegOp () rep -> MCOp op rep
ParOp Maybe (SegOp () (Wise MC))
forall a. Maybe a
Nothing