[make Fixer keep track of changed nodes so it doesn't have to scan them all. 20% speedup results
John Meacham <john@repetae.net>**20050916081728] hunk ./Fixer.hs 19
-import Monad
+import Data.Unique
hunk ./Fixer.hs 21
+import Monad
+import qualified Data.Set as Set
hunk ./Fixer.hs 33
-newtype Fixer  = Fixer { vars :: IORef [MkFixable] }
+
+data Fixer  = Fixer {
+    vars :: !(IORef [MkFixable]),
+    todo :: !(IORef (Set.Set MkFixable))
+    }
+
hunk ./Fixer.hs 43
-    return Fixer { vars = v }
+    t <- newIORef Set.empty
+    return Fixer { vars = v, todo = t }
hunk ./Fixer.hs 50
-    action :: IORef [a -> IO ()],
-    pending :: IORef a,
-    current :: IORef a
+    ident :: {-# UNPACK #-} !Unique,
+    action :: !(IORef [a -> IO ()]),
+    pending :: !(IORef a),
+    current :: !(IORef a),
+    fixer :: Fixer
hunk ./Fixer.hs 57
+instance Eq MkFixable where
+    MkFixable a == MkFixable b = ident a == ident b
+    MkFixable a /= MkFixable b = ident a /= ident b
+instance Ord MkFixable where
+    MkFixable a `compare` MkFixable b = ident a `compare` ident b
+    MkFixable a >= MkFixable b = ident a >= ident b
+    MkFixable a <= MkFixable b = ident a <= ident b
+    MkFixable a > MkFixable b = ident a > ident b
+    MkFixable a < MkFixable b = ident a < ident b
hunk ./Fixer.hs 71
-newValue Fixer { vars = vars } v = do
+newValue fixer@Fixer { vars = vars } v = do
+    ident <- newUnique
hunk ./Fixer.hs 77
-        rv =  RvValue { current = current, pending = pending, action = action }
+        rv =  RvValue { ident = ident, fixer = fixer, current = current, pending = pending, action = action }
hunk ./Fixer.hs 113
+    if isBottom p then return () else do
+    (modifyIORef (todo $ fixer v) (Set.insert $ MkFixable v))
hunk ./Fixer.hs 132
-findFixpoint Fixer { vars = vars } = do
+findFixpoint Fixer { vars = vars, todo = todo } = do
+    to <- readIORef todo
hunk ./Fixer.hs 136
-    let f [] n | n > 0 = putStr "(" >> putStr (show n) >> putStr ")" >> hFlush stdout >> f vars 0
+    let f [] n | n > 0 = do
+            vs <- readIORef todo
+            writeIORef todo Set.empty
+            putStr "(" >> putStr (show n) >> putStr ")" >> hFlush stdout
+            f (Set.toList vs) 0
hunk ./Fixer.hs 155
-    f vars (0::Int)
+    f (Set.toList to) (0::Int)