diff --git a/clang/tools/driver/CMakeLists.txt b/clang/tools/driver/CMakeLists.txt --- a/clang/tools/driver/CMakeLists.txt +++ b/clang/tools/driver/CMakeLists.txt @@ -35,6 +35,8 @@ cc1as_main.cpp cc1gen_reproducer_main.cpp + ENABLE_PLUGINS + DEPENDS ${tablegen_deps} ) @@ -122,7 +124,3 @@ 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 --- a/clang/tools/driver/cc1_main.cpp +++ b/clang/tools/driver/cc1_main.cpp @@ -69,12 +69,6 @@ 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() { @@ -183,11 +177,6 @@ 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 DiagOpts = new DiagnosticOptions(); diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -446,29 +446,6 @@ 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 ) @@ -1118,3 +1095,27 @@ add_subdirectory(utils/benchmark) add_subdirectory(benchmarks) endif() + +# 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. +get_target_property(LLVM_EXTENSIONS LLVM_PLUGINS 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") + 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_different "${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") diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake --- a/llvm/cmake/modules/AddLLVM.cmake +++ b/llvm/cmake/modules/AddLLVM.cmake @@ -715,7 +715,7 @@ macro(add_llvm_executable name) cmake_parse_arguments(ARG - "DISABLE_LLVM_LINK_LLVM_DYLIB;IGNORE_EXTERNALIZE_DEBUGINFO;NO_INSTALL_RPATH" + "DISABLE_LLVM_LINK_LLVM_DYLIB;IGNORE_EXTERNALIZE_DEBUGINFO;NO_INSTALL_RPATH;ENABLE_PLUGINS" "ENTITLEMENTS;BUNDLE_PATH" "DEPENDS" ${ARGN}) @@ -798,9 +798,45 @@ target_link_libraries(${name} PRIVATE ${LLVM_PTHREAD_LIB}) endif() + if (ARG_ENABLE_PLUGINS) + target_link_libraries(${name} PRIVATE $) + endif() + llvm_codesign(${name} ENTITLEMENTS ${ARG_ENTITLEMENTS} BUNDLE_PATH ${ARG_BUNDLE_PATH}) endmacro(add_llvm_executable name) +# register_llvm_extension(name entry_point) +# Register ${name} as an llvm compiler extension. +# This extension must provide a top-level function named ${entry_point} with the following signature: +# llvm::PassPluginLibraryInfo ${entry_point}(); +add_custom_target(LLVM_PLUGINS) # target used to hold global properties referencable from generator-expression +function(register_llvm_extension llvm_extension entry_point) + 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}) + + option(LLVM_${llvm_extension_upper}_LINK_INTO_TOOLS "Statically link ${llvm_extension_project} into tools (if available)" ON) + option(LLVM_${llvm_extension_upper}_BUILD "Build LLVM with ${llvm_extension_project}" ON) + + if(LLVM_${llvm_extension_upper}_BUILD) + message(STATUS "Registering ${llvm_extension_project} as a compiler extension (static build: ${LLVM_${llvm_extension_upper}_LINK_INTO_TOOLS})") + if(LLVM_${llvm_extension_upper}_LINK_INTO_TOOLS) + set_property(TARGET LLVM_PLUGINS APPEND PROPERTY LLVM_COMPILE_EXTENSIONS ${llvm_extension}) + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/entry_point.cpp + "#include \n" + "llvm::PassPluginLibraryInfo ${entry_point}();\n" + "llvm::PassPluginLibraryInfo get${llvm_extension_project}PluginInfo() { return ${entry_point}(); }") + target_sources(${llvm_extension_project} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/entry_point.cpp) + + endif() + else() + message(STATUS "Skipping compiler extension ${llvm_extension_project}") + endif() +endfunction(register_llvm_extension) + 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 --- a/llvm/docs/WritingAnLLVMPass.rst +++ b/llvm/docs/WritingAnLLVMPass.rst @@ -1219,6 +1219,30 @@ this internal state. This method is called after the ``run*`` method for the class, before the next call of ``run*`` in your pass. +Building out-of-tree passes +=========================== + +LLVM provides a mechanism to automatically register compiler passes for ``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_library(Name source0.cpp) + register_llvm_extension(Name entry_point) + +``entry_point`` is a top-level, user provided function with the following +signature: ``llvm::PassPluginLibraryInfo entry_point()``. It is used for +pass description by the new PM. + +Out-of-tree passes are compiled and link statically by default, but it's +possible to set the following variables to change this behavior: + +- ``LLVM_${NAME}_LINK_INTO_TOOLS``, when sets to ``OFF``, turns the project into a dynamically loaded extension. +- ``LLVM_${NAME}_BUILD``, when sets to ``OFF`` deactivate the extension. + + Registering dynamically loaded passes ===================================== diff --git a/llvm/include/llvm/Config/llvm-config.h.cmake b/llvm/include/llvm/Config/llvm-config.h.cmake --- 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/tools/CMakeLists.txt b/llvm/tools/CMakeLists.txt --- 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() @@ -50,6 +42,8 @@ # 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 --- a/llvm/tools/bugpoint/CMakeLists.txt +++ b/llvm/tools/bugpoint/CMakeLists.txt @@ -35,13 +35,9 @@ ToolRunner.cpp bugpoint.cpp + ENABLE_PLUGINS + DEPENDS intrinsics_gen ) 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 --- a/llvm/tools/bugpoint/bugpoint.cpp +++ b/llvm/tools/bugpoint/bugpoint.cpp @@ -109,12 +109,6 @@ }; } -#ifdef LINK_POLLY_INTO_TOOLS -namespace polly { -void initializePollyPasses(llvm::PassRegistry &Registry); -} -#endif - int main(int argc, char **argv) { #ifndef DEBUG_BUGPOINT InitLLVM X(argc, argv); @@ -134,10 +128,6 @@ initializeInstrumentation(Registry); initializeTarget(Registry); -#ifdef LINK_POLLY_INTO_TOOLS - polly::initializePollyPasses(Registry); -#endif - if (std::getenv("bar") == (char*) -1) { InitializeAllTargets(); InitializeAllTargetMCs(); diff --git a/llvm/tools/opt/CMakeLists.txt b/llvm/tools/opt/CMakeLists.txt --- a/llvm/tools/opt/CMakeLists.txt +++ b/llvm/tools/opt/CMakeLists.txt @@ -37,11 +37,9 @@ PrintSCC.cpp opt.cpp + ENABLE_PLUGINS + DEPENDS intrinsics_gen ) 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 --- a/llvm/tools/opt/NewPMDriver.cpp +++ b/llvm/tools/opt/NewPMDriver.cpp @@ -202,11 +202,9 @@ }); } -#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 @@ 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 --- a/llvm/tools/opt/opt.cpp +++ b/llvm/tools/opt/opt.cpp @@ -470,12 +470,6 @@ getCodeModel(), GetCodeGenOptLevel()); } -#ifdef LINK_POLLY_INTO_TOOLS -namespace polly { -void initializePollyPasses(llvm::PassRegistry &Registry); -} -#endif - //===----------------------------------------------------------------------===// // main for opt // @@ -530,10 +524,6 @@ initializeWriteBitcodePassPass(Registry); initializeHardwareLoopsPass(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 --- a/llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn @@ -321,7 +321,6 @@ 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 --- a/polly/include/polly/RegisterPasses.h +++ b/polly/include/polly/RegisterPasses.h @@ -22,6 +22,5 @@ namespace polly { void initializePollyPasses(llvm::PassRegistry &Registry); -void registerPollyPasses(llvm::legacy::PassManagerBase &PM); } // namespace polly #endif diff --git a/polly/lib/CMakeLists.txt b/polly/lib/CMakeLists.txt --- a/polly/lib/CMakeLists.txt +++ b/polly/lib/CMakeLists.txt @@ -134,7 +134,6 @@ set_target_properties(LLVMPolly PROPERTIES FOLDER "Polly") else () add_polly_loadable_module(LLVMPolly - Polly.cpp $ ) @@ -161,3 +160,8 @@ # Check if we are building as part of an LLVM build add_dependencies(PollyCore intrinsics_gen) endif() + +register_llvm_extension(Polly getPassPluginInfo) +# Polly-ACC requires the NVPTX target to be present in the executable it is linked to +set_property(TARGET bugpoint APPEND PROPERTY LLVM_COMPILER_EXTENSIONS LLVMTarget) + diff --git a/polly/lib/Polly.cpp b/polly/lib/Polly.cpp deleted file mode 100644 --- 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 -/// different 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 --- a/polly/lib/Support/RegisterPasses.cpp +++ b/polly/lib/Support/RegisterPasses.cpp @@ -701,9 +701,29 @@ } } // namespace polly -// Plugin Entrypoint: -extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK -llvmGetPassPluginInfo() { +/// Initialize Polly passes when library is loaded (shared library mode) or +/// linked into executable (static library mode) +/// +/// We use the constructor of a statically declared object to initialize the +/// different 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; + +// Pass Plugin Entrypoints +llvm::PassPluginLibraryInfo getPassPluginInfo() { return {LLVM_PLUGIN_API_VERSION, "Polly", LLVM_VERSION_STRING, polly::RegisterPollyPasses}; } + +extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK +llvmGetPassPluginInfo() { + return getPassPluginInfo(); +} diff --git a/polly/test/Unit/lit.site.cfg.in b/polly/test/Unit/lit.site.cfg.in --- a/polly/test/Unit/lit.site.cfg.in +++ b/polly/test/Unit/lit.site.cfg.in @@ -13,7 +13,7 @@ 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 --- a/polly/test/lit.site.cfg.in +++ b/polly/test/lit.site.cfg.in @@ -8,7 +8,7 @@ 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 @@ # 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@LLVM_SHLIBEXT@' + ' -load-pass-plugin ' diff --git a/polly/test/update_check.py b/polly/test/update_check.py --- 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.*)') filecheckre = re.compile(r'\s*(?P.*)\|\s*(?PFileCheck\s[^|]*)') @@ -298,7 +298,7 @@ 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')