10
10
-}
11
11
12
12
{-# LANGUAGE CPP #-}
13
+ {-# LANGUAGE FlexibleContexts #-}
13
14
{-# LANGUAGE OverloadedStrings #-}
14
15
{-# LANGUAGE QuasiQuotes #-}
15
16
{-# LANGUAGE TemplateHaskell #-}
16
17
17
18
module Clash.Normalize where
18
19
20
+ import qualified Control.Concurrent.Async.Lifted as Async
21
+ import Control.Concurrent.MVar.Lifted (MVar )
19
22
import qualified Control.Concurrent.MVar.Lifted as MVar
20
23
import Control.Concurrent.Supply (Supply )
21
24
import Control.Exception (throw )
22
25
import qualified Control.Lens as Lens
23
26
import Control.Monad (when )
27
+ import qualified Control.Monad.IO.Class as Monad (liftIO )
24
28
import Control.Monad.State.Strict (State )
25
29
import Data.Default (def )
26
30
import Data.Either (lefts ,partitionEithers )
@@ -79,7 +83,7 @@ import Clash.Normalize.Util
79
83
import Clash.Rewrite.Combinators ((>->) ,(!->) ,repeatR ,topdownR )
80
84
import Clash.Rewrite.Types
81
85
(RewriteEnv (.. ), RewriteState (.. ), bindings , debugOpts , extra ,
82
- tcCache , topEntities , newInlineStrategy )
86
+ tcCache , topEntities , newInlineStrategy , ioLock )
83
87
import Clash.Rewrite.Util
84
88
(apply , isUntranslatableType , runRewriteSession )
85
89
import Clash.Util
@@ -89,9 +93,9 @@ import Data.Binary (encode)
89
93
import qualified Data.ByteString as BS
90
94
import qualified Data.ByteString.Lazy as BL
91
95
92
- import System.IO.Unsafe (unsafePerformIO )
93
96
import Clash.Rewrite.Types (RewriteStep (.. ))
94
97
98
+ import Clash.Debug -- TODO
95
99
96
100
-- | Run a NormalizeSession in a given environment
97
101
runNormalization
@@ -109,12 +113,14 @@ runNormalization
109
113
-- ^ Hardcoded evaluator for WHNF (old evaluator)
110
114
-> VarEnv Bool
111
115
-- ^ Map telling whether a components is part of a recursive group
116
+ -> MVar ()
117
+ -- ^ Synchronization on stdout
112
118
-> [Id ]
113
119
-- ^ topEntities
114
120
-> NormalizeSession a
115
121
-- ^ NormalizeSession to run
116
122
-> IO a
117
- runNormalization env supply globals typeTrans peEval eval rcsMap entities session = do
123
+ runNormalization env supply globals typeTrans peEval eval rcsMap lock entities session = do
118
124
normState <- NormalizeState
119
125
<$> MVar. newMVar emptyVarEnv
120
126
<*> MVar. newMVar Map. empty
@@ -131,6 +137,7 @@ runNormalization env supply globals typeTrans peEval eval rcsMap entities sessio
131
137
<*> MVar. newMVar 0
132
138
<*> MVar. newMVar (mempty , 0 )
133
139
<*> MVar. newMVar emptyVarEnv
140
+ <*> pure lock
134
141
<*> pure normState
135
142
136
143
runRewriteSession rwEnv rwState session
@@ -143,20 +150,17 @@ runNormalization env supply globals typeTrans peEval eval rcsMap entities sessio
143
150
, _topEntities = mkVarSet entities
144
151
}
145
152
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)
153
+ normalize :: [Id ] -> NormalizeSession BindingMap
154
+ normalize tops = do
155
+ normBinds <- Async. mapConcurrently normalize' tops
156
+ pure (mkVarEnv (concat normBinds))
154
157
155
- normalize' :: Id -> NormalizeSession ([ Id ], (Id , Binding Term ))
158
+ normalize' :: Id -> NormalizeSession [ (Id , Binding Term )]
156
159
normalize' nm = do
157
160
bndrsV <- Lens. use bindings
158
161
exprM <- MVar. withMVar bndrsV (pure . lookupVarEnv nm)
159
162
let nmS = showPpr (varName nm)
163
+ -- traceM ("normalize: start " <> nmS)
160
164
case exprM of
161
165
Just (Binding nm' sp inl pr tm r) -> do
162
166
tcm <- Lens. view tcCache
@@ -196,11 +200,17 @@ normalize' nm = do
196
200
197
201
normV <- Lens. use (extra. normalized)
198
202
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))
203
+ toNormalize <-
204
+ MVar. withMVar normV $ \ norm ->
205
+ let prevNorm = mapVarEnv bindingId norm
206
+ toNormalize = filter (`notElemVarSet` topEnts)
207
+ $ filter (`notElemVarEnv` extendVarEnv nm nm prevNorm) usedBndrs
208
+ in pure toNormalize
209
+
210
+ -- traceM ("normalize: end: " <> nmS)
211
+
212
+ normChildren <- Async. mapConcurrently normalize' toNormalize
213
+ return ((nm, tmNorm) : concat normChildren)
204
214
else
205
215
do
206
216
-- Throw an error for unrepresentable topEntities and functions
@@ -222,7 +232,7 @@ normalize' nm = do
222
232
, showPpr (coreTypeOf nm')
223
233
, " ) has a non-representable return type."
224
234
, " Not normalising:\n " , showPpr tm] )
225
- (return ( [] , (nm,(Binding nm' sp inl pr tm r))) )
235
+ (return [ (nm,(Binding nm' sp inl pr tm r))] )
226
236
227
237
228
238
Nothing -> error $ $ (curLoc) ++ " Expr belonging to bndr: " ++ nmS ++ " not found"
@@ -354,18 +364,22 @@ flattenCallTree (CBranch (nm,(Binding nm' sp inl pr tm r)) used) = do
354
364
-- NB: When -fclash-debug-history is on, emit binary data holding the recorded rewrite steps
355
365
opts <- Lens. view debugOpts
356
366
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 ()
367
+
368
+ when (Maybe. isJust rewriteHistFile) $ do
369
+ lock <- Lens. use ioLock
370
+
371
+ MVar. withMVar lock $ \ () ->
372
+ Monad. liftIO
373
+ . BS. appendFile (Maybe. fromJust rewriteHistFile)
374
+ . BL. toStrict
375
+ $ encode RewriteStep
376
+ { t_ctx = []
377
+ , t_name = " INLINE"
378
+ , t_bndrS = showPpr (varName nm')
379
+ , t_before = tm
380
+ , t_after = tm1
381
+ }
382
+
369
383
rewriteExpr (" flattenExpr" ,flatten) (showPpr nm, tm1) (nm', sp)
370
384
let allUsed = newUsed ++ concat il_used
371
385
-- inline all components when the resulting expression after flattening
0 commit comments