1010-}
1111
1212{-# LANGUAGE CPP #-}
13+ {-# LANGUAGE FlexibleContexts #-}
1314{-# LANGUAGE OverloadedStrings #-}
1415{-# LANGUAGE QuasiQuotes #-}
1516{-# LANGUAGE TemplateHaskell #-}
1617
1718module Clash.Normalize where
1819
20+ import qualified Control.Concurrent.Async.Lifted as Async
21+ import Control.Concurrent.MVar.Lifted (MVar )
1922import qualified Control.Concurrent.MVar.Lifted as MVar
2023import Control.Concurrent.Supply (Supply )
2124import Control.Exception (throw )
2225import qualified Control.Lens as Lens
2326import Control.Monad (when )
27+ import qualified Control.Monad.IO.Class as Monad (liftIO )
2428import Control.Monad.State.Strict (State )
2529import Data.Default (def )
2630import Data.Either (lefts ,partitionEithers )
@@ -64,7 +68,7 @@ import Clash.Core.Var (Id, varName, varType)
6468import Clash.Core.VarEnv
6569 (VarEnv , elemVarSet , eltsVarEnv , emptyInScopeSet , emptyVarEnv ,
6670 extendVarEnv , lookupVarEnv , mapVarEnv , mapMaybeVarEnv ,
67- mkVarEnv , mkVarSet , notElemVarEnv , notElemVarSet , nullVarEnv , unionVarEnv )
71+ mkVarEnv , mkVarSet , notElemVarEnv , notElemVarSet , nullVarEnv )
6872import Clash.Debug (traceIf )
6973import Clash.Driver.Types
7074 (BindingMap , Binding (.. ), DebugOpts (.. ), ClashEnv (.. ))
@@ -79,7 +83,7 @@ import Clash.Normalize.Util
7983import Clash.Rewrite.Combinators ((>->) ,(!->) ,repeatR ,topdownR )
8084import Clash.Rewrite.Types
8185 (RewriteEnv (.. ), RewriteState (.. ), bindings , debugOpts , extra ,
82- tcCache , topEntities , newInlineStrategy )
86+ tcCache , topEntities , newInlineStrategy , ioLock )
8387import Clash.Rewrite.Util
8488 (apply , isUntranslatableType , runRewriteSession )
8589import Clash.Util
@@ -89,10 +93,8 @@ import Data.Binary (encode)
8993import qualified Data.ByteString as BS
9094import qualified Data.ByteString.Lazy as BL
9195
92- import System.IO.Unsafe (unsafePerformIO )
9396import Clash.Rewrite.Types (RewriteStep (.. ))
9497
95-
9698-- | Run a NormalizeSession in a given environment
9799runNormalization
98100 :: ClashEnv
@@ -109,12 +111,14 @@ runNormalization
109111 -- ^ Hardcoded evaluator for WHNF (old evaluator)
110112 -> VarEnv Bool
111113 -- ^ Map telling whether a components is part of a recursive group
114+ -> MVar ()
115+ -- ^ Synchronization on stdout
112116 -> [Id ]
113117 -- ^ topEntities
114118 -> NormalizeSession a
115119 -- ^ NormalizeSession to run
116120 -> IO a
117- runNormalization env supply globals typeTrans peEval eval rcsMap entities session = do
121+ runNormalization env supply globals typeTrans peEval eval rcsMap lock entities session = do
118122 normState <- NormalizeState
119123 <$> MVar. newMVar emptyVarEnv
120124 <*> MVar. newMVar Map. empty
@@ -131,6 +135,7 @@ runNormalization env supply globals typeTrans peEval eval rcsMap entities sessio
131135 <*> MVar. newMVar 0
132136 <*> MVar. newMVar (mempty , 0 )
133137 <*> MVar. newMVar emptyVarEnv
138+ <*> pure lock
134139 <*> pure normState
135140
136141 runRewriteSession rwEnv rwState session
@@ -143,20 +148,17 @@ runNormalization env supply globals typeTrans peEval eval rcsMap entities sessio
143148 , _topEntities = mkVarSet entities
144149 }
145150
146- normalize
147- :: [Id ]
148- -> NormalizeSession BindingMap
149- normalize [] = return emptyVarEnv
150- normalize top = do
151- (new,topNormalized) <- unzip <$> mapM normalize' top
152- newNormalized <- normalize (concat new)
153- return (unionVarEnv (mkVarEnv topNormalized) newNormalized)
151+ normalize :: [Id ] -> NormalizeSession BindingMap
152+ normalize tops = do
153+ normBinds <- Async. mapConcurrently normalize' tops
154+ pure (mkVarEnv (concat normBinds))
154155
155- normalize' :: Id -> NormalizeSession ([ Id ], (Id , Binding Term ))
156+ normalize' :: Id -> NormalizeSession [ (Id , Binding Term )]
156157normalize' nm = do
157158 bndrsV <- Lens. use bindings
158159 exprM <- MVar. withMVar bndrsV (pure . lookupVarEnv nm)
159160 let nmS = showPpr (varName nm)
161+ -- traceM ("normalize: start " <> nmS)
160162 case exprM of
161163 Just (Binding nm' sp inl pr tm r) -> do
162164 tcm <- Lens. view tcCache
@@ -196,11 +198,17 @@ normalize' nm = do
196198
197199 normV <- Lens. use (extra. normalized)
198200
199- MVar. withMVar normV $ \ norm ->
200- let prevNorm = mapVarEnv bindingId norm
201- toNormalize = filter (`notElemVarSet` topEnts)
202- $ filter (`notElemVarEnv` extendVarEnv nm nm prevNorm) usedBndrs
203- in return (toNormalize,(nm,tmNorm))
201+ toNormalize <-
202+ MVar. withMVar normV $ \ norm ->
203+ let prevNorm = mapVarEnv bindingId norm
204+ toNormalize = filter (`notElemVarSet` topEnts)
205+ $ filter (`notElemVarEnv` extendVarEnv nm nm prevNorm) usedBndrs
206+ in pure toNormalize
207+
208+ -- traceM ("normalize: end: " <> nmS)
209+
210+ normChildren <- Async. mapConcurrently normalize' toNormalize
211+ return ((nm, tmNorm) : concat normChildren)
204212 else
205213 do
206214 -- Throw an error for unrepresentable topEntities and functions
@@ -222,7 +230,7 @@ normalize' nm = do
222230 , showPpr (coreTypeOf nm')
223231 , " ) has a non-representable return type."
224232 , " Not normalising:\n " , showPpr tm] )
225- (return ( [] , (nm,(Binding nm' sp inl pr tm r))) )
233+ (return [ (nm,(Binding nm' sp inl pr tm r))] )
226234
227235
228236 Nothing -> error $ $ (curLoc) ++ " Expr belonging to bndr: " ++ nmS ++ " not found"
@@ -354,18 +362,22 @@ flattenCallTree (CBranch (nm,(Binding nm' sp inl pr tm r)) used) = do
354362 -- NB: When -fclash-debug-history is on, emit binary data holding the recorded rewrite steps
355363 opts <- Lens. view debugOpts
356364 let rewriteHistFile = dbg_historyFile opts
357- when (Maybe. isJust rewriteHistFile) $
358- let ! _ = unsafePerformIO
359- $ BS. appendFile (Maybe. fromJust rewriteHistFile)
360- $ BL. toStrict
361- $ encode RewriteStep
362- { t_ctx = []
363- , t_name = " INLINE"
364- , t_bndrS = showPpr (varName nm')
365- , t_before = tm
366- , t_after = tm1
367- }
368- in pure ()
365+
366+ when (Maybe. isJust rewriteHistFile) $ do
367+ lock <- Lens. use ioLock
368+
369+ MVar. withMVar lock $ \ () ->
370+ Monad. liftIO
371+ . BS. appendFile (Maybe. fromJust rewriteHistFile)
372+ . BL. toStrict
373+ $ encode RewriteStep
374+ { t_ctx = []
375+ , t_name = " INLINE"
376+ , t_bndrS = showPpr (varName nm')
377+ , t_before = tm
378+ , t_after = tm1
379+ }
380+
369381 rewriteExpr (" flattenExpr" ,flatten) (showPpr nm, tm1) (nm', sp)
370382 let allUsed = newUsed ++ concat il_used
371383 -- inline all components when the resulting expression after flattening
0 commit comments