From 95d99706e3569aa94796fab34e8e49faf17866cb Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Tue, 29 Jan 2008 21:05:37 +0000 Subject: [PATCH] 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) --- checks/Check.hs | 7 +++++-- checks/UsageCheckAlgorithms.hs | 3 +-- common/FlowAlgorithms.hs | 7 +++---- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/checks/Check.hs b/checks/Check.hs index 658eed6..31a165c 100644 --- a/checks/Check.hs +++ b/checks/Check.hs @@ -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 } diff --git a/checks/UsageCheckAlgorithms.hs b/checks/UsageCheckAlgorithms.hs index 1ecf621..5defc77 100644 --- a/checks/UsageCheckAlgorithms.hs +++ b/checks/UsageCheckAlgorithms.hs @@ -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 } diff --git a/common/FlowAlgorithms.hs b/common/FlowAlgorithms.hs index 30cec25..f43da52 100644 --- a/common/FlowAlgorithms.hs +++ b/common/FlowAlgorithms.hs @@ -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)