[clang] 24ab9b5 - Generalize the pass registration mechanism used by Polly to any third-party tool

Eric Christopher via cfe-commits cfe-commits at lists.llvm.org
Mon Jan 6 15:45:15 PST 2020


Hi Serge,

I have a few questions here about this:

In general this appears to be a lot more complex than the existing plugin
solutions and requires quite a lot of custom cmake rules that are difficult
to maintain. Why do we want this in general for the project? I understand
the desire to make polly less of a special case, but I don't think that the
overall complexity is worth the added ability to register polly plugins.
Perhaps disabling the polly plugin registration scheme is a better option?

That being said, perhaps it is worth it? But I think we need to call out
why we want it. I would also have expected something to llvm-dev for a
change of this magnitude. I didn't see anyone from the pass manager
hierarchy on the reviews and the final reviewer wasn't someone who
contributes to these areas typically.

In addition, what's with the OSX failure? It's currently turned off and was
breaking the bots, but does it mean that you don't expect this machinery to
work on OSX? That seems like a severely limiting factor for the project.

+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 appears to be from an earlier incarnation of the patch? There's only
one layout now.


 ; CHECK-EP-VECTORIZER-START-NEXT: Running pass: NoOpFunctionPass
+; CHECK-EXT: Running pass: {{.*}}::Bye on foo

Why is this running on every test of the pass manager? It should be an
example run in the examples directory and not on by default? Same for every
other PM test. This seems like a bug?

Thanks!

-eric


On Thu, Jan 2, 2020 at 7:52 AM via cfe-commits <cfe-commits at lists.llvm.org>
wrote:

>
> Author: serge_sans_paille
> Date: 2020-01-02T16:45:31+01:00
> New Revision: 24ab9b537e61b3fe5e6a1019492ff6530d82a3ee
>
> URL:
> https://github.com/llvm/llvm-project/commit/24ab9b537e61b3fe5e6a1019492ff6530d82a3ee
> DIFF:
> https://github.com/llvm/llvm-project/commit/24ab9b537e61b3fe5e6a1019492ff6530d82a3ee.diff
>
> LOG: Generalize the pass registration mechanism used by Polly to any
> third-party tool
>
> There's quite a lot of references to Polly in the LLVM CMake codebase.
> However
> the registration pattern used by Polly could be useful to other external
> projects: thanks to that mechanism it would be possible to develop LLVM
> extension without touching the LLVM code base.
>
> This patch has two effects:
>
> 1. Remove all code specific to Polly in the llvm/clang codebase,
> replaicing it
>    with a generic mechanism
>
> 2. Provide a generic mechanism to register compiler extensions.
>
> A compiler extension is similar to a pass plugin, with the notable
> difference
> that the compiler extension can be configured to be built dynamically (like
> plugins) or statically (like regular passes).
>
> As a result, people willing to add extra passes to clang/opt can do it
> using a
> separate code repo, but still have their pass be linked in clang/opt as
> built-in
> passes.
>
> Differential Revision: https://reviews.llvm.org/D61446
>
> Added:
>     llvm/examples/Bye/Bye.cpp
>     llvm/examples/Bye/CMakeLists.txt
>     llvm/test/Feature/load_extension.ll
>     polly/lib/Plugin/Polly.cpp
>
> Modified:
>     clang/lib/CodeGen/BackendUtil.cpp
>     clang/lib/CodeGen/CMakeLists.txt
>     clang/tools/driver/CMakeLists.txt
>     clang/tools/driver/cc1_main.cpp
>     llvm/CMakeLists.txt
>     llvm/cmake/modules/AddLLVM.cmake
>     llvm/docs/WritingAnLLVMPass.rst
>     llvm/examples/CMakeLists.txt
>     llvm/include/llvm/Config/llvm-config.h.cmake
>     llvm/test/Other/new-pm-defaults.ll
>     llvm/test/Other/new-pm-thinlto-defaults.ll
>     llvm/test/Other/opt-O0-pipeline.ll
>     llvm/test/Other/opt-O2-pipeline.ll
>     llvm/test/Other/opt-O3-pipeline.ll
>     llvm/test/Other/opt-Os-pipeline.ll
>     llvm/test/lit.cfg.py
>     llvm/test/lit.site.cfg.py.in
>     llvm/tools/CMakeLists.txt
>     llvm/tools/bugpoint/CMakeLists.txt
>     llvm/tools/bugpoint/bugpoint.cpp
>     llvm/tools/opt/CMakeLists.txt
>     llvm/tools/opt/NewPMDriver.cpp
>     llvm/tools/opt/opt.cpp
>     llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn
>     polly/include/polly/RegisterPasses.h
>     polly/lib/CMakeLists.txt
>     polly/lib/Support/RegisterPasses.cpp
>     polly/test/Unit/lit.site.cfg.in
>     polly/test/lit.site.cfg.in
>     polly/test/update_check.py
>
> Removed:
>     polly/lib/Polly.cpp
>
>
>
> ################################################################################
> diff  --git a/clang/lib/CodeGen/BackendUtil.cpp
> b/clang/lib/CodeGen/BackendUtil.cpp
> index 645ef0165a53..ed881f2ddf68 100644
> --- a/clang/lib/CodeGen/BackendUtil.cpp
> +++ b/clang/lib/CodeGen/BackendUtil.cpp
> @@ -75,6 +75,10 @@
>  using namespace clang;
>  using namespace llvm;
>
> +#define HANDLE_EXTENSION(Ext)
>       \
> +  llvm::PassPluginLibraryInfo get##Ext##PluginInfo();
> +#include "llvm/Support/Extension.def"
> +
>  namespace {
>
>  // Default filename used for profile generation.
> @@ -1076,6 +1080,9 @@ void
> EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
>            << PluginFN << toString(PassPlugin.takeError());
>      }
>    }
> +#define HANDLE_EXTENSION(Ext)
>       \
> +  get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB);
> +#include "llvm/Support/Extension.def"
>
>    LoopAnalysisManager LAM(CodeGenOpts.DebugPassManager);
>    FunctionAnalysisManager FAM(CodeGenOpts.DebugPassManager);
>
> diff  --git a/clang/lib/CodeGen/CMakeLists.txt
> b/clang/lib/CodeGen/CMakeLists.txt
> index a3980637c592..d8b3c234a1ef 100644
> --- a/clang/lib/CodeGen/CMakeLists.txt
> +++ b/clang/lib/CodeGen/CMakeLists.txt
> @@ -96,6 +96,8 @@ add_clang_library(clangCodeGen
>    TargetInfo.cpp
>    VarBypassDetector.cpp
>
> +  ENABLE_PLUGINS
> +
>    DEPENDS
>    ${codegen_deps}
>
>
> diff  --git a/clang/tools/driver/CMakeLists.txt
> b/clang/tools/driver/CMakeLists.txt
> index 52a95e6bc6b1..2b783cff0955 100644
> --- a/clang/tools/driver/CMakeLists.txt
> +++ b/clang/tools/driver/CMakeLists.txt
> @@ -122,7 +122,3 @@ if(CLANG_ORDER_FILE AND
>      set_target_properties(clang PROPERTIES LINK_DEPENDS
> ${CLANG_ORDER_FILE})
>    endif()
>  endif()
> -
> -if(WITH_POLLY AND LINK_POLLY_INTO_TOOLS)
> -  target_link_libraries(clang PRIVATE Polly)
> -endif(WITH_POLLY AND LINK_POLLY_INTO_TOOLS)
>
> diff  --git a/clang/tools/driver/cc1_main.cpp
> b/clang/tools/driver/cc1_main.cpp
> index 2b82a4378111..b551e9f4cf82 100644
> --- a/clang/tools/driver/cc1_main.cpp
> +++ b/clang/tools/driver/cc1_main.cpp
> @@ -72,12 +72,6 @@ static void LLVMErrorHandler(void *UserData, const
> std::string &Message,
>    exit(GenCrashDiag ? 70 : 1);
>  }
>
> -#ifdef LINK_POLLY_INTO_TOOLS
> -namespace polly {
> -void initializePollyPasses(llvm::PassRegistry &Registry);
> -}
> -#endif
> -
>  #ifdef CLANG_HAVE_RLIMITS
>  #if defined(__linux__) && defined(__PIE__)
>  static size_t getCurrentStackAllocation() {
> @@ -203,11 +197,6 @@ int cc1_main(ArrayRef<const char *> Argv, const char
> *Argv0, void *MainAddr) {
>    llvm::InitializeAllAsmPrinters();
>    llvm::InitializeAllAsmParsers();
>
> -#ifdef LINK_POLLY_INTO_TOOLS
> -  llvm::PassRegistry &Registry = *llvm::PassRegistry::getPassRegistry();
> -  polly::initializePollyPasses(Registry);
> -#endif
> -
>    // Buffer diagnostics from argument parsing so that we can output them
> using a
>    // well formed diagnostic object.
>    IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new
> DiagnosticOptions();
>
> diff  --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
> index 05e93f67e990..25f60da41a20 100644
> --- a/llvm/CMakeLists.txt
> +++ b/llvm/CMakeLists.txt
> @@ -465,29 +465,6 @@ set(LLVM_LIB_FUZZING_ENGINE "" CACHE PATH
>  option(LLVM_USE_SPLIT_DWARF
>    "Use -gsplit-dwarf when compiling llvm." OFF)
>
> -option(LLVM_POLLY_LINK_INTO_TOOLS "Statically link Polly into tools (if
> available)" ON)
> -option(LLVM_POLLY_BUILD "Build LLVM with Polly" ON)
> -
> -if (EXISTS ${LLVM_MAIN_SRC_DIR}/tools/polly/CMakeLists.txt)
> -  set(POLLY_IN_TREE TRUE)
> -elseif(LLVM_EXTERNAL_POLLY_SOURCE_DIR)
> -  set(POLLY_IN_TREE TRUE)
> -else()
> -  set(POLLY_IN_TREE FALSE)
> -endif()
> -
> -if (LLVM_POLLY_BUILD AND POLLY_IN_TREE)
> -  set(WITH_POLLY ON)
> -else()
> -  set(WITH_POLLY OFF)
> -endif()
> -
> -if (LLVM_POLLY_LINK_INTO_TOOLS AND WITH_POLLY)
> -  set(LINK_POLLY_INTO_TOOLS ON)
> -else()
> -  set(LINK_POLLY_INTO_TOOLS OFF)
> -endif()
> -
>  # Define an option controlling whether we should build for 32-bit on
> 64-bit
>  # platforms, where supported.
>  if( CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32 )
> @@ -1112,3 +1089,5 @@ endif()
>  if (LLVM_INCLUDE_UTILS AND LLVM_INCLUDE_TOOLS)
>    add_subdirectory(utils/llvm-locstats)
>  endif()
> +
> +process_llvm_pass_plugins()
>
> diff  --git a/llvm/cmake/modules/AddLLVM.cmake
> b/llvm/cmake/modules/AddLLVM.cmake
> index 34f532c9e455..82345690d958 100644
> --- a/llvm/cmake/modules/AddLLVM.cmake
> +++ b/llvm/cmake/modules/AddLLVM.cmake
> @@ -404,7 +404,7 @@ endfunction(set_windows_version_resource_properties)
>  #   )
>  function(llvm_add_library name)
>    cmake_parse_arguments(ARG
> -
> "MODULE;SHARED;STATIC;OBJECT;DISABLE_LLVM_LINK_LLVM_DYLIB;SONAME;NO_INSTALL_RPATH;COMPONENT_LIB"
> +
> "MODULE;SHARED;STATIC;OBJECT;DISABLE_LLVM_LINK_LLVM_DYLIB;SONAME;NO_INSTALL_RPATH;COMPONENT_LIB;ENABLE_PLUGINS"
>      "OUTPUT_NAME;PLUGIN_TOOL;ENTITLEMENTS;BUNDLE_PATH"
>      "ADDITIONAL_HEADERS;DEPENDS;LINK_COMPONENTS;LINK_LIBS;OBJLIBS"
>      ${ARGN})
> @@ -418,6 +418,9 @@ function(llvm_add_library name)
>    else()
>      llvm_process_sources(ALL_FILES ${ARG_UNPARSED_ARGUMENTS}
> ${ARG_ADDITIONAL_HEADERS})
>    endif()
> +  if(ARG_ENABLE_PLUGINS)
> +    set_property(GLOBAL APPEND PROPERTY LLVM_PLUGIN_TARGETS ${name})
> +  endif()
>
>    if(ARG_MODULE)
>      if(ARG_SHARED OR ARG_STATIC)
> @@ -745,7 +748,7 @@ endmacro(add_llvm_library name)
>
>  macro(add_llvm_executable name)
>    cmake_parse_arguments(ARG
> -
> "DISABLE_LLVM_LINK_LLVM_DYLIB;IGNORE_EXTERNALIZE_DEBUGINFO;NO_INSTALL_RPATH;SUPPORT_PLUGINS"
> +
> "DISABLE_LLVM_LINK_LLVM_DYLIB;IGNORE_EXTERNALIZE_DEBUGINFO;NO_INSTALL_RPATH;SUPPORT_PLUGINS;ENABLE_PLUGINS"
>      "ENTITLEMENTS;BUNDLE_PATH"
>      "DEPENDS"
>      ${ARGN})
> @@ -832,10 +835,78 @@ macro(add_llvm_executable name)
>      # API for all shared libaries loaded by this executable.
>      target_link_libraries(${name} PRIVATE ${LLVM_PTHREAD_LIB})
>    endif()
> +  if(ARG_ENABLE_PLUGINS)
> +    set_property(GLOBAL APPEND PROPERTY LLVM_PLUGIN_TARGETS ${name})
> +  endif()
>
>    llvm_codesign(${name} ENTITLEMENTS ${ARG_ENTITLEMENTS} BUNDLE_PATH
> ${ARG_BUNDLE_PATH})
>  endmacro(add_llvm_executable name)
>
> +# add_llvm_pass_plugin(name)
> +#   Add ${name} as an llvm plugin.
> +#   If option LLVM_${name_upper}_LINK_INTO_TOOLS is set to ON, the plugin
> is registered statically.
> +#   Otherwise a pluggable shared library is registered.
> +function(add_llvm_pass_plugin name)
> +
> +  string(TOUPPER ${name} name_upper)
> +
> +  option(LLVM_${name_upper}_LINK_INTO_TOOLS "Statically link ${name} into
> tools (if available)" OFF)
> +
> +  # process_llvm_pass_plugins takes care of the actual linking, just
> create an
> +  # object library as of now
> +  add_llvm_library(${name} OBJECT ${ARGN})
> +
> +  if(LLVM_${name_upper}_LINK_INTO_TOOLS)
> +      target_compile_definitions(${name} PRIVATE
> LLVM_${name_upper}_LINK_INTO_TOOLS)
> +      set_property(TARGET ${name} APPEND PROPERTY COMPILE_DEFINITIONS
> LLVM_LINK_INTO_TOOLS)
> +      if (TARGET intrinsics_gen)
> +        add_dependencies(obj.${name} intrinsics_gen)
> +      endif()
> +  endif()
> +
> +  message(STATUS "Registering ${name} as a pass plugin (static build:
> ${LLVM_${name_upper}_LINK_INTO_TOOLS})")
> +  if(LLVM_${name_upper}_LINK_INTO_TOOLS)
> +    set_property(GLOBAL APPEND PROPERTY LLVM_COMPILE_EXTENSIONS ${name})
> +  endif()
> +endfunction(add_llvm_pass_plugin)
> +
> +# Generate X Macro file for extension handling. It provides a
> +# HANDLE_EXTENSION(extension_namespace, ExtensionProject) call for each
> extension
> +# allowing client code to define HANDLE_EXTENSION to have a specific code
> be run for
> +# each extension.
> +#
> +# Also correctly set lib dependencies between plugins and tools.
> +function(process_llvm_pass_plugins)
> +  get_property(LLVM_EXTENSIONS GLOBAL PROPERTY LLVM_COMPILE_EXTENSIONS)
> +  file(WRITE "${CMAKE_BINARY_DIR}/include/llvm/Support/Extension.def.tmp"
> "//extension handlers\n")
> +  foreach(llvm_extension ${LLVM_EXTENSIONS})
> +    string(TOLOWER ${llvm_extension} llvm_extension_lower)
> +
> +    string(TOUPPER ${llvm_extension} llvm_extension_upper)
> +    string(SUBSTRING ${llvm_extension_upper} 0 1
> llvm_extension_upper_first)
> +    string(SUBSTRING ${llvm_extension_lower} 1 -1
> llvm_extension_lower_tail)
> +    string(CONCAT llvm_extension_project ${llvm_extension_upper_first}
> ${llvm_extension_lower_tail})
> +
> +    if(LLVM_${llvm_extension_upper}_LINK_INTO_TOOLS)
> +        file(APPEND
> "${CMAKE_BINARY_DIR}/include/llvm/Support/Extension.def.tmp"
> "HANDLE_EXTENSION(${llvm_extension_project})\n")
> +
> +        get_property(llvm_plugin_targets GLOBAL PROPERTY
> LLVM_PLUGIN_TARGETS)
> +        foreach(llvm_plugin_target ${llvm_plugin_targets})
> +          set_property(TARGET ${llvm_plugin_target} APPEND PROPERTY
> LINK_LIBRARIES ${llvm_extension})
> +          set_property(TARGET ${llvm_plugin_target} APPEND PROPERTY
> INTERFACE_LINK_LIBRARIES ${llvm_extension})
> +        endforeach()
> +    else()
> +      add_llvm_library(${llvm_extension_lower} MODULE
> obj.${llvm_extension_lower})
> +    endif()
> +
> +  endforeach()
> +  file(APPEND
> "${CMAKE_BINARY_DIR}/include/llvm/Support/Extension.def.tmp" "#undef
> HANDLE_EXTENSION\n")
> +
> +  # only replace if there's an actual change
> +  execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_
> diff erent "${CMAKE_BINARY_DIR}/include/llvm/Support/Extension.def.tmp"
> "${CMAKE_BINARY_DIR}/include/llvm/Support/Extension.def")
> +  file(REMOVE
> "${CMAKE_BINARY_DIR}/include/llvm/Support/Extension.def.tmp")
> +endfunction()
> +
>  function(export_executable_symbols target)
>    if (LLVM_EXPORTED_SYMBOL_FILE)
>      # The symbol file should contain the symbols we want the executable to
>
> diff  --git a/llvm/docs/WritingAnLLVMPass.rst
> b/llvm/docs/WritingAnLLVMPass.rst
> index fae14d8ca320..ecd1db1344d8 100644
> --- a/llvm/docs/WritingAnLLVMPass.rst
> +++ b/llvm/docs/WritingAnLLVMPass.rst
> @@ -1175,6 +1175,51 @@ implement ``releaseMemory`` to, well, release the
> memory allocated to maintain
>  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
>  =====================================
>
>
> diff  --git a/llvm/examples/Bye/Bye.cpp b/llvm/examples/Bye/Bye.cpp
> new file mode 100644
> index 000000000000..6a2fea44d4cc
> --- /dev/null
> +++ b/llvm/examples/Bye/Bye.cpp
> @@ -0,0 +1,69 @@
> +#include "llvm/IR/Function.h"
> +#include "llvm/IR/LegacyPassManager.h"
> +#include "llvm/Pass.h"
> +#include "llvm/Passes/PassBuilder.h"
> +#include "llvm/Passes/PassPlugin.h"
> +#include "llvm/Support/raw_ostream.h"
> +#include "llvm/Transforms/IPO/PassManagerBuilder.h"
> +
> +using namespace llvm;
> +
> +static cl::opt<bool> Wave("wave-goodbye", cl::init(false),
> +                          cl::desc("wave good bye"));
> +
> +namespace {
> +
> +bool runBye(Function &F) {
> +  if (Wave) {
> +    errs() << "Bye: ";
> +    errs().write_escaped(F.getName()) << '\n';
> +  }
> +  return false;
> +}
> +
> +struct LegacyBye : public FunctionPass {
> +  static char ID;
> +  LegacyBye() : FunctionPass(ID) {}
> +  bool runOnFunction(Function &F) override { return runBye(F); }
> +};
> +
> +struct Bye : PassInfoMixin<Bye> {
> +  PreservedAnalyses run(Function &F, FunctionAnalysisManager &) {
> +    if (!runBye(F))
> +      return PreservedAnalyses::all();
> +    return PreservedAnalyses::none();
> +  }
> +};
> +
> +} // namespace
> +
> +char LegacyBye::ID = 0;
> +
> +static RegisterPass<LegacyBye> X("goodbye", "Good Bye World Pass",
> +                                 false /* Only looks at CFG */,
> +                                 false /* Analysis Pass */);
> +
> +/* Legacy PM Registration */
> +static llvm::RegisterStandardPasses RegisterBye(
> +    llvm::PassManagerBuilder::EP_EarlyAsPossible,
> +    [](const llvm::PassManagerBuilder &Builder,
> +       llvm::legacy::PassManagerBase &PM) { PM.add(new LegacyBye()); });
> +
> +/* New PM Registration */
> +llvm::PassPluginLibraryInfo getByePluginInfo() {
> +  return {LLVM_PLUGIN_API_VERSION, "Bye", LLVM_VERSION_STRING,
> +          [](PassBuilder &PB) {
> +            PB.registerVectorizerStartEPCallback(
> +                [](llvm::FunctionPassManager &PM,
> +                   llvm::PassBuilder::OptimizationLevel Level) {
> +                  PM.addPass(Bye());
> +                });
> +          }};
> +}
> +
> +#ifndef LLVM_BYE_LINK_INTO_TOOLS
> +extern "C" LLVM_ATTRIBUTE_WEAK ::llvm::PassPluginLibraryInfo
> +llvmGetPassPluginInfo() {
> +  return getByePluginInfo();
> +}
> +#endif
>
> diff  --git a/llvm/examples/Bye/CMakeLists.txt
> b/llvm/examples/Bye/CMakeLists.txt
> new file mode 100644
> index 000000000000..9ce49fcc56e8
> --- /dev/null
> +++ b/llvm/examples/Bye/CMakeLists.txt
> @@ -0,0 +1,13 @@
> +add_llvm_pass_plugin(Bye Bye.cpp)
> +if (LLVM_LINK_LLVM_DYLIB)
> +  target_link_libraries(Bye PUBLIC LLVM)
> +else()
> +  target_link_libraries(Bye
> +    PUBLIC
> +    LLVMSupport
> +    LLVMCore
> +    LLVMipo
> +    LLVMPasses
> +    )
> +endif()
> +
>
> diff  --git a/llvm/examples/CMakeLists.txt b/llvm/examples/CMakeLists.txt
> index ad99d4c7e312..a464d52e28e7 100644
> --- a/llvm/examples/CMakeLists.txt
> +++ b/llvm/examples/CMakeLists.txt
> @@ -6,6 +6,7 @@ add_subdirectory(LLJITExamples)
>  add_subdirectory(Kaleidoscope)
>  add_subdirectory(ModuleMaker)
>  add_subdirectory(SpeculativeJIT)
> +add_subdirectory(Bye)
>
>  if(LLVM_ENABLE_EH AND (NOT WIN32) AND (NOT "${LLVM_NATIVE_ARCH}" STREQUAL
> "ARM"))
>      add_subdirectory(ExceptionDemo)
>
> diff  --git a/llvm/include/llvm/Config/llvm-config.h.cmake
> b/llvm/include/llvm/Config/llvm-config.h.cmake
> index e6b6f78f71cd..475c93efd653 100644
> --- a/llvm/include/llvm/Config/llvm-config.h.cmake
> +++ b/llvm/include/llvm/Config/llvm-config.h.cmake
> @@ -17,9 +17,6 @@
>  /* Define if LLVM_ENABLE_DUMP is enabled */
>  #cmakedefine LLVM_ENABLE_DUMP
>
> -/* Define if we link Polly to the tools */
> -#cmakedefine LINK_POLLY_INTO_TOOLS
> -
>  /* Target triple LLVM will generate code for by default */
>  #cmakedefine LLVM_DEFAULT_TARGET_TRIPLE "${LLVM_DEFAULT_TARGET_TRIPLE}"
>
>
> diff  --git a/llvm/test/Feature/load_extension.ll
> b/llvm/test/Feature/load_extension.ll
> new file mode 100644
> index 000000000000..3c3469499a7c
> --- /dev/null
> +++ b/llvm/test/Feature/load_extension.ll
> @@ -0,0 +1,10 @@
> +; RUN: opt %s %loadbye -goodbye -wave-goodbye -disable-output | FileCheck
> %s
> +; REQUIRES: plugins, examples
> +; CHECK: Bye
> +
> + at junk = global i32 0
> +
> +define i32* @somefunk() {
> +  ret i32* @junk
> +}
> +
>
> diff  --git a/llvm/test/Other/new-pm-defaults.ll
> b/llvm/test/Other/new-pm-defaults.ll
> index e79a359277f6..bece4d46e976 100644
> --- a/llvm/test/Other/new-pm-defaults.ll
> +++ b/llvm/test/Other/new-pm-defaults.ll
> @@ -9,72 +9,83 @@
>
>  ; RUN: opt -disable-verify -debug-pass-manager \
>  ; RUN:     -passes='default<O1>' -S %s 2>&1 \
> -; RUN:     | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O1
> +; RUN:     | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O1 \
> +; RUN:      --check-prefix=%llvmcheckext
>  ; RUN: opt -disable-verify -debug-pass-manager \
>  ; RUN:     -passes='default<O2>' -S  %s 2>&1 \
>  ; RUN:     | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O2 \
> -; RUN:     --check-prefix=CHECK-O23SZ
> +; RUN:      --check-prefix=CHECK-O23SZ --check-prefix=%llvmcheckext
>  ; RUN: opt -disable-verify -debug-pass-manager \
>  ; RUN:     -passes='default<O3>' -S  %s 2>&1 \
>  ; RUN:     | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O3 \
> -; RUN:     --check-prefix=CHECK-O23SZ
> +; RUN:      --check-prefix=CHECK-O23SZ --check-prefix=%llvmcheckext
>  ; RUN: opt -disable-verify -debug-pass-manager \
>  ; RUN:     -passes='default<Os>' -S %s 2>&1 \
>  ; RUN:     | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-Os \
> -; RUN:     --check-prefix=CHECK-O23SZ
> +; RUN:      --check-prefix=CHECK-O23SZ --check-prefix=%llvmcheckext
>  ; RUN: opt -disable-verify -debug-pass-manager \
>  ; RUN:     -passes='default<Oz>' -S %s 2>&1 \
>  ; RUN:     | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-Oz \
> -; RUN:     --check-prefix=CHECK-O23SZ
> +; RUN:     --check-prefix=CHECK-O23SZ --check-prefix=%llvmcheckext
>  ; RUN: opt -disable-verify -debug-pass-manager \
>  ; RUN:     -passes='lto-pre-link<O2>' -S %s 2>&1 \
>  ; RUN:     | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O2 \
> -; RUN:     --check-prefix=CHECK-O2-LTO --check-prefix=CHECK-O23SZ
> +; RUN:     --check-prefix=CHECK-O23SZ --check-prefix=%llvmcheckext \
> +; RUN:     --check-prefix=CHECK-O2-LTO
>
>  ; RUN: opt -disable-verify -debug-pass-manager \
>  ; RUN:     -passes-ep-peephole='no-op-function' \
>  ; RUN:     -passes='default<O3>' -S  %s 2>&1 \
>  ; RUN:     | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O3 \
> +; RUN:     --check-prefix=%llvmcheckext \
>  ; RUN:     --check-prefix=CHECK-EP-PEEPHOLE --check-prefix=CHECK-O23SZ
>  ; RUN: opt -disable-verify -debug-pass-manager \
>  ; RUN:     -passes-ep-late-loop-optimizations='no-op-loop' \
>  ; RUN:     -passes='default<O3>' -S  %s 2>&1 \
>  ; RUN:     | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O3 \
> +; RUN:     --check-prefix=%llvmcheckext \
>  ; RUN:     --check-prefix=CHECK-EP-LOOP-LATE --check-prefix=CHECK-O23SZ
>  ; RUN: opt -disable-verify -debug-pass-manager \
>  ; RUN:     -passes-ep-loop-optimizer-end='no-op-loop' \
>  ; RUN:     -passes='default<O3>' -S  %s 2>&1 \
>  ; RUN:     | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O3 \
> +; RUN:     --check-prefix=%llvmcheckext \
>  ; RUN:     --check-prefix=CHECK-EP-LOOP-END --check-prefix=CHECK-O23SZ
>  ; RUN: opt -disable-verify -debug-pass-manager \
>  ; RUN:     -passes-ep-scalar-optimizer-late='no-op-function' \
>  ; RUN:     -passes='default<O3>' -S  %s 2>&1 \
>  ; RUN:     | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O3 \
> +; RUN:     --check-prefix=%llvmcheckext \
>  ; RUN:     --check-prefix=CHECK-EP-SCALAR-LATE --check-prefix=CHECK-O23SZ
>  ; RUN: opt -disable-verify -debug-pass-manager \
>  ; RUN:     -passes-ep-cgscc-optimizer-late='no-op-cgscc' \
>  ; RUN:     -passes='default<O3>' -S  %s 2>&1 \
>  ; RUN:     | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O3 \
> +; RUN:     --check-prefix=%llvmcheckext \
>  ; RUN:     --check-prefix=CHECK-EP-CGSCC-LATE --check-prefix=CHECK-O23SZ
>  ; RUN: opt -disable-verify -debug-pass-manager \
>  ; RUN:     -passes-ep-vectorizer-start='no-op-function' \
>  ; RUN:     -passes='default<O3>' -S  %s 2>&1 \
>  ; RUN:     | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O3 \
> +; RUN:     --check-prefix=%llvmcheckext \
>  ; RUN:     --check-prefix=CHECK-EP-VECTORIZER-START
> --check-prefix=CHECK-O23SZ
>  ; RUN: opt -disable-verify -debug-pass-manager \
>  ; RUN:     -passes-ep-pipeline-start='no-op-module' \
>  ; RUN:     -passes='default<O3>' -S  %s 2>&1 \
>  ; RUN:     | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O3 \
> +; RUN:     --check-prefix=%llvmcheckext \
>  ; RUN:     --check-prefix=CHECK-EP-PIPELINE-START
> --check-prefix=CHECK-O23SZ
>  ; RUN: opt -disable-verify -debug-pass-manager \
>  ; RUN:     -passes-ep-pipeline-start='no-op-module' \
>  ; RUN:     -passes='lto-pre-link<O3>' -S  %s 2>&1 \
>  ; RUN:     | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O3 \
> +; RUN:     --check-prefix=%llvmcheckext \
>  ; RUN:     --check-prefix=CHECK-EP-PIPELINE-START
> --check-prefix=CHECK-O23SZ
>  ; RUN: opt -disable-verify -debug-pass-manager \
>  ; RUN:     -passes-ep-optimizer-last='no-op-function' \
>  ; RUN:     -passes='default<O3>' -S  %s 2>&1 \
>  ; RUN:     | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O3 \
> +; RUN:     --check-prefix=%llvmcheckext \
>  ; RUN:     --check-prefix=CHECK-EP-OPTIMIZER-LAST
> --check-prefix=CHECK-O23SZ
>
>  ; CHECK-O: Running analysis: PassInstrumentationAnalysis
> @@ -226,6 +237,7 @@
>  ; CHECK-O-NEXT: Running pass: Float2IntPass
>  ; CHECK-O-NEXT: Running pass: LowerConstantIntrinsicsPass on foo
>  ; CHECK-EP-VECTORIZER-START-NEXT: Running pass: NoOpFunctionPass
> +; CHECK-EXT: Running pass: {{.*}}::Bye on foo
>  ; CHECK-O-NEXT: Running pass:
> FunctionToLoopPassAdaptor<{{.*}}LoopRotatePass
>  ; CHECK-O-NEXT: Starting llvm::Function pass manager run.
>  ; CHECK-O-NEXT: Running pass: LoopSimplifyPass
>
> diff  --git a/llvm/test/Other/new-pm-thinlto-defaults.ll
> b/llvm/test/Other/new-pm-thinlto-defaults.ll
> index c93b360009b2..a071f243dbcf 100644
> --- a/llvm/test/Other/new-pm-thinlto-defaults.ll
> +++ b/llvm/test/Other/new-pm-thinlto-defaults.ll
> @@ -30,22 +30,22 @@
>  ; Postlink pipelines:
>  ; RUN: opt -disable-verify -debug-pass-manager \
>  ; RUN:     -passes='thinlto<O1>' -S %s 2>&1 \
> -; RUN:     | FileCheck %s
> --check-prefixes=CHECK-O,CHECK-O1,CHECK-POSTLINK-O,CHECK-POSTLINK-O1
> +; RUN:     | FileCheck %s
> --check-prefixes=CHECK-O,CHECK-O1,CHECK-POSTLINK-O,%llvmcheckext,CHECK-POSTLINK-O1
>  ; RUN: opt -disable-verify -debug-pass-manager \
>  ; RUN:     -passes='thinlto<O2>' -S  %s 2>&1 \
> -; RUN:     | FileCheck %s
> --check-prefixes=CHECK-O,CHECK-O2,CHECK-O23SZ,CHECK-POSTLINK-O,CHECK-POSTLINK-O2
> +; RUN:     | FileCheck %s
> --check-prefixes=CHECK-O,CHECK-O2,CHECK-O23SZ,CHECK-POSTLINK-O,%llvmcheckext,CHECK-POSTLINK-O2
>  ; RUN: opt -disable-verify -debug-pass-manager
> -passes-ep-pipeline-start='no-op-module' \
>  ; RUN:     -passes='thinlto<O3>' -S  %s 2>&1 \
> -; RUN:     | FileCheck %s
> --check-prefixes=CHECK-O,CHECK-O3,CHECK-O23SZ,CHECK-POSTLINK-O,CHECK-POSTLINK-O3
> +; RUN:     | FileCheck %s
> --check-prefixes=CHECK-O,CHECK-O3,CHECK-O23SZ,CHECK-POSTLINK-O,%llvmcheckext,CHECK-POSTLINK-O3
>  ; RUN: opt -disable-verify -debug-pass-manager \
>  ; RUN:     -passes='thinlto<Os>' -S %s 2>&1 \
> -; RUN:     | FileCheck %s
> --check-prefixes=CHECK-O,CHECK-Os,CHECK-O23SZ,CHECK-POSTLINK-O,CHECK-POSTLINK-Os
> +; RUN:     | FileCheck %s
> --check-prefixes=CHECK-O,CHECK-Os,CHECK-O23SZ,CHECK-POSTLINK-O,%llvmcheckext,CHECK-POSTLINK-Os
>  ; RUN: opt -disable-verify -debug-pass-manager \
>  ; RUN:     -passes='thinlto<Oz>' -S %s 2>&1 \
> -; RUN:     | FileCheck %s
> --check-prefixes=CHECK-O,CHECK-Oz,CHECK-O23SZ,CHECK-POSTLINK-O,CHECK-POSTLINK-Oz
> +; RUN:     | FileCheck %s
> --check-prefixes=CHECK-O,CHECK-Oz,CHECK-O23SZ,CHECK-POSTLINK-O,%llvmcheckext,CHECK-POSTLINK-Oz
>  ; RUN: opt -disable-verify -debug-pass-manager
> -new-pm-debug-info-for-profiling \
>  ; RUN:     -passes='thinlto<O2>' -S  %s 2>&1 \
> -; RUN:     | FileCheck %s
> --check-prefixes=CHECK-O,CHECK-O2,CHECK-O23SZ,CHECK-POSTLINK-O,CHECK-POSTLINK-O2
> +; RUN:     | FileCheck %s
> --check-prefixes=CHECK-O,CHECK-O2,CHECK-O23SZ,CHECK-POSTLINK-O,%llvmcheckext,CHECK-POSTLINK-O2
>  ;
>  ; CHECK-O: Running analysis: PassInstrumentationAnalysis
>  ; CHECK-O-NEXT: Starting llvm::Module pass manager run.
> @@ -207,6 +207,7 @@
>  ; CHECK-POSTLINK-O-NEXT: Starting llvm::Function pass manager run.
>  ; CHECK-POSTLINK-O-NEXT: Running pass: Float2IntPass
>  ; CHECK-POSTLINK-O-NEXT: Running pass: LowerConstantIntrinsicsPass
> +; CHECK-EXT: Running pass: {{.*}}::Bye
>  ; CHECK-POSTLINK-O-NEXT: Running pass:
> FunctionToLoopPassAdaptor<{{.*}}LoopRotatePass
>  ; CHECK-POSTLINK-O-NEXT: Starting llvm::Function pass manager run
>  ; CHECK-POSTLINK-O-NEXT: Running pass: LoopSimplifyPass
>
> diff  --git a/llvm/test/Other/opt-O0-pipeline.ll
> b/llvm/test/Other/opt-O0-pipeline.ll
> index 090620652069..ce431a502f93 100644
> --- a/llvm/test/Other/opt-O0-pipeline.ll
> +++ b/llvm/test/Other/opt-O0-pipeline.ll
> @@ -1,4 +1,4 @@
> -; RUN: opt -mtriple=x86_64-- -O0 -debug-pass=Structure < %s -o /dev/null
> 2>&1 | FileCheck %s
> +; RUN: opt -mtriple=x86_64-- -O0 -debug-pass=Structure < %s -o /dev/null
> 2>&1 | FileCheck %s --check-prefixes=CHECK,%llvmcheckext
>
>  ; REQUIRES: asserts
>
> @@ -6,6 +6,7 @@
>  ; CHECK-NEXT: Target Transform Information
>  ; CHECK-NEXT:   FunctionPass Manager
>  ; CHECK-NEXT:     Module Verifier
> +; CHECK-EXT:     Good Bye World Pass
>  ; CHECK-NEXT:     Instrument function entry/exit with calls to e.g.
> mcount() (pre inlining)
>  ; CHECK-NEXT: Pass Arguments:
>  ; CHECK-NEXT: Target Library Information
>
> diff  --git a/llvm/test/Other/opt-O2-pipeline.ll
> b/llvm/test/Other/opt-O2-pipeline.ll
> index d2630500fbdb..7e957651992e 100644
> --- a/llvm/test/Other/opt-O2-pipeline.ll
> +++ b/llvm/test/Other/opt-O2-pipeline.ll
> @@ -1,4 +1,4 @@
> -; RUN: opt -mtriple=x86_64-- -O2 -debug-pass=Structure < %s -o /dev/null
> 2>&1 | FileCheck %s
> +; RUN: opt -mtriple=x86_64-- -O2 -debug-pass=Structure < %s -o /dev/null
> 2>&1 | FileCheck --check-prefixes=CHECK-,%llvmcheckext %s
>
>  ; REQUIRES: asserts
>
> @@ -10,6 +10,8 @@
>  ; CHECK-NEXT: Target Library Information
>  ; CHECK-NEXT:   FunctionPass Manager
>  ; CHECK-NEXT:     Module Verifier
> +; CHECK-EXT:      Good Bye World Pass
> +; CHECK-NOEXT-NOT:      Good Bye World Pass
>  ; CHECK-NEXT:     Instrument function entry/exit with calls to e.g.
> mcount() (pre inlining)
>  ; CHECK-NEXT:     Simplify the CFG
>  ; CHECK-NEXT:     Dominator Tree Construction
>
> diff  --git a/llvm/test/Other/opt-O3-pipeline.ll
> b/llvm/test/Other/opt-O3-pipeline.ll
> index 82f6e8f5b558..d163d23df27a 100644
> --- a/llvm/test/Other/opt-O3-pipeline.ll
> +++ b/llvm/test/Other/opt-O3-pipeline.ll
> @@ -1,4 +1,4 @@
> -; RUN: opt -mtriple=x86_64-- -O3 -debug-pass=Structure < %s -o /dev/null
> 2>&1 | FileCheck %s
> +; RUN: opt -mtriple=x86_64-- -O3 -debug-pass=Structure < %s -o /dev/null
> 2>&1 | FileCheck --check-prefixes=CHECK-,%llvmcheckext %s
>
>  ; REQUIRES: asserts
>
> @@ -10,6 +10,8 @@
>  ; CHECK-NEXT: Target Library Information
>  ; CHECK-NEXT:   FunctionPass Manager
>  ; CHECK-NEXT:     Module Verifier
> +; CHECK-EXT:      Good Bye World Pass
> +; CHECK-NOEXT-NOT:      Good Bye World Pass
>  ; CHECK-NEXT:     Instrument function entry/exit with calls to e.g.
> mcount() (pre inlining)
>  ; CHECK-NEXT:     Simplify the CFG
>  ; CHECK-NEXT:     Dominator Tree Construction
>
> diff  --git a/llvm/test/Other/opt-Os-pipeline.ll
> b/llvm/test/Other/opt-Os-pipeline.ll
> index c690cc5d9641..9ec7325575a6 100644
> --- a/llvm/test/Other/opt-Os-pipeline.ll
> +++ b/llvm/test/Other/opt-Os-pipeline.ll
> @@ -1,4 +1,4 @@
> -; RUN: opt -mtriple=x86_64-- -Os -debug-pass=Structure < %s -o /dev/null
> 2>&1 | FileCheck %s
> +; RUN: opt -mtriple=x86_64-- -Os -debug-pass=Structure < %s -o /dev/null
> 2>&1 | FileCheck --check-prefixes=CHECK-,%llvmcheckext %s
>
>  ; REQUIRES: asserts
>
> @@ -10,6 +10,8 @@
>  ; CHECK-NEXT: Target Library Information
>  ; CHECK-NEXT:   FunctionPass Manager
>  ; CHECK-NEXT:     Module Verifier
> +; CHECK-EXT:      Good Bye World Pass
> +; CHECK-NOEXT-NOT:      Good Bye World Pass
>  ; CHECK-NEXT:     Instrument function entry/exit with calls to e.g.
> mcount() (pre inlining)
>  ; CHECK-NEXT:     Simplify the CFG
>  ; CHECK-NEXT:     Dominator Tree Construction
>
> diff  --git a/llvm/test/lit.cfg.py b/llvm/test/lit.cfg.py
> index f9ebf88aac95..e785b220540f 100644
> --- a/llvm/test/lit.cfg.py
> +++ b/llvm/test/lit.cfg.py
> @@ -197,6 +197,18 @@ def get_asan_rtlib():
>  if config.has_plugins:
>      config.available_features.add('plugins')
>
> +if config.build_examples:
> +    config.available_features.add('examples')
> +
> +if config.linked_bye_extension and config.build_examples:
> +    config.substitutions.append(('%llvmcheckext', 'CHECK-EXT'))
> +    config.substitutions.append(('%loadbye', ''))
> +else:
> +    config.substitutions.append(('%llvmcheckext', 'CHECK-NOEXT'))
> +    config.substitutions.append(('%loadbye',
> +
>  '-load={}/libBye{}'.format(config.llvm_shlib_dir,
> +
> config.llvm_shlib_ext)))
> +
>  # Static libraries are not built if BUILD_SHARED_LIBS is ON.
>  if not config.build_shared_libs and not config.link_llvm_dylib:
>      config.available_features.add('static-libs')
>
> diff  --git a/llvm/test/lit.site.cfg.py.in b/llvm/test/lit.site.cfg.py.in
> index 2af688ed72db..0f5e09b6cdaa 100644
> --- a/llvm/test/lit.site.cfg.py.in
> +++ b/llvm/test/lit.site.cfg.py.in
> @@ -2,6 +2,9 @@
>
>  import sys
>
> +def cmake_bool(val):
> +    return val.lower() in (1, "on", "yes", "true", "y",)
> +
>  config.host_triple = "@LLVM_HOST_TRIPLE@"
>  config.target_triple = "@TARGET_TRIPLE@"
>  config.llvm_src_root = "@LLVM_SOURCE_DIR@"
> @@ -47,6 +50,7 @@ config.host_arch = "@HOST_ARCH@"
>  config.have_opt_viewer_modules = @LLVM_HAVE_OPT_VIEWER_MODULES@
>  config.libcxx_used = @LLVM_LIBCXX_USED@
>  config.has_plugins = @LLVM_ENABLE_PLUGINS@
> +config.linked_bye_extension = cmake_bool("@LLVM_BYE_LINK_INTO_TOOLS@")
>
>  # Support substitution of the tools_dir with user parameters. This is
>  # used when we can't determine the tool dir at configuration time.
>
> diff  --git a/llvm/tools/CMakeLists.txt b/llvm/tools/CMakeLists.txt
> index b0069e4f2ece..2ac35d733cf9 100644
> --- a/llvm/tools/CMakeLists.txt
> +++ b/llvm/tools/CMakeLists.txt
> @@ -9,14 +9,6 @@
>  # traversing each directory.
>  create_llvm_tool_options()
>
> -# Build polly before the tools: the tools link against polly when
> -# LINK_POLLY_INTO_TOOLS is set.
> -if(WITH_POLLY)
> -  add_llvm_external_project(polly)
> -else()
> -  set(LLVM_TOOL_POLLY_BUILD Off)
> -endif()
> -
>  if(NOT LLVM_BUILD_LLVM_DYLIB AND NOT LLVM_BUILD_LLVM_C_DYLIB)
>    set(LLVM_TOOL_LLVM_SHLIB_BUILD Off)
>  endif()
> @@ -51,6 +43,8 @@ add_llvm_external_project(mlir)
>  # file as external projects.
>  add_llvm_implicit_projects()
>
> +add_llvm_external_project(polly)
> +
>  # Add subprojects specified using LLVM_EXTERNAL_PROJECTS
>  foreach(p ${LLVM_EXTERNAL_PROJECTS})
>    add_llvm_external_project(${p})
>
> diff  --git a/llvm/tools/bugpoint/CMakeLists.txt
> b/llvm/tools/bugpoint/CMakeLists.txt
> index c1ef9173928c..0b5998e181eb 100644
> --- a/llvm/tools/bugpoint/CMakeLists.txt
> +++ b/llvm/tools/bugpoint/CMakeLists.txt
> @@ -32,14 +32,10 @@ add_llvm_tool(bugpoint
>    ToolRunner.cpp
>    bugpoint.cpp
>
> +  ENABLE_PLUGINS
> +
>    DEPENDS
>    intrinsics_gen
>    SUPPORT_PLUGINS
>    )
>  export_executable_symbols(bugpoint)
> -
> -if(WITH_POLLY AND LINK_POLLY_INTO_TOOLS)
> -  target_link_libraries(bugpoint PRIVATE Polly)
> -  # Ensure LLVMTarget can resolve dependences in Polly.
> -  target_link_libraries(bugpoint PRIVATE LLVMTarget)
> -endif(WITH_POLLY AND LINK_POLLY_INTO_TOOLS)
>
> diff  --git a/llvm/tools/bugpoint/bugpoint.cpp
> b/llvm/tools/bugpoint/bugpoint.cpp
> index 41ea9992a539..d29a79ee3e13 100644
> --- a/llvm/tools/bugpoint/bugpoint.cpp
> +++ b/llvm/tools/bugpoint/bugpoint.cpp
> @@ -21,6 +21,7 @@
>  #include "llvm/InitializePasses.h"
>  #include "llvm/LinkAllIR.h"
>  #include "llvm/LinkAllPasses.h"
> +#include "llvm/Passes/PassPlugin.h"
>  #include "llvm/Support/CommandLine.h"
>  #include "llvm/Support/InitLLVM.h"
>  #include "llvm/Support/ManagedStatic.h"
> @@ -134,11 +135,9 @@ static void
> AddOptimizationPasses(legacy::FunctionPassManager &FPM,
>    Builder.populateModulePassManager(FPM);
>  }
>
> -#ifdef LINK_POLLY_INTO_TOOLS
> -namespace polly {
> -void initializePollyPasses(llvm::PassRegistry &Registry);
> -}
> -#endif
> +#define HANDLE_EXTENSION(Ext)
>       \
> +  llvm::PassPluginLibraryInfo get##Ext##PluginInfo();
> +#include "llvm/Support/Extension.def"
>
>  int main(int argc, char **argv) {
>  #ifndef DEBUG_BUGPOINT
> @@ -159,10 +158,6 @@ int main(int argc, char **argv) {
>    initializeInstrumentation(Registry);
>    initializeTarget(Registry);
>
> -#ifdef LINK_POLLY_INTO_TOOLS
> -  polly::initializePollyPasses(Registry);
> -#endif
> -
>    if (std::getenv("bar") == (char*) -1) {
>      InitializeAllTargets();
>      InitializeAllTargetMCs();
> @@ -234,6 +229,13 @@ int main(int argc, char **argv) {
>    sys::Process::PreventCoreFiles();
>  #endif
>
> +// Needed to pull in symbols from statically linked extensions, including
> static
> +// registration. It is unused otherwise because bugpoint has no support
> for
> +// NewPM.
> +#define HANDLE_EXTENSION(Ext)
>       \
> +  (void)get##Ext##PluginInfo();
> +#include "llvm/Support/Extension.def"
> +
>    if (Error E = D.run()) {
>      errs() << toString(std::move(E));
>      return 1;
>
> diff  --git a/llvm/tools/opt/CMakeLists.txt b/llvm/tools/opt/CMakeLists.txt
> index 4ea9baf447a9..b19291849577 100644
> --- a/llvm/tools/opt/CMakeLists.txt
> +++ b/llvm/tools/opt/CMakeLists.txt
> @@ -33,12 +33,10 @@ add_llvm_tool(opt
>    PrintSCC.cpp
>    opt.cpp
>
> +  ENABLE_PLUGINS
> +
>    DEPENDS
>    intrinsics_gen
>    SUPPORT_PLUGINS
>    )
>  export_executable_symbols(opt)
> -
> -if(WITH_POLLY AND LINK_POLLY_INTO_TOOLS)
> -  target_link_libraries(opt PRIVATE Polly)
> -endif(WITH_POLLY AND LINK_POLLY_INTO_TOOLS)
>
> diff  --git a/llvm/tools/opt/NewPMDriver.cpp
> b/llvm/tools/opt/NewPMDriver.cpp
> index c3b0db57e867..ac04a32d93fd 100644
> --- a/llvm/tools/opt/NewPMDriver.cpp
> +++ b/llvm/tools/opt/NewPMDriver.cpp
> @@ -202,11 +202,9 @@ static void registerEPCallbacks(PassBuilder &PB, bool
> VerifyEachPass,
>          });
>  }
>
> -#ifdef LINK_POLLY_INTO_TOOLS
> -namespace polly {
> -void RegisterPollyPasses(PassBuilder &);
> -}
> -#endif
> +#define HANDLE_EXTENSION(Ext)
>       \
> +  llvm::PassPluginLibraryInfo get##Ext##PluginInfo();
> +#include "llvm/Support/Extension.def"
>
>  bool llvm::runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM,
>                             ToolOutputFile *Out, ToolOutputFile
> *ThinLTOLinkOut,
> @@ -290,9 +288,9 @@ bool llvm::runPassPipeline(StringRef Arg0, Module &M,
> TargetMachine *TM,
>          return false;
>        });
>
> -#ifdef LINK_POLLY_INTO_TOOLS
> -  polly::RegisterPollyPasses(PB);
> -#endif
> +#define HANDLE_EXTENSION(Ext)
>       \
> +  get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB);
> +#include "llvm/Support/Extension.def"
>
>    // Specially handle the alias analysis manager so that we can register
>    // a custom pipeline of AA passes with it.
>
> diff  --git a/llvm/tools/opt/opt.cpp b/llvm/tools/opt/opt.cpp
> index 1cfc56e1f56a..6c947e77b55b 100644
> --- a/llvm/tools/opt/opt.cpp
> +++ b/llvm/tools/opt/opt.cpp
> @@ -482,11 +482,6 @@ static TargetMachine* GetTargetMachine(Triple
> TheTriple, StringRef CPUStr,
>                                          getCodeModel(),
> GetCodeGenOptLevel());
>  }
>
> -#ifdef LINK_POLLY_INTO_TOOLS
> -namespace polly {
> -void initializePollyPasses(llvm::PassRegistry &Registry);
> -}
> -#endif
>
>  void exportDebugifyStats(llvm::StringRef Path, const DebugifyStatsMap
> &Map) {
>    std::error_code EC;
> @@ -564,10 +559,6 @@ int main(int argc, char **argv) {
>    initializeHardwareLoopsPass(Registry);
>    initializeTypePromotionPass(Registry);
>
> -#ifdef LINK_POLLY_INTO_TOOLS
> -  polly::initializePollyPasses(Registry);
> -#endif
> -
>    cl::ParseCommandLineOptions(argc, argv,
>      "llvm .bc -> .bc modular optimizer and analysis printer\n");
>
>
> diff  --git a/llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn
> b/llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn
> index f39c193ba87e..517d96d7ee89 100644
> --- a/llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn
> +++ b/llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn
> @@ -319,7 +319,6 @@ write_cmake_config("llvm-config") {
>    output = "$target_gen_dir/llvm-config.h"
>    values = [
>      "LLVM_ENABLE_DUMP=",
> -    "LINK_POLLY_INTO_TOOLS=",
>      "LLVM_DEFAULT_TARGET_TRIPLE=$llvm_target_triple",
>      "LLVM_HAS_ATOMICS=1",
>      "LLVM_HOST_TRIPLE=$llvm_current_triple",
>
> diff  --git a/polly/include/polly/RegisterPasses.h
> b/polly/include/polly/RegisterPasses.h
> index 2126db9c2df5..afa9cd85b636 100644
> --- a/polly/include/polly/RegisterPasses.h
> +++ b/polly/include/polly/RegisterPasses.h
> @@ -15,6 +15,8 @@
>
>  namespace llvm {
>  class PassRegistry;
> +class PassBuilder;
> +class PassPluginLibraryInfo;
>  namespace legacy {
>  class PassManagerBase;
>  } // namespace legacy
> @@ -22,6 +24,9 @@ class PassManagerBase;
>
>  namespace polly {
>  void initializePollyPasses(llvm::PassRegistry &Registry);
> -void registerPollyPasses(llvm::legacy::PassManagerBase &PM);
> +void registerPollyPasses(llvm::PassBuilder &PB);
>  } // namespace polly
> +
> +llvm::PassPluginLibraryInfo getPollyPluginInfo();
> +
>  #endif
>
> diff  --git a/polly/lib/CMakeLists.txt b/polly/lib/CMakeLists.txt
> index 5bbc4dcf1090..e76d6039ad5a 100644
> --- a/polly/lib/CMakeLists.txt
> +++ b/polly/lib/CMakeLists.txt
> @@ -23,7 +23,7 @@ endif ()
>
>  # Use an object-library to add the same files to multiple libs without
> requiring
>  # the sources them to be recompiled for each of them.
> -add_library(PollyCore OBJECT
> +add_llvm_pass_plugin(Polly
>    Analysis/DependenceInfo.cpp
>    Analysis/PolyhedralInfo.cpp
>    Analysis/ScopDetection.cpp
> @@ -70,13 +70,13 @@ add_library(PollyCore OBJECT
>    Transform/ScopInliner.cpp
>    ${POLLY_HEADER_FILES}
>    )
> -set_target_properties(PollyCore PROPERTIES FOLDER "Polly")
> +set_target_properties(obj.Polly PROPERTIES FOLDER "Polly")
> +set_target_properties(Polly PROPERTIES FOLDER "Polly")
>
>  # Create the library that can be linked into LLVM's tools and Polly's
> unittests.
>  # It depends on all library it needs, such that with
>  # LLVM_POLLY_LINK_INTO_TOOLS=ON, its dependencies like PollyISL are
> linked as
>  # well.
> -add_polly_library(Polly $<TARGET_OBJECTS:PollyCore>)
>  target_link_libraries(Polly PUBLIC
>    ${ISL_TARGET}
>  )
> @@ -124,6 +124,9 @@ else ()
>      LLVMTarget
>      LLVMVectorize
>      )
> +
> +    # Polly-ACC requires the NVPTX target to be present in the executable
> it is linked to
> +    set_property(TARGET bugpoint APPEND PROPERTY LINK_LIBRARIES
> LLVMTarget)
>  endif ()
>
>  # Create a loadable module Polly.so that can be loaded using
> @@ -134,8 +137,8 @@ if (MSVC)
>    set_target_properties(LLVMPolly PROPERTIES FOLDER "Polly")
>  else ()
>    add_polly_loadable_module(LLVMPolly
> -    Polly.cpp
> -    $<TARGET_OBJECTS:PollyCore>
> +    Plugin/Polly.cpp
> +    $<TARGET_OBJECTS:obj.Polly>
>    )
>
>    # Only add the dependencies that are not part of LLVM. The latter are
> assumed
> @@ -159,5 +162,5 @@ endif ()
>
>  if (TARGET intrinsics_gen)
>    # Check if we are building as part of an LLVM build
> -  add_dependencies(PollyCore intrinsics_gen)
> +  add_dependencies(obj.Polly intrinsics_gen)
>  endif()
>
> diff  --git a/polly/lib/Plugin/Polly.cpp b/polly/lib/Plugin/Polly.cpp
> new file mode 100644
> index 000000000000..f567d37c07ea
> --- /dev/null
> +++ b/polly/lib/Plugin/Polly.cpp
> @@ -0,0 +1,20 @@
> +//===---------- Polly.cpp - Initialize the Polly Module
> -------------------===//
> +//
> +// Part of the LLVM Project, under the Apache License v2.0 with LLVM
> Exceptions.
> +// See https://llvm.org/LICENSE.txt for license information.
> +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "polly/RegisterPasses.h"
> +#include "llvm/PassRegistry.h"
> +#include "llvm/Passes/PassPlugin.h"
> +
> +// Pass Plugin Entrypoints
> +
> +extern "C" LLVM_ATTRIBUTE_WEAK ::llvm::PassPluginLibraryInfo
> +llvmGetPassPluginInfo() {
> +  return getPollyPluginInfo();
> +}
>
> diff  --git a/polly/lib/Polly.cpp b/polly/lib/Polly.cpp
> deleted file mode 100644
> index e6bae931fc5d..000000000000
> --- a/polly/lib/Polly.cpp
> +++ /dev/null
> @@ -1,29 +0,0 @@
> -//===---------- Polly.cpp - Initialize the Polly Module
> -------------------===//
> -//
> -// Part of the LLVM Project, under the Apache License v2.0 with LLVM
> Exceptions.
> -// See https://llvm.org/LICENSE.txt for license information.
> -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
> -//
>
> -//===----------------------------------------------------------------------===//
> -//
>
> -//===----------------------------------------------------------------------===//
> -
> -#include "polly/RegisterPasses.h"
> -#include "llvm/PassRegistry.h"
> -
> -namespace {
> -
> -/// Initialize Polly passes when library is loaded.
> -///
> -/// We use the constructor of a statically declared object to initialize
> the
> -///
> diff erent Polly passes right after the Polly library is loaded. This
> ensures
> -/// that the Polly passes are available e.g. in the 'opt' tool.
> -class StaticInitializer {
> -public:
> -  StaticInitializer() {
> -    llvm::PassRegistry &Registry = *llvm::PassRegistry::getPassRegistry();
> -    polly::initializePollyPasses(Registry);
> -  }
> -};
> -static StaticInitializer InitializeEverything;
> -} // end of anonymous namespace.
>
> diff  --git a/polly/lib/Support/RegisterPasses.cpp
> b/polly/lib/Support/RegisterPasses.cpp
> index 1d31db5e9845..4ceca070b37f 100644
> --- a/polly/lib/Support/RegisterPasses.cpp
> +++ b/polly/lib/Support/RegisterPasses.cpp
> @@ -235,6 +235,23 @@ static cl::opt<bool> EnablePruneUnprofitable(
>      cl::desc("Bail out on unprofitable SCoPs before rescheduling"),
> cl::Hidden,
>      cl::init(true), cl::cat(PollyCategory));
>
> +namespace {
> +
> +/// Initialize Polly passes when library is loaded.
> +///
> +/// We use the constructor of a statically declared object to initialize
> the
> +///
> diff erent Polly passes right after the Polly library is loaded. This
> ensures
> +/// that the Polly passes are available e.g. in the 'opt' tool.
> +class StaticInitializer {
> +public:
> +  StaticInitializer() {
> +    llvm::PassRegistry &Registry = *llvm::PassRegistry::getPassRegistry();
> +    polly::initializePollyPasses(Registry);
> +  }
> +};
> +static StaticInitializer InitializeEverything;
> +} // end of anonymous namespace.
> +
>  namespace polly {
>  void initializePollyPasses(PassRegistry &Registry) {
>    initializeCodeGenerationPass(Registry);
> @@ -690,7 +707,7 @@ parseTopLevelPipeline(ModulePassManager &MPM,
>    return true;
>  }
>
> -void RegisterPollyPasses(PassBuilder &PB) {
> +void registerPollyPasses(PassBuilder &PB) {
>    PB.registerAnalysisRegistrationCallback(registerFunctionAnalyses);
>    PB.registerPipelineParsingCallback(parseFunctionPipeline);
>    PB.registerPipelineParsingCallback(parseScopPipeline);
> @@ -702,9 +719,7 @@ void RegisterPollyPasses(PassBuilder &PB) {
>  }
>  } // namespace polly
>
> -// Plugin Entrypoint:
> -extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
> -llvmGetPassPluginInfo() {
> +llvm::PassPluginLibraryInfo getPollyPluginInfo() {
>    return {LLVM_PLUGIN_API_VERSION, "Polly", LLVM_VERSION_STRING,
> -          polly::RegisterPollyPasses};
> +          polly::registerPollyPasses};
>  }
>
> diff  --git a/polly/test/Unit/lit.site.cfg.in b/polly/test/Unit/
> lit.site.cfg.in
> index 930fef5884ff..837d6c685ce2 100644
> --- a/polly/test/Unit/lit.site.cfg.in
> +++ b/polly/test/Unit/lit.site.cfg.in
> @@ -13,7 +13,7 @@ config.enable_shared = @ENABLE_SHARED@
>  config.shlibdir = "@SHLIBDIR@"
>  config.target_triple = "@TARGET_TRIPLE@"
>  config.enable_gpgpu_codegen = "@GPU_CODEGEN@"
> -config.link_polly_into_tools = "@LINK_POLLY_INTO_TOOLS@"
> +config.llvm_polly_link_into_tools = "@LLVM_POLLY_LINK_INTO_TOOLS@"
>  config.has_unittests = @POLLY_GTEST_AVAIL@
>
>  # Support substitution of the tools_dir, libs_dirs, and build_mode with
> user
>
> diff  --git a/polly/test/lit.site.cfg.in b/polly/test/lit.site.cfg.in
> index ad8437478b16..83f3aa470fc4 100644
> --- a/polly/test/lit.site.cfg.in
> +++ b/polly/test/lit.site.cfg.in
> @@ -8,7 +8,7 @@ config.polly_obj_root = "@POLLY_BINARY_DIR@"
>  config.polly_lib_dir = "@POLLY_LIB_DIR@"
>  config.target_triple = "@TARGET_TRIPLE@"
>  config.enable_gpgpu_codegen = "@GPU_CODEGEN@"
> -config.link_polly_into_tools = "@LINK_POLLY_INTO_TOOLS@"
> +config.llvm_polly_link_into_tools = "@LLVM_POLLY_LINK_INTO_TOOLS@"
>  config.targets_to_build = "@TARGETS_TO_BUILD@"
>  config.extra_paths = "@POLLY_TEST_EXTRA_PATHS@".split(";")
>
> @@ -36,14 +36,14 @@ except KeyError:
>  # directories.
>  config.excludes = ['Inputs']
>
> -if config.link_polly_into_tools == '' or \
> -   config.link_polly_into_tools.lower() == '0' or \
> -   config.link_polly_into_tools.lower() == 'n' or \
> -   config.link_polly_into_tools.lower() == 'no' or \
> -   config.link_polly_into_tools.lower() == 'off' or \
> -   config.link_polly_into_tools.lower() == 'false' or \
> -   config.link_polly_into_tools.lower() == 'notfound' or \
> -   config.link_polly_into_tools.lower() ==
> 'link_polly_into_tools-notfound':
> +if config.llvm_polly_link_into_tools == '' or \
> +   config.llvm_polly_link_into_tools.lower() == '0' or \
> +   config.llvm_polly_link_into_tools.lower() == 'n' or \
> +   config.llvm_polly_link_into_tools.lower() == 'no' or \
> +   config.llvm_polly_link_into_tools.lower() == 'off' or \
> +   config.llvm_polly_link_into_tools.lower() == 'false' or \
> +   config.llvm_polly_link_into_tools.lower() == 'notfound' or \
> +   config.llvm_polly_link_into_tools.lower() ==
> 'llvm_polly_link_into_tools-notfound':
>      config.substitutions.append(('%loadPolly', '-load '
>                                   + config.polly_lib_dir +
> '/LLVMPolly at LLVM_SHLIBEXT@'
>                                   + ' -load-pass-plugin '
>
> diff  --git a/polly/test/update_check.py b/polly/test/update_check.py
> index 318fcfe53c9f..53c0845b8907 100644
> --- a/polly/test/update_check.py
> +++ b/polly/test/update_check.py
> @@ -15,7 +15,7 @@
>  polly_lib_dir = '''@POLLY_LIB_DIR@'''
>  shlibext = '''@LLVM_SHLIBEXT@'''
>  llvm_tools_dir = '''@LLVM_TOOLS_DIR@'''
> -link_polly_into_tools = not '''@LINK_POLLY_INTO_TOOLS@'''.lower() in
> {'','0','n','no','off','false','notfound','link_polly_into_tools-notfound'}
> +llvm_polly_link_into_tools = not '''@LLVM_POLLY_LINK_INTO_TOOLS@'''.lower()
> in
> {'','0','n','no','off','false','notfound','llvm_polly_link_into_tools-notfound'}
>
>  runre = re.compile(r'\s*\;\s*RUN\s*\:(?P<tool>.*)')
>  filecheckre =
> re.compile(r'\s*(?P<tool>.*)\|\s*(?P<filecheck>FileCheck\s[^|]*)')
> @@ -298,7 +298,7 @@ def main():
>              toolarg = toolarg.replace('%s', filename)
>              toolarg = toolarg.replace('%S', os.path.dirname(filename))
>              if toolarg == '%loadPolly':
> -                if not link_polly_into_tools:
> +                if not llvm_polly_link_into_tools:
>                      newtool +=
> ['-load',os.path.join(polly_lib_dir,'LLVMPolly' + shlibext)]
>                  newtool.append('-polly-process-unprofitable')
>                  newtool.append('-polly-remarks-minimal')
>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200106/b73ff697/attachment-0001.html>


More information about the cfe-commits mailing list