diff options
author | Douglas Wilson <douglas.wilson@gmail.com> | 2017-06-08 15:02:01 -0400 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2017-06-08 15:35:58 -0400 |
commit | 56ef54444b89b2332abe68ee62d88792f785f5a7 (patch) | |
tree | d1bc9363c403a16d0532379fdbf0b8695ee800e2 /compiler/main/GHC.hs | |
parent | 3ee3822ce588565e912ab6211e9d2cd545fc6ba6 (diff) | |
download | haskell-56ef54444b89b2332abe68ee62d88792f785f5a7.tar.gz |
Add tcRnGetNameToInstancesIndex
This function in tcRnDriver, retrieves an index by name of all Class and
Family instances in the current environment.
This is to be used by haddock which currently looks up instances for
each name, which looks at every instance for every lookup.
Using this function instead of tcRnGetInfo, the haddock.base performance
test improves by 10%
Reviewers: austin, bgamari
Reviewed By: bgamari
Subscribers: alexbiehl, rwbarton, thomie
Differential Revision: https://phabricator.haskell.org/D3624
Diffstat (limited to 'compiler/main/GHC.hs')
-rw-r--r-- | compiler/main/GHC.hs | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/compiler/main/GHC.hs b/compiler/main/GHC.hs index eda3471ece..ec9e271ff7 100644 --- a/compiler/main/GHC.hs +++ b/compiler/main/GHC.hs @@ -1,4 +1,5 @@ {-# LANGUAGE CPP, NondecreasingIndentation, ScopedTypeVariables #-} +{-# LANGUAGE TupleSections, NamedFieldPuns #-} -- ----------------------------------------------------------------------------- -- @@ -113,6 +114,7 @@ module GHC ( getInfo, showModule, moduleIsBootOrNotObjectLinkable, + getNameToInstancesIndex, -- ** Inspecting types and kinds exprType, TcRnExprMode(..), @@ -333,9 +335,18 @@ import qualified Parser import Lexer import ApiAnnotation import qualified GHC.LanguageExtensions as LangExt +import NameEnv +import CoreFVs ( orphNamesOfFamInst ) +import FamInstEnv ( famInstEnvElts ) +import TcRnDriver +import Inst +import FamInst import FileCleanup +import Data.Foldable +import qualified Data.Map.Strict as Map import Data.Set (Set) +import qualified Data.Sequence as Seq import System.Directory ( doesFileExist ) import Data.Maybe import Data.List ( find ) @@ -1228,6 +1239,36 @@ findGlobalAnns deserialize target = withSession $ \hsc_env -> do getGRE :: GhcMonad m => m GlobalRdrEnv getGRE = withSession $ \hsc_env-> return $ ic_rn_gbl_env (hsc_IC hsc_env) +-- | Retrieve all type and family instances in the environment, indexed +-- by 'Name'. Each name's lists will contain every instance in which that name +-- is mentioned in the instance head. +getNameToInstancesIndex :: HscEnv + -> IO (Messages, Maybe (NameEnv ([ClsInst], [FamInst]))) +getNameToInstancesIndex hsc_env + = runTcInteractive hsc_env $ + do { loadUnqualIfaces hsc_env (hsc_IC hsc_env) + ; InstEnvs {ie_global, ie_local, ie_visible} <- tcGetInstEnvs + ; (pkg_fie, home_fie) <- tcGetFamInstEnvs + -- We use flip mappend to maintain the order of instances, + -- and Data.Sequence.Seq to keep flip mappend fast + ; let cls_index = Map.fromListWith (flip mappend) + [ (n, Seq.singleton ispec) + | ispec <- instEnvElts ie_local ++ instEnvElts ie_global + , instIsVisible ie_visible ispec + , n <- nameSetElemsStable $ orphNamesOfClsInst ispec + ] + ; let fam_index = Map.fromListWith (flip mappend) + [ (n, Seq.singleton fispec) + | fispec <- famInstEnvElts home_fie ++ famInstEnvElts pkg_fie + , n <- nameSetElemsStable $ orphNamesOfFamInst fispec + ] + ; return $ mkNameEnv $ + [ (nm, (toList clss, toList fams)) + | (nm, (clss, fams)) <- Map.toList $ Map.unionWith mappend + (fmap (,Seq.empty) cls_index) + (fmap (Seq.empty,) fam_index) + ] } + -- ----------------------------------------------------------------------------- {- ToDo: Move the primary logic here to compiler/main/Packages.hs |