module Data.Array.Repa.Plugin.Pass.Lower
(passLower)
where
import Data.Array.Repa.Plugin.Primitives
import Data.Array.Repa.Plugin.ToDDC.Detect
import Data.Array.Repa.Plugin.ToDDC
import Data.Array.Repa.Plugin.ToGHC
import Data.Array.Repa.Plugin.GHC.Pretty
import DDC.Core.Exp
import qualified DDC.Core.Flow as Flow
import qualified DDC.Core.Flow.Profile as Flow
import qualified DDC.Core.Flow.Transform.Prep as Flow
import qualified DDC.Core.Flow.Transform.Slurp as Flow
import qualified DDC.Core.Flow.Transform.Schedule as Flow
import qualified DDC.Core.Flow.Transform.Extract as Flow
import qualified DDC.Core.Flow.Transform.Concretize as Flow
import qualified DDC.Core.Flow.Transform.Thread as Flow
import qualified DDC.Core.Flow.Transform.Wind as Flow
import qualified DDC.Core.Module as Core
import qualified DDC.Core.Check as Core
import qualified DDC.Core.Simplifier as Core
import qualified DDC.Core.Fragment as Core
import qualified DDC.Core.Transform.Namify as Core
import qualified DDC.Core.Transform.Flatten as Core
import qualified DDC.Core.Transform.Forward as Forward
import qualified DDC.Core.Transform.Thread as Core
import qualified DDC.Core.Transform.Reannotate as Core
import qualified DDC.Core.Transform.Snip as Snip
import qualified DDC.Core.Transform.Eta as Eta
import qualified HscTypes as G
import qualified CoreMonad as G
import qualified UniqSupply as G
import qualified DDC.Base.Pretty as D
import qualified Data.Map as Map
import System.IO.Unsafe
import Control.Monad.State.Strict
import Data.List
letsHopeThisIsUnique :: Char
letsHopeThisIsUnique = 's'
passLower :: [G.CommandLineOption] -> String -> G.ModGuts -> G.CoreM G.ModGuts
passLower options name guts0
= unsafePerformIO
$ do
us <- G.mkSplitUniqSupply letsHopeThisIsUnique
let shouldDump = elem "dump" options
let dump thing str = when shouldDump
$ writeFile ("dump." ++ name ++ "." ++ thing) str
dump "01-ghc.hs"
$ D.renderIndent (pprModGuts guts0)
let (Just (primitives, guts), us2)
= G.initUs us (slurpPrimitives guts0)
let (mm_dc, failsConvert) = convertModGuts guts
dump "02-raw.dcf"
$ D.renderIndent (D.ppr mm_dc)
dump "02-raw.fails"
$ D.renderIndent (D.vcat $ intersperse D.empty $ map D.ppr failsConvert)
let (mm_detect, names) = detectModule mm_dc
dump "03-detect.dcf"
$ D.renderIndent (D.ppr mm_detect)
dump "03-detect.names"
$ D.renderIndent (D.vcat $ map D.ppr $ Map.toList names)
let etaConfig = Eta.configZero { Eta.configExpand = True }
let mm_eta = Core.result $ Eta.etaModule etaConfig Flow.profile mm_detect
dump "04-norm.1-eta.dcf"
$ D.renderIndent (D.ppr mm_eta)
let mkNamT = Core.makeNamifier Flow.freshT
let mkNamX = Core.makeNamifier Flow.freshX
let snipConfig = Snip.configZero { Snip.configSnipLetBody = True }
let mm_snip' = Core.flatten $ Snip.snip snipConfig mm_eta
let mm_snip = evalState (Core.namifyUnique mkNamT mkNamX mm_snip') 0
dump "04-norm.dcf"
$ D.renderIndent (D.ppr mm_snip)
let (_, workerNameArgs)
= Flow.prepModule mm_snip
let isFloatable lts
= case lts of
LLet (BName n _) _
| Just{} <- Map.lookup n workerNameArgs
-> Forward.FloatForce
_ -> Forward.FloatAllow
let config = Forward.Config isFloatable False
let result_forward = Forward.forwardModule Flow.profile config mm_snip
let mm_forward = Core.result result_forward
dump "05-prep.1-forward.dcf"
$ D.renderIndent (D.ppr mm_forward)
let mm_namify = evalState (Core.namifyUnique mkNamT mkNamX mm_forward) 0
dump "05-prep.2-namify.dcf"
$ D.renderIndent (D.ppr mm_namify)
let mm_prep = checkFlowModule_ mm_namify
dump "05-prep.3-check.dcf"
$ D.renderIndent (D.ppr mm_prep)
let processes = Flow.slurpProcesses mm_prep
let procs = map Flow.scheduleProcess processes
let mm_lowered' = Flow.extractModule mm_prep procs
let mm_lowered = evalState (Core.namifyUnique mkNamT mkNamX mm_lowered') 0
dump "06-lowered.1-processes.txt"
$ D.renderIndent (D.vcat $ intersperse D.empty $ map D.ppr $ processes)
dump "06-lowered.dcf"
$ D.renderIndent (D.ppr mm_lowered)
let mm_concrete = Flow.concretizeModule mm_lowered
dump "07-concrete.dcf"
$ D.renderIndent (D.ppr mm_concrete)
let mm_wind = Core.result $ Forward.forwardModule Flow.profile
(Forward.Config (const Forward.FloatAllow) True)
$ Core.result $ Forward.forwardModule Flow.profile
(Forward.Config (const Forward.FloatAllow) True)
$ Core.result $ Forward.forwardModule Flow.profile
(Forward.Config (const Forward.FloatAllow) True)
$ Core.result $ Forward.forwardModule Flow.profile
(Forward.Config (const Forward.FloatAllow) True)
$ Flow.windModule mm_concrete
dump "08-wind.dcf"
$ D.renderIndent (D.ppr mm_wind)
let mm_checked = checkFlowModule mm_wind
dump "09-checked.dcf"
$ D.renderIndent (D.ppr mm_checked)
let mm_thread' = Core.thread Flow.threadConfig
(Core.profilePrimKinds Flow.profile)
(Core.profilePrimTypes Flow.profile)
mm_checked
let mm_thread = evalState (Core.namifyUnique mkNamT mkNamX mm_thread') 0
dump "10-threaded.dcf"
$ D.renderIndent (D.ppr mm_thread)
let guts' = G.initUs_ us2
$ spliceModGuts primitives names mm_thread guts
dump "11-spliced.fc"
$ D.renderIndent (pprModGuts guts')
return (return guts')
checkFlowModule_
:: Core.Module () Flow.Name
-> Core.Module () Flow.Name
checkFlowModule_ mm
= Core.reannotate Core.annotTail
$ checkFlowModule mm
checkFlowModule
:: Core.Module () Flow.Name
-> Core.Module (Core.AnTEC () Flow.Name) Flow.Name
checkFlowModule mm
= let result = Core.checkModule
(Core.configOfProfile Flow.profile)
mm
in case result of
Right mm' -> mm'
Left err
-> error $ D.renderIndent $ D.indent 8 $ D.vcat
[ D.empty
, D.text "repa-plugin:"
, D.indent 2
$ D.vcat [ D.text "Type error in generated code"
, D.ppr err ] ]