diff --git a/llvm/docs/NewPassManager.rst b/llvm/docs/NewPassManager.rst --- a/llvm/docs/NewPassManager.rst +++ b/llvm/docs/NewPassManager.rst @@ -179,6 +179,11 @@ ``AMDGPUTargetMachine::registerPassBuilderCallbacks()`` is an example of a backend adding passes to various parts of the pipeline. +Pass plugins can also add passes into default pipelines. Different tools have +different ways of loading dynamic pass plugins. For example, ``opt +-load-pass-plugin=path/to/plugin.so`` loads a pass plugin into ``opt``. For +information on writing a pass plugin, see :doc:`WritingAnLLVMNewPMPass`. + Using Analyses ============== diff --git a/llvm/docs/WritingAnLLVMNewPMPass.rst b/llvm/docs/WritingAnLLVMNewPMPass.rst --- a/llvm/docs/WritingAnLLVMNewPMPass.rst +++ b/llvm/docs/WritingAnLLVMNewPMPass.rst @@ -232,3 +232,58 @@ For more implementation details, see ``PassInstrumentation::runBeforePass()``. + +Registering passes as plugins +----------------------------- + +LLVM provides a mechanism to register pass plugins within various tools like +``clang`` or ``opt``. A pass plugin can add passes to default optimization +pipelines or to be manually run via tools like ``opt``. For more information, +see :doc:`NewPassManager`. + +Create a CMake project at the root of the repo alongside +other projects. This project must contain the following minimal +``CMakeLists.txt``: + +.. code-block:: cmake + + add_llvm_pass_plugin(MyPassName source.cpp) + +See the definition of ``add_llvm_pass_plugin`` for more CMake details. + +The pass must provide at least one of two entry points for the new pass manager, +one for static registration and one for dynamically loaded plugins: + +- ``llvm::PassPluginLibraryInfo get##Name##PluginInfo();`` +- ``extern "C" ::llvm::PassPluginLibraryInfo llvmGetPassPluginInfo() LLVM_ATTRIBUTE_WEAK;`` + +Pass plugins are compiled and linked dynamically by default. Setting +``LLVM_${NAME}_LINK_INTO_TOOLS`` to ``ON`` turns the project into a statically +linked extension. + +For an in-tree example, see ``llvm/examples/Bye/``. + +To make ``PassBuilder`` aware of statically linked pass plugins: + +.. code-block:: c++ + + // Declare plugin extension function declarations. + #define HANDLE_EXTENSION(Ext) llvm::PassPluginLibraryInfo get##Ext##PluginInfo(); + #include "llvm/Support/Extension.def" + + ... + + // Register plugin extensions in PassBuilder. + #define HANDLE_EXTENSION(Ext) get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB); + #include "llvm/Support/Extension.def" + +To make ``PassBuilder`` aware of dynamically linked pass plugins: + +.. code-block:: c++ + + // Load plugin dynamically. + auto Plugin = PassPlugin::Load(PathToPlugin); + if (!Plugin) + report_error(); + // Register plugin extensions in PassBuilder. + Plugin.registerPassBuilderCallbacks(PB); diff --git a/llvm/docs/WritingAnLLVMPass.rst b/llvm/docs/WritingAnLLVMPass.rst --- a/llvm/docs/WritingAnLLVMPass.rst +++ b/llvm/docs/WritingAnLLVMPass.rst @@ -1183,51 +1183,6 @@ this internal state. This method is called after the ``run*`` method for the class, before the next call of ``run*`` in your pass. -Building pass plugins -===================== - -As an alternative to using ``PLUGIN_TOOL``, LLVM provides a mechanism to -automatically register pass plugins within ``clang``, ``opt`` and ``bugpoint``. -One first needs to create an independent project and add it to either ``tools/`` -or, using the MonoRepo layout, at the root of the repo alongside other projects. -This project must contain the following minimal ``CMakeLists.txt``: - -.. code-block:: cmake - - add_llvm_pass_plugin(Name source0.cpp) - -The pass must provide two entry points for the new pass manager, one for static -registration and one for dynamically loaded plugins: - -- ``llvm::PassPluginLibraryInfo get##Name##PluginInfo();`` -- ``extern "C" ::llvm::PassPluginLibraryInfo llvmGetPassPluginInfo() LLVM_ATTRIBUTE_WEAK;`` - -Pass plugins are compiled and link dynamically by default, but it's -possible to set the following variables to change this behavior: - -- ``LLVM_${NAME}_LINK_INTO_TOOLS``, when set to ``ON``, turns the project into - a statically linked extension - - -When building a tool that uses the new pass manager, one can use the following snippet to -include statically linked pass plugins: - -.. code-block:: c++ - - // fetch the declaration - #define HANDLE_EXTENSION(Ext) llvm::PassPluginLibraryInfo get##Ext##PluginInfo(); - #include "llvm/Support/Extension.def" - - [...] - - // use them, PB is an llvm::PassBuilder instance - #define HANDLE_EXTENSION(Ext) get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB); - #include "llvm/Support/Extension.def" - - - - - Registering dynamically loaded passes =====================================