Store postdominators as Array Node [Node] for a significant win

This commit is contained in:
Vidar Holen 2022-07-29 21:05:33 -07:00
parent 04db46381f
commit 77069f7445
2 changed files with 14 additions and 11 deletions
src/ShellCheck

View File

@ -47,6 +47,8 @@ import ShellCheck.Regex
import Control.DeepSeq
import Control.Monad
import Control.Monad.Identity
import Data.Array.Unboxed
import Data.Array.ST
import Data.List hiding (map)
import Data.Maybe
import qualified Data.Map as M
@ -174,10 +176,10 @@ data CFGResult = CFGResult {
cfIdToRange :: M.Map Id (Node, Node),
-- A set of all nodes belonging to an Id, recursively
cfIdToNodes :: M.Map Id (S.Set Node),
-- A map to nodes that the given node postdominates
cfPostDominators :: M.Map Node (S.Set Node)
-- An array (from,to) saying whether 'from' postdominates 'to'
cfPostDominators :: Array Node [Node]
}
deriving (Show, Generic, NFData)
deriving (Show)
buildGraph :: CFGParameters -> Token -> CFGResult
buildGraph params root =
@ -200,7 +202,7 @@ buildGraph params root =
cfPostDominators = findPostDominators mainExit $ mkGraph nodes onlyRealEdges
}
in
deepseq result result
result
remapGraph :: M.Map Node Node -> CFW -> CFW
remapGraph remap (nodes, edges, mapping, assoc) =
@ -1256,8 +1258,8 @@ findTerminalNodes graph = ufold find [] graph
f (IdTagged _ (CFDefineFunction _ id start end):rest) list = f rest (end:list)
f (_:rest) list = f rest list
findPostDominators :: Node -> CFGraph -> M.Map Node (S.Set Node)
findPostDominators mainexit graph = asSetMap
findPostDominators :: Node -> CFGraph -> Array Node [Node]
findPostDominators mainexit graph = asArray
where
inlined = inlineSubshells graph
terminals = findTerminalNodes inlined
@ -1265,7 +1267,8 @@ findPostDominators mainexit graph = asSetMap
withExitEdges = (incoming ++ map (\c -> (CFEFlow, c)) terminals, mainexit, label, outgoing) `safeUpdate` inlined
reversed = grev withExitEdges
postDoms = dom reversed mainexit
asSetMap = M.fromList $ map (\(node, list) -> (node, S.fromList list)) postDoms
(_, maxNode) = nodeRange graph
asArray = array (0, maxNode) postDoms
return []
runTests = $( [| $(forAllProperties) (quickCheckWithResult (stdArgs { maxSuccess = 1 }) ) |])

View File

@ -69,6 +69,7 @@ import Control.Monad
import Control.Monad.ST
import Control.DeepSeq
import Data.List hiding (map)
import Data.Array.Unboxed
import Data.STRef
import Data.Maybe
import qualified Data.Map as M
@ -100,9 +101,9 @@ data CFGAnalysis = CFGAnalysis {
graph :: CFGraph,
tokenToRange :: M.Map Id (Node, Node),
tokenToNodes :: M.Map Id (S.Set Node),
postDominators :: M.Map Node (S.Set Node),
postDominators :: Array Node [Node],
nodeToData :: M.Map Node (ProgramState, ProgramState)
} deriving (Show, Generic, NFData)
} deriving (Show)
-- The program state we expose externally
data ProgramState = ProgramState {
@ -147,8 +148,7 @@ doesPostDominate :: CFGAnalysis -> Id -> Id -> Bool
doesPostDominate analysis target base = fromMaybe False $ do
(_, baseEnd) <- M.lookup base $ tokenToRange analysis
(targetStart, _) <- M.lookup target $ tokenToRange analysis
postDoms <- M.lookup baseEnd $ postDominators analysis
return $ S.member targetStart postDoms
return $ targetStart `elem` (postDominators analysis ! baseEnd)
getDataForNode analysis node = M.lookup node $ nodeToData analysis