X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2Futils%2FDigraph.lhs;h=0eff6da6980e6d87e24d3fb45c506325e61c1ed0;hb=59c796f8e77325d35f29ddd3e724bfa780466d40;hp=a9cf31dd428b095749c2c387923af0c5cd08cf74;hpb=c0a09c8f931ae6b5204bf0595adb4224ed565bc7;p=ghc-hetmet.git diff --git a/ghc/compiler/utils/Digraph.lhs b/ghc/compiler/utils/Digraph.lhs index a9cf31d..0eff6da 100644 --- a/ghc/compiler/utils/Digraph.lhs +++ b/ghc/compiler/utils/Digraph.lhs @@ -1,17 +1,13 @@ \begin{code} -#if defined(COMPILING_GHC) -# include "HsVersions.h" -#endif - module Digraph( -- At present the only one with a "nice" external interface - stronglyConnComp, stronglyConnCompR, SCC(..), + stronglyConnComp, stronglyConnCompR, SCC(..), flattenSCC, flattenSCCs, - SYN_IE(Graph), SYN_IE(Vertex), + Graph, Vertex, graphFromEdges, buildG, transposeG, reverseE, outdegree, indegree, - Tree(..), SYN_IE(Forest), + Tree(..), Forest, showTree, showForest, dfs, dff, @@ -24,6 +20,8 @@ module Digraph( ) where +# include "HsVersions.h" + ------------------------------------------------------------------------------ -- A version of the graph algorithms described in: -- @@ -33,31 +31,23 @@ module Digraph( -- Also included is some additional code for printing tree structures ... ------------------------------------------------------------------------------ -#ifdef REALLY_HASKELL_1_3 -#define ARR_ELT (COMMA) +import Util ( sortLe ) + +-- Extensions +import MONAD_ST +-- std interfaces +import Maybe import Array import List -import ST -import ArrBase -import Maybe +import Outputable +#if __GLASGOW_HASKELL__ >= 504 +import Data.Array.ST hiding ( indices, bounds ) #else - -#define ARR_ELT (:=) -#define runST _runST -#define MutableArray _MutableArray -#define Show Text - -import PreludeGlaST -import Maybes ( mapMaybe ) - +import ST #endif - -import Util ( Ord3(..), - sortLt - ) \end{code} @@ -71,12 +61,25 @@ import Util ( Ord3(..), data SCC vertex = AcyclicSCC vertex | CyclicSCC [vertex] +flattenSCCs :: [SCC a] -> [a] +flattenSCCs = concatMap flattenSCC + +flattenSCC (AcyclicSCC v) = [v] +flattenSCC (CyclicSCC vs) = vs + +instance Outputable a => Outputable (SCC a) where + ppr (AcyclicSCC v) = text "NONREC" $$ (nest 3 (ppr v)) + ppr (CyclicSCC vs) = text "REC" $$ (nest 3 (vcat (map ppr vs))) +\end{code} + +\begin{code} stronglyConnComp - :: Ord3 key + :: Ord key => [(node, key, [key])] -- The graph; its ok for the -- out-list to contain keys which arent -- a vertex key, they are ignored - -> [SCC node] + -> [SCC node] -- Returned in topologically sorted order + -- Later components depend on earlier ones, but not vice versa stronglyConnComp edges = map get_node (stronglyConnCompR edges) @@ -87,18 +90,18 @@ stronglyConnComp edges -- The "R" interface is used when you expect to apply SCC to -- the (some of) the result of SCC, so you dont want to lose the dependency info stronglyConnCompR - :: Ord3 key + :: Ord key => [(node, key, [key])] -- The graph; its ok for the -- out-list to contain keys which arent -- a vertex key, they are ignored - -> [SCC (node, key, [key])] + -> [SCC (node, key, [key])] -- Topologically sorted stronglyConnCompR [] = [] -- added to avoid creating empty array in graphFromEdges -- SOF stronglyConnCompR edges = map decode forest where - (graph, vertex_fn) = graphFromEdges edges - forest = scc graph + (graph, vertex_fn) = _scc_ "graphFromEdges" graphFromEdges edges + forest = _scc_ "Digraph.scc" scc graph decode (Node v []) | mentions_itself v = CyclicSCC [vertex_fn v] | otherwise = AcyclicSCC (vertex_fn v) decode other = CyclicSCC (dec other []) @@ -130,14 +133,10 @@ edges :: Graph -> [Edge] edges g = [ (v, w) | v <- vertices g, w <- g!v ] mapT :: (Vertex -> a -> b) -> Table a -> Table b -mapT f t = array (bounds t) [ ARR_ELT v (f v (t!v)) | v <- indices t ] +mapT f t = array (bounds t) [ (,) v (f v (t!v)) | v <- indices t ] buildG :: Bounds -> [Edge] -> Graph -#ifdef REALLY_HASKELL_1_3 buildG bounds edges = accumArray (flip (:)) [] bounds edges -#else -buildG bounds edges = accumArray (flip (:)) [] bounds [ARR_ELT k v | (k,v) <- edges] -#endif transposeG :: Graph -> Graph transposeG g = buildG (bounds g) (reverseE g) @@ -156,7 +155,7 @@ indegree = outdegree . transposeG \begin{code} graphFromEdges - :: Ord3 key + :: Ord key => [(node, key, [key])] -> (Graph, Vertex -> (node, key, [key])) graphFromEdges edges @@ -164,14 +163,16 @@ graphFromEdges edges where max_v = length edges - 1 bounds = (0,max_v) :: (Vertex, Vertex) - sorted_edges = sortLt lt edges - edges1 = zipWith ARR_ELT [0..] sorted_edges - - graph = array bounds [ARR_ELT v (mapMaybe key_vertex ks) | ARR_ELT v (_, _, ks) <- edges1] - key_map = array bounds [ARR_ELT v k | ARR_ELT v (_, k, _ ) <- edges1] + sorted_edges = let + (_,k1,_) `le` (_,k2,_) = case k1 `compare` k2 of { GT -> False; other -> True } + in + sortLe le edges + edges1 = zipWith (,) [0..] sorted_edges + + graph = array bounds [(,) v (mapMaybe key_vertex ks) | (,) v (_, _, ks) <- edges1] + key_map = array bounds [(,) v k | (,) v (_, k, _ ) <- edges1] vertex_map = array bounds edges1 - (_,k1,_) `lt` (_,k2,_) = case k1 `cmp` k2 of { LT_ -> True; other -> False } -- key_vertex :: key -> Maybe Vertex -- returns Nothing for non-interesting vertices @@ -179,10 +180,10 @@ graphFromEdges edges where find a b | a > b = Nothing - find a b = case cmp k (key_map ! mid) of - LT_ -> find a (mid-1) - EQ_ -> Just mid - GT_ -> find (mid+1) b + find a b = case compare k (key_map ! mid) of + LT -> find a (mid-1) + EQ -> Just mid + GT -> find (mid+1) b where mid = (a + b) `div` 2 \end{code} @@ -217,7 +218,7 @@ drawTree = unlines . draw draw (Node x ts) = grp this (space (length this)) (stLoop ts) where this = s1 ++ x ++ " " - space n = take n (repeat ' ') + space n = replicate n ' ' stLoop [] = [""] stLoop [t] = grp s2 " " (draw t) @@ -239,16 +240,27 @@ draw (Node x ts) = grp this (space (length this)) (stLoop ts) %************************************************************************ \begin{code} -type Set s = MutableArray s Vertex Bool +#if __GLASGOW_HASKELL__ >= 504 +newSTArray :: Ix i => (i,i) -> e -> ST s (STArray s i e) +newSTArray = newArray + +readSTArray :: Ix i => STArray s i e -> i -> ST s e +readSTArray = readArray + +writeSTArray :: Ix i => STArray s i e -> i -> e -> ST s () +writeSTArray = writeArray +#endif + +type Set s = STArray s Vertex Bool mkEmpty :: Bounds -> ST s (Set s) -mkEmpty bnds = newArray bnds False +mkEmpty bnds = newSTArray bnds False contains :: Set s -> Vertex -> ST s Bool -contains m v = readArray m v +contains m v = readSTArray m v include :: Set s -> Vertex -> ST s () -include m v = writeArray m v True +include m v = writeSTArray m v True \end{code} \begin{code} @@ -262,20 +274,20 @@ generate :: Graph -> Vertex -> Tree Vertex generate g v = Node v (map (generate g) (g!v)) prune :: Bounds -> Forest Vertex -> Forest Vertex -prune bnds ts = runST (mkEmpty bnds `thenST` \m -> +prune bnds ts = runST (mkEmpty bnds >>= \m -> chop m ts) chop :: Set s -> Forest Vertex -> ST s (Forest Vertex) -chop m [] = returnST [] +chop m [] = return [] chop m (Node v ts : us) - = contains m v `thenStrictlyST` \visited -> + = contains m v >>= \visited -> if visited then chop m us else - include m v `thenStrictlyST` \_ -> - chop m ts `thenStrictlyST` \as -> - chop m us `thenStrictlyST` \bs -> - returnST (Node v as : bs) + include m v >>= \_ -> + chop m ts >>= \as -> + chop m us >>= \bs -> + return (Node v as : bs) \end{code} @@ -296,11 +308,8 @@ preorder (Node a ts) = a : preorderF ts preorderF :: Forest a -> [a] preorderF ts = concat (map preorder ts) -preOrd :: Graph -> [Vertex] -preOrd = preorderF . dff - tabulate :: Bounds -> [Vertex] -> Table Int -tabulate bnds vs = array bnds (zipWith ARR_ELT vs [1..]) +tabulate bnds vs = array bnds (zipWith (,) vs [1..]) preArr :: Bounds -> Forest Vertex -> Table Int preArr bnds = tabulate bnds . preorderF @@ -352,12 +361,6 @@ scc g = dfs g (reverse (postOrd (transposeG g))) ------------------------------------------------------------ \begin{code} -tree :: Bounds -> Forest Vertex -> Graph -tree bnds ts = buildG bnds (concat (map flat ts)) - where - flat (Node v rs) = [ (v, w) | Node w us <- ts ] ++ - concat (map flat ts) - back :: Graph -> Table Int -> Graph back g post = mapT select g where select v ws = [ w | w <- ws, post!v < post!w ] @@ -391,13 +394,13 @@ path g v w = w `elem` (reachable g v) \begin{code} bcc :: Graph -> Forest [Vertex] -bcc g = (concat . map bicomps . map (label g dnum)) forest +bcc g = (concat . map bicomps . map (do_label g dnum)) forest where forest = dff g dnum = preArr (bounds g) forest -label :: Graph -> Table Int -> Tree Vertex -> Tree (Vertex,Int,Int) -label g dnum (Node v ts) = Node (v,dnum!v,lv) us - where us = map (label g dnum) ts +do_label :: Graph -> Table Int -> Tree Vertex -> Tree (Vertex,Int,Int) +do_label g dnum (Node v ts) = Node (v,dnum!v,lv) us + where us = map (do_label g dnum) ts lv = minimum ([dnum!v] ++ [dnum!w | w <- g!v] ++ [lu | Node (u,du,lu) xs <- us])