Readjusted the parameters of flowAlgorithm so that the initial value for the starting node is passed in more obviously (since that was the only use of initVal, which has now been removed)

This commit is contained in:
Neil Brown 2008-01-29 21:05:37 +00:00
parent 28fd400d89
commit 95d99706e3
3 changed files with 9 additions and 8 deletions

View File

@ -143,13 +143,17 @@ showCodeExSet (NormalSet s)
-- | Checks that no variable is used uninitialised. That is, it checks that every variable is written to before it is read.
checkInitVar :: forall m. (Monad m, Die m, CSM m) => Meta -> FlowGraph m (Maybe Decl, Vars) -> Node -> m ()
checkInitVar m graph startNode
= do vwb <- case flowAlgorithm graphFuncs (dfs [startNode] graph) startNode of
= do startLabel <- checkJust (Just m, "Could not find starting node in the control-flow graph")
(lab graph startNode) >>* writeNode
vwb <- case flowAlgorithm graphFuncs connectedNodes (startNode, startLabel) of
Left err -> dieP m $ "Error building control-flow graph: " ++ err
Right x -> return x
-- vwb is a map from Node to a set of Vars that have been written by that point
-- Now we check that for every variable read in each node, it has already been written to by then
mapM_ (checkInitVar' vwb) (map readNode (labNodes graph))
where
connectedNodes = dfs [startNode] graph
-- Gets all variables read-from in a particular node, and the node identifier
readNode :: (Node, FNode m (Maybe Decl, Vars)) -> (Node, ExSet Var)
readNode (n, Node (_,(_,Vars read _ _),_)) = (n,NormalSet read)
@ -170,7 +174,6 @@ checkInitVar m graph startNode
nodeFunc = nodeFunction
,prevNodes = lpre graph
,nextNodes = lsuc graph
,initVal = emptySet
,defVal = Everything
}

View File

@ -98,7 +98,7 @@ checkPar f g = map f allParItems
-- | Returns either an error, or map *from* the node with a read, *to* the node whose definitions might be available at that point
findReachDef :: forall m. Monad m => FlowGraph m (Maybe Decl, Vars) -> Node -> Either String (Map.Map Node (Map.Map Var (Set.Set Node)))
findReachDef graph startNode
= do r <- flowAlgorithm graphFuncs (nodes graph) startNode
= do r <- flowAlgorithm graphFuncs (nodes graph) (startNode, Map.empty)
-- These lines remove the maps where the variable is not read in that particular node:
let r' = Map.mapWithKey (\n -> Map.filterWithKey (readInNode' n)) r
return $ Map.filter (not . Map.null) r'
@ -109,7 +109,6 @@ findReachDef graph startNode
nodeFunc = processNode
,prevNodes = lpre graph
,nextNodes = lsuc graph
,initVal = Map.empty
,defVal = Map.empty
}

View File

@ -28,7 +28,6 @@ data GraphFuncs n e a = GF {
nodeFunc :: (n,e) -> a -> Maybe a -> a
,prevNodes :: n -> [(n,e)]
,nextNodes :: n -> [(n,e)]
,initVal :: a
-- defVal should be the unit of the aggregation. That is, if (nodeFunc a b) == defVal, then (nodeFunc a b defVal) == defVal too
-- TODO not sure if the above is still true
,defVal :: a
@ -39,11 +38,11 @@ data GraphFuncs n e a = GF {
-- | Given the graph functions, a list of nodes and an entry node, performs
-- an iterative data-flow analysis. All the nodes in the list should be connected to
-- the entry node, and there should be no nodes without predecessors in the list.
flowAlgorithm :: forall n e a. (Ord n, Show n, Eq a) => GraphFuncs n e a -> [n] -> n -> Either String (Map.Map n a)
flowAlgorithm funcs nodes startNode
flowAlgorithm :: forall n e a. (Ord n, Show n, Eq a) => GraphFuncs n e a -> [n] -> (n, a) -> Either String (Map.Map n a)
flowAlgorithm funcs nodes (startNode, startVal)
= iterate
(Set.fromList nonStartNodes)
(Map.fromList $ (startNode,initVal funcs):(zip nonStartNodes (repeat (defVal funcs))))
(Map.fromList $ (startNode, startVal):(zip nonStartNodes (repeat (defVal funcs))))
where
nonStartNodes = (filter ((/=) startNode) nodes)