{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
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.TileLoops
import Futhark.Optimise.DoubleBuffer
import Futhark.Optimise.Unstream
import Futhark.Optimise.MemoryBlockMerging
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)
import Futhark.Util
standardPipeline :: Pipeline SOACS SOACS
standardPipeline =
passes [ simplifySOACS
, inlineAndRemoveDeadFunctions
, simplifySOACS
, performCSE True
, simplifySOACS
, fuseSOACs
, performCSE True
, simplifySOACS
, fuseSOACs
, performCSE True
, simplifySOACS
, resolveAssertions
, removeDeadFunctions
]
usesInPlaceLowering :: Bool
usesInPlaceLowering =
isEnvVarSet "IN_PLACE_LOWERING" True
inPlaceLoweringMaybe :: Pipeline Kernels Kernels
inPlaceLoweringMaybe =
if usesInPlaceLowering
then onePass inPlaceLowering
else passes []
usesMemoryBlockMergingCoalescing :: Bool
usesMemoryBlockMergingCoalescing =
isEnvVarSet "MEMORY_BLOCK_MERGING_COALESCING" False
memoryBlockMergingCoalescingMaybe :: Pipeline ExplicitMemory ExplicitMemory
memoryBlockMergingCoalescingMaybe =
passes $ if usesMemoryBlockMergingCoalescing
then [ memoryBlockMergingCoalescing
, simplifyExplicitMemory
]
else []
memoryBlockMergingCoalescingMaybeCPU :: Pipeline ExplicitMemory ExplicitMemory
memoryBlockMergingCoalescingMaybeCPU = memoryBlockMergingCoalescingMaybe
memoryBlockMergingCoalescingMaybeGPU :: Pipeline ExplicitMemory ExplicitMemory
memoryBlockMergingCoalescingMaybeGPU = memoryBlockMergingCoalescingMaybe
usesMemoryBlockMergingReuse :: Bool
usesMemoryBlockMergingReuse =
isEnvVarSet "MEMORY_BLOCK_MERGING_REUSE" False
memoryBlockMergingReuseMaybe :: Pipeline ExplicitMemory ExplicitMemory
memoryBlockMergingReuseMaybe =
passes $ if usesMemoryBlockMergingReuse
then [ memoryBlockMergingReuse
, simplifyExplicitMemory
]
else []
memoryBlockMergingReuseMaybeCPU :: Pipeline ExplicitMemory ExplicitMemory
memoryBlockMergingReuseMaybeCPU = memoryBlockMergingReuseMaybe
memoryBlockMergingReuseMaybeGPU :: Pipeline ExplicitMemory ExplicitMemory
memoryBlockMergingReuseMaybeGPU = memoryBlockMergingReuseMaybe
kernelsPipeline :: Pipeline SOACS Kernels
kernelsPipeline =
standardPipeline >>>
onePass extractKernels >>>
passes [ simplifyKernels
, babysitKernels
, simplifyKernels
, tileLoops
, unstream
, simplifyKernels
, performCSE True
, simplifyKernels
] >>>
inPlaceLoweringMaybe
sequentialPipeline :: Pipeline SOACS Kernels
sequentialPipeline =
standardPipeline >>>
onePass firstOrderTransform >>>
passes [ simplifyKernels
] >>>
inPlaceLoweringMaybe
sequentialCpuPipeline :: Pipeline SOACS ExplicitMemory
sequentialCpuPipeline =
sequentialPipeline >>>
onePass explicitAllocations >>>
passes [ simplifyExplicitMemory
, performCSE False
, simplifyExplicitMemory
, doubleBuffer
, simplifyExplicitMemory
] >>>
memoryBlockMergingCoalescingMaybeCPU >>>
memoryBlockMergingReuseMaybeCPU
gpuPipeline :: Pipeline SOACS ExplicitMemory
gpuPipeline =
kernelsPipeline >>>
onePass explicitAllocations >>>
passes [ simplifyExplicitMemory
, performCSE False
, simplifyExplicitMemory
, doubleBuffer
, simplifyExplicitMemory
, expandAllocations
, simplifyExplicitMemory
] >>>
memoryBlockMergingCoalescingMaybeGPU >>>
memoryBlockMergingReuseMaybeGPU