X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;ds=sidebyside;f=ghc%2Fcompiler%2Futils%2FDigraph.lhs;h=c49087c8f3ca7f4e47d8b7551187009eaa50981f;hb=45252b35151fc55aa19fb6770df5ed8267639083;hp=f09d465bc259cdb65a0d5d40e0365d4e821b8db4;hpb=6c393867f02f2f7482a0431d4abb8d998ef88dc5;p=ghc-hetmet.git diff --git a/ghc/compiler/utils/Digraph.lhs b/ghc/compiler/utils/Digraph.lhs index f09d465..c49087c 100644 --- a/ghc/compiler/utils/Digraph.lhs +++ b/ghc/compiler/utils/Digraph.lhs @@ -2,10 +2,11 @@ module Digraph( -- At present the only one with a "nice" external interface - stronglyConnComp, stronglyConnCompR, SCC(..), + stronglyConnComp, stronglyConnCompR, SCC(..), flattenSCC, flattenSCCs, Graph, Vertex, - graphFromEdges, buildG, transposeG, reverseE, outdegree, indegree, + graphFromEdges, graphFromEdges', + buildG, transposeG, reverseE, outdegree, indegree, Tree(..), Forest, showTree, showForest, @@ -32,17 +33,22 @@ module Digraph( ------------------------------------------------------------------------------ -#define ARR_ELT (COMMA) - -import Util ( sortLt ) +import Util ( sortLe ) -- Extensions -import ST +import MONAD_ST -- std interfaces import Maybe import Array import List +import Outputable + +#if __GLASGOW_HASKELL__ >= 504 +import Data.Array.ST hiding ( indices, bounds ) +#else +import ST +#endif \end{code} @@ -56,12 +62,25 @@ import List 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 :: 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) @@ -76,14 +95,14 @@ stronglyConnCompR => [(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 []) @@ -136,23 +155,32 @@ indegree = outdegree . transposeG \begin{code} -graphFromEdges +graphFromEdges :: Ord key => [(node, key, [key])] -> (Graph, Vertex -> (node, key, [key])) -graphFromEdges edges - = (graph, \v -> vertex_map ! v) +graphFromEdges edges = + case graphFromEdges' edges of (graph, vertex_fn, _) -> (graph, vertex_fn) + +graphFromEdges' + :: Ord key + => [(node, key, [key])] + -> (Graph, Vertex -> (node, key, [key]), key -> Maybe Vertex) +graphFromEdges' edges + = (graph, \v -> vertex_map ! v, key_vertex) where max_v = length edges - 1 bounds = (0,max_v) :: (Vertex, Vertex) - sorted_edges = sortLt lt edges + 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 `compare` k2 of { LT -> True; other -> False } -- key_vertex :: key -> Maybe Vertex -- returns Nothing for non-interesting vertices @@ -198,7 +226,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) @@ -220,6 +248,17 @@ draw (Node x ts) = grp this (space (length this)) (stLoop ts) %************************************************************************ \begin{code} +#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) @@ -277,9 +316,6 @@ 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 (,) vs [1..]) @@ -333,12 +369,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 ]