X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2Fcmm%2FDataflow.hs;h=6c54f73fc2689c55b8cb995d4ee19da52fb50f07;hp=0b84016a0f59e08e350e03a614859c6a66e814ea;hb=ad94d40948668032189ad22a0ad741ac1f645f50;hpb=77cc133da7af6961add020cab1ba9eadee3a0b67 diff --git a/compiler/cmm/Dataflow.hs b/compiler/cmm/Dataflow.hs index 0b84016..6c54f73 100644 --- a/compiler/cmm/Dataflow.hs +++ b/compiler/cmm/Dataflow.hs @@ -1,22 +1,16 @@ +{-# OPTIONS -w #-} +-- The above warning supression flag is a temporary kludge. +-- While working on this module you are encouraged to remove it and fix +-- any warnings in the module. See +-- http://hackage.haskell.org/trac/ghc/wiki/CodingStyle#Warnings +-- for details + module Dataflow ( fixedpoint ) where --------------------------------------------------------------------------------- - --- Solve a fixed-point of a dataflow problem. --- --- dependants: map from nodes to those who's value depend on the argument node --- update: --- Given the node which needs to be updated, and --- which node caused that node to need to be updated, --- update the state. --- (The causing node will be 'Nothing' if this is the initial update.) --- Must return 'Nothing' if no change, --- otherwise returrn 'Just' of the new state --- nodes: a set of nodes that initially need updating --- state: some sort of state (usually a map) --- containing the initial value for each node +----------------------------------------------------------------------------- +-- | Solve the fixed-point of a dataflow problem. -- -- Complexity: O(N+H*E) calls to 'update' where -- N = number of nodes, @@ -26,19 +20,39 @@ module Dataflow ( -- Sketch for proof of complexity: -- Note that the state is threaded through the entire execution. -- Also note that the height of the latice at any particular node --- is the number of times 'update' can return non-Nothing for a particular node. --- Every call (except for the top level one) must be caused by a non-Nothing --- result and each non-Nothing result causes as many calls as it has --- out-going edges. Thus any particular node, n, may cause in total --- at most H*out(n) further calls. When summed over all nodes, +-- is the number of times 'update' can return non-Nothing for a +-- particular node. Every call (except for the top level one) +-- must be caused by a non-Nothing result and each non-Nothing +-- result causes as many calls as it has out-going edges. +-- Thus any particular node, n, may cause in total at +-- most H*out(n) further calls. When summed over all nodes, -- that is H*E. The N term of the complexity is from the initial call -- when 'update' will be passed 'Nothing'. fixedpoint :: - (node -> [node]) + (node -> [node]) -- ^ map from nodes to those who's + -- value depend on the argument node -> (node -> Maybe node -> s -> Maybe s) - -> [node] -> s -> s + -- ^ Given the node which needs to be + -- updated, and which node caused that node + -- to need to be updated, update the state. + -- + -- The causing node will be 'Nothing' if + -- this is the initial/bootstrapping update. + -- + -- Must return 'Nothing' if no change, + -- otherwise returrn 'Just' of the new state. + + -> [node] -- ^ Nodes that should initially be updated + + -> s -- ^ Initial state + -- (usually a map from node to + -- the value for that node) + + -> s -- ^ Final state fixedpoint dependants update nodes state = foldr (fixedpoint' Nothing) state nodes where + -- Use a depth first traversal of nodes based on the update graph. + -- Terminate the traversal when the update doesn't change anything. fixedpoint' cause node state = case update node cause state of Nothing -> state