This is an archive of the discontinued LLVM Phabricator instance.

[PM] Enable registration of out-of-tree or plugin passes
AbandonedPublic

Authored by philip.pfaffe on Jul 8 2015, 2:38 AM.

Details

Reviewers
chandlerc
Summary

The PassBuilder used for creating pass pipelines for the new pass manager currently doesn't support out-of-tree passes or passes in plugins. This patch adds a mechanism for registering such passes, enabling them inside the PassBuilder.

Registration is done by installing Hooks, managed in a name -> hook map. Such a hook is a callable which, when invoked, gets passed an AnalysisManager or PassManager instance which the external pass can insert itself into. When parsing a pass pipeline, PassBuilder will first consult the list of installed hooks before it looks at the builtin passes. This way, external passes are able to steal the name of a builtin pass.

The HookManager, which manages the name->hook mapping, offers interfaces for registering, querying and invoking installed hooks. I maintain three global instances of it (one for each IRUnit type), accessible through a getGlobalHookManager() function. Moreover, the patch contains convenience types which abbreviate the default way to register passes a bit.

Unittest attached.

Diff Detail

Event Timeline

philip.pfaffe retitled this revision from to [PM] Enable registration of out-of-tree or plugin passes .
philip.pfaffe updated this object.
philip.pfaffe added a reviewer: chandlerc.
philip.pfaffe set the repository for this revision to rL LLVM.
philip.pfaffe added a subscriber: llvm-commits.
hfinkel added a subscriber: hfinkel.Jul 9 2015, 8:02 PM

PassBuilder will first consult the list of installed hooks before it looks at the builtin passes. This way, external passes are able to steal the name of a builtin pass.

Does the original pass still run? Why not give the hook the ability to insert a new pass somewhere into the pipeline (perhaps by being able to examine the current pipeline configuration and modifying it)?

Does the original pass still run?

Not in this case, no. That way, you can actively override a built-in pass.

Why not give the hook the ability to insert a new pass somewhere into the pipeline (perhaps by being able to examine the current pipeline configuration and modifying it)?

I think that would mix different responsibilities. It is the PassBuilder's task to construct the pipeline from its textual description, and I as a user would expect the pipeline to afterwards consist of precisely the passes I specified, and in that order. I think a pass should not be able to take this away from the PassBuilder and modify the pipeline setup externally (of course besides adding itself to the PassManager on request).

Does the original pass still run?

Not in this case, no. That way, you can actively override a built-in pass.

Why not give the hook the ability to insert a new pass somewhere into the pipeline (perhaps by being able to examine the current pipeline configuration and modifying it)?

I think that would mix different responsibilities. It is the PassBuilder's task to construct the pipeline from its textual description, and I as a user would expect the pipeline to afterwards consist of precisely the passes I specified, and in that order. I think a pass should not be able to take this away from the PassBuilder and modify the pipeline setup externally (of course besides adding itself to the PassManager on request).

I don't understand how you intend for this to be used. If I wanted to add a new pass that would run after InstCombine, for example, how would I do that? How about adding a pass to be run at the very end of the pass manager, or at the very beginning?

I don't understand how you intend for this to be used. If I wanted to add a new pass that would run after InstCombine, for example, how would I do that? How about adding a pass to be run at the very end of the pass manager, or at the very beginning?

Currently, this is primarily a supplement to PassBuilder. So pass scheduling is done as it always was. In your example: "module(my-awesome-pass,instcombine)". Now, PassBuilder will first invoke the registered Hook for my-awesome-pass (which will in turn add the pass to the PassManager), and subsequently put instcombine into the PassManager.

This is not limited to PassBuilder though. Any other entity setting up PassManagers may do the same.

philip.pfaffe removed rL LLVM as the repository for this revision.

Rebased and applied latest changes to the Pass Manager infrastructure and to PassBuilder, including AA and Loop Managers.

Also reworked the testcase a bit.

philip.pfaffe set the repository for this revision to rL LLVM.Mar 21 2016, 3:49 AM

Ping.

I'm aware that this patch has rotted a bit doesn't apply cleanly currently due to a few upstream API changes. Will update!

Un-bitrot the patch.

Redesign the HookManager to incorporate extension points. The basic idea is to maintain tables of hooks for the different places the PassBuilder will want to run them, for instance for different IRUnits when parsing textual pipeline descriptions, or the individual extension points. The places are identified by Tags, which need to be specified when registering a hook. The individual tags are either the respective IRUnit, for pipeline parsing, or an extension point. Extension points define certain positions in the various optimizer/LTO/PGO pipelines.

I've tried to match the extension points as closely as possible to the legacy PassManagerBuilder, but I'm not sure I succeeded. Most importantly in the context of the function simplification, the pipelines have changed a little bit, and I wasn't able to identify all the correct spots: At PassManagerBuilder::addFunctionSimplificationPasses, vectorizer passes are added to the PassManager, which isn't reflected in PassBuilder right now. There are hence 2 instances of the Peephole extension point missing.

An additional modification I made is adding a reference to a HookManager instance to PassBuilder objects. They now default to using a global, singleton HM instance, but may also be constructed with a given existing HM object.

philip.pfaffe abandoned this revision.Jul 12 2017, 7:36 AM

Superseded by r307532.