Page MenuHomePhabricator

Generalize the pass registration mechanism used by Polly to any third-party tool
Needs ReviewPublic

Authored by serge-sans-paille on May 2 2019, 9:11 AM.

Details

Summary

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 an attempt at doing so, using Polly as reference.

Diff Detail

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes

Fail the regression tests under Linux:

$ ninja check-polly
[...]
: 'RUN: at line 1';   opt -load /home/meinersbur/build/llvm/release/lib/LLVMPolly.so -load-pass-plugin /home/meinersbur/build/llvm/release/lib/LLVMPolly.so [...]
--
Exit Code: 2

Command Output (stderr):
--
opt: CommandLine Error: Option 'polly-dependences-computeout' registered more than once!
LLVM ERROR: inconsistency in registered CommandLine options
[...]

This error typically appears when polly is statically linked into tools (LINK_POLLY_INTO_TOOLS=ON), but the shared library is loaded as well at run-time (-load /home/meinersbur/build/llvm/release/lib/LLVMPolly.so). You probably will have to adjust polly/test/lit.site.cfg.in:

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':

To these long turnarounds, you could test these configurations yourself. Some time ago I made an overview on which combinations of dynamic/static linking should work: https://groups.google.com/d/msg/polly-dev/vxumPMhrSEs/E50kboqlAQAJ

For LTO, the llvm_extensions might need to be linked into lld as well. The recent polly-dev thread: https://groups.google.com/d/msg/polly-dev/BeC_v_oJIVM/LAA7vVT9AwAJ

However, since we don't even have this for Polly, I would leave it up to you whether to include this in this patch review.

@Meinersbur thanks a lot for the previous review! lld integration, as well as new PM integration, will be for another commit, in order to prevent this review from growing too large

Herald added a project: Restricted Project. · View Herald TranscriptJun 3 2019, 2:00 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript

I fear you'll need to plan at least for new pm right now. Otherwise your change will be obsolete in half a year. What is it really that LINK_X_INTO_TOOLS is supposed to do? Effectively bake in something that's consumable by -load or -load-plugin, right? So can we use that interface directly? Effectively, can we have statically built-in plugins, that prepopulate the plug-in loader mechanisms?

If the patch becomes too large then it should be split into separate functional units, e.g., one adding the cmake functionality, one updating the plugins and the tools.

You could also ask @beanz for a review of the cmake change.

Meinersbur requested changes to this revision.Jun 3 2019, 3:09 PM

It still fails with the same error. LINK_POLLY_INTO_TOOLS is only set after the polly subdirectory is processed. Because it is an option, the ON value will be stored in the CMakeCache.txt and be available during the next run, it actually works after running the cmake configure step a second time. We should not expect users to do so. Because of this, any option(...) or set(... CACHED) should be done at the beginning of the file.

llvm/CMakeLists.txt
460

Note that there is LLVM_POLLY_LINK_INTO_TOOLS and LINK_POLLY_INTO_TOOLS. The former is the user-configurable option, the latter is for internal querying. At least, this is what is was meant for.

916

Polly is included here. LINK_POLLY_INTO_TOOLS will not be visible in there if set only later.

llvm/cmake/modules/AddLLVM.cmake
828

[remark] Use LLVM_ prefix for LLVM-level options.

This revision now requires changes to proceed.Jun 3 2019, 3:09 PM
beanz added a comment.Jun 3 2019, 5:24 PM

I have a thought for how we can make the CMake interface for this better. Instead of LLVM_EXTENSIONS being a global property if it were a pre-defined list like LLVM_ALL_PROJECTS, then the LLVM_LINK_<X>_INTO_TOOLS variables can be generated by LLVM's configuration instead of relying on Polly's to run. If you do that LLVM_LINK_POLLY_INTO_TOOLS could be set to On even if Polly isn't enabled to build, but that actually will be fine if you change the calls to target_link_libraries in the tools to use a generator expression something like: $<$<TARGET_EXISTS:Polly>,Polly>.

These changes should eliminate the order-dependence on the tools and allow the first configuration run to be accurate.

  • reorder registration to make sure options are correctly taken into account
  • make LINK_POLLY_INTO_TOOLS obsolete in favor of just using LLVM_LINK_POLLY_INTO_TOOLS

@philip.pfaffe : NewPM integeration actually works thanks to `Register${Name}Passes(llvm::PassBuilder &PB)`. It's already used by Polly for NewPM integration and we mimic that.

@beanz turns out the depdendency problem was just a matter of moving the register_llvm_extension call at the top of the file.

Take into account @philip.pfaffe remarks and improve support for new PM.

  • harmonize static/dynamic loading, although two functions are still needed, one for dynamic loading and one for static loading (new PM)
  • do not clutter the required API with extra namespaces

I've updated https://sergesanspaille.fedorapeople.org/bye.tgz to showcase a minimal example.

  • make it possible for client code to speicify the registration function for new PM, thanks @philip.pfaffe for the hint. @Meinersbur this should be ok now.
  • get Rid of the constraint on initializePasses : it can be registered suing a static constructor, no need to clutter the API with it

This fails with Polly/Linux regression tests:

********************
FAIL: Polly :: Simplify/gemm.ll (1148 of 1149)
******************** TEST 'Polly :: Simplify/gemm.ll' FAILED ********************
Script:
--
: 'RUN: at line 1';   opt  -polly-process-unprofitable  -polly-remarks-minimal  -polly-use-llvm-names  -polly-import-jscop-dir=/home/meinersbur/src/llvm/tools/polly/test/Simplify  -polly-codegen-verify  -polly-import-jscop    -polly-import-jscop-postfix=transformed -polly-simplify -analyze < /home/meinersbur/src/llvm/tools/polly/test/Simplify/gemm.ll    | FileCheck /home/meinersbur/src/llvm/tools/polly/test/Simplify/gemm.ll
--
Exit Code: 2

Command Output (stderr):
--
opt: for the   -o option: may not occur within a group!
opt: Unknown command line argument '-polly-import-jscop'.  Try: 'opt --help'
opt: Did you mean '  -o'?
opt: for the   -p option: may only occur zero or one times!
opt: for the   -o option: may not occur within a group!
opt: Unknown command line argument '-polly-simplify'.  Try: 'opt --help'
opt: Did you mean '  -o'?
FileCheck error: '-' is empty.
FileCheck command line:  FileCheck /home/meinersbur/src/llvm/tools/polly/test/Simplify/gemm.ll

I think this means that the Polly passes have not been registered (initializePollyPasses must be called someway in opt/clang_cc1/bugpoint). Linking from static libraries will NOT include Polly.o (and run its static initializers) unless it is needed to resolve at least one symbol.

PLEASE run make/ninja check-polly before uploading a patch.

llvm/tools/opt/opt.cpp
541

Where is the equivalent for this in your change? I see it's been done for clang_cc1, but not for opt/bugpoint.

polly/CMakeLists.txt
210 ↗(On Diff #203086)

[nit] Whitespace change

polly/lib/CMakeLists.txt
27

Why this change? Polly.cpp should only be necessary for the loadable module, but not for LLVM_LINK_POLLY_INTO_TOOLS.

Meinersbur requested changes to this revision.Jun 5 2019, 10:02 AM
This revision now requires changes to proceed.Jun 5 2019, 10:02 AM

Sorry, you might have tested it with LLVM_LINK_POLLY_INTO_TOOLS=OFF and/or BUILD_SHARED_LIBS/LLVM_LINK_LLVM_DYLIV where it might work, but unfortunately not with the default configuration using static component libraries.

beanz added inline comments.Jun 5 2019, 10:25 AM
llvm/cmake/modules/AddLLVM.cmake
840

I don't think we should hard code this list. It would be much better if we add an option to llvm_add_executable so that extension targets denote themselves.

842

if(TARGET ...) is order dependent. That's why you need to change tools/CMakeLists.txt, which you won't need to do if you change this to work how I suggested in my earlier comment.

@Meinersbur Itested with the following configuration

cmake3 ../llvm -DLLVM_EXTERNAL_PROJECTS=bye -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release  -DLLVM_TARGETS_TO_BUILD=X86

cmake3 ../llvm -DLLVM_EXTERNAL_PROJECTS=bye -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release  -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_POLLY_LINK_INTO_TOOLS=OFF

with old and mono repo layout. I'll test with BUILD_SHARED_LIBS=OFF too.

Just an idea: We could avoid the explicit calls to 'initializeXYZPass' in opt/bugpoint/clang by adding Polly.cpp as a source file or object library to the executables. This would guarantee that its static initializer is called without dynamic library.

Just an idea: We could avoid the explicit calls to 'initializeXYZPass' in opt/bugpoint/clang by adding Polly.cpp as a source file or object library to the executables. This would guarantee that its static initializer is called without dynamic library.

That's what I tried to do when always adding Polly.cpp to PollyCore, but it doesn't seem to be enough, I still need to invstigate why (it is actually enough when using BUILD_SHARED_LIBS=ON)

Using @beanz idea, provide an option to add_llvm_executable to declare it as receiving plugins, which provides lower coupling with actual plugins

Tested with four configurations: BUILD_SHARED_LIBS ON/OFF and with llvm-project / legacy configuration, but *not* on Windows

As suggested by @Meinersbur, use static constructor for initialization step with legacy PM, for both shared and static libraries.

The patch looks much less intrusive now, thanks a lot to all reviewers for the provided guidance.

serge-sans-paille marked 4 inline comments as done.Jun 8 2019, 9:00 AM
beanz added inline comments.Jun 10 2019, 10:40 AM
llvm/cmake/modules/AddLLVM.cmake
817

Change this to llvm-plugins to match our convention and wrap it in if (NOT TARGET...) so it doesn't error if AddLLVM is included twice.

Meinersbur requested changes to this revision.Jun 10 2019, 12:26 PM

That's what I tried to do when always adding Polly.cpp to PollyCore, but it doesn't seem to be enough, I still need to invstigate why (it is actually enough when using BUILD_SHARED_LIBS=ON)

With static libraries, you had the following structure:

PollyCore.a:
  RegisterPasses.o
  Polly.o <-- static initializer here, but never used

LLVMPolly.so (for use with -load mechanism)
  RegisterPasses.o
  Polly.o <-- static initializer here, executed when loading the .so

opt:
  main.o <-- call to initializePollyPass removed

With static linking, there is no reason for the linker to add Polly.o to the opt executable because no symbol from Polly.o (or any of PollyCore) was required to resolve any symbol in opt. Building a shared library using the object library files will include all object files, since it does not know which symbols will be used at runtime. I recommend reading http://www.lurklurk.org/linkers/linkers.html#staticlibs and https://www.bfilipek.com/2018/02/static-vars-static-lib.html.

What I proposed was

PollyCore.a:
  RegisterPasses.o

LLVMPolly.so (for use with -load mechanism)
  RegisterPasses.o
  Polly.o

opt: // or any ENABLE_PLUGINS tool
  main.o
  Polly.o // via add_executable(opt Polly.cpp) or target_sources

Adding the object file explicitly to the add_executable will add it unconditionally, even if no none of its symbol is required, like for LLVMPolly.so.

In the latest update you changed the location of the static initalizer to RegisterPasses.o, which contains the symbol llvmGetPassPluginInfo which is pulled-in by the new pass manager plugin system. This makes an unfortunate dependence of the static initializer on the llvmGetPassPluginInfo mechanism (which I think only works for opt in the current patch).

There is a reason why pass loading in Polly is organized as it is.

llvm/cmake/modules/AddLLVM.cmake
817

[serious] I get multiple of these errors by cmake:

CMake Error at cmake/modules/AddLLVM.cmake:812 (add_custom_target):
  add_custom_target cannot create target "LLVM_PLUGINS" because another
  target with the same name already exists.  The existing target is a custom
  target created in source directory "/home/meinersbur/src/llvm".  See
  documentation for policy CMP0002 for more details.
Call Stack (most recent call first):
  projects/compiler-rt/unittests/CMakeLists.txt:2 (include)
llvm/tools/opt/NewPMDriver.cpp
292

[serious] This will pull-in the symbol llvmGetPassPluginInfo from the plugin for opt, but what about the other tools (bugpoint/clang)?

polly/lib/Support/RegisterPasses.cpp
727

[serious] Unfortunately, the new pass manager's plugin system relies on the function name to be llvmGetPassPluginInfo in each plugin. This works with multiple dynamic libraries all declaring the same name using the PassPlugin::Load mechanism, but linking them all statically will violate the one-definition-rule.

IMHO, Polly.cpp would have been a better place for this function.

This revision now requires changes to proceed.Jun 10 2019, 12:26 PM
serge-sans-paille marked 3 inline comments as done.

@beanz : In addition to your suggested changes, I've renamed the cmake utility into add_llvm_pass_plugin to match other functions from AddLLVM.cmake

@Meinersbur : thanks a lot for the polly layout explanation. I've slighlty updated your suggection like this:

PollyCore.a:
  RegisterPasses.o
  polly_static_entry_point.cpp

LLVMPolly.so (for use with -load mechanism)
  RegisterPasses.o
  polly_plugin_entry_point.cpp

initialization is done in both cases through a static initializer in RegisterPasses.cpp. llvmGetPassPluginInfo is only available in polly_plugin_entry_point.cpp.

polly/lib/Support/RegisterPasses.cpp
727

but linking them all statically will violate the one-definition-rule.

They are unused when liked statically, and flagged as weak to avoid link-time conflict.

IMHO, Polly.cpp would have been a better place for this function.

I still agree it's more explicit if linked conditionaly.

Mostly documentation update + helper function renaming.

@Meinersbur, I've tested the setup with static and dynamic builds on Linux, please let me know your thoughts on this.

Meinersbur added inline comments.Jun 26 2019, 5:30 AM
llvm/cmake/modules/AddLLVM.cmake
813

[serious] I get the following error:

CMake Error at cmake/modules/AddLLVM.cmake:813 (add_custom_target):
  add_custom_target cannot create target "llvm-pass-plugins" because another
  target with the same name already exists.  The existing target is a custom
  target created in source directory "/home/meinersbur/src/llvm".  See
  documentation for policy CMP0002 for more details.
Call Stack (most recent call first):
  projects/compiler-rt/test/CMakeLists.txt:2 (include)

What you meant to use is

if (NOT TARGET llvm-pass-plugins)

See https://cmake.org/cmake/help/latest/command/if.html

856

[serious] Under Windows, I get the following error:

CMake Error at cmake/modules/AddLLVM.cmake:853 (target_sources):
  target_sources called with non-compilable target type
Call Stack (most recent call first):
  tools/polly/lib/CMakeLists.txt:164 (register_llvm_pass_plugin)

This is because "LLVMPolly" is not a library, but a dummy "add_custom_target" since loadable modules are not supported under Windows.

llvm/docs/WritingAnLLVMPass.rst
1244

"out-of-tree" is the wrong term. This registration only works if the plugin if configured in the same cmake-run. "out-of-tree" would describe a processes with a separate cmake source- and build-tree using LLVM_MAIN_SRC_DIR or https://llvm.org/docs/CMake.html#embedding-llvm-in-your-project

llvm/tools/CMakeLists.txt
45

What is the reason to have this after add_llvm_implicit_projects in contrast to the other LLVM subprojects?

polly/lib/Support/RegisterPasses.cpp
727

You seem to have removed the weak attribute. Did you mean to put it into the polly namespace to avoid name clashing with other plugins?

serge-sans-paille marked an inline comment as done.

@Meinersbur your comment and my devs crossed, but this should be fine. This update enables new PM static plugin support for clang, something that was lacking to polly previously. I've tested it a bit and it builds fine with static setup, still need to test it with more config.

serge-sans-paille marked 10 inline comments as done.Jun 26 2019, 6:37 AM
serge-sans-paille added inline comments.
llvm/cmake/modules/AddLLVM.cmake
813

I'm no longer using that mechanism, it was showing some limits wrt. cmake generator-expression and export set.

856

I'm no longer using target_sources, it should be fine now.

llvm/docs/WritingAnLLVMPass.rst
1244

I'm not super happy with the new title, but I gave it a try.

llvm/tools/CMakeLists.txt
45

polly used to be included before the other external projects, so that clang/opt could depend on it. We are now injecting dependencies a posteriori, so polly needs to be included after opt/clang/bugpoint. I've put it right before the loop on add_llvm_external_project because they share the same function call name.

polly/lib/Support/RegisterPasses.cpp
727

There are two entry points: llvmGetPassPluginInfo for new PM (marked as weak) and get##name##PluginInfo for legacy PM (name is supposed to be unique, no need for weak linkage)

Meinersbur requested changes to this revision.Jul 10 2019, 2:08 PM

Windows seems to work. Good job!

Linux works with static libraries, but not with BUILD_SHARED_LIBS=ON:

$ bin/opt
: CommandLine Error: Option 'polly-dependences-computeout' registered more than once!
LLVM ERROR: inconsistency in registered CommandLine options

This error is typical for having translation units (in this case: Polly's DependenceInfo.cpp) multiple times in the address space.

See https://groups.google.com/forum/#!topic/polly-dev/vxumPMhrSEs for the configurations I intend to test and which currently work.

llvm/cmake/modules/AddLLVM.cmake
818

Why use cmake_parse_arguments if there are no options to parse?

828

[concern] This requires that all plugin-able tool have been registered before. It might be confusing that not all plugins will be loaded into every tool if the relative order is not <all add_llvm_executable(... ENABLE_PLUGINS)> <all add_llvm_pass_plugin(...)>.

Is it possible to error-out if a ENABLE_PLUGINS happens after a plugin has been added via add_llvm_pass_plugin?

830

This injects all plugin sources directly into tool executable (in addition to loading them as a library with LINK_LIBRARIES), probably the reason for the error I see with BUILD_SHARED_LIBS.

It ignores the library separation, which is not a nice solution for the same reasons why LLVM does not simply add all object files from all its libraries to each of the add_llvm_executables, but instead uses target_link_libraries.

llvm/cmake/modules/LLVMProcessSources.cmake
112 ↗(On Diff #206648)

[nit] unrelated?

llvm/docs/WritingAnLLVMPass.rst
1262

"Out-of-tree" still mentioned here.

polly/lib/Support/RegisterPasses.cpp
727

Unfortunately, the Windows platform has no concept of weak symbols.

get##name##PluginInfo is not related to the legacy pass manager. The legacy passe manager uses llvm::PassRegistry and llvm::RegisterStandardPasses. polly::RegisterPollyPasses is only used by the new pass manager.

Could you create a second plugin using add_llvm_pass_plugin, for instance convert LLVMHello? Then we could check whether this works.

This revision now requires changes to proceed.Jul 10 2019, 2:08 PM
serge-sans-paille marked 5 inline comments as done and 2 inline comments as done.

Added a Bye project in examples/
Fixed linking of plugins into core tools
Fixed dependency issue

Meinersbur requested changes to this revision.Wed, Jul 24, 1:54 PM

Thank you for adding the Bye pass. It is really useful! Is there a specific reason to not modify the Hello pass?


If I enable both passes statically (LLVM_BYE_LINK_INTO_TOOLS=ON and LLVM_POLLY_LINK_INTO_TOOLS=ON), the following regression tests fail (ninja check-llvm):

Failing Tests (8):
    LLVM :: DebugInfo/debugify-each.ll
    LLVM :: Other/new-pm-defaults.ll
    LLVM :: Other/new-pm-thinlto-defaults.ll
    LLVM :: Other/opt-O0-pipeline.ll
    LLVM :: Other/opt-O2-pipeline.ll
    LLVM :: Other/opt-O3-pipeline.ll
    LLVM :: Other/opt-Os-pipeline.ll
    LLVM :: Transforms/LoopVectorize/X86/reg-usage.ll

The pass output such as

Bye: foo
Bye: goo
Bye: bar
Bye: hoo

seem to interfere with the CHECK lines in the test cases.


Using the configuration LLVM_LINK_LLVM_DYLIB=1 and LLVM_POLLY_LINK_INTO_TOOLS=ON, the following tests fail:

Failing Tests (10):
    LLVM :: BugPoint/compile-custom.ll
    LLVM :: BugPoint/crash-narrowfunctiontest.ll
    LLVM :: BugPoint/func-attrs-keyval.ll
    LLVM :: BugPoint/func-attrs.ll
    LLVM :: BugPoint/invalid-debuginfo.ll
    LLVM :: BugPoint/metadata.ll
    LLVM :: BugPoint/named-md.ll
    LLVM :: BugPoint/remove_arguments_test.ll
    LLVM :: BugPoint/replace-funcs-with-null.ll
    LLVM :: BugPoint/unsymbolized.ll

The error output is:

: CommandLine Error: Option 'disable-basicaa' registered more than once!
LLVM ERROR: inconsistency in registered CommandLine options"

As expected, on Windows, I get the following linker error with both LLVM_BYE_LINK_INTO_TOOLS=ON and LLVM_POLLY_LINK_INTO_TOOLS=ON:

[1/1] Linking CXX executable bin\clang.exe
FAILED: bin/clang.exe
cmd.exe /C "cd . && "C:\Program Files\CMake\bin\cmake.exe" -E vs_link_exe --intdir=tools\clang\tools\driver\CMakeFiles\clang.dir --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100177~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100177~1.0\x64\mt.exe --manifests  -- C:\PROGRA~2\MICROS~1\2017\COMMUN~1\VC\Tools\MSVC\1416~1.270\bin\Hostx64\x64\link.exe /nologo @CMakeFiles\clang.rsp  /out:bin\clang.exe /implib:lib\clang.lib /pdb:bin\clang.pdb /version:0.0  /machine:x64 /STACK:10000000 /INCREMENTAL:NO /subsystem:console  && cmd.exe /C "cd /D C:\Users\meinersbur\build\llvm\release\tools\clang\tools\driver && "C:\Program Files\CMake\bin\cmake.exe" -E copy C:/Users/meinersbur/build/llvm/release/bin/clang.exe C:/Users/meinersbur/build/llvm/release/./bin/clang++.exe && cd /D C:\Users\meinersbur\build\llvm\release\tools\clang\tools\driver && "C:\Program Files\CMake\bin\cmake.exe" -E copy C:/Users/meinersbur/build/llvm/release/bin/clang.exe C:/Users/meinersbur/build/llvm/release/./bin/clang-cl.exe && cd /D C:\Users\meinersbur\build\llvm\release\tools\clang\tools\driver && "C:\Program Files\CMake\bin\cmake.exe" -E copy C:/Users/meinersbur/build/llvm/release/bin/clang.exe C:/Users/meinersbur/build/llvm/release/./bin/clang-cpp.exe""
LINK: command "C:\PROGRA~2\MICROS~1\2017\COMMUN~1\VC\Tools\MSVC\1416~1.270\bin\Hostx64\x64\link.exe /nologo @CMakeFiles\clang.rsp /out:bin\clang.exe /implib:lib\clang.lib /pdb:bin\clang.pdb /version:0.0 /machine:x64 /STACK:10000000 /INCREMENTAL:NO /subsystem:console /MANIFEST /MANIFESTFILE:bin\clang.exe.manifest" failed (exit code 1169) with the following output:
Bye.lib(Bye.cpp.obj) : error LNK2005: llvmGetPassPluginInfo already defined in Polly.lib(RegisterPasses.cpp.obj)
bin\clang.exe : fatal error LNK1169: one or more multiply defined symbols found
ninja: build stopped: subcommand failed.
llvm/cmake/modules/AddLLVM.cmake
856–858

[nit] Please remove commented code entirely

llvm/examples/Bye/Bye.cpp
15

Could you add a test that verifies that the Bye test has been loaded and is working?

This revision now requires changes to proceed.Wed, Jul 24, 1:54 PM
  • Test extension point registration when extension is built-in
  • Correctly handle -DLLVM_LINK_LLVM_DYLIB=0
  • Fix a few details

@Meinersbur I've updated the test case to test extension point if the extension is linked in, this is not so intrusive, I'm happy with the solution.

Also fixed some linkage options when using llvm dynlib, validation looks nice on my side.

Make validation more resilient depending on shared/static build.

Did you resolve the conflicting llvmGetPassPluginInfo symbols for windows?

@Meinersbur nop, forgot that one, I'll have a look, thanks for pointing that out.

Also fix symbol redefinition during static builds on Windows