@@ -1,9 +1,6 @@
1{-# LANGUAGE PatternGuards #-}
1{-# LANGUAGE PatternGuards #-}
3−module Idris.Erasure
3+module Idris.Erasure (performUsageAnalysis) where
8import Idris.AbsSyntax
5import Idris.AbsSyntax
9import Idris.Core.CaseTree
6import Idris.Core.CaseTree
@@ -51,6 +48,42 @@ type Cond = Set Node
51type Var = Set Node
48type Var = Set Node
52type Vars = Map Name Var
49type Vars = Map Name Var
51+-- Perform usage analysis, write the relevant information in the internal
52+-- structures, returning the list of reachable names.
53+performUsageAnalysis :: Idris [Name]
54+performUsageAnalysis = do
55+ ctx <- tt_ctxt <$> getIState
56+ ci <- idris_classes <$> getIState
58+ -- Build the dependency graph.
59+ let depMap = buildDepMap ci ctx (sNS (sUN "main") ["Main"])
61+ -- Search for reachable nodes in the graph.
62+ let (residDeps, (reachableNames, minUse)) = minimalUsage depMap
64+ -- Print some debug info.
65+ logLvl 3 $ "Reachable names:\n" ++ unlines (map show . S.toList $ reachableNames)
66+ logLvl 4 $ "Minimal usage:\n" ++ fmtUseMap minUse
67+ logLvl 5 $ "Residual deps:\n" ++ unlines (map fmtItem . M.toList $ residDeps)
69+ -- Store the usage info in the internal state.
70+ mapM_ storeUsage . M.toList $ minUse
72+ return $ S.toList reachableNames
74+ fmtItem :: (Cond, Set Node) -> String
75+ fmtItem (cond, deps) = show (S.toList cond) ++ " -> " ++ show (S.toList deps)
77+ fmtUseMap :: UseMap -> String
78+ fmtUseMap = unlines . map (\(n,is) -> show n ++ " -> " ++ show (IS.toList is)) . M.toList
80+ storeUsage :: (Name, IntSet) -> Idris ()
81+ storeUsage (n, args) = do
82+ cg <- idris_callgraph <$> getIState
83+ case lookupCtxt n cg of
84+ [x] -> addToCG n x{ usedpos = IS.toList args } -- functions
85+ _ -> addToCG n (CGInfo [] [] [] [] (IS.toList args)) -- data ctors
54-- Find the minimal consistent usage by forward chaining.
87-- Find the minimal consistent usage by forward chaining.
55minimalUsage :: Deps -> (Deps, (Set Name, UseMap))
88minimalUsage :: Deps -> (Deps, (Set Name, UseMap))
56minimalUsage = second gather . forwardChain
89minimalUsage = second gather . forwardChain
@@ -75,8 +108,8 @@ forwardChain deps
76-- Build the dependency graph,
109-- Build the dependency graph,
77-- starting the depth-first search from a list of Names.
110-- starting the depth-first search from a list of Names.
78−buildDepMap :: Ctxt ClassInfo -> Context -> [Name] -> Deps
111+buildDepMap :: Ctxt ClassInfo -> Context -> Name -> Deps
79−buildDepMap ci ctx ns = addPostulates $ dfs S.empty M.empty ns
112+buildDepMap ci ctx rootName = addPostulates $ dfs S.empty M.empty [rootName]
81 -- mark the result of Main.main as used with the empty assumption
114 -- mark the result of Main.main as used with the empty assumption
82 addPostulates :: Deps -> Deps
115 addPostulates :: Deps -> Deps