| 1 | 1 patch for repository /home/a/src/ghc-head: |
|---|
| 2 | |
|---|
| 3 | Fri Nov 19 20:37:47 CST 2010 austin seipp <as@hacks.yi.org> |
|---|
| 4 | * Implement support for writing and loading plugins for GHC |
|---|
| 5 | Based on Max Bolingbroke's original patch for implementing plugin support in GHC, |
|---|
| 6 | which can be gotten from here: http://hackage.haskell.org/trac/ghc/ticket/3843 |
|---|
| 7 | |
|---|
| 8 | A little bit of the linker interface changed and the simplifier interface changed |
|---|
| 9 | inbetween now and then. This patch brings most of the work Max did up to date although |
|---|
| 10 | there may be a few loose ends. The interface for plugins that rewrite core hasn't changed |
|---|
| 11 | (that is, most people will be writing passes of type [CoreBind] -> CoreM [CoreBind]) |
|---|
| 12 | |
|---|
| 13 | Plugins are registered the same way as they were previously: plugin modules provide an installation |
|---|
| 14 | function of type [CoreToDo] -> CoreM [CoreToDo] |
|---|
| 15 | |
|---|
| 16 | Changes: |
|---|
| 17 | * -plg and -P flags replaced by -fplugin and -fplugin-arg (consistent with what GCC uses) |
|---|
| 18 | |
|---|
| 19 | |
|---|
| 20 | |
|---|
| 21 | New patches: |
|---|
| 22 | |
|---|
| 23 | [Implement support for writing and loading plugins for GHC |
|---|
| 24 | austin seipp <as@hacks.yi.org>**20101120023747 |
|---|
| 25 | Ignore-this: c396164d4bab5305df35df654e27fb55 |
|---|
| 26 | Based on Max Bolingbroke's original patch for implementing plugin support in GHC, |
|---|
| 27 | which can be gotten from here: http://hackage.haskell.org/trac/ghc/ticket/3843 |
|---|
| 28 | |
|---|
| 29 | A little bit of the linker interface changed and the simplifier interface changed |
|---|
| 30 | inbetween now and then. This patch brings most of the work Max did up to date although |
|---|
| 31 | there may be a few loose ends. The interface for plugins that rewrite core hasn't changed |
|---|
| 32 | (that is, most people will be writing passes of type [CoreBind] -> CoreM [CoreBind]) |
|---|
| 33 | |
|---|
| 34 | Plugins are registered the same way as they were previously: plugin modules provide an installation |
|---|
| 35 | function of type [CoreToDo] -> CoreM [CoreToDo] |
|---|
| 36 | |
|---|
| 37 | Changes: |
|---|
| 38 | * -plg and -P flags replaced by -fplugin and -fplugin-arg (consistent with what GCC uses) |
|---|
| 39 | |
|---|
| 40 | ] { |
|---|
| 41 | hunk ./compiler/basicTypes/Module.lhs 42 |
|---|
| 42 | dphSeqPackageId, |
|---|
| 43 | dphParPackageId, |
|---|
| 44 | mainPackageId, |
|---|
| 45 | - |
|---|
| 46 | + thisGhcPackageId, |
|---|
| 47 | + |
|---|
| 48 | -- * The Module type |
|---|
| 49 | Module, |
|---|
| 50 | modulePackageId, moduleName, |
|---|
| 51 | hunk ./compiler/basicTypes/Module.lhs 351 |
|---|
| 52 | integerPackageId, primPackageId, |
|---|
| 53 | basePackageId, rtsPackageId, |
|---|
| 54 | thPackageId, dphSeqPackageId, dphParPackageId, |
|---|
| 55 | - mainPackageId :: PackageId |
|---|
| 56 | + mainPackageId, thisGhcPackageId :: PackageId |
|---|
| 57 | primPackageId = fsToPackageId (fsLit "ghc-prim") |
|---|
| 58 | integerPackageId = fsToPackageId (fsLit cIntegerLibrary) |
|---|
| 59 | basePackageId = fsToPackageId (fsLit "base") |
|---|
| 60 | hunk ./compiler/basicTypes/Module.lhs 359 |
|---|
| 61 | thPackageId = fsToPackageId (fsLit "template-haskell") |
|---|
| 62 | dphSeqPackageId = fsToPackageId (fsLit "dph-seq") |
|---|
| 63 | dphParPackageId = fsToPackageId (fsLit "dph-par") |
|---|
| 64 | +thisGhcPackageId = fsToPackageId (fsLit ("ghc-" ++ cProjectVersion)) |
|---|
| 65 | |
|---|
| 66 | -- | This is the package Id for the current program. It is the default |
|---|
| 67 | -- package Id if you don't specify a package name. We don't add this prefix |
|---|
| 68 | hunk ./compiler/ghc.cabal.in 325 |
|---|
| 69 | ErrUtils |
|---|
| 70 | Finder |
|---|
| 71 | GHC |
|---|
| 72 | + Plugins |
|---|
| 73 | + GHCPlugins |
|---|
| 74 | + LoadPlugins |
|---|
| 75 | + DynamicLoading |
|---|
| 76 | HeaderInfo |
|---|
| 77 | HscMain |
|---|
| 78 | HscStats |
|---|
| 79 | hunk ./compiler/ghci/Linker.lhs 18 |
|---|
| 80 | linkExpr, unload, withExtendedLinkEnv, |
|---|
| 81 | extendLinkEnv, deleteFromLinkEnv, |
|---|
| 82 | extendLoadedPkgs, |
|---|
| 83 | - linkPackages,initDynLinker, |
|---|
| 84 | - dataConInfoPtrToName |
|---|
| 85 | + linkPackages,initDynLinker,linkModule, |
|---|
| 86 | + dataConInfoPtrToName, lessUnsafeCoerce |
|---|
| 87 | ) where |
|---|
| 88 | |
|---|
| 89 | #include "HsVersions.h" |
|---|
| 90 | hunk ./compiler/ghci/Linker.lhs 58 |
|---|
| 91 | import FastString |
|---|
| 92 | import Config |
|---|
| 93 | |
|---|
| 94 | +import GHC.Exts (unsafeCoerce#) |
|---|
| 95 | + |
|---|
| 96 | -- Standard libraries |
|---|
| 97 | import Control.Monad |
|---|
| 98 | |
|---|
| 99 | hunk ./compiler/ghci/Linker.lhs 262 |
|---|
| 100 | -- Throws a 'ProgramError' if loading fails or the name cannot be found. |
|---|
| 101 | getHValue :: HscEnv -> Name -> IO HValue |
|---|
| 102 | getHValue hsc_env name = do |
|---|
| 103 | + initDynLinker (hsc_dflags hsc_env) |
|---|
| 104 | pls <- modifyMVar v_PersistentLinkerState $ \pls -> do |
|---|
| 105 | if (isExternalName name) then do |
|---|
| 106 | (pls', ok) <- linkDependencies hsc_env pls noSrcSpan [nameModule name] |
|---|
| 107 | hunk ./compiler/ghci/Linker.lhs 276 |
|---|
| 108 | -> SrcSpan -> [Module] |
|---|
| 109 | -> IO (PersistentLinkerState, SuccessFlag) |
|---|
| 110 | linkDependencies hsc_env pls span needed_mods = do |
|---|
| 111 | +-- initDynLinker (hsc_dflags hsc_env) |
|---|
| 112 | let hpt = hsc_HPT hsc_env |
|---|
| 113 | dflags = hsc_dflags hsc_env |
|---|
| 114 | -- The interpreter and dynamic linker can only handle object code built |
|---|
| 115 | hunk ./compiler/ghci/Linker.lhs 696 |
|---|
| 116 | adjust_ul _ _ = panic "adjust_ul" |
|---|
| 117 | \end{code} |
|---|
| 118 | |
|---|
| 119 | +%************************************************************************ |
|---|
| 120 | +%* * |
|---|
| 121 | + Loading a single module |
|---|
| 122 | +%* * |
|---|
| 123 | +%************************************************************************ |
|---|
| 124 | +\begin{code} |
|---|
| 125 | + |
|---|
| 126 | +-- | Link a single module |
|---|
| 127 | +linkModule :: HscEnv -> Module -> IO () |
|---|
| 128 | +linkModule hsc_env mod = do |
|---|
| 129 | + initDynLinker (hsc_dflags hsc_env) |
|---|
| 130 | + modifyMVar v_PersistentLinkerState $ \pls -> do |
|---|
| 131 | + (pls', ok) <- linkDependencies hsc_env pls noSrcSpan [mod] |
|---|
| 132 | + if (failed ok) then ghcError (ProgramError "") |
|---|
| 133 | + else return (pls',()) |
|---|
| 134 | + |
|---|
| 135 | +-- | Coerce a value as usual, but: |
|---|
| 136 | +-- |
|---|
| 137 | +-- 1) Evaluate it immediately to get a segfault early if the coercion was wrong |
|---|
| 138 | +-- |
|---|
| 139 | +-- 2) Wrap it in some debug messages at verbosity 3 or higher so we can see what happened |
|---|
| 140 | +-- if it /does/ segfault |
|---|
| 141 | +lessUnsafeCoerce :: DynFlags -> String -> a -> IO b |
|---|
| 142 | +lessUnsafeCoerce dflags context what = do |
|---|
| 143 | + debugTraceMsg dflags 3 $ (ptext $ sLit "Coercing a value in") <+> (text context) <> (ptext $ sLit "...") |
|---|
| 144 | + output <- evaluate (unsafeCoerce# what) |
|---|
| 145 | + debugTraceMsg dflags 3 $ ptext $ sLit "Successfully evaluated coercion" |
|---|
| 146 | + return output |
|---|
| 147 | + |
|---|
| 148 | + |
|---|
| 149 | + |
|---|
| 150 | +\end{code} |
|---|
| 151 | |
|---|
| 152 | %************************************************************************ |
|---|
| 153 | %* * |
|---|
| 154 | hunk ./compiler/ghci/Linker.lhs 1029 |
|---|
| 155 | linkPackages dflags new_pkgs = do |
|---|
| 156 | -- It's probably not safe to try to load packages concurrently, so we take |
|---|
| 157 | -- a lock. |
|---|
| 158 | + initDynLinker dflags |
|---|
| 159 | modifyMVar_ v_PersistentLinkerState $ \pls -> do |
|---|
| 160 | linkPackages' dflags new_pkgs pls |
|---|
| 161 | |
|---|
| 162 | hunk ./compiler/main/DynFlags.hs 139 |
|---|
| 163 | | Opt_D_dump_occur_anal |
|---|
| 164 | | Opt_D_dump_parsed |
|---|
| 165 | | Opt_D_dump_rn |
|---|
| 166 | + | Opt_D_dump_core_pipeline -- TODO FIXME: dump after simplifier stats |
|---|
| 167 | | Opt_D_dump_simpl |
|---|
| 168 | | Opt_D_dump_simpl_iterations |
|---|
| 169 | | Opt_D_dump_simpl_phases |
|---|
| 170 | hunk ./compiler/main/DynFlags.hs 446 |
|---|
| 171 | |
|---|
| 172 | hpcDir :: String, -- ^ Path to store the .mix files |
|---|
| 173 | |
|---|
| 174 | + -- Plugins |
|---|
| 175 | + pluginModNames :: [ModuleName], |
|---|
| 176 | + pluginModNameOpts :: [(ModuleName,String)], |
|---|
| 177 | + |
|---|
| 178 | -- options for particular phases |
|---|
| 179 | opt_L :: [String], |
|---|
| 180 | opt_P :: [String], |
|---|
| 181 | hunk ./compiler/main/DynFlags.hs 686 |
|---|
| 182 | hcSuf = phaseInputExt HCc, |
|---|
| 183 | hiSuf = "hi", |
|---|
| 184 | |
|---|
| 185 | + pluginModNames = [], |
|---|
| 186 | + pluginModNameOpts = [], |
|---|
| 187 | + |
|---|
| 188 | outputFile = Nothing, |
|---|
| 189 | outputHi = Nothing, |
|---|
| 190 | dynLibLoader = SystemDependent, |
|---|
| 191 | hunk ./compiler/main/DynFlags.hs 899 |
|---|
| 192 | setOutputFile f d = d{ outputFile = f} |
|---|
| 193 | setOutputHi f d = d{ outputHi = f} |
|---|
| 194 | |
|---|
| 195 | +addPluginModuleName :: String -> DynFlags -> DynFlags |
|---|
| 196 | +addPluginModuleName name d = d { pluginModNames = (mkModuleName name) : (pluginModNames d) } |
|---|
| 197 | + |
|---|
| 198 | +addPluginModuleNameOption :: String -> DynFlags -> DynFlags |
|---|
| 199 | +addPluginModuleNameOption optflag d = d { pluginModNameOpts = (mkModuleName m, option) : (pluginModNameOpts d) } |
|---|
| 200 | + where (m, rest) = break (== ':') optflag |
|---|
| 201 | + option = case rest of |
|---|
| 202 | + [] -> "" -- should probably signal an error |
|---|
| 203 | + (_:plug_opt) -> plug_opt -- ignore the ':' from break |
|---|
| 204 | + |
|---|
| 205 | parseDynLibLoaderMode f d = |
|---|
| 206 | case splitAt 8 f of |
|---|
| 207 | ("deploy", "") -> d{ dynLibLoader = Deployable } |
|---|
| 208 | hunk ./compiler/main/DynFlags.hs 1252 |
|---|
| 209 | , Flag "ddump-occur-anal" (setDumpFlag Opt_D_dump_occur_anal) |
|---|
| 210 | , Flag "ddump-parsed" (setDumpFlag Opt_D_dump_parsed) |
|---|
| 211 | , Flag "ddump-rn" (setDumpFlag Opt_D_dump_rn) |
|---|
| 212 | + , Flag "ddump-core-pipeline" (setDumpFlag Opt_D_dump_core_pipeline) |
|---|
| 213 | , Flag "ddump-simpl" (setDumpFlag Opt_D_dump_simpl) |
|---|
| 214 | , Flag "ddump-simpl-iterations" (setDumpFlag Opt_D_dump_simpl_iterations) |
|---|
| 215 | , Flag "ddump-simpl-phases" (OptPrefix setDumpSimplPhases) |
|---|
| 216 | hunk ./compiler/main/DynFlags.hs 1309 |
|---|
| 217 | , Flag "Wnot" (NoArg (do { mapM_ unSetDynFlag minusWallOpts |
|---|
| 218 | ; deprecate "Use -w instead" })) |
|---|
| 219 | , Flag "w" (NoArg (mapM_ unSetDynFlag minuswRemovesOpts)) |
|---|
| 220 | - |
|---|
| 221 | + |
|---|
| 222 | + ------ Plugin flags ------------------------------------------------ |
|---|
| 223 | + , Flag "fplugin" (hasArg addPluginModuleName) |
|---|
| 224 | + , Flag "fplugin-opt" (hasArg addPluginModuleNameOption) |
|---|
| 225 | + |
|---|
| 226 | ------ Optimisation flags ------------------------------------------ |
|---|
| 227 | , Flag "O" (noArg (setOptLevel 1)) |
|---|
| 228 | , Flag "Onot" (noArgDF (setOptLevel 0) "Use -O0 instead") |
|---|
| 229 | addfile ./compiler/main/DynamicLoading.hs |
|---|
| 230 | hunk ./compiler/main/DynamicLoading.hs 1 |
|---|
| 231 | +-- | Dynamically lookup up values from modules and loading them. |
|---|
| 232 | +module DynamicLoading ( |
|---|
| 233 | +#ifdef GHCI |
|---|
| 234 | + -- * Force loading information |
|---|
| 235 | + forceLoadModuleInterfaces, |
|---|
| 236 | + forceLoadNameModuleInterface, |
|---|
| 237 | + forceLoadTyCon, |
|---|
| 238 | + |
|---|
| 239 | + -- * Finding names |
|---|
| 240 | + lookupRdrNameInModule, |
|---|
| 241 | + |
|---|
| 242 | + -- * Loading values |
|---|
| 243 | + getValueSafely, |
|---|
| 244 | + lessUnsafeCoerce |
|---|
| 245 | +#endif |
|---|
| 246 | + ) where |
|---|
| 247 | + |
|---|
| 248 | +#ifdef GHCI |
|---|
| 249 | +import Linker ( linkModule, getHValue, lessUnsafeCoerce ) |
|---|
| 250 | +import OccName ( occNameSpace ) |
|---|
| 251 | +import Name ( nameOccName ) |
|---|
| 252 | +import SrcLoc ( noSrcSpan ) |
|---|
| 253 | +import Finder ( findImportedModule, cannotFindModule ) |
|---|
| 254 | +import DriverPhases ( HscSource(HsSrcFile) ) |
|---|
| 255 | +import TcRnDriver ( getModuleExports ) |
|---|
| 256 | +import TcRnMonad ( initTc, initIfaceTcRn ) |
|---|
| 257 | +import LoadIface ( loadUserInterface ) |
|---|
| 258 | +import RdrName ( RdrName, Provenance(..), ImportSpec(..), ImpDeclSpec(..), ImpItemSpec(..), |
|---|
| 259 | + mkGlobalRdrEnv, lookupGRE_RdrName, gre_name, rdrNameSpace ) |
|---|
| 260 | +import RnNames ( gresFromAvails ) |
|---|
| 261 | +import PrelNames ( iNTERACTIVE ) |
|---|
| 262 | + |
|---|
| 263 | +import HscTypes ( HscEnv(..), FindResult(..), lookupTypeHscEnv ) |
|---|
| 264 | +import TypeRep ( TyThing(..), pprTyThingCategory ) |
|---|
| 265 | +import Type ( Type, coreEqType ) |
|---|
| 266 | +import TyCon ( TyCon ) |
|---|
| 267 | +import Name ( Name, nameModule_maybe ) |
|---|
| 268 | +import Id ( idType ) |
|---|
| 269 | +import Module ( Module, ModuleName ) |
|---|
| 270 | +import Panic ( GhcException(..), throwGhcException, panic ) |
|---|
| 271 | +import FastString |
|---|
| 272 | +import Outputable |
|---|
| 273 | + |
|---|
| 274 | +import Data.Maybe ( mapMaybe ) |
|---|
| 275 | + |
|---|
| 276 | + |
|---|
| 277 | +-- | Force the interfaces for the given modules to be loaded. The 'SDoc' parameter is used |
|---|
| 278 | +-- for debugging (@-ddump-if-trace@) only: it is shown as the reason why the module is being loaded. |
|---|
| 279 | +forceLoadModuleInterfaces :: HscEnv -> SDoc -> [Module] -> IO () |
|---|
| 280 | +forceLoadModuleInterfaces hsc_env doc modules |
|---|
| 281 | + = (initTc hsc_env HsSrcFile False iNTERACTIVE $ initIfaceTcRn $ mapM_ (loadUserInterface False doc) modules) >> return () |
|---|
| 282 | + |
|---|
| 283 | +-- | Force the interface for the module containing the name to be loaded. The 'SDoc' parameter is used |
|---|
| 284 | +-- for debugging (@-ddump-if-trace@) only: it is shown as the reason why the module is being loaded. |
|---|
| 285 | +forceLoadNameModuleInterface :: HscEnv -> SDoc -> Name -> IO () |
|---|
| 286 | +forceLoadNameModuleInterface hsc_env reason name = do |
|---|
| 287 | + let name_modules = mapMaybe nameModule_maybe [name] |
|---|
| 288 | + forceLoadModuleInterfaces hsc_env reason name_modules |
|---|
| 289 | + |
|---|
| 290 | +-- | Load the 'TyCon' associated with the given name, come hell or high water. Fails if: |
|---|
| 291 | +-- |
|---|
| 292 | +-- * The interface could not be loaded |
|---|
| 293 | +-- * The name is not that of a 'TyCon' |
|---|
| 294 | +-- * The name did not exist in the loaded module |
|---|
| 295 | +forceLoadTyCon :: HscEnv -> Name -> IO TyCon |
|---|
| 296 | +forceLoadTyCon hsc_env con_name = do |
|---|
| 297 | + forceLoadNameModuleInterface hsc_env (ptext (sLit "contains a name used in an invocation of loadTyConTy")) con_name |
|---|
| 298 | + |
|---|
| 299 | + mb_con_thing <- lookupTypeHscEnv hsc_env con_name |
|---|
| 300 | + case mb_con_thing of |
|---|
| 301 | + Nothing -> throwCmdLineErrorS $ missingTyThingError con_name |
|---|
| 302 | + Just (ATyCon tycon) -> return tycon |
|---|
| 303 | + Just con_thing -> throwCmdLineErrorS $ wrongTyThingError con_name con_thing |
|---|
| 304 | + |
|---|
| 305 | +-- | Loads the value corresponding to a 'Name' if that value has the given 'Type'. This only provides limited safety |
|---|
| 306 | +-- in that it is up to the user to ensure that that type corresponds to the type you try to use the return value at! |
|---|
| 307 | +-- |
|---|
| 308 | +-- If the value found was not of the correct type, returns @Nothing@. Any other condition results in an exception: |
|---|
| 309 | +-- |
|---|
| 310 | +-- * If we could not load the names module |
|---|
| 311 | +-- * If the thing being loaded is not a value |
|---|
| 312 | +-- * If the Name does not exist in the module |
|---|
| 313 | +-- * If the link failed |
|---|
| 314 | + |
|---|
| 315 | +getValueSafely :: HscEnv -> Name -> Type -> IO (Maybe a) |
|---|
| 316 | +getValueSafely hsc_env val_name expected_type = do |
|---|
| 317 | + forceLoadNameModuleInterface hsc_env (ptext (sLit "contains a name used in an invocation of getValueSafely")) val_name |
|---|
| 318 | + |
|---|
| 319 | + -- Now look up the names for the value and type constructor in the type environment |
|---|
| 320 | + mb_val_thing <- lookupTypeHscEnv hsc_env val_name |
|---|
| 321 | + case mb_val_thing of |
|---|
| 322 | + Nothing -> throwCmdLineErrorS $ missingTyThingError val_name |
|---|
| 323 | + Just (AnId id) -> do |
|---|
| 324 | + -- Check the value type in the interface against the type recovered from the type constructor |
|---|
| 325 | + -- before finally casting the value to the type we assume corresponds to that constructor |
|---|
| 326 | + if expected_type `coreEqType` idType id |
|---|
| 327 | + then do |
|---|
| 328 | + -- Link in the module that contains the value, if it has such a module |
|---|
| 329 | + case nameModule_maybe val_name of |
|---|
| 330 | + Just mod -> do linkModule hsc_env mod |
|---|
| 331 | + return () |
|---|
| 332 | + Nothing -> return () |
|---|
| 333 | + -- Find the value that we just linked in and cast it given that we have proved it's type |
|---|
| 334 | + hval <- getHValue hsc_env val_name |
|---|
| 335 | + value <- lessUnsafeCoerce (hsc_dflags hsc_env) "getValueSafely" hval |
|---|
| 336 | + return $ Just value |
|---|
| 337 | + else return Nothing |
|---|
| 338 | + Just val_thing -> throwCmdLineErrorS $ wrongTyThingError val_name val_thing |
|---|
| 339 | + |
|---|
| 340 | +-- | Finds the 'Name' corresponding to the given 'RdrName' in the context of the 'ModuleName'. Returns @Nothing@ if no |
|---|
| 341 | +-- such 'Name' could be found. Any other condition results in an exception: |
|---|
| 342 | +-- |
|---|
| 343 | +-- * If the module could not be found |
|---|
| 344 | +-- * If we could not determine the imports of the module |
|---|
| 345 | +lookupRdrNameInModule :: HscEnv -> ModuleName -> RdrName -> IO (Maybe Name) |
|---|
| 346 | +lookupRdrNameInModule hsc_env mod_name rdr_name = do |
|---|
| 347 | + -- First find the package the module resides in by searching exposed packages and home modules |
|---|
| 348 | + found_module <- findImportedModule hsc_env mod_name Nothing |
|---|
| 349 | + case found_module of |
|---|
| 350 | + Found _ mod -> do |
|---|
| 351 | + -- Find the exports of the module |
|---|
| 352 | + (_, mb_avail_info) <- getModuleExports hsc_env mod |
|---|
| 353 | + case mb_avail_info of |
|---|
| 354 | + Just avail_info -> do |
|---|
| 355 | + -- Try and find the required name in the exports |
|---|
| 356 | + let decl_spec = ImpDeclSpec { is_mod = mod_name, is_as = mod_name, is_qual = False, is_dloc = noSrcSpan } |
|---|
| 357 | + provenance = Imported [ImpSpec decl_spec ImpAll] |
|---|
| 358 | + env = mkGlobalRdrEnv (gresFromAvails provenance avail_info) |
|---|
| 359 | + case [name | gre <- lookupGRE_RdrName rdr_name env, let name = gre_name gre, rdrNameSpace rdr_name == occNameSpace (nameOccName name)] of |
|---|
| 360 | + [name] -> return (Just name) |
|---|
| 361 | + [] -> return Nothing |
|---|
| 362 | + _ -> panic "lookupRdrNameInModule" |
|---|
| 363 | + Nothing -> throwCmdLineErrorS $ hsep [ptext (sLit "Could not determine the exports of the module"), ppr mod_name] |
|---|
| 364 | + err -> throwCmdLineErrorS $ cannotFindModule dflags mod_name err |
|---|
| 365 | + where |
|---|
| 366 | + dflags = hsc_dflags hsc_env |
|---|
| 367 | + |
|---|
| 368 | + |
|---|
| 369 | +wrongTyThingError :: Name -> TyThing -> SDoc |
|---|
| 370 | +wrongTyThingError name got_thing = hsep [ptext (sLit "The name"), ppr name, ptext (sLit "is not that of a value but rather a"), pprTyThingCategory got_thing] |
|---|
| 371 | + |
|---|
| 372 | +missingTyThingError :: Name -> SDoc |
|---|
| 373 | +missingTyThingError name = hsep [ptext (sLit "The name"), ppr name, ptext (sLit "is not in the type environment: are you sure it exists?")] |
|---|
| 374 | + |
|---|
| 375 | +throwCmdLineErrorS :: SDoc -> IO a |
|---|
| 376 | +throwCmdLineErrorS = throwCmdLineError . showSDoc |
|---|
| 377 | + |
|---|
| 378 | +throwCmdLineError :: String -> IO a |
|---|
| 379 | +throwCmdLineError = throwGhcException . CmdLineError |
|---|
| 380 | +#endif |
|---|
| 381 | addfile ./compiler/main/GHCPlugins.hs |
|---|
| 382 | hunk ./compiler/main/GHCPlugins.hs 1 |
|---|
| 383 | +{-# OPTIONS_GHC -fno-warn-duplicate-exports #-} |
|---|
| 384 | + |
|---|
| 385 | +-- | Re-exports all of the functions and types you are likely to need when |
|---|
| 386 | +-- writing a plugin for GHC. Particularly interesting modules for plugin writers |
|---|
| 387 | +-- include "Plugins", "CoreSyn" and "CoreMonad". |
|---|
| 388 | +module GHCPlugins( |
|---|
| 389 | +#ifdef GHCI |
|---|
| 390 | + -- This must be under #ifdef GHCI since it exports nothing when GHCI is disabled and hence generates a warning |
|---|
| 391 | + module Plugins, |
|---|
| 392 | +#endif |
|---|
| 393 | + module CoreMonad, |
|---|
| 394 | + module RdrName, module OccName, module Name, module Var, module Id, module IdInfo, |
|---|
| 395 | + module CoreSyn, module Literal, module DataCon, module CoreUtils, module MkCore, module CoreFVs, module CoreSubst, |
|---|
| 396 | + module Rules, module Annotations, |
|---|
| 397 | + module DynFlags, module Packages, |
|---|
| 398 | + module Module, module Type, module TyCon, module Coercion, module TysWiredIn, module HscTypes, module BasicTypes, |
|---|
| 399 | + module VarSet, module VarEnv, module NameSet, module NameEnv, module UniqSet, module UniqFM, module FiniteMap, |
|---|
| 400 | + module Util, module Serialized, module SrcLoc, module Outputable, module UniqSupply, module Unique, module FastString, module FastTypes |
|---|
| 401 | + ) where |
|---|
| 402 | + |
|---|
| 403 | +-- Plugin stuff itself |
|---|
| 404 | +#ifdef GHCI |
|---|
| 405 | +-- As with the export |
|---|
| 406 | +import Plugins |
|---|
| 407 | +#endif |
|---|
| 408 | +import CoreMonad |
|---|
| 409 | + |
|---|
| 410 | +-- Variable naming |
|---|
| 411 | +import RdrName |
|---|
| 412 | +import OccName hiding ( varName {- conflicts with Var.varName -} ) |
|---|
| 413 | +import Name hiding ( varName {- reexport from OccName, conflicts with Var.varName -} ) |
|---|
| 414 | +import Var |
|---|
| 415 | +import Id hiding ( lazySetIdInfo, setIdExported, setIdNotExported {- all three conflict with Var -} ) |
|---|
| 416 | +import IdInfo |
|---|
| 417 | + |
|---|
| 418 | +-- Core |
|---|
| 419 | +import CoreSyn |
|---|
| 420 | +import Literal |
|---|
| 421 | +import DataCon |
|---|
| 422 | +import CoreUtils |
|---|
| 423 | +import MkCore |
|---|
| 424 | +import CoreFVs |
|---|
| 425 | +import CoreSubst |
|---|
| 426 | + |
|---|
| 427 | +-- Core "extras" |
|---|
| 428 | +import Rules |
|---|
| 429 | +import Annotations |
|---|
| 430 | + |
|---|
| 431 | +-- Pipeline-related stuff |
|---|
| 432 | +import DynFlags |
|---|
| 433 | +import Packages |
|---|
| 434 | + |
|---|
| 435 | +-- Important GHC types |
|---|
| 436 | +import Module |
|---|
| 437 | +import Type hiding ( substTy, extendTvSubst, extendTvSubstList, isInScope {- conflict with CoreSubst -} ) |
|---|
| 438 | +import TyCon |
|---|
| 439 | +import Coercion |
|---|
| 440 | +import TysWiredIn |
|---|
| 441 | +import HscTypes |
|---|
| 442 | +import BasicTypes hiding ( Version {- conflicts with Packages.Version -} ) |
|---|
| 443 | + |
|---|
| 444 | +-- Collections and maps |
|---|
| 445 | +import VarSet |
|---|
| 446 | +import VarEnv |
|---|
| 447 | +import NameSet |
|---|
| 448 | +import NameEnv |
|---|
| 449 | +import UniqSet |
|---|
| 450 | +import UniqFM |
|---|
| 451 | +-- Conflicts with UniqFM: |
|---|
| 452 | +--import LazyUniqFM |
|---|
| 453 | +import FiniteMap |
|---|
| 454 | + |
|---|
| 455 | +-- Common utilities |
|---|
| 456 | +import Util |
|---|
| 457 | +import Serialized |
|---|
| 458 | +import SrcLoc |
|---|
| 459 | +import Outputable |
|---|
| 460 | +import UniqSupply |
|---|
| 461 | +import Unique ( Unique, Uniquable(..) ) |
|---|
| 462 | +import FastString |
|---|
| 463 | +import FastTypes |
|---|
| 464 | addfile ./compiler/main/LoadPlugins.lhs |
|---|
| 465 | hunk ./compiler/main/LoadPlugins.lhs 1 |
|---|
| 466 | +% |
|---|
| 467 | +% (c) The GRASP/AQUA Project, Glasgow University, 1993-2008 |
|---|
| 468 | +% |
|---|
| 469 | +\begin{code} |
|---|
| 470 | + |
|---|
| 471 | +-- | Code relating purely to the administration of plugins, i.e. no code that would actually |
|---|
| 472 | +-- be useful to plugins! |
|---|
| 473 | +module LoadPlugins ( |
|---|
| 474 | +#ifdef GHCI |
|---|
| 475 | + loadPlugins |
|---|
| 476 | +#endif |
|---|
| 477 | + ) where |
|---|
| 478 | + |
|---|
| 479 | +#ifdef GHCI |
|---|
| 480 | +import DynamicLoading |
|---|
| 481 | + |
|---|
| 482 | +import OccName ( mkVarOcc ) |
|---|
| 483 | +import RdrName ( mkRdrQual ) |
|---|
| 484 | + |
|---|
| 485 | +import DynFlags ( DynFlags, pluginModNames ) |
|---|
| 486 | +import HscTypes ( HscEnv(..) ) |
|---|
| 487 | +import Type ( mkTyConTy ) |
|---|
| 488 | +import PrelNames ( pluginTyConName ) |
|---|
| 489 | +import Module ( ModuleName ) |
|---|
| 490 | +import Panic ( GhcException(..), throwGhcException ) |
|---|
| 491 | +import FastString |
|---|
| 492 | +import Outputable |
|---|
| 493 | + |
|---|
| 494 | +import Plugins |
|---|
| 495 | +\end{code} |
|---|
| 496 | + |
|---|
| 497 | +\begin{code} |
|---|
| 498 | +loadPlugins :: HscEnv -> IO [(ModuleName, Plugin)] |
|---|
| 499 | +loadPlugins hsc_env = do |
|---|
| 500 | + let to_load = pluginModNames dflags |
|---|
| 501 | + plugins <- mapM (loadPlugin hsc_env) to_load |
|---|
| 502 | + return $ to_load `zip` plugins |
|---|
| 503 | + where dflags = hsc_dflags hsc_env |
|---|
| 504 | + |
|---|
| 505 | +loadPlugin :: HscEnv -> ModuleName -> IO Plugin |
|---|
| 506 | +loadPlugin hsc_env mod_name = do |
|---|
| 507 | + mb_name <- lookupRdrNameInModule hsc_env mod_name plugin_rdr_name |
|---|
| 508 | + case mb_name of |
|---|
| 509 | + Nothing -> throwGhcException (CmdLineError $ showSDoc $ hsep [ |
|---|
| 510 | + ptext (sLit "The module"), ppr mod_name |
|---|
| 511 | + , ptext (sLit "did not export the plugin name"), ppr plugin_rdr_name |
|---|
| 512 | + ]) |
|---|
| 513 | + Just name -> do |
|---|
| 514 | + plugin_tycon <- forceLoadTyCon hsc_env pluginTyConName |
|---|
| 515 | + mb_plugin <- getValueSafely hsc_env name (mkTyConTy plugin_tycon) |
|---|
| 516 | + case mb_plugin of |
|---|
| 517 | + Nothing -> throwGhcException (CmdLineError $ showSDoc $ hsep [ |
|---|
| 518 | + ptext (sLit "The value"), ppr name, ptext (sLit "did not have the type") |
|---|
| 519 | + , ppr pluginTyConName, ptext (sLit "as required")]) |
|---|
| 520 | + Just plugin -> return plugin |
|---|
| 521 | + where plugin_rdr_name = mkRdrQual mod_name (mkVarOcc "plugin") |
|---|
| 522 | + |
|---|
| 523 | +#endif |
|---|
| 524 | +\end{code} |
|---|
| 525 | addfile ./compiler/main/Plugins.lhs |
|---|
| 526 | hunk ./compiler/main/Plugins.lhs 1 |
|---|
| 527 | +% |
|---|
| 528 | +% (c) The GRASP/AQUA Project, Glasgow University, 1993-2008 |
|---|
| 529 | +% |
|---|
| 530 | + |
|---|
| 531 | +\section[Plugins]{Plugins for GHC} |
|---|
| 532 | +\begin{code} |
|---|
| 533 | + |
|---|
| 534 | +-- | Contains code and definitions that are used by both the compiler and the plugins themselves. All the |
|---|
| 535 | +-- functions likely to be useful for plugins are exported from 'GHCPlugins'. |
|---|
| 536 | +module Plugins ( |
|---|
| 537 | +#ifdef GHCI |
|---|
| 538 | + -- * Plugin data types |
|---|
| 539 | + Plugin(..), CommandLineOption, defaultPlugin, |
|---|
| 540 | + PluginPass(..), |
|---|
| 541 | +#endif |
|---|
| 542 | + ) where |
|---|
| 543 | + |
|---|
| 544 | +#ifdef GHCI |
|---|
| 545 | +import HscTypes |
|---|
| 546 | +import CoreSyn ( CoreBind ) |
|---|
| 547 | +import CoreMonad |
|---|
| 548 | +\end{code} |
|---|
| 549 | + |
|---|
| 550 | +\subsection{Essential data type} |
|---|
| 551 | + |
|---|
| 552 | +\begin{code} |
|---|
| 553 | +-- | The kinds of core pass a plugin can install |
|---|
| 554 | +data PluginPass = BindsToBindsPluginPass ([CoreBind] -> CoreM [CoreBind]) -- ^ Simple pass just mutating the Core bindings |
|---|
| 555 | + | ModGutsToBindsPluginPass (ModGuts -> CoreM [CoreBind]) -- ^ Pass that has access to the information from a 'ModGuts' |
|---|
| 556 | + -- from which to generate it's bindings |
|---|
| 557 | + | ModGutsToModGutsPluginPass (ModGuts -> CoreM ModGuts) -- ^ Pass that can change everything about the module being compiled. |
|---|
| 558 | + -- Do not change any field other than 'HscTypes.mg_binds' unless you |
|---|
| 559 | + -- know what you're doing! Plugins using this are unlikely to be stable |
|---|
| 560 | + -- between GHC versions |
|---|
| 561 | + |
|---|
| 562 | +-- | Command line options gathered from the -PModule.Name:stuff syntax are given to you as this type |
|---|
| 563 | +type CommandLineOption = String |
|---|
| 564 | + |
|---|
| 565 | +-- | Core compiler plugin data type. Try to avoid constructing one of these |
|---|
| 566 | +-- directly, and just modify some fields of 'defaultPlugin' instead: this |
|---|
| 567 | +-- is to try and preserve source-code compatability when we add fields to this. |
|---|
| 568 | +-- |
|---|
| 569 | +-- Nonetheless, this API is preliminary and highly likely to change in the future. |
|---|
| 570 | +data Plugin = Plugin { |
|---|
| 571 | + installCoreToDos :: [CommandLineOption] -> [CoreToDo] -> CoreM [CoreToDo] |
|---|
| 572 | + -- ^ Modify the Core pipeline that will be used for compilation. This is called as the Core pipeline is built for every module being compiled, |
|---|
| 573 | + -- and plugins get the opportunity to modify the pipeline in a nondeterministic order. |
|---|
| 574 | +} |
|---|
| 575 | + |
|---|
| 576 | +-- | Default plugin: does nothing at all! For compatability reasons you should base all your |
|---|
| 577 | +-- plugin definitions on this default value. |
|---|
| 578 | +defaultPlugin :: Plugin |
|---|
| 579 | +defaultPlugin = Plugin { |
|---|
| 580 | + installCoreToDos = const return |
|---|
| 581 | +} |
|---|
| 582 | +#endif |
|---|
| 583 | +\end{code} |
|---|
| 584 | addfile ./compiler/main/Plugins.lhs-boot |
|---|
| 585 | hunk ./compiler/main/Plugins.lhs-boot 1 |
|---|
| 586 | +\begin{code} |
|---|
| 587 | +module Plugins where |
|---|
| 588 | + |
|---|
| 589 | +data Plugin |
|---|
| 590 | +data PluginPass |
|---|
| 591 | +\end{code} |
|---|
| 592 | hunk ./compiler/prelude/PrelNames.lhs 220 |
|---|
| 593 | -- The Either type |
|---|
| 594 | , eitherTyConName, leftDataConName, rightDataConName |
|---|
| 595 | |
|---|
| 596 | + -- Plugins |
|---|
| 597 | + , pluginTyConName |
|---|
| 598 | + |
|---|
| 599 | -- dotnet interop |
|---|
| 600 | , objectTyConName, marshalObjectName, unmarshalObjectName |
|---|
| 601 | , marshalStringName, unmarshalStringName, checkDotnetResName |
|---|
| 602 | hunk ./compiler/prelude/PrelNames.lhs 254 |
|---|
| 603 | gHC_ST, gHC_ARR, gHC_STABLE, gHC_ADDR, gHC_PTR, gHC_ERR, gHC_REAL, |
|---|
| 604 | gHC_FLOAT, gHC_TOP_HANDLER, sYSTEM_IO, dYNAMIC, tYPEABLE, gENERICS, |
|---|
| 605 | dOTNET, rEAD_PREC, lEX, gHC_INT, gHC_WORD, mONAD, mONAD_FIX, aRROW, cONTROL_APPLICATIVE, |
|---|
| 606 | - gHC_DESUGAR, rANDOM, gHC_EXTS, cONTROL_EXCEPTION_BASE :: Module |
|---|
| 607 | + gHC_DESUGAR, rANDOM, gHC_EXTS, cONTROL_EXCEPTION_BASE, pLUGINS :: Module |
|---|
| 608 | |
|---|
| 609 | gHC_PRIM = mkPrimModule (fsLit "GHC.Prim") -- Primitive types and values |
|---|
| 610 | gHC_TYPES = mkPrimModule (fsLit "GHC.Types") |
|---|
| 611 | hunk ./compiler/prelude/PrelNames.lhs 309 |
|---|
| 612 | rANDOM = mkBaseModule (fsLit "System.Random") |
|---|
| 613 | gHC_EXTS = mkBaseModule (fsLit "GHC.Exts") |
|---|
| 614 | cONTROL_EXCEPTION_BASE = mkBaseModule (fsLit "Control.Exception.Base") |
|---|
| 615 | +pLUGINS = mkThisGhcModule (fsLit "Plugins") |
|---|
| 616 | |
|---|
| 617 | mAIN, rOOT_MAIN :: Module |
|---|
| 618 | mAIN = mkMainModule_ mAIN_NAME |
|---|
| 619 | hunk ./compiler/prelude/PrelNames.lhs 338 |
|---|
| 620 | mkBaseModule_ :: ModuleName -> Module |
|---|
| 621 | mkBaseModule_ m = mkModule basePackageId m |
|---|
| 622 | |
|---|
| 623 | +mkThisGhcModule :: FastString -> Module |
|---|
| 624 | +mkThisGhcModule m = mkModule thisGhcPackageId (mkModuleNameFS m) |
|---|
| 625 | + |
|---|
| 626 | +mkThisGhcModule_ :: ModuleName -> Module |
|---|
| 627 | +mkThisGhcModule_ m = mkModule thisGhcPackageId m |
|---|
| 628 | + |
|---|
| 629 | mkMainModule :: FastString -> Module |
|---|
| 630 | mkMainModule m = mkModule mainPackageId (mkModuleNameFS m) |
|---|
| 631 | |
|---|
| 632 | hunk ./compiler/prelude/PrelNames.lhs 848 |
|---|
| 633 | marshalStringName = varQual dOTNET (fsLit "marshalString") marshalStringIdKey |
|---|
| 634 | unmarshalStringName = varQual dOTNET (fsLit "unmarshalString") unmarshalStringIdKey |
|---|
| 635 | checkDotnetResName = varQual dOTNET (fsLit "checkResult") checkDotnetResNameIdKey |
|---|
| 636 | + |
|---|
| 637 | +-- plugins |
|---|
| 638 | +pluginTyConName :: Name |
|---|
| 639 | +pluginTyConName = tcQual pLUGINS (fsLit "Plugin") pluginTyConKey |
|---|
| 640 | + |
|---|
| 641 | + |
|---|
| 642 | \end{code} |
|---|
| 643 | |
|---|
| 644 | %************************************************************************ |
|---|
| 645 | hunk ./compiler/prelude/PrelNames.lhs 1082 |
|---|
| 646 | stringTyConKey :: Unique |
|---|
| 647 | stringTyConKey = mkPreludeTyConUnique 134 |
|---|
| 648 | |
|---|
| 649 | +pluginTyConKey :: Unique |
|---|
| 650 | +pluginTyConKey = mkPreludeTyConUnique 135 |
|---|
| 651 | + |
|---|
| 652 | ---------------- Template Haskell ------------------- |
|---|
| 653 | -- USES TyConUniques 100-129 |
|---|
| 654 | ----------------------------------------------------- |
|---|
| 655 | hunk ./compiler/simplCore/CoreMonad.lhs 16 |
|---|
| 656 | FloatOutSwitches(..), |
|---|
| 657 | getCoreToDo, dumpSimplPhase, |
|---|
| 658 | |
|---|
| 659 | + defaultGentleSimplToDo, |
|---|
| 660 | + |
|---|
| 661 | -- * Counting |
|---|
| 662 | SimplCount, doSimplTick, doFreeSimplTick, simplCountN, |
|---|
| 663 | pprSimplCount, plusSimplCount, zeroSimplCount, isZeroSimplCount, Tick(..), |
|---|
| 664 | hunk ./compiler/simplCore/CoreMonad.lhs 99 |
|---|
| 665 | #ifdef GHCI |
|---|
| 666 | import {-# SOURCE #-} TcSplice ( lookupThName_maybe ) |
|---|
| 667 | import qualified Language.Haskell.TH as TH |
|---|
| 668 | + |
|---|
| 669 | +import {-# SOURCE #-} Plugins |
|---|
| 670 | #endif |
|---|
| 671 | \end{code} |
|---|
| 672 | |
|---|
| 673 | hunk ./compiler/simplCore/CoreMonad.lhs 205 |
|---|
| 674 | %************************************************************************ |
|---|
| 675 | |
|---|
| 676 | \begin{code} |
|---|
| 677 | + |
|---|
| 678 | data CoreToDo -- These are diff core-to-core passes, |
|---|
| 679 | -- which may be invoked in any order, |
|---|
| 680 | -- as many times as you like. |
|---|
| 681 | hunk ./compiler/simplCore/CoreMonad.lhs 213 |
|---|
| 682 | = CoreDoSimplify -- The core-to-core simplifier. |
|---|
| 683 | Int -- Max iterations |
|---|
| 684 | SimplifierMode |
|---|
| 685 | - |
|---|
| 686 | +#ifdef GHCI |
|---|
| 687 | + | CoreDoPluginPass String PluginPass |
|---|
| 688 | +#endif |
|---|
| 689 | | CoreDoFloatInwards |
|---|
| 690 | | CoreDoFloatOutwards FloatOutSwitches |
|---|
| 691 | | CoreLiberateCase |
|---|
| 692 | hunk ./compiler/simplCore/CoreMonad.lhs 241 |
|---|
| 693 | |
|---|
| 694 | coreDumpFlag :: CoreToDo -> Maybe DynFlag |
|---|
| 695 | coreDumpFlag (CoreDoSimplify {}) = Just Opt_D_dump_simpl_phases |
|---|
| 696 | +#ifdef GHCI |
|---|
| 697 | +coreDumpFlag (CoreDoPluginPass {}) = Just Opt_D_dump_core_pipeline |
|---|
| 698 | +#endif |
|---|
| 699 | coreDumpFlag CoreDoFloatInwards = Just Opt_D_verbose_core2core |
|---|
| 700 | coreDumpFlag (CoreDoFloatOutwards {}) = Just Opt_D_verbose_core2core |
|---|
| 701 | coreDumpFlag CoreLiberateCase = Just Opt_D_verbose_core2core |
|---|
| 702 | hunk ./compiler/simplCore/CoreMonad.lhs 268 |
|---|
| 703 | ppr (CoreDoSimplify n md) = ptext (sLit "Simplifier") |
|---|
| 704 | <+> ppr md |
|---|
| 705 | <+> ptext (sLit "max-iterations=") <> int n |
|---|
| 706 | +#ifdef GHCI |
|---|
| 707 | + ppr (CoreDoPluginPass desc _) = ptext (sLit "Core plugin: ") <+> ptext (sLit desc) |
|---|
| 708 | +#endif |
|---|
| 709 | ppr CoreDoFloatInwards = ptext (sLit "Float inwards") |
|---|
| 710 | ppr (CoreDoFloatOutwards f) = ptext (sLit "Float out") <> parens (ppr f) |
|---|
| 711 | ppr CoreLiberateCase = ptext (sLit "Liberate case") |
|---|
| 712 | hunk ./compiler/simplCore/CoreMonad.lhs 531 |
|---|
| 713 | simpl_phase 0 ["final"] max_iter |
|---|
| 714 | ] |
|---|
| 715 | |
|---|
| 716 | +-- | A reasonably gentle simplification pass for doing "obvious" simplifications |
|---|
| 717 | +defaultGentleSimplToDo :: CoreToDo |
|---|
| 718 | +defaultGentleSimplToDo = CoreDoSimplify 4 -- 4 is the default maxSimpleIterations |
|---|
| 719 | + (SimplMode { sm_phase = InitialPhase |
|---|
| 720 | + , sm_names = ["Gentle"] |
|---|
| 721 | + , sm_rules = True -- Note [RULEs enabled in SimplGently] |
|---|
| 722 | + , sm_inline = False |
|---|
| 723 | + , sm_eta_expand = False |
|---|
| 724 | + , sm_case_case = False |
|---|
| 725 | + }) |
|---|
| 726 | + |
|---|
| 727 | -- The core-to-core pass ordering is derived from the DynFlags: |
|---|
| 728 | runWhen :: Bool -> CoreToDo -> CoreToDo |
|---|
| 729 | runWhen True do_this = do_this |
|---|
| 730 | hunk ./compiler/simplCore/CoreMonad.lhs 551 |
|---|
| 731 | runMaybe (Just x) f = f x |
|---|
| 732 | runMaybe Nothing _ = CoreDoNothing |
|---|
| 733 | |
|---|
| 734 | + |
|---|
| 735 | dumpSimplPhase :: DynFlags -> SimplifierMode -> Bool |
|---|
| 736 | dumpSimplPhase dflags mode |
|---|
| 737 | | Just spec_string <- shouldDumpSimplPhase dflags |
|---|
| 738 | hunk ./compiler/simplCore/SimplCore.lhs 11 |
|---|
| 739 | |
|---|
| 740 | #include "HsVersions.h" |
|---|
| 741 | |
|---|
| 742 | -import DynFlags ( DynFlags, DynFlag(..), dopt ) |
|---|
| 743 | +import DynFlags ( DynFlags, DynFlag(..), dopt) |
|---|
| 744 | import CoreSyn |
|---|
| 745 | import CoreSubst |
|---|
| 746 | import HscTypes |
|---|
| 747 | hunk ./compiler/simplCore/SimplCore.lhs 48 |
|---|
| 748 | import UniqSupply ( UniqSupply, mkSplitUniqSupply, splitUniqSupply ) |
|---|
| 749 | import Outputable |
|---|
| 750 | import Control.Monad |
|---|
| 751 | + |
|---|
| 752 | +#ifdef GHCI |
|---|
| 753 | +import Plugins |
|---|
| 754 | +import LoadPlugins ( loadPlugins ) |
|---|
| 755 | +#endif |
|---|
| 756 | + |
|---|
| 757 | \end{code} |
|---|
| 758 | |
|---|
| 759 | %************************************************************************ |
|---|
| 760 | hunk ./compiler/simplCore/SimplCore.lhs 66 |
|---|
| 761 | core2core :: HscEnv -> ModGuts -> IO ModGuts |
|---|
| 762 | core2core hsc_env guts |
|---|
| 763 | = do { us <- mkSplitUniqSupply 's' |
|---|
| 764 | - ; (guts2, stats) <- runCoreM hsc_env hpt_rule_base us mod $ |
|---|
| 765 | - doCorePasses (getCoreToDo dflags) guts |
|---|
| 766 | + -- make sure all plugins are loaded |
|---|
| 767 | +#ifdef GHCI |
|---|
| 768 | + ; named_plugins <- loadPlugins hsc_env |
|---|
| 769 | +#endif |
|---|
| 770 | + ; (guts2, stats) <- runCoreM hsc_env hpt_rule_base us mod |
|---|
| 771 | + (do { let builtin_passes = getCoreToDo dflags |
|---|
| 772 | +#ifdef GHCI |
|---|
| 773 | + ; let queryPlugin todos (mod_nm,plug) = installCoreToDos plug options todos |
|---|
| 774 | + where options = [ option | (opt_mod_nm, option) <- pluginModNameOpts dflags |
|---|
| 775 | + , opt_mod_nm == mod_nm ] |
|---|
| 776 | + ; all_passes <- foldM queryPlugin builtin_passes named_plugins |
|---|
| 777 | +#else |
|---|
| 778 | + ; let all_passes = builtin_passes |
|---|
| 779 | +#endif |
|---|
| 780 | + ; doCorePasses all_passes guts }) |
|---|
| 781 | |
|---|
| 782 | hunk ./compiler/simplCore/SimplCore.lhs 82 |
|---|
| 783 | +{-- |
|---|
| 784 | + ; Err.dumpIfSet_dyn dflags Opt_D_dump_core_pipeline |
|---|
| 785 | + "Plugin information" "" -- TODO FIXME: dump plugin info |
|---|
| 786 | +--} |
|---|
| 787 | ; Err.dumpIfSet_dyn dflags Opt_D_dump_simpl_stats |
|---|
| 788 | "Grand total simplifier statistics" |
|---|
| 789 | (pprSimplCount stats) |
|---|
| 790 | hunk ./compiler/simplCore/SimplCore.lhs 157 |
|---|
| 791 | doCorePass (CoreDoRuleCheck phase pat) = ruleCheck phase pat |
|---|
| 792 | doCorePass CoreDoNothing = return |
|---|
| 793 | doCorePass (CoreDoPasses passes) = doCorePasses passes |
|---|
| 794 | +#ifdef GHCI |
|---|
| 795 | +doCorePass (CoreDoPluginPass _ pass) = {-# SCC "Plugin" #-} |
|---|
| 796 | + doPluginPass pass |
|---|
| 797 | + where doPluginPass (BindsToBindsPluginPass p) = doPassM p |
|---|
| 798 | + doPluginPass (ModGutsToBindsPluginPass p) = doPassMG p |
|---|
| 799 | + doPluginPass (ModGutsToModGutsPluginPass p) = p |
|---|
| 800 | +#endif |
|---|
| 801 | doCorePass pass = pprPanic "doCorePass" (ppr pass) |
|---|
| 802 | hunk ./compiler/simplCore/SimplCore.lhs 165 |
|---|
| 803 | + |
|---|
| 804 | \end{code} |
|---|
| 805 | |
|---|
| 806 | %************************************************************************ |
|---|
| 807 | hunk ./compiler/simplCore/SimplCore.lhs 212 |
|---|
| 808 | binds' <- bind_f (mg_binds guts) |
|---|
| 809 | return (guts { mg_binds = binds' }) |
|---|
| 810 | |
|---|
| 811 | +#ifdef GHCI |
|---|
| 812 | +-- Only used by ModGutsToBindsPluginPass - it seems it was removed from when |
|---|
| 813 | +-- max originally wrote this patch. Do we still need/want this? |
|---|
| 814 | +doPassMG :: Monad m => (ModGuts -> m [CoreBind]) -> ModGuts -> m ModGuts |
|---|
| 815 | +doPassMG bind_f guts = do |
|---|
| 816 | + binds' <- bind_f guts |
|---|
| 817 | + return (guts { mg_binds = binds' }) |
|---|
| 818 | +#endif |
|---|
| 819 | + |
|---|
| 820 | doPass :: ([CoreBind] -> [CoreBind]) -> ModGuts -> CoreM ModGuts |
|---|
| 821 | doPass bind_f guts = return $ guts { mg_binds = bind_f (mg_binds guts) } |
|---|
| 822 | |
|---|
| 823 | } |
|---|
| 824 | |
|---|
| 825 | Context: |
|---|
| 826 | |
|---|
| 827 | [ForceSpecConstr now forces specialisation even for arguments which aren't scrutinised |
|---|
| 828 | Roman Leshchinskiy <rl@cse.unsw.edu.au>**20101118212839 |
|---|
| 829 | Ignore-this: db45721d29a694e53746f8b76513efa4 |
|---|
| 830 | ] |
|---|
| 831 | [Move the superclass generation to the canonicaliser |
|---|
| 832 | simonpj@microsoft.com**20101118120533 |
|---|
| 833 | Ignore-this: 5e0e525402a240b709f2b8104c1682b2 |
|---|
| 834 | |
|---|
| 835 | Doing superclass generation in the canonicaliser (rather than |
|---|
| 836 | TcInteract) uses less code, and is generally more efficient. |
|---|
| 837 | |
|---|
| 838 | See Note [Adding superclasses] in TcCanonical. |
|---|
| 839 | |
|---|
| 840 | Fixes Trac #4497. |
|---|
| 841 | ] |
|---|
| 842 | [Fix the generation of in-scope variables for IfaceLint check |
|---|
| 843 | simonpj@microsoft.com**20101118090057 |
|---|
| 844 | Ignore-this: bbcdba61ddf89d07fe69ca99c2017e3f |
|---|
| 845 | ] |
|---|
| 846 | [Comments only |
|---|
| 847 | simonpj@microsoft.com**20101118090034 |
|---|
| 848 | Ignore-this: fa2936d35a0f7be4e4535ea9e2b7bf7b |
|---|
| 849 | ] |
|---|
| 850 | [Omit bogus test for -XDeriveFunctor |
|---|
| 851 | simonpj@microsoft.com**20101118090028 |
|---|
| 852 | Ignore-this: a534243011809ebbb788b910961601c5 |
|---|
| 853 | |
|---|
| 854 | It was duplicated in the case of 'deriving( Functor )' |
|---|
| 855 | and wrong for 'deriving( Foldable )' |
|---|
| 856 | ] |
|---|
| 857 | [Improve error message on advice from a user |
|---|
| 858 | simonpj@microsoft.com**20101118085306 |
|---|
| 859 | Ignore-this: bd4f3858ff24e602e985288f27d536f3 |
|---|
| 860 | |
|---|
| 861 | See Trac #4499 |
|---|
| 862 | ] |
|---|
| 863 | [TAG 2010-11-18 |
|---|
| 864 | Ian Lynagh <igloo@earth.li>**20101118011554 |
|---|
| 865 | Ignore-this: ccadbe7fadd1148d2ee3caa8c8821ec5 |
|---|
| 866 | ] |
|---|
| 867 | Patch bundle hash: |
|---|
| 868 | 950bfeef80b9b436d180190850c507c846b6b876 |
|---|