Changes between Version 3 and Version 4 of Plugins


Ignore:
Timestamp:
Mar 20, 2008 7:45:40 PM (7 years ago)
Author:
guest
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Plugins

    v3 v4  
    1717module Main where
    1818
    19 {-# PLUGIN nVidiaGPU NVidiaGPUSettings { useTextureMemoryMb = 256 } #-}
     19{-# PLUGIN NVidia.GHC.GPU NVidiaGPUSettings { useTextureMemoryMb = 256 } #-}
    2020
    21 {-# PLUGIN nVidiaGPU doSomethingExpensive NVidiaGPUFunctionSettings { maxStackDepth = 1024 } #-}
     21{-# PLUGIN NVidia.GHC.GPU doSomethingExpensive NVidiaGPUFunctionSettings { maxStackDepth = 1024 } #-}
    2222doSomethingExpensive :: Int -> ImpressiveResult
    2323doSomethingExpensive = ....
     
    2727}}}
    2828
    29 That is, they can include two types of pragmas. Ambient configuration ones:
     29That is, they can include two types of pragmas. Ambient configuration ones analagous to GHC_OPTIONS:
    3030
    3131{{{
     
    3333}}}
    3434
    35 And binder-specific ones:
     35And binder-specific ones analagous to INLINE:
    3636
    3737{{{
     
    4949The plugin writer would provide:
    5050 * Loadable library that contains their plugin code: this would be placed in a magic GHC subdirectory, referenced somehow in package.conf or something. It would probably be best if we had plugins distributed as source and cabal-built / installed via the usual package mechanism so that they can deal with many architectures / GHC versions.
    51  * ''Optionally'', a separate library / component of their plugin library which contains the definitions for the data types they are going to want to use in their pragmas, such as NVidiaGPUSettings.
     51 * ''Optionally'', a component of their plugin library which contains the definitions for the data types they are going to want to use in their pragmas, such as NVidiaGPUSettings.
    5252
    5353We should provide at least the following hooks to the plugin library:
    5454 * Initial configuration: this is when it gets fed the modules ambient PLUGIN pragma information
    5555 * Ability to install extra core passes (their library would be fed the core syntax tree either as [wiki:ExternalCore] or as GHCs core data type (via the GHC-as-a-library stuff))
    56  * Ability to add notify GHC about extra things to link in (e.g. GPU code compilation artifacts). This does not necessarily play well with separate compilation: would have to do something like add info to .hi so the eventual linking stage can find out about any extra artifacts that might be required
     56 * Ability to add notify GHC about extra things to link in (e.g. GPU code compilation artifacts). This does not necessarily play well with separate compilation: would have to do something like add info to .hi so the eventual linking stage can find out about any extra artifacts that might be required. This actually causes problems right now when you e.g. compile a module that uses FFI separately: GHC will need to be fed an appropriate linker command line along with the .o file names rather than inferring it from the .hi files
    5757 * Any more you can think of....
     58
     59SPJ believes that external core would not protect against versioning in GHCs core representation as it will change with core itself and so we should use core directly for simplicity. This also allows reuse of GHCs substantial internal utility library for manipulating core representations by the plugin authors.
     60
     61Concretely, the plugin writer would implement an interface that looked something like this:
     62
     63{{{
     64
     65-- The pragma supplied options must be of type dynamic because they are instantiated by GHC. The plugin author
     66-- will want to check that the data the user supplied is something they are prepared to accept as a pragma
     67-- Command line options will be supplied as a simple string list of those things supplied to GHC with a -p prefix
     68-- Note that this design means that the type of command line plugin option are limited to:
     69--  * -pfoo
     70--  * -pfoo-arg (NOT -pfoo arg)
     71--  * -pfoo=n
     72--  * -pfoo;
     73-- Furthermore we cannot warn about unrecognized -p args unless we have plugins report back unrecognized args. Reporting the error at that
     74-- late stage will also be problematic, so we probably shouldn't bother.
     75-- We should provide a library that is able to parse these for plugin writers so they don't reinvent the wheel (maybe just using
     76-- GHCs CmdLineParser)
     77-- An alternative design for functionPragmaOptions would be to attach the pragma data structures to Notes in the Core syntax tree.
     78-- However, SPJ feels that would interact too much with other compiler stages, that have a habit of moving Notes around..
     79newtype PluginOptions = PluginOptions { ambientPragmaOptions :: [Dynamic], functionPragmaOptions :: Map Id [Dynamic], commandLineOptions :: [String] }
     80initialize :: PluginOptions -> IO GHCPluginInstance
     81             
     82data GHCPluginInstance = GHCPluginInstance {
     83  -- We could either have them change the pipeline explicitly, by providing a CoreDoPluginPass constructor in CoreToDo:
     84  installCorePasses :: [CoreToDo] -> [CoreToDo]
     85  -- Or (possibly less fragile and operational, but more complicated) just something like:
     86  providedCorePasses :: [(CorePassPlacementSpec, PluginCorePassName, PluginCorePass)]
     87  -- For details see note [Declarative Core Pass Placement]
     88
     89  -- TODO: work out the best way to allow plugins to specify link artifacts
     90}
     91
     92
     93type PluginCorePass = DynFlags -> UniqSupply -> [CoreBind] -> IO [CoreBind]
     94
     95-- Note: [Declarative Core Pass Placement]
     96-- If we went the declarative route for core pass placement we would have something like this:
     97type CorePassPlacementSpec = [CorePassPlacement]
     98data CorePassPlacement
     99  = CertainlyBefore CorePassName
     100  | CertainlyAfter CorePassName
     101  | IdeallyBefore CorePassName
     102  | IdeallyAfter CorePassName
     103  | InPhase Int -- Phase 0, 1 or 2 as they currently exist in GHC
     104  | WhenOptimizationLevelAtLeast Int -- Level 0, 1 or 2 as they currently exist in GHC
     105
     106type CorePassName = String
     107type PluginCorePassName = CorePassName
     108-- Alternatively we could expose a CoreToDo style of thing as the core
     109-- pass names, e.g:
     110type PluginCorePassName = String
     111data CorePassName
     112  = SimplifyCorePass
     113  | FloatInwardsCorePass
     114  | CSECorePass
     115  | ...
     116  | PluginCorePass PluginCorePassName
     117  deriving (Eq)             
     118-- This would let us recover some compile time safety while still allowing plugins to refer
     119-- to passes installed by other plugins, which may be desirable.
     120-- End Note: [Declarative Core Pass Placement]
     121
     122
     123--
     124
     125}}}
     126
     127Alternative design that would let the plugin authors reuse GHCs parsing infrastructure and also let us warn about unrecognized command line flags in command line parsing as usual:
     128
     129{{{
     130-- The actions encapsulated within the OptKind will be run by
     131-- the GHC command line parser: you can use the action to accumulate flags that will
     132-- be output by the runCommandLineM thing and eventually fed back to the initialize function
     133runCommandLineM :: CommandLineM a -> (a, CommandLineOptions)
     134dynamicFlags :: [(String, OptKind CommandLineM)]
     135
     136-- These will be defined by the particular plugin author: clearly this makes it hard for GHC to
     137-- type check the plugin, but we'll ignore the type safety of dynamic linking here!
     138newtype CommandLineM = ...
     139newtype CommandLineOptions = ...
     140}}}
    58141
    59142=== GHC Stuff ===
    60143
    61144The compiler needs to bring the plugin writer and users contributions together. A possible game plan might be:
     145 0. Check for plugins referenced on the command line and give them a chance to parse command
    62146 1. Suck in Haskell source as normal, but also parsing PLUGIN pragmas
    63147 2. Load up any plugins we see referenced by PLUGIN pragmas, discarding those we don't know about (on the basis that PRAGMAS are meant to be extra information that isn't essential to compile the program, though we might want to at least warn if we can't find one!). This could happen via [http://www.cse.unsw.edu.au/~dons/hs-plugins/ hs-plugins].