{-# LANGUAGE FlexibleContexts #-}
-- | Optimisation pipelines.
module Futhark.Passes
  ( standardPipeline
  , sequentialPipeline
  , kernelsPipeline
  , sequentialCpuPipeline
  , gpuPipeline
  )
where

import Control.Category ((>>>))

import Futhark.Optimise.CSE
import Futhark.Optimise.Fusion
import Futhark.Optimise.InPlaceLowering
import Futhark.Optimise.InliningDeadFun
import Futhark.Optimise.Sink
import Futhark.Optimise.TileLoops
import Futhark.Optimise.DoubleBuffer
import Futhark.Optimise.Unstream
import Futhark.Pass.ExpandAllocations
import Futhark.Pass.ExplicitAllocations
import Futhark.Pass.ExtractKernels
import Futhark.Pass.FirstOrderTransform
import Futhark.Pass.KernelBabysitting
import Futhark.Pass.ResolveAssertions
import Futhark.Pass.Simplify
import Futhark.Pipeline
import Futhark.Representation.ExplicitMemory (ExplicitMemory)
import Futhark.Representation.Kernels (Kernels)
import Futhark.Representation.SOACS (SOACS)

standardPipeline :: Pipeline SOACS SOACS
standardPipeline :: Pipeline SOACS SOACS
standardPipeline =
  [Pass SOACS SOACS] -> Pipeline SOACS SOACS
forall lore.
Checkable lore =>
[Pass lore lore] -> Pipeline lore lore
passes [ Pass SOACS SOACS
simplifySOACS
         , Pass SOACS SOACS
inlineFunctions
         , Pass SOACS SOACS
simplifySOACS
         , Bool -> Pass SOACS SOACS
forall lore.
(Attributes lore, CanBeAliased (Op lore),
 CSEInOp (OpWithAliases (Op lore))) =>
Bool -> Pass lore lore
performCSE Bool
True
         , Pass SOACS SOACS
simplifySOACS
           -- We run fusion twice
         , Pass SOACS SOACS
fuseSOACs
         , Bool -> Pass SOACS SOACS
forall lore.
(Attributes lore, CanBeAliased (Op lore),
 CSEInOp (OpWithAliases (Op lore))) =>
Bool -> Pass lore lore
performCSE Bool
True
         , Pass SOACS SOACS
simplifySOACS
         , Pass SOACS SOACS
fuseSOACs
         , Bool -> Pass SOACS SOACS
forall lore.
(Attributes lore, CanBeAliased (Op lore),
 CSEInOp (OpWithAliases (Op lore))) =>
Bool -> Pass lore lore
performCSE Bool
True
         , Pass SOACS SOACS
simplifySOACS
         , Pass SOACS SOACS
resolveAssertions
         , Pass SOACS SOACS
removeDeadFunctions
         ]

kernelsPipeline :: Pipeline SOACS Kernels
kernelsPipeline :: Pipeline SOACS Kernels
kernelsPipeline =
  Pipeline SOACS SOACS
standardPipeline Pipeline SOACS SOACS
-> Pipeline SOACS Kernels -> Pipeline SOACS Kernels
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>>
  Pass SOACS Kernels -> Pipeline SOACS Kernels
forall tolore fromlore.
Checkable tolore =>
Pass fromlore tolore -> Pipeline fromlore tolore
onePass Pass SOACS Kernels
extractKernels Pipeline SOACS Kernels
-> Pipeline Kernels Kernels -> Pipeline SOACS Kernels
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>>
  [Pass Kernels Kernels] -> Pipeline Kernels Kernels
forall lore.
Checkable lore =>
[Pass lore lore] -> Pipeline lore lore
passes [ Pass Kernels Kernels
simplifyKernels
         , Pass Kernels Kernels
babysitKernels
         , Pass Kernels Kernels
tileLoops
         , Pass Kernels Kernels
unstream
         , Bool -> Pass Kernels Kernels
forall lore.
(Attributes lore, CanBeAliased (Op lore),
 CSEInOp (OpWithAliases (Op lore))) =>
Bool -> Pass lore lore
performCSE Bool
True
         , Pass Kernels Kernels
simplifyKernels
         , Pass Kernels Kernels
sink
         , Pass Kernels Kernels
inPlaceLowering
         ]

sequentialPipeline :: Pipeline SOACS Kernels
sequentialPipeline :: Pipeline SOACS Kernels
sequentialPipeline =
  Pipeline SOACS SOACS
standardPipeline Pipeline SOACS SOACS
-> Pipeline SOACS Kernels -> Pipeline SOACS Kernels
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>>
  Pass SOACS Kernels -> Pipeline SOACS Kernels
forall tolore fromlore.
Checkable tolore =>
Pass fromlore tolore -> Pipeline fromlore tolore
onePass Pass SOACS Kernels
firstOrderTransform Pipeline SOACS Kernels
-> Pipeline Kernels Kernels -> Pipeline SOACS Kernels
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>>
  [Pass Kernels Kernels] -> Pipeline Kernels Kernels
forall lore.
Checkable lore =>
[Pass lore lore] -> Pipeline lore lore
passes [ Pass Kernels Kernels
simplifyKernels
         , Pass Kernels Kernels
sink
         , Pass Kernels Kernels
inPlaceLowering
         ]

sequentialCpuPipeline :: Pipeline SOACS ExplicitMemory
sequentialCpuPipeline :: Pipeline SOACS ExplicitMemory
sequentialCpuPipeline =
  Pipeline SOACS Kernels
sequentialPipeline Pipeline SOACS Kernels
-> Pipeline Kernels ExplicitMemory -> Pipeline SOACS ExplicitMemory
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>>
  Pass Kernels ExplicitMemory -> Pipeline Kernels ExplicitMemory
forall tolore fromlore.
Checkable tolore =>
Pass fromlore tolore -> Pipeline fromlore tolore
onePass Pass Kernels ExplicitMemory
explicitAllocations Pipeline Kernels ExplicitMemory
-> Pipeline ExplicitMemory ExplicitMemory
-> Pipeline Kernels ExplicitMemory
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>>
  [Pass ExplicitMemory ExplicitMemory]
-> Pipeline ExplicitMemory ExplicitMemory
forall lore.
Checkable lore =>
[Pass lore lore] -> Pipeline lore lore
passes [ Bool -> Pass ExplicitMemory ExplicitMemory
forall lore.
(Attributes lore, CanBeAliased (Op lore),
 CSEInOp (OpWithAliases (Op lore))) =>
Bool -> Pass lore lore
performCSE Bool
False
         , Pass ExplicitMemory ExplicitMemory
simplifyExplicitMemory
         , Pass ExplicitMemory ExplicitMemory
doubleBuffer
         , Pass ExplicitMemory ExplicitMemory
simplifyExplicitMemory
         ]

gpuPipeline :: Pipeline SOACS ExplicitMemory
gpuPipeline :: Pipeline SOACS ExplicitMemory
gpuPipeline =
  Pipeline SOACS Kernels
kernelsPipeline Pipeline SOACS Kernels
-> Pipeline Kernels ExplicitMemory -> Pipeline SOACS ExplicitMemory
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>>
  Pass Kernels ExplicitMemory -> Pipeline Kernels ExplicitMemory
forall tolore fromlore.
Checkable tolore =>
Pass fromlore tolore -> Pipeline fromlore tolore
onePass Pass Kernels ExplicitMemory
explicitAllocations Pipeline Kernels ExplicitMemory
-> Pipeline ExplicitMemory ExplicitMemory
-> Pipeline Kernels ExplicitMemory
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>>
  [Pass ExplicitMemory ExplicitMemory]
-> Pipeline ExplicitMemory ExplicitMemory
forall lore.
Checkable lore =>
[Pass lore lore] -> Pipeline lore lore
passes [ Pass ExplicitMemory ExplicitMemory
simplifyExplicitMemory
         , Bool -> Pass ExplicitMemory ExplicitMemory
forall lore.
(Attributes lore, CanBeAliased (Op lore),
 CSEInOp (OpWithAliases (Op lore))) =>
Bool -> Pass lore lore
performCSE Bool
False
         , Pass ExplicitMemory ExplicitMemory
simplifyExplicitMemory
         , Pass ExplicitMemory ExplicitMemory
doubleBuffer
         , Pass ExplicitMemory ExplicitMemory
simplifyExplicitMemory
         , Pass ExplicitMemory ExplicitMemory
expandAllocations
         , Pass ExplicitMemory ExplicitMemory
simplifyExplicitMemory
         ]