{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}

module Futhark.IR.GPU.Simplify
  ( simplifyGPU,
    simplifyLambda,
    GPU,

    -- * Building blocks
    simplifyKernelOp,
  )
where

import qualified Futhark.Analysis.UsageTable as UT
import Futhark.IR.GPU
import qualified Futhark.IR.SOACS.Simplify as SOAC
import Futhark.MonadFreshNames
import qualified Futhark.Optimise.Simplify as Simplify
import qualified Futhark.Optimise.Simplify.Engine as Engine
import Futhark.Optimise.Simplify.Rep
import Futhark.Optimise.Simplify.Rule
import Futhark.Optimise.Simplify.Rules
import Futhark.Pass
import Futhark.Tools

simpleGPU :: Simplify.SimpleOps GPU
simpleGPU :: SimpleOps GPU
simpleGPU = SimplifyOp GPU (Op (Wise GPU)) -> SimpleOps GPU
forall rep.
(SimplifiableRep rep, Buildable rep) =>
SimplifyOp rep (Op (Wise rep)) -> SimpleOps rep
Simplify.bindableSimpleOps (SimplifyOp GPU (Op (Wise GPU)) -> SimpleOps GPU)
-> SimplifyOp GPU (Op (Wise GPU)) -> SimpleOps GPU
forall a b. (a -> b) -> a -> b
$ SimplifyOp GPU (SOAC (Wise GPU))
-> HostOp (Wise GPU) (SOAC (Wise GPU))
-> SimpleM
     GPU (HostOp (Wise GPU) (SOAC (Wise GPU)), Stms (Wise GPU))
forall rep op.
(SimplifiableRep rep, BodyDec rep ~ ()) =>
SimplifyOp rep op
-> HostOp (Wise rep) op
-> SimpleM rep (HostOp (Wise rep) op, Stms (Wise rep))
simplifyKernelOp SimplifyOp GPU (SOAC (Wise GPU))
forall rep. SimplifiableRep rep => SimplifyOp rep (SOAC (Wise rep))
SOAC.simplifySOAC

simplifyGPU :: Prog GPU -> PassM (Prog GPU)
simplifyGPU :: Prog GPU -> PassM (Prog GPU)
simplifyGPU =
  SimpleOps GPU
-> RuleBook (Wise GPU)
-> HoistBlockers GPU
-> Prog GPU
-> PassM (Prog GPU)
forall rep.
SimplifiableRep rep =>
SimpleOps rep
-> RuleBook (Wise rep)
-> HoistBlockers rep
-> Prog rep
-> PassM (Prog rep)
Simplify.simplifyProg SimpleOps GPU
simpleGPU RuleBook (Wise GPU)
kernelRules HoistBlockers GPU
forall rep. HoistBlockers rep
Simplify.noExtraHoistBlockers

simplifyLambda ::
  (HasScope GPU m, MonadFreshNames m) =>
  Lambda GPU ->
  m (Lambda GPU)
simplifyLambda :: Lambda GPU -> m (Lambda GPU)
simplifyLambda =
  SimpleOps GPU
-> RuleBook (Wise GPU)
-> HoistBlockers GPU
-> Lambda GPU
-> m (Lambda GPU)
forall (m :: * -> *) rep.
(MonadFreshNames m, HasScope rep m, SimplifiableRep rep) =>
SimpleOps rep
-> RuleBook (Wise rep)
-> HoistBlockers rep
-> Lambda rep
-> m (Lambda rep)
Simplify.simplifyLambda SimpleOps GPU
simpleGPU RuleBook (Wise GPU)
kernelRules HoistBlockers GPU
forall rep. HoistBlockers rep
Engine.noExtraHoistBlockers

simplifyKernelOp ::
  ( Engine.SimplifiableRep rep,
    BodyDec rep ~ ()
  ) =>
  Simplify.SimplifyOp rep op ->
  HostOp (Wise rep) op ->
  Engine.SimpleM rep (HostOp (Wise rep) op, Stms (Wise rep))
simplifyKernelOp :: SimplifyOp rep op
-> HostOp (Wise rep) op
-> SimpleM rep (HostOp (Wise rep) op, Stms (Wise rep))
simplifyKernelOp SimplifyOp rep op
f (OtherOp op
op) = do
  (op
op', Stms (Wise rep)
stms) <- SimplifyOp rep op
f op
op
  (HostOp (Wise rep) op, Stms (Wise rep))
-> SimpleM rep (HostOp (Wise rep) op, Stms (Wise rep))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (op -> HostOp (Wise rep) op
forall rep op. op -> HostOp rep op
OtherOp op
op', Stms (Wise rep)
stms)
simplifyKernelOp SimplifyOp rep op
_ (SegOp SegOp SegLevel (Wise rep)
op) = do
  (SegOp SegLevel (Wise rep)
op', Stms (Wise rep)
hoisted) <- SegOp SegLevel (Wise rep)
-> SimpleM rep (SegOp SegLevel (Wise rep), Stms (Wise rep))
forall rep lvl.
(SimplifiableRep rep, BodyDec rep ~ (), Simplifiable lvl) =>
SegOp lvl (Wise rep)
-> SimpleM rep (SegOp lvl (Wise rep), Stms (Wise rep))
simplifySegOp SegOp SegLevel (Wise rep)
op
  (HostOp (Wise rep) op, Stms (Wise rep))
-> SimpleM rep (HostOp (Wise rep) op, Stms (Wise rep))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SegOp SegLevel (Wise rep) -> HostOp (Wise rep) op
forall rep op. SegOp SegLevel rep -> HostOp rep op
SegOp SegOp SegLevel (Wise rep)
op', Stms (Wise rep)
hoisted)
simplifyKernelOp SimplifyOp rep op
_ (SizeOp (SplitSpace SplitOrdering
o SubExp
w SubExp
i SubExp
elems_per_thread)) =
  (,)
    (HostOp (Wise rep) op
 -> Stms (Wise rep) -> (HostOp (Wise rep) op, Stms (Wise rep)))
-> SimpleM rep (HostOp (Wise rep) op)
-> SimpleM
     rep (Stms (Wise rep) -> (HostOp (Wise rep) op, Stms (Wise rep)))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ( SizeOp -> HostOp (Wise rep) op
forall rep op. SizeOp -> HostOp rep op
SizeOp
            (SizeOp -> HostOp (Wise rep) op)
-> SimpleM rep SizeOp -> SimpleM rep (HostOp (Wise rep) op)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ( SplitOrdering -> SubExp -> SubExp -> SubExp -> SizeOp
SplitSpace (SplitOrdering -> SubExp -> SubExp -> SubExp -> SizeOp)
-> SimpleM rep SplitOrdering
-> SimpleM rep (SubExp -> SubExp -> SubExp -> SizeOp)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SplitOrdering -> SimpleM rep SplitOrdering
forall e rep.
(Simplifiable e, SimplifiableRep rep) =>
e -> SimpleM rep e
Engine.simplify SplitOrdering
o SimpleM rep (SubExp -> SubExp -> SubExp -> SizeOp)
-> SimpleM rep SubExp -> SimpleM rep (SubExp -> SubExp -> SizeOp)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SubExp -> SimpleM rep SubExp
forall e rep.
(Simplifiable e, SimplifiableRep rep) =>
e -> SimpleM rep e
Engine.simplify SubExp
w
                    SimpleM rep (SubExp -> SubExp -> SizeOp)
-> SimpleM rep SubExp -> SimpleM rep (SubExp -> SizeOp)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SubExp -> SimpleM rep SubExp
forall e rep.
(Simplifiable e, SimplifiableRep rep) =>
e -> SimpleM rep e
Engine.simplify SubExp
i
                    SimpleM rep (SubExp -> SizeOp)
-> SimpleM rep SubExp -> SimpleM rep SizeOp
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> SubExp -> SimpleM rep SubExp
forall e rep.
(Simplifiable e, SimplifiableRep rep) =>
e -> SimpleM rep e
Engine.simplify SubExp
elems_per_thread
                )
        )
    SimpleM
  rep (Stms (Wise rep) -> (HostOp (Wise rep) op, Stms (Wise rep)))
-> SimpleM rep (Stms (Wise rep))
-> SimpleM rep (HostOp (Wise rep) op, Stms (Wise rep))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Stms (Wise rep) -> SimpleM rep (Stms (Wise rep))
forall (f :: * -> *) a. Applicative f => a -> f a
pure Stms (Wise rep)
forall a. Monoid a => a
mempty
simplifyKernelOp SimplifyOp rep op
_ (SizeOp (GetSize Name
key SizeClass
size_class)) =
  (HostOp (Wise rep) op, Stms (Wise rep))
-> SimpleM rep (HostOp (Wise rep) op, Stms (Wise rep))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SizeOp -> HostOp (Wise rep) op
forall rep op. SizeOp -> HostOp rep op
SizeOp (SizeOp -> HostOp (Wise rep) op) -> SizeOp -> HostOp (Wise rep) op
forall a b. (a -> b) -> a -> b
$ Name -> SizeClass -> SizeOp
GetSize Name
key SizeClass
size_class, Stms (Wise rep)
forall a. Monoid a => a
mempty)
simplifyKernelOp SimplifyOp rep op
_ (SizeOp (GetSizeMax SizeClass
size_class)) =
  (HostOp (Wise rep) op, Stms (Wise rep))
-> SimpleM rep (HostOp (Wise rep) op, Stms (Wise rep))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SizeOp -> HostOp (Wise rep) op
forall rep op. SizeOp -> HostOp rep op
SizeOp (SizeOp -> HostOp (Wise rep) op) -> SizeOp -> HostOp (Wise rep) op
forall a b. (a -> b) -> a -> b
$ SizeClass -> SizeOp
GetSizeMax SizeClass
size_class, Stms (Wise rep)
forall a. Monoid a => a
mempty)
simplifyKernelOp SimplifyOp rep op
_ (SizeOp (CmpSizeLe Name
key SizeClass
size_class SubExp
x)) = do
  SubExp
x' <- SubExp -> SimpleM rep SubExp
forall e rep.
(Simplifiable e, SimplifiableRep rep) =>
e -> SimpleM rep e
Engine.simplify SubExp
x
  (HostOp (Wise rep) op, Stms (Wise rep))
-> SimpleM rep (HostOp (Wise rep) op, Stms (Wise rep))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SizeOp -> HostOp (Wise rep) op
forall rep op. SizeOp -> HostOp rep op
SizeOp (SizeOp -> HostOp (Wise rep) op) -> SizeOp -> HostOp (Wise rep) op
forall a b. (a -> b) -> a -> b
$ Name -> SizeClass -> SubExp -> SizeOp
CmpSizeLe Name
key SizeClass
size_class SubExp
x', Stms (Wise rep)
forall a. Monoid a => a
mempty)
simplifyKernelOp SimplifyOp rep op
_ (SizeOp (CalcNumGroups SubExp
w Name
max_num_groups SubExp
group_size)) = do
  SubExp
w' <- SubExp -> SimpleM rep SubExp
forall e rep.
(Simplifiable e, SimplifiableRep rep) =>
e -> SimpleM rep e
Engine.simplify SubExp
w
  (HostOp (Wise rep) op, Stms (Wise rep))
-> SimpleM rep (HostOp (Wise rep) op, Stms (Wise rep))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SizeOp -> HostOp (Wise rep) op
forall rep op. SizeOp -> HostOp rep op
SizeOp (SizeOp -> HostOp (Wise rep) op) -> SizeOp -> HostOp (Wise rep) op
forall a b. (a -> b) -> a -> b
$ SubExp -> Name -> SubExp -> SizeOp
CalcNumGroups SubExp
w' Name
max_num_groups SubExp
group_size, Stms (Wise rep)
forall a. Monoid a => a
mempty)
simplifyKernelOp SimplifyOp rep op
_ (GPUBody [Type]
ts Body (Wise rep)
body) = do
  [Type]
ts' <- [Type] -> SimpleM rep [Type]
forall e rep.
(Simplifiable e, SimplifiableRep rep) =>
e -> SimpleM rep e
Engine.simplify [Type]
ts
  (Stms (Wise rep)
hoisted, Body (Wise rep)
body') <-
    BlockPred (Wise rep)
-> UsageTable
-> [Usages]
-> Body (Wise rep)
-> SimpleM rep (Stms (Wise rep), Body (Wise rep))
forall rep.
SimplifiableRep rep =>
BlockPred (Wise rep)
-> UsageTable
-> [Usages]
-> Body (Wise rep)
-> SimpleM rep (Stms (Wise rep), Body (Wise rep))
Engine.simplifyBody BlockPred (Wise rep)
forall p p rep. p -> p -> Stm rep -> Bool
keepOnGPU UsageTable
forall a. Monoid a => a
mempty ((Type -> Usages) -> [Type] -> [Usages]
forall a b. (a -> b) -> [a] -> [b]
map (Usages -> Type -> Usages
forall a b. a -> b -> a
const Usages
forall a. Monoid a => a
mempty) [Type]
ts) Body (Wise rep)
body
  (HostOp (Wise rep) op, Stms (Wise rep))
-> SimpleM rep (HostOp (Wise rep) op, Stms (Wise rep))
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Type] -> Body (Wise rep) -> HostOp (Wise rep) op
forall rep op. [Type] -> Body rep -> HostOp rep op
GPUBody [Type]
ts' Body (Wise rep)
body', Stms (Wise rep)
hoisted)
  where
    keepOnGPU :: p -> p -> Stm rep -> Bool
keepOnGPU p
_ p
_ = Exp rep -> Bool
forall rep. Exp rep -> Bool
keepExpOnGPU (Exp rep -> Bool) -> (Stm rep -> Exp rep) -> Stm rep -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Stm rep -> Exp rep
forall rep. Stm rep -> Exp rep
stmExp
    keepExpOnGPU :: Exp rep -> Bool
keepExpOnGPU (BasicOp Index {}) = Bool
True
    keepExpOnGPU (BasicOp (ArrayLit [SubExp]
_ Type
t)) | Type -> Bool
forall shape u. TypeBase shape u -> Bool
primType Type
t = Bool
True
    keepExpOnGPU DoLoop {} = Bool
True
    keepExpOnGPU Exp rep
_ = Bool
False

instance TraverseOpStms (Wise GPU) where
  traverseOpStms :: OpStmsTraverser m (Op (Wise GPU)) (Wise GPU)
traverseOpStms = OpStmsTraverser m (SOAC (Wise GPU)) (Wise GPU)
-> OpStmsTraverser
     m (HostOp (Wise GPU) (SOAC (Wise GPU))) (Wise GPU)
forall (m :: * -> *) op rep.
Monad m =>
OpStmsTraverser m op rep -> OpStmsTraverser m (HostOp rep op) rep
traverseHostOpStms OpStmsTraverser m (SOAC (Wise GPU)) (Wise GPU)
forall (m :: * -> *) rep.
Monad m =>
OpStmsTraverser m (SOAC rep) rep
traverseSOACStms

instance BuilderOps (Wise GPU)

instance HasSegOp (Wise GPU) where
  type SegOpLevel (Wise GPU) = SegLevel
  asSegOp :: Op (Wise GPU) -> Maybe (SegOp (SegOpLevel (Wise GPU)) (Wise GPU))
asSegOp (SegOp op) = SegOp SegLevel (Wise GPU) -> Maybe (SegOp SegLevel (Wise GPU))
forall a. a -> Maybe a
Just SegOp SegLevel (Wise GPU)
op
  asSegOp Op (Wise GPU)
_ = Maybe (SegOp (SegOpLevel (Wise GPU)) (Wise GPU))
forall a. Maybe a
Nothing
  segOp :: SegOp (SegOpLevel (Wise GPU)) (Wise GPU) -> Op (Wise GPU)
segOp = SegOp (SegOpLevel (Wise GPU)) (Wise GPU) -> Op (Wise GPU)
forall rep op. SegOp SegLevel rep -> HostOp rep op
SegOp

instance SOAC.HasSOAC (Wise GPU) where
  asSOAC :: Op (Wise GPU) -> Maybe (SOAC (Wise GPU))
asSOAC (OtherOp soac) = SOAC (Wise GPU) -> Maybe (SOAC (Wise GPU))
forall a. a -> Maybe a
Just SOAC (Wise GPU)
soac
  asSOAC Op (Wise GPU)
_ = Maybe (SOAC (Wise GPU))
forall a. Maybe a
Nothing
  soacOp :: SOAC (Wise GPU) -> Op (Wise GPU)
soacOp = SOAC (Wise GPU) -> Op (Wise GPU)
forall rep op. op -> HostOp rep op
OtherOp

kernelRules :: RuleBook (Wise GPU)
kernelRules :: RuleBook (Wise GPU)
kernelRules =
  RuleBook (Wise GPU)
forall rep.
(BuilderOps rep, TraverseOpStms rep, Aliased rep) =>
RuleBook rep
standardRules RuleBook (Wise GPU) -> RuleBook (Wise GPU) -> RuleBook (Wise GPU)
forall a. Semigroup a => a -> a -> a
<> RuleBook (Wise GPU)
forall rep.
(HasSegOp rep, BuilderOps rep, Buildable rep, Aliased rep) =>
RuleBook rep
segOpRules
    RuleBook (Wise GPU) -> RuleBook (Wise GPU) -> RuleBook (Wise GPU)
forall a. Semigroup a => a -> a -> a
<> [TopDownRule (Wise GPU)]
-> [BottomUpRule (Wise GPU)] -> RuleBook (Wise GPU)
forall m. [TopDownRule m] -> [BottomUpRule m] -> RuleBook m
ruleBook
      [ RuleOp (Wise GPU) (TopDown (Wise GPU)) -> TopDownRule (Wise GPU)
forall rep a. RuleOp rep a -> SimplificationRule rep a
RuleOp RuleOp (Wise GPU) (TopDown (Wise GPU))
forall rep.
(Buildable rep, BuilderOps rep, HasSOAC rep) =>
TopDownRuleOp rep
SOAC.simplifyKnownIterationSOAC,
        RuleOp (Wise GPU) (TopDown (Wise GPU)) -> TopDownRule (Wise GPU)
forall rep a. RuleOp rep a -> SimplificationRule rep a
RuleOp RuleOp (Wise GPU) (TopDown (Wise GPU))
forall rep.
(Aliased rep, Buildable rep, BuilderOps rep, HasSOAC rep) =>
TopDownRuleOp rep
SOAC.removeReplicateMapping,
        RuleOp (Wise GPU) (TopDown (Wise GPU)) -> TopDownRule (Wise GPU)
forall rep a. RuleOp rep a -> SimplificationRule rep a
RuleOp RuleOp (Wise GPU) (TopDown (Wise GPU))
forall rep.
(Buildable rep, BuilderOps rep, HasSOAC rep) =>
TopDownRuleOp rep
SOAC.liftIdentityMapping,
        RuleOp (Wise GPU) (TopDown (Wise GPU)) -> TopDownRule (Wise GPU)
forall rep a. RuleOp rep a -> SimplificationRule rep a
RuleOp RuleOp (Wise GPU) (TopDown (Wise GPU))
forall rep.
(Buildable rep, BuilderOps rep, HasSOAC rep) =>
TopDownRuleOp rep
SOAC.simplifyMapIota,
        RuleOp (Wise GPU) (TopDown (Wise GPU)) -> TopDownRule (Wise GPU)
forall rep a. RuleOp rep a -> SimplificationRule rep a
RuleOp RuleOp (Wise GPU) (TopDown (Wise GPU))
forall rep.
(Aliased rep, Buildable rep, BuilderOps rep, HasSOAC rep) =>
TopDownRuleOp rep
SOAC.removeUnusedSOACInput
      ]
      [ RuleBasicOp (Wise GPU) (BottomUp (Wise GPU))
-> BottomUpRule (Wise GPU)
forall rep a. RuleBasicOp rep a -> SimplificationRule rep a
RuleBasicOp RuleBasicOp (Wise GPU) (BottomUp (Wise GPU))
forall rep. BuilderOps rep => BottomUpRuleBasicOp rep
removeUnnecessaryCopy,
        RuleOp (Wise GPU) (BottomUp (Wise GPU)) -> BottomUpRule (Wise GPU)
forall rep a. RuleOp rep a -> SimplificationRule rep a
RuleOp RuleOp (Wise GPU) (BottomUp (Wise GPU))
removeDeadGPUBodyResult
      ]

-- | Remove the unused return values of a GPUBody.
removeDeadGPUBodyResult :: BottomUpRuleOp (Wise GPU)
removeDeadGPUBodyResult :: RuleOp (Wise GPU) (BottomUp (Wise GPU))
removeDeadGPUBodyResult (TopDown (Wise GPU)
_, UsageTable
used) Pat (LetDec (Wise GPU))
pat StmAux (ExpDec (Wise GPU))
aux (GPUBody types body)
  | -- Figure out which of the names in 'pat' are used...
    [Bool]
pat_used <- (VName -> Bool) -> [VName] -> [Bool]
forall a b. (a -> b) -> [a] -> [b]
map (VName -> UsageTable -> Bool
`UT.isUsedDirectly` UsageTable
used) ([VName] -> [Bool]) -> [VName] -> [Bool]
forall a b. (a -> b) -> a -> b
$ Pat (VarWisdom, Type) -> [VName]
forall dec. Pat dec -> [VName]
patNames Pat (VarWisdom, Type)
Pat (LetDec (Wise GPU))
pat,
    -- If they are not all used, then this rule applies.
    Bool -> Bool
not ([Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and [Bool]
pat_used) =
      -- Remove the parts of the GPUBody results that correspond to dead
      -- return value bindings.  Note that this leaves dead code in the
      -- kernel, but that will be removed later.
      let pick :: [a] -> [a]
          pick :: [a] -> [a]
pick = ((Bool, a) -> a) -> [(Bool, a)] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map (Bool, a) -> a
forall a b. (a, b) -> b
snd ([(Bool, a)] -> [a]) -> ([a] -> [(Bool, a)]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Bool, a) -> Bool) -> [(Bool, a)] -> [(Bool, a)]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool, a) -> Bool
forall a b. (a, b) -> a
fst ([(Bool, a)] -> [(Bool, a)])
-> ([a] -> [(Bool, a)]) -> [a] -> [(Bool, a)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Bool] -> [a] -> [(Bool, a)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Bool]
pat_used
          pat' :: [PatElem (VarWisdom, Type)]
pat' = [PatElem (VarWisdom, Type)] -> [PatElem (VarWisdom, Type)]
forall a. [a] -> [a]
pick (Pat (VarWisdom, Type) -> [PatElem (VarWisdom, Type)]
forall dec. Pat dec -> [PatElem dec]
patElems Pat (VarWisdom, Type)
Pat (LetDec (Wise GPU))
pat)
          types' :: [Type]
types' = [Type] -> [Type]
forall a. [a] -> [a]
pick [Type]
types
          body' :: Body (Wise GPU)
body' = Body (Wise GPU)
body {bodyResult :: Result
bodyResult = Result -> Result
forall a. [a] -> [a]
pick (Body (Wise GPU) -> Result
forall rep. Body rep -> Result
bodyResult Body (Wise GPU)
body)}
       in RuleM (Wise GPU) () -> Rule (Wise GPU)
forall rep. RuleM rep () -> Rule rep
Simplify (RuleM (Wise GPU) () -> Rule (Wise GPU))
-> RuleM (Wise GPU) () -> Rule (Wise GPU)
forall a b. (a -> b) -> a -> b
$ StmAux (ExpWisdom, ())
-> RuleM (Wise GPU) () -> RuleM (Wise GPU) ()
forall (m :: * -> *) anyrep a.
MonadBuilder m =>
StmAux anyrep -> m a -> m a
auxing StmAux (ExpWisdom, ())
StmAux (ExpDec (Wise GPU))
aux (RuleM (Wise GPU) () -> RuleM (Wise GPU) ())
-> RuleM (Wise GPU) () -> RuleM (Wise GPU) ()
forall a b. (a -> b) -> a -> b
$ Pat (LetDec (Rep (RuleM (Wise GPU))))
-> Exp (Rep (RuleM (Wise GPU))) -> RuleM (Wise GPU) ()
forall (m :: * -> *).
MonadBuilder m =>
Pat (LetDec (Rep m)) -> Exp (Rep m) -> m ()
letBind ([PatElem (VarWisdom, Type)] -> Pat (VarWisdom, Type)
forall dec. [PatElem dec] -> Pat dec
Pat [PatElem (VarWisdom, Type)]
pat') (Exp (Rep (RuleM (Wise GPU))) -> RuleM (Wise GPU) ())
-> Exp (Rep (RuleM (Wise GPU))) -> RuleM (Wise GPU) ()
forall a b. (a -> b) -> a -> b
$ Op (Wise GPU) -> Exp (Wise GPU)
forall rep. Op rep -> Exp rep
Op (Op (Wise GPU) -> Exp (Wise GPU))
-> Op (Wise GPU) -> Exp (Wise GPU)
forall a b. (a -> b) -> a -> b
$ [Type] -> Body (Wise GPU) -> HostOp (Wise GPU) (SOAC (Wise GPU))
forall rep op. [Type] -> Body rep -> HostOp rep op
GPUBody [Type]
types' Body (Wise GPU)
body'
  | Bool
otherwise = Rule (Wise GPU)
forall rep. Rule rep
Skip
removeDeadGPUBodyResult BottomUp (Wise GPU)
_ Pat (LetDec (Wise GPU))
_ StmAux (ExpDec (Wise GPU))
_ Op (Wise GPU)
_ = Rule (Wise GPU)
forall rep. Rule rep
Skip