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].