[PATCH] D33464: [PM][WIP] Enable out-of-tree registration of passes with the new PassBuilder
Chandler Carruth via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 1 05:17:38 PDT 2017
chandlerc added a comment.
First round of high-level feedback on this approach, thanks so much for working no this!
================
Comment at: include/llvm/Passes/PassBuilder.h:323
+
+public:
+ enum class ExtensionPoint {
----------------
Generally, I'd like to not add more transitions between public and private. I would prefer the following rough order:
0. Before the first public, any private types / aliases needed to define the public API.
1. Public API
2. Protected API (if it exists)
3. Private API
================
Comment at: include/llvm/Passes/PassBuilder.h:324
+public:
+ enum class ExtensionPoint {
+ /// EarlyAsPossible - This extension point allows adding passes before
----------------
Could you sort these based on the order in which they first are used in the default pipeline?
================
Comment at: include/llvm/Passes/PassBuilder.h:352-355
+ /// EnabledOnOptLevel0 - This extension point allows adding passes that
+ /// should not be disabled by O0 optimization level. The passes will be
+ /// inserted after the inlining pass.
+ EnabledOnOptLevel0,
----------------
This seems redundant with `OptimizerLast`. I think in the new PM we should just have `OptimizerLast` and we should pass the `OptimizationLevel` as a parameter to *all* of these callbacks.
================
Comment at: include/llvm/Passes/PassBuilder.h:377-386
+ template <typename PassManagerT>
+ using EPCallback = std::function<void(ExtensionPoint, PassManagerT &)>;
+ template <typename PassManagerT>
+ using PassCallback = std::function<bool(StringRef Name, PassManagerT &)>;
+ template <typename PassManagerT>
+ using PipelineCallback =
+ std::function<bool(StringRef Name, PassManagerT &,
----------------
What do you think about naming these `FooT`-style? I don't feel strongly about it, but often like it to identify pure type aliases.
================
Comment at: include/llvm/Passes/PassBuilder.h:380-384
+ using PassCallback = std::function<bool(StringRef Name, PassManagerT &)>;
+ template <typename PassManagerT>
+ using PipelineCallback =
+ std::function<bool(StringRef Name, PassManagerT &,
+ ArrayRef<PassBuilder::PipelineElement> Pipeline)>;
----------------
I don't think it makes sense to have these be two different kinds of callbacks. At least, not until there are complaints about how annoying it is to ignore the rest.
I think your second signature is pretty good. It lets users that don't care about nested pipelines just use an unnamed parameter and ignore even the struct type, etc.
I would call this callback type something to do with *parsing* though as that is all it does.
================
Comment at: include/llvm/Passes/PassBuilder.h:386
+ template <typename AnalysisManagerT>
+ using AnalysisCallback = std::function<void(AnalysisManagerT &)>;
+
----------------
This should be called something to do with *registering*.
================
Comment at: include/llvm/Passes/PassBuilder.h:407-414
+ /// \brief Call all loaded plugins
+ ///
+ /// For all plugins regeistered with the PluginLoader, this method will call
+ /// the plugins' registration entrypoint, if it exists. The entrypoint is a
+ /// method with the extern "C" signature `void
+ /// RegisterPluginPasses(PassBuilder &PB)`.
+ /// Plugin passes can register callbacks with this PassBuilder instance.
----------------
I would suggest separating this into a later change. The extension mechanisms should work well out of the box for non-plugin use cases and it lets the review be a bit more focused.
As an example, I'd like to use some of this to implement support for using the new PM in Clang when running sanitizers.
================
Comment at: include/llvm/Passes/PassBuilder.h:422-425
+ void registerEPCallback(const CGSCCEPCallback &C);
+ void registerEPCallback(const FunctionEPCallback &C);
+ void registerEPCallback(const LoopEPCallback &C);
+ void registerEPCallback(const ModuleEPCallback &C);
----------------
Rather than all four of these plus the huge swath of extension point enums above, how do you feel about a different API:
All of the extension points above have a fixed pass manager type. So what if we have one `registerFooCallback` for each extension point, completely remove the enum from the public API, and make the pass manager type concrete and precise?
While this would mean more `register...` functions, not more than we already have enumerators. You should move the comments currently on the enumerators to be on the registration routines. I also generally think it would be best to document the extension points separately from the rest of the registration stuff as its much less boiler-plate-y.
One reason why I prefer this -- with the current API, there are a lot of combinations of pass manager types and enumerations that won't get any compile time error but cannot actually fire in practice.
================
Comment at: include/llvm/Passes/PassBuilder.h:436-462
+ /// {{@ Run all registered callbacks for a given pass type
+ void invokeAnalysisCallbacks(CGSCCAnalysisManager &PM) const;
+ void invokeAnalysisCallbacks(FunctionAnalysisManager &PM) const;
+ void invokeAnalysisCallbacks(LoopAnalysisManager &PM) const;
+ void invokeAnalysisCallbacks(ModuleAnalysisManager &PM) const;
+ void invokeEPCallbacks(ExtensionPoint EP, CGSCCPassManager &PM) const;
+ void invokeEPCallbacks(ExtensionPoint EP, FunctionPassManager &PM) const;
----------------
Why are these public? I would make them implementation details. And in most cases they're called in only one place and could be completely inlined.
================
Comment at: include/llvm/Passes/PassBuilder.h:489-491
+/// This utility template takes care of adding require<> and invalidate<>
+/// passes for an analysis to a given \c PassManager. It is intended to be used
+/// during parsing of a pass pipeline when parsing a single PipelineEntry.
----------------
I think you should show an example of how to use this here.
================
Comment at: include/llvm/Passes/PassBuilder.h:494
+ typename... ExtraArgTs>
+bool HandleAnalysisUtilities(
+ StringRef AnalysisName, StringRef PipelineEntry,
----------------
Naming convention suggests fooBarBaz here.
Also, "handle" doesn't really help the reader much IMO. I would name it after the name of the callback above. IE, if above it is something like `ParsePassCallbackT` I would call this `parseAnalysisUtilityPasses`.
================
Comment at: include/llvm/Passes/PassBuilder.h:495
+bool HandleAnalysisUtilities(
+ StringRef AnalysisName, StringRef PipelineEntry,
+ PassManager<IRUnitT, AnalysisManagerT, ExtraArgTs...> &PM) {
----------------
There is a type `PipelineEntry`. I don't think that makes a good parameter name here, especially when the parameter is extracted *from* that type...
https://reviews.llvm.org/D33464
More information about the llvm-commits
mailing list