@@ -23,18 +23,21 @@ import qualified Control.Concurrent.MVar.Lifted as MVar
23
23
import Control.Concurrent.Supply (Supply )
24
24
import Control.Exception (throw )
25
25
import qualified Control.Lens as Lens
26
- import Control.Monad (when )
26
+ import Control.Monad (when , unless )
27
27
import qualified Control.Monad.IO.Class as Monad (liftIO )
28
28
import Control.Monad.State.Strict (State )
29
+ import Data.Bifunctor (bimap )
29
30
import Data.Default (def )
30
31
import Data.Either (lefts ,partitionEithers )
32
+ import Data.Foldable (traverse_ )
31
33
import qualified Data.HashMap.Strict as HashMap
32
34
import Data.List
33
35
(intersect , mapAccumL )
34
36
import qualified Data.Map as Map
35
37
import qualified Data.Maybe as Maybe
36
38
import qualified Data.Set as Set
37
39
import qualified Data.Set.Lens as Lens
40
+ import qualified Data.Concurrent.Queue.MichaelScott as MS
38
41
39
42
#if MIN_VERSION_prettyprinter(1,7,0)
40
43
import Prettyprinter (vcat )
@@ -66,8 +69,8 @@ import Clash.Core.TyCon (TyConMap)
66
69
import Clash.Core.Type (isPolyTy )
67
70
import Clash.Core.Var (Id , varName , varType )
68
71
import Clash.Core.VarEnv
69
- (VarEnv , elemVarSet , eltsVarEnv , emptyInScopeSet , emptyVarEnv ,
70
- extendVarEnv , lookupVarEnv , mapVarEnv , mapMaybeVarEnv ,
72
+ (VarEnv , VarSet , elemVarSet , eltsVarEnv , emptyInScopeSet , emptyVarEnv , emptyVarSet ,
73
+ extendVarEnv , extendVarSet , lookupVarEnv , mapVarEnv , mapMaybeVarEnv ,
71
74
mkVarEnv , mkVarSet , notElemVarEnv , notElemVarSet , nullVarEnv )
72
75
import Clash.Debug (traceIf )
73
76
import Clash.Driver.Types
@@ -150,11 +153,30 @@ runNormalization env supply globals typeTrans peEval eval rcsMap lock entities s
150
153
151
154
normalize :: [Id ] -> NormalizeSession BindingMap
152
155
normalize tops = do
153
- normBinds <- Async. mapConcurrently normalize' tops
154
- pure (mkVarEnv (concat normBinds))
155
-
156
- normalize' :: Id -> NormalizeSession [(Id , Binding Term )]
157
- normalize' nm = do
156
+ q <- Monad. liftIO MS. newQ
157
+ traverse_ (Monad. liftIO . MS. pushL q) tops
158
+ binds <- MVar. newMVar (emptyVarSet, [] )
159
+ -- one thread per top-level binding
160
+ Async. mapConcurrently_ (\ _ -> normalizeStep q binds) tops
161
+ mkVarEnv . snd <$> MVar. readMVar binds
162
+
163
+ normalizeStep
164
+ :: MS. LinkedQueue Id
165
+ -> MVar (VarSet , [(Id , Binding Term )])
166
+ -> NormalizeSession ()
167
+ normalizeStep q binds = do
168
+ res <- Monad. liftIO $ MS. tryPopR q
169
+ case res of
170
+ Just id' -> do
171
+ (bound, _) <- MVar. readMVar binds
172
+ unless (id' `elemVarSet` bound) $ do
173
+ pair <- normalize' id' q
174
+ MVar. modifyMVar_ binds (pure . bimap (`extendVarSet` id') (pair: ))
175
+ normalizeStep q binds
176
+ Nothing -> pure ()
177
+
178
+ normalize' :: Id -> MS. LinkedQueue Id -> NormalizeSession (Id , Binding Term )
179
+ normalize' nm q = do
158
180
bndrsV <- Lens. use bindings
159
181
exprM <- MVar. withMVar bndrsV (pure . lookupVarEnv nm)
160
182
let nmS = showPpr (varName nm)
@@ -207,8 +229,8 @@ normalize' nm = do
207
229
208
230
-- traceM ("normalize: end: " <> nmS)
209
231
210
- normChildren <- Async. mapConcurrently normalize' toNormalize
211
- return (( nm, tmNorm) : concat normChildren )
232
+ traverse_ ( Monad. liftIO . MS. pushL q) toNormalize
233
+ pure ( nm, tmNorm)
212
234
else
213
235
do
214
236
-- Throw an error for unrepresentable topEntities and functions
@@ -230,7 +252,7 @@ normalize' nm = do
230
252
, showPpr (coreTypeOf nm')
231
253
, " ) has a non-representable return type."
232
254
, " Not normalising:\n " , showPpr tm] )
233
- (return [ (nm,(Binding nm' sp inl pr tm r))] )
255
+ (return (nm,(Binding nm' sp inl pr tm r)))
234
256
235
257
236
258
Nothing -> error $ $ (curLoc) ++ " Expr belonging to bndr: " ++ nmS ++ " not found"
0 commit comments