diff options
Diffstat (limited to 'Stackify.hs')
-rw-r--r-- | Stackify.hs | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/Stackify.hs b/Stackify.hs new file mode 100644 index 0000000..a09c6f0 --- /dev/null +++ b/Stackify.hs @@ -0,0 +1,36 @@ +module Stackify ( + stackify +) where + +import qualified Data.Map.Strict as Map +import qualified Data.Set as Set + +import Intermediate + + +data Funcinfo = + FuncInfo { fiGFD :: GlobFuncDef + , fiBBs :: [BB] + , fiTemps :: [Int] } + +stackify :: IRProgram -> IRProgram +stackify (IRProgram origbbs gfds datas) = + let infos = [FuncInfo gfd bbs [i | RTemp i <- allRefs bbs] + | (gfd, bbs) <- partitionFunctions gfds origbbs] + -- LIVENESS ANALYSIS within the function! + +partitionFunctions :: Map.Map Name GlobFuncDef -> [BB] -> [(GlobFuncDef, [BB])] +partitionFunctions gfds bbs = + let bbmap = Map.fromList [(bidOf bb, bb) | bb <- bbs] + pairs = [(gfd, floodFill bbmap bid) | gfd@(GlobFuncDef bid _ _) <- Map.elems gfds] + accums = scanl (<>) Set.empty (map snd pairs) + triples = zip3 accums pairs (tail accums) + in if all (\(from, (_, bbset), to) -> Set.size from + Set.size bbset == Set.size to) triples + && Set.size (last accums) == length bbs + then [(gfd, map (bbmap Map.!) (Set.toList bbset)) | (gfd, bbset) <- pairs] + else error "Non-partitionable BBs in partitionFunctions" + where + floodFill bbmap origin = go Set.empty origin + where + go seen at = let newseen = seen <> Set.fromList (outEdges (bbmap Map.! at)) + in foldl go newseen (Set.toList (newseen Set.\\ seen)) |