[llvm-commits] [llvm] r131581 - in /llvm/trunk: include/llvm/DefaultPasses.h include/llvm/Support/StandardPasses.h lib/Support/StandardPasses.cpp

David Chisnall csdavec at swan.ac.uk
Sun May 22 03:21:36 PDT 2011


On 22 May 2011, at 10:08, Nick Lewycky wrote:

> On 05/22/2011 01:40 AM, David Chisnall wrote:
>> On 22 May 2011, at 00:13, Chris Lattner wrote:
>> 
>>>> My point was that there should be no tight coupling between the front ends and the optimisations at all, because then you need one plugin for every front end that might use the passes, which adds silly amounts of complexity.
>>> 
>>> I don't understand what you mean here.  Plugins are inherently tied to the frontend they are plugging into, and I don't see how that is related to tight coupling between frontends and optimizations.
>> 
>> LLVM plugins do not plug in to front ends, they plug in to LLVM.  A pass defined in a plugin has no awareness of any specific front ends - it just transforms IR.  Currently we have to load them explicitly, but the next thing on my LLVM TODO list is providing a mechanism for LLVM to automatically load plugins.  The goal is to be able to just install a new plugin via your normal package manager and have installed LLVM-based compilers automatically take advantage of it.
> 
> The frontend is still responsible for loading the plugin. Is there any reason we can't define an API for plugins that we look for and have the frontend pass the plugin PMBuilder object to manipulate? It means that supporting plugins that modify code generation becomes opt-in for the llvm-using program, but it we do that once per frontend and don't need to worry about dealing with every possible frontend-plugin combination.
> 
> Making it opt-in would be much preferred, actually.

The more I think about this, the more I come to the conclusion that the correct solution is to properly define the plugin interface.  Currently, we basically just dlopen() a plugin and expect static constructors in the plugin to do everything.  This makes means that all interaction works with code flow from the plugin to the main program, which is a bit counter intuitive.

I wonder if the correct solution is to define an llvm::PluginRegistry or similar.  This can collect plugins, loaded both from command-line options and from a config file, and provide a unified entry point for invoking plugins.  We then construct the PluginRegistry in the tools, and (optionally) pass a reference of it to the PassManagerBuilder, and to anything else that wants to provide hooks for plugins.  

I'd imagine using it something like this.  In the plugin:

class MyPlugin : public PassManagerBuilderPlugin {
	public virtual addPasses(ExtensionPointTy Ty, PassManagerBase &PM);
}
...
static RegisterPlugin<MyPlugin> X;

In the tool:

// Gives a lazily-allocated singleton instance.  Alternatively, the tool can explicitly create it.
llvm::PluginRegistry* PR = llvm::PluginRegistry::SharedPluginRegistry();
PBM.populateFunctionPassManager(FPM, PR);

In the PassManagerBuilder:

SmallVector< PassManagerBuilderPlugin, 8> Plugins;
if (PR) {
	PR->collectPlugins<PassManagerBuilderPlugin>(Plugins);
}
// call ->addPasses on all of the returned plugins

This same interface can then be used for other plugin hooks, so clang might export a ClangPragmaParserPlugin interface, for example.

Does this sound sensible?  If so, then I'll make a start on implementing it.  

David



More information about the llvm-commits mailing list