[fix exponential behavior bug when traversing CompNode graph
John Meacham <john@repetae.net>**20090808063010
 Ignore-this: ebc8699c3a3d09694002854d5b6504f2
] hunk ./src/Ho/Build.hs 31
+import System.Mem
hunk ./src/Ho/Build.hs 258
---    | CompCollected CollectedHo CompUnit
-    | CompTCed HoTcInfo (Maybe (HoTcInfo,TiData,[(HoHash,HsModule)],[String])) CompUnit
+    | CompTCed ((HoTcInfo,TiData,[(HoHash,HsModule)],[String]))
hunk ./src/Ho/Build.hs 380
-parseFiles :: [Either Module String]                             -- ^ Either a module or filename to find
-               -> (CollectedHo -> Ho -> IO CollectedHo)              -- ^ Process initial ho loaded from file
+parseFiles :: [Either Module String]                                   -- ^ Either a module or filename to find
+               -> (CollectedHo -> Ho -> IO CollectedHo)                -- ^ Process initial ho loaded from file
hunk ./src/Ho/Build.hs 383
---               -> (CollectedHo -> [HsModule] -> IO (CollectedHo,Ho)) -- ^ Process set of mutually recursive modules to produce final Ho
-               -> IO CollectedHo                                     -- ^ Final accumulated ho
+               -> IO CollectedHo                                       -- ^ Final accumulated ho
hunk ./src/Ho/Build.hs 389
+    performGC
hunk ./src/Ho/Build.hs 392
+    performGC
hunk ./src/Ho/Build.hs 454
-countNodes (CompNode hh deps ref) = do
-    ds <- mapM countNodes deps
-    let g cn =  case cn of
+countNodes cn = do
+    seen <- newIORef Set.empty
+    let h (CompNode hh deps ref) = do
+            s <- readIORef seen
+            if hh `Set.member` s then return Set.empty else do
+                writeIORef seen (Set.insert hh s)
+                ds <- mapM countNodes deps
+                cm <- readIORef ref >>= g
+                return (Set.unions (cm:ds))
+        g cn =  case cn of
hunk ./src/Ho/Build.hs 469
-            CompTCed _ _ cn   -> f cn
---            CompCollected _ _ -> return Set.empty
+            CompTCed (_,_,_,ss)   -> return $ Set.fromList ss
hunk ./src/Ho/Build.hs 471
-                ds <- mconcat `fmap` mapM countNodes deps
-                return $ ds `Set.union` Set.fromList (map (show.fst) (hoDepends idep))
+                return $ Set.fromList (map (show.fst) (hoDepends idep))
hunk ./src/Ho/Build.hs 473
-                ds <- mconcat `fmap` mapM countNodes deps
-                return $ ds `Set.union` Set.fromList (map sourceIdent sc)
-    cm <- readIORef ref >>= g
-    return (Set.unions (cm:ds))
+                return $ Set.fromList (map sourceIdent sc)
+    h cn
hunk ./src/Ho/Build.hs 491
---                CompCollected ch _ -> error "compcollected in typechecknig phase"
-                CompTCed tcc _ _  -> return tcc
hunk ./src/Ho/Build.hs 509
-                    writeIORef ref (CompTcCollected ctc' (CompLinkUnit $ CompTCed ctc' (Just (htc,tidata,modules,map sourceHoName sc)) lu))
+                    writeIORef ref (CompTcCollected ctc' (CompLinkUnit $ CompTCed ((htc,tidata,modules,map sourceHoName sc))))
hunk ./src/Ho/Build.hs 513
-compileCompNode :: (CollectedHo -> Ho -> IO CollectedHo)              -- ^ Process initial ho loaded from file
+compileCompNode :: (CollectedHo -> Ho -> IO CollectedHo)                 -- ^ Process initial ho loaded from file
hunk ./src/Ho/Build.hs 541
-                CompTCed _ Nothing nn -> h nn
-                CompTCed _ (Just (htc,tidata,modules,shns)) _  -> do
+                CompTCed ((htc,tidata,modules,shns))  -> do