[llvm-dev] Opt plugin linkage

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

[llvm-dev] Opt plugin linkage

Alex L via llvm-dev
Hi,
I have a dynamically loaded llvm pass built in-tree with ninja (generated with cmake, basically a copy of the hallo pass plugin, linux, llvm/clang version 6.0.1).
It uses the ExecutionEngine.
Building it without linking against LLVMExecutionEngine library results in an undefined symbol to the vtable of the EngineBuilder when loaded to opt. Linking the plugin with LLVMExecutionEngine results in the pass simply not being executable with giving "opt: Unkown command line argument '-passArg'."
For a minimal example add set(LLVM_LINK_COMPONENTS Core) to the CMakeLists.txt of the Hello llvm pass.

There is no error or warning at any point when linking or loading a plugin linked against some  libs.
How do I find out which llvm libs I can't link with a dynamically loaded plugin?
How can I use the EngineBuilder in my plugin with proper symbol resolution?

For reproductivity:
cmake -G "Sublime Text 2 - Ninja" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DLLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON -DLLVM_BUILD_TESTS=ON -DLLVM_BUILD_EXAMPLES=ON -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" -DLLVM_TOOL_CLANG_BUILD=ON -DLLVM_TOOL_CLANG_TOOLS_EXTRA=ON -DLLVM_OPTIMIZED_TABLEGEN=ON -DCLANG_BUILD_EXAMPLES=ON -DCLANG_PLUGIN_SUPPORT=ON

Hope someone can help me out.
Viktor

_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Opt plugin linkage

Alex L via llvm-dev
Ooops didn’t read that clearly. I assume it’s due to your pass now uses the cl:: infrastructure in it’s own Core, not the opt’s. Try linking the components separately

Zhang

> 在 2019年4月16日,04:37,Viktor Was BSc via llvm-dev <[hidden email]> 写道:
>
> Hi,
> I have a dynamically loaded llvm pass built in-tree with ninja (generated with cmake, basically a copy of the hallo pass plugin, linux, llvm/clang version 6.0.1).
> It uses the ExecutionEngine.
> Building it without linking against LLVMExecutionEngine library results in an undefined symbol to the vtable of the EngineBuilder when loaded to opt. Linking the plugin with LLVMExecutionEngine results in the pass simply not being executable with giving "opt: Unkown command line argument '-passArg'."
> For a minimal example add set(LLVM_LINK_COMPONENTS Core) to the CMakeLists.txt of the Hello llvm pass.
>
> There is no error or warning at any point when linking or loading a plugin linked against some  libs.
> How do I find out which llvm libs I can't link with a dynamically loaded plugin?
> How can I use the EngineBuilder in my plugin with proper symbol resolution?
>
> For reproductivity:
> cmake -G "Sublime Text 2 - Ninja" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DLLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON -DLLVM_BUILD_TESTS=ON -DLLVM_BUILD_EXAMPLES=ON -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" -DLLVM_TOOL_CLANG_BUILD=ON -DLLVM_TOOL_CLANG_TOOLS_EXTRA=ON -DLLVM_OPTIMIZED_TABLEGEN=ON -DCLANG_BUILD_EXAMPLES=ON -DCLANG_PLUGIN_SUPPORT=ON
>
> Hope someone can help me out.
> Viktor
> _______________________________________________
> LLVM Developers mailing list
> [hidden email]
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev



_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Opt plugin linkage

Alex L via llvm-dev
In reply to this post by Alex L via llvm-dev
How come the hello pass example is so totally useless as a starting point? Why is this not using any library/compontent which could conflict with opt or clang and showing how to handle this? I have no clue as to how I have to setup llvm to get this to work or why it doesn't work in the first place with the setup described in "Getting started" and "writing an llvm pass" pages etc.
Also there is basically no documentation for the custom cmake commands.

Can please somebody help me with this issue? How do I get dynamically loaded llvm pass plugins to work? Am I the only one ever having this issue?

Thanks
Viktor
On Apr 16, 2019, at 05:38, Viktor Was BSc via llvm-dev <[hidden email]> wrote:
Hi,
I have a dynamically loaded llvm pass built in-tree with ninja (generated with cmake, basically a copy of the hallo pass plugin, linux, llvm/clang version 6.0.1).
It uses the ExecutionEngine.
Building it without linking against LLVMExecutionEngine library results in an undefined symbol to the vtable of the EngineBuilder when loaded to opt. Linking the plugin with LLVMExecutionEngine results in the pass simply not being executable with giving "opt: Unkown command line argument '-passArg'."
For a minimal example add set(LLVM_LINK_COMPONENTS Core) to the CMakeLists.txt of the Hello llvm pass.

There is no error or warning at any point when linking or loading a plugin linked against some  libs.
How do I find out which llvm libs I can't link with a dynamically loaded plugin?
How can I use the EngineBuilder in my plugin with proper symbol resolution?

For reproductivity:
cmake -G "Sublime Text 2 - Ninja" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DLLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON -DLLVM_BUILD_TESTS=ON -DLLVM_BUILD_EXAMPLES=ON -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" -DLLVM_TOOL_CLANG_BUILD=ON -DLLVM_TOOL_CLANG_TOOLS_EXTRA=ON -DLLVM_OPTIMIZED_TABLEGEN=ON -DCLANG_BUILD_EXAMPLES=ON -DCLANG_PLUGIN_SUPPORT=ON

Hope someone can help me out.
Viktor


LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Opt plugin linkage

Alex L via llvm-dev
Hey:
I spent sometime debugging this, it seems like editing ``llvm/tools/opt.cpp`` and move ``cl::ParseCommandLineOptions(argc, argv,
    "llvm .bc -> .bc modular optimizer and analysis printer\n");`` to the beginning of main() solved it for me. I'm not sure if this is a bug on LLVM side


Zhang
 
 
------------------ Original ------------------
Date:  Wed, Apr 17, 2019 03:09 AM
To:  "llvm-dev"<[hidden email]>;
Subject:  Re: [llvm-dev] Opt plugin linkage
 
How come the hello pass example is so totally useless as a starting point? Why is this not using any library/compontent which could conflict with opt or clang and showing how to handle this? I have no clue as to how I have to setup llvm to get this to work or why it doesn't work in the first place with the setup described in "Getting started" and "writing an llvm pass" pages etc.
Also there is basically no documentation for the custom cmake commands.

Can please somebody help me with this issue? How do I get dynamically loaded llvm pass plugins to work? Am I the only one ever having this issue?

Thanks
Viktor
On Apr 16, 2019, at 05:38, Viktor Was BSc via llvm-dev <[hidden email]> wrote:
Hi,
I have a dynamically loaded llvm pass built in-tree with ninja (generated with cmake, basically a copy of the hallo pass plugin, linux, llvm/clang version 6.0.1).
It uses the ExecutionEngine.
Building it without linking against LLVMExecutionEngine library results in an undefined symbol to the vtable of the EngineBuilder when loaded to opt. Linking the plugin with LLVMExecutionEngine results in the pass simply not being executable with giving "opt: Unkown command line argument '-passArg'."
For a minimal example add set(LLVM_LINK_COMPONENTS Core) to the CMakeLists.txt of the Hello llvm pass.

There is no error or warning at any point when linking or loading a plugin linked against some  libs.
How do I find out which llvm libs I can't link with a dynamically loaded plugin?
How can I use the EngineBuilder in my plugin with proper symbol resolution?

For reproductivity:
cmake -G "Sublime Text 2 - Ninja" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DLLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON -DLLVM_BUILD_TESTS=ON -DLLVM_BUILD_EXAMPLES=ON -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" -DLLVM_TOOL_CLANG_BUILD=ON -DLLVM_TOOL_CLANG_TOOLS_EXTRA=ON -DLLVM_OPTIMIZED_TABLEGEN=ON -DCLANG_BUILD_EXAMPLES=ON -DCLANG_PLUGIN_SUPPORT=ON

Hope someone can help me out.
Viktor


LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Opt plugin linkage

Alex L via llvm-dev
Just another follow-up, seems like ExecutionEngine is still not usable without editing CMakeLists, on my setup I had to edit CMakeLists.txt as well to get the example working.
Below is the modifications I made:

Modified Hello.cpp for testing:
```
    bool runOnFunction(Function &F) override {
      ++HelloCounter;
      std::string errStr;
      EngineBuilder eb;
      eb.setErrorStr(&errStr);
      eb.setEngineKind(EngineKind::Kind::JIT);
      ExecutionEngine* ee=eb.create();
      errs()<<"ExecutionEngine:"<<ee<<" Error:"<<errStr<<"\n";
      delete ee;
      errs() << "Hello: ";
      errs().write_escaped(F.getName()) << '\n';
      return false;
    }
```

Modified opt's CMakeLists.txt:

```
set(LLVM_LINK_COMPONENTS
  ${LLVM_TARGETS_TO_BUILD}
  AggressiveInstCombine
  Analysis
  BitWriter
  CodeGen
  Core
  MC
  MCJIT
  Object
  OrcJIT
  Interpreter
  RuntimeDyld
  Coroutines
  IPO
  IRReader
  InstCombine
  Instrumentation
  MC
  ObjCARCOpts
  ScalarOpts
  Support
  Target
  TransformUtils
  Vectorize
  Passes
  ExecutionEngine
  )

# Support plugins.
set(LLVM_NO_DEAD_STRIP 1)

add_llvm_tool(opt
  AnalysisWrappers.cpp
  BreakpointPrinter.cpp
  Debugify.cpp
  GraphPrinters.cpp
  NewPMDriver.cpp
  PassPrinters.cpp
  PrintSCC.cpp
  opt.cpp

  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)
target_link_libraries(opt PUBLIC LLVMExecutionEngine)

```

Modified opt's LLVMBuild.txt:

```
;===- ./tools/opt/LLVMBuild.txt --------------------------------*- Conf -*--===;
;
;                     The LLVM Compiler Infrastructure
;
; This file is distributed under the University of Illinois Open Source
; License. See LICENSE.TXT for details.
;
;===------------------------------------------------------------------------===;
;
; This is an LLVMBuild description file for the components in this subdirectory.
;
; For more information on the LLVMBuild system, please see:
;
;   http://llvm.org/docs/LLVMBuild.html
;
;===------------------------------------------------------------------------===;

[component_0]
type = Tool
name = opt
parent = Tools
required_libraries =
 AsmParser
 BitReader
 BitWriter
 CodeGen
 IRReader
 IPO
 Instrumentation
 Scalar
 ObjCARC
 Passes
 ExecutionEngine
 Interpreter
 MCJIT
 Native
 NativeCodeGen
 all-targets

```

On top of that I also added these lines to the beginning of main function in opt.cpp to force linking ExecutionEngine:

```
  if(argc==-1){
    EngineBuilder eb;
    ExecutionEngine* ee=eb.create();
    delete ee;
  }
```

as well as force linking MCJIT and Interpreter by including headers in opt:

```
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/MCJIT.h"
```

Moving cl::parseCommandLineOptions doesn't seem to be related to the issue, my previous assumption was wrong.

Those modifications works at least on my setup with the following output:

```
λ : >>> bin/opt -load lib/LLVMHello.dylib hw.ll -hello
WARNING: You're attempting to print out a bitcode file.
This is inadvisable as it may cause display problems. If
you REALLY want to taste LLVM bitcode first-hand, you
can force output with the `-f' option.

Assertion failed: (M && "Module is null?"), function Init, file /Users/naville/Development/Hikari/lib/ExecutionEngine/ExecutionEngine.cpp, line 80.

```

Which is due to i didn't initialize the EEBuilder properly, but at least the pass now loads and executes properly


Zhang



 
 
------------------ Original ------------------
Date:  Wed, Apr 17, 2019 04:35 AM
To:  "Viktor Was BSc"<[hidden email]>; "llvm-dev"<[hidden email]>;
Subject:  Re: [llvm-dev] Opt plugin linkage
 
Hey:
I spent sometime debugging this, it seems like editing ``llvm/tools/opt.cpp`` and move ``cl::ParseCommandLineOptions(argc, argv,
    "llvm .bc -> .bc modular optimizer and analysis printer\n");`` to the beginning of main() solved it for me. I'm not sure if this is a bug on LLVM side


Zhang
 
 
------------------ Original ------------------
Date:  Wed, Apr 17, 2019 03:09 AM
To:  "llvm-dev"<[hidden email]>;
Subject:  Re: [llvm-dev] Opt plugin linkage
 
How come the hello pass example is so totally useless as a starting point? Why is this not using any library/compontent which could conflict with opt or clang and showing how to handle this? I have no clue as to how I have to setup llvm to get this to work or why it doesn't work in the first place with the setup described in "Getting started" and "writing an llvm pass" pages etc.
Also there is basically no documentation for the custom cmake commands.

Can please somebody help me with this issue? How do I get dynamically loaded llvm pass plugins to work? Am I the only one ever having this issue?

Thanks
Viktor
On Apr 16, 2019, at 05:38, Viktor Was BSc via llvm-dev <[hidden email]> wrote:
Hi,
I have a dynamically loaded llvm pass built in-tree with ninja (generated with cmake, basically a copy of the hallo pass plugin, linux, llvm/clang version 6.0.1).
It uses the ExecutionEngine.
Building it without linking against LLVMExecutionEngine library results in an undefined symbol to the vtable of the EngineBuilder when loaded to opt. Linking the plugin with LLVMExecutionEngine results in the pass simply not being executable with giving "opt: Unkown command line argument '-passArg'."
For a minimal example add set(LLVM_LINK_COMPONENTS Core) to the CMakeLists.txt of the Hello llvm pass.

There is no error or warning at any point when linking or loading a plugin linked against some  libs.
How do I find out which llvm libs I can't link with a dynamically loaded plugin?
How can I use the EngineBuilder in my plugin with proper symbol resolution?

For reproductivity:
cmake -G "Sublime Text 2 - Ninja" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DLLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON -DLLVM_BUILD_TESTS=ON -DLLVM_BUILD_EXAMPLES=ON -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" -DLLVM_TOOL_CLANG_BUILD=ON -DLLVM_TOOL_CLANG_TOOLS_EXTRA=ON -DLLVM_OPTIMIZED_TABLEGEN=ON -DCLANG_BUILD_EXAMPLES=ON -DCLANG_PLUGIN_SUPPORT=ON

Hope someone can help me out.
Viktor


LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Opt plugin linkage

Alex L via llvm-dev

The fundamental problem here is that opt doesn’t use ExecutionEngine (because it has no need to), so trying

to use ExecutionEngine (or any other bit of llvm that opt doesn’t use for that matter) in an opt plugin isn’t

going to work.

 

The solution I’d go with would be to build llvm with shared libraries (use –DBUILD_SHARED_LIBS=ON on the

cmake command) then link the plugin against ExecutionEngine. That shouldn’t require any changes anywhere

(when I gave it a quick try it seemed to work).

 

John

 

From: llvm-dev [mailto:[hidden email]] On Behalf Of Zhang via llvm-dev
Sent: 16 April 2019 22:04
To: Viktor Was BSc; llvm-dev
Subject: Re: [llvm-dev] Opt plugin linkage

 

Just another follow-up, seems like ExecutionEngine is still not usable without editing CMakeLists, on my setup I had to edit CMakeLists.txt as well to get the example working.

Below is the modifications I made:

 

Modified Hello.cpp for testing:

```

    bool runOnFunction(Function &F) override {

      ++HelloCounter;

      std::string errStr;

      EngineBuilder eb;

      eb.setErrorStr(&errStr);

      eb.setEngineKind(EngineKind::Kind::JIT);

      ExecutionEngine* ee=eb.create();

      errs()<<"ExecutionEngine:"<<ee<<" Error:"<<errStr<<"\n";

      delete ee;

      errs() << "Hello: ";

      errs().write_escaped(F.getName()) << '\n';

      return false;

    }

```

 

Modified opt's CMakeLists.txt:

 

```

set(LLVM_LINK_COMPONENTS

  ${LLVM_TARGETS_TO_BUILD}

  AggressiveInstCombine

  Analysis

  BitWriter

  CodeGen

  Core

  MC

  MCJIT

  Object

  OrcJIT

  Interpreter

  RuntimeDyld

  Coroutines

  IPO

  IRReader

  InstCombine

  Instrumentation

  MC

  ObjCARCOpts

  ScalarOpts

  Support

  Target

  TransformUtils

  Vectorize

  Passes

  ExecutionEngine

  )

 

# Support plugins.

set(LLVM_NO_DEAD_STRIP 1)

 

add_llvm_tool(opt

  AnalysisWrappers.cpp

  BreakpointPrinter.cpp

  Debugify.cpp

  GraphPrinters.cpp

  NewPMDriver.cpp

  PassPrinters.cpp

  PrintSCC.cpp

  opt.cpp

 

  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)

target_link_libraries(opt PUBLIC LLVMExecutionEngine)

 

```

 

Modified opt's LLVMBuild.txt:

 

```

;===- ./tools/opt/LLVMBuild.txt --------------------------------*- Conf -*--===;

;

;                     The LLVM Compiler Infrastructure

;

; This file is distributed under the University of Illinois Open Source

; License. See LICENSE.TXT for details.

;

;===------------------------------------------------------------------------===;

;

; This is an LLVMBuild description file for the components in this subdirectory.

;

; For more information on the LLVMBuild system, please see:

;

;   http://llvm.org/docs/LLVMBuild.html

;

;===------------------------------------------------------------------------===;

 

[component_0]

type = Tool

name = opt

parent = Tools

required_libraries =

 AsmParser

 BitReader

 BitWriter

 CodeGen

 IRReader

 IPO

 Instrumentation

 Scalar

 ObjCARC

 Passes

 ExecutionEngine

 Interpreter

 MCJIT

 Native

 NativeCodeGen

 all-targets

 

```

 

On top of that I also added these lines to the beginning of main function in opt.cpp to force linking ExecutionEngine:

 

```

  if(argc==-1){

    EngineBuilder eb;

    ExecutionEngine* ee=eb.create();

    delete ee;

  }

```

 

as well as force linking MCJIT and Interpreter by including headers in opt:

 

```

#include "llvm/ExecutionEngine/ExecutionEngine.h"

#include "llvm/ExecutionEngine/Interpreter.h"

#include "llvm/ExecutionEngine/MCJIT.h"

```

 

Moving cl::parseCommandLineOptions doesn't seem to be related to the issue, my previous assumption was wrong.

 

Those modifications works at least on my setup with the following output:

 

```

λ : >>> bin/opt -load lib/LLVMHello.dylib hw.ll -hello

WARNING: You're attempting to print out a bitcode file.

This is inadvisable as it may cause display problems. If

you REALLY want to taste LLVM bitcode first-hand, you

can force output with the `-f' option.

 

Assertion failed: (M && "Module is null?"), function Init, file /Users/naville/Development/Hikari/lib/ExecutionEngine/ExecutionEngine.cpp, line 80.

 

```

 

Which is due to i didn't initialize the EEBuilder properly, but at least the pass now loads and executes properly

 

 

Zhang

 

 

 

 

 

------------------ Original ------------------

Date:  Wed, Apr 17, 2019 04:35 AM

To:  "Viktor Was BSc"<[hidden email]>; "llvm-dev"<[hidden email]>;

Subject:  Re: [llvm-dev] Opt plugin linkage

 

Hey:

I spent sometime debugging this, it seems like editing ``llvm/tools/opt.cpp`` and move ``cl::ParseCommandLineOptions(argc, argv,

    "llvm .bc -> .bc modular optimizer and analysis printer\n");`` to the beginning of main() solved it for me. I'm not sure if this is a bug on LLVM side

 

 

Zhang

 

 

------------------ Original ------------------

Date:  Wed, Apr 17, 2019 03:09 AM

To:  "llvm-dev"<[hidden email]>;

Subject:  Re: [llvm-dev] Opt plugin linkage

 

How come the hello pass example is so totally useless as a starting point? Why is this not using any library/compontent which could conflict with opt or clang and showing how to handle this? I have no clue as to how I have to setup llvm to get this to work or why it doesn't work in the first place with the setup described in "Getting started" and "writing an llvm pass" pages etc.

Also there is basically no documentation for the custom cmake commands.

Can please somebody help me with this issue? How do I get dynamically loaded llvm pass plugins to work? Am I the only one ever having this issue?

Thanks

Viktor

On Apr 16, 2019, at 05:38, Viktor Was BSc via llvm-dev <[hidden email]> wrote:

Hi,

I have a dynamically loaded llvm pass built in-tree with ninja (generated with cmake, basically a copy of the hallo pass plugin, linux, llvm/clang version 6.0.1).

It uses the ExecutionEngine.

Building it without linking against LLVMExecutionEngine library results in an undefined symbol to the vtable of the EngineBuilder when loaded to opt. Linking the plugin with LLVMExecutionEngine results in the pass simply not being executable with giving "opt: Unkown command line argument '-passArg'."

For a minimal example add set(LLVM_LINK_COMPONENTS Core) to the CMakeLists.txt of the Hello llvm pass.

There is no error or warning at any point when linking or loading a plugin linked against some  libs.

How do I find out which llvm libs I can't link with a dynamically loaded plugin?

How can I use the EngineBuilder in my plugin with proper symbol resolution?

For reproductivity:

cmake -G "Sublime Text 2 - Ninja" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DLLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON -DLLVM_BUILD_TESTS=ON -DLLVM_BUILD_EXAMPLES=ON -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" -DLLVM_TOOL_CLANG_BUILD=ON -DLLVM_TOOL_CLANG_TOOLS_EXTRA=ON -DLLVM_OPTIMIZED_TABLEGEN=ON -DCLANG_BUILD_EXAMPLES=ON -DCLANG_PLUGIN_SUPPORT=ON

Hope someone can help me out.

Viktor



LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Opt plugin linkage

Alex L via llvm-dev

Hi John,

Thanks for the suggestion, will definitely try it out, seems like the cleanest and least invasive way to do this.

Though, I feel like this should also be possible with statically linking the ExecutionEngine into the plugin shared object.

I don't quite understand how the concrete Interpreter/MCJIT linking via llvm/ExecutionEngine/Interpreter.h and llvm/ExecutionEngine/MCJIT.h works. So far I was only using ExecutionEngine.h without Interpreter or MCJIT, so that could have been the problem why static linking didn't work.

After playing around with Zhangs solution I've found out that I get the same undefined symbol to llvm::EngineBuilder error when omitting the MCJIT header and lib (since I actually only need an interpreter), my guess is that this is due to Interpreter.h missing the getenv trick used in MCJIT.h to prevent it being optimized away by the compiler? I might take a closer look at this at some point, right now I'm just happy to finally be able to work on my opt pass.


Thanks,

Viktor


On 4/18/19 7:38 PM, John Brawn wrote:

The fundamental problem here is that opt doesn’t use ExecutionEngine (because it has no need to), so trying

to use ExecutionEngine (or any other bit of llvm that opt doesn’t use for that matter) in an opt plugin isn’t

going to work.

 

The solution I’d go with would be to build llvm with shared libraries (use –DBUILD_SHARED_LIBS=ON on the

cmake command) then link the plugin against ExecutionEngine. That shouldn’t require any changes anywhere

(when I gave it a quick try it seemed to work).

 

John

 

From: llvm-dev [[hidden email]] On Behalf Of Zhang via llvm-dev
Sent: 16 April 2019 22:04
To: Viktor Was BSc; llvm-dev
Subject: Re: [llvm-dev] Opt plugin linkage

 

Just another follow-up, seems like ExecutionEngine is still not usable without editing CMakeLists, on my setup I had to edit CMakeLists.txt as well to get the example working.

Below is the modifications I made:

 

Modified Hello.cpp for testing:

```

    bool runOnFunction(Function &F) override {

      ++HelloCounter;

      std::string errStr;

      EngineBuilder eb;

      eb.setErrorStr(&errStr);

      eb.setEngineKind(EngineKind::Kind::JIT);

      ExecutionEngine* ee=eb.create();

      errs()<<"ExecutionEngine:"<<ee<<" Error:"<<errStr<<"\n";

      delete ee;

      errs() << "Hello: ";

      errs().write_escaped(F.getName()) << '\n';

      return false;

    }

```

 

Modified opt's CMakeLists.txt:

 

```

set(LLVM_LINK_COMPONENTS

  ${LLVM_TARGETS_TO_BUILD}

  AggressiveInstCombine

  Analysis

  BitWriter

  CodeGen

  Core

  MC

  MCJIT

  Object

  OrcJIT

  Interpreter

  RuntimeDyld

  Coroutines

  IPO

  IRReader

  InstCombine

  Instrumentation

  MC

  ObjCARCOpts

  ScalarOpts

  Support

  Target

  TransformUtils

  Vectorize

  Passes

  ExecutionEngine

  )

 

# Support plugins.

set(LLVM_NO_DEAD_STRIP 1)

 

add_llvm_tool(opt

  AnalysisWrappers.cpp

  BreakpointPrinter.cpp

  Debugify.cpp

  GraphPrinters.cpp

  NewPMDriver.cpp

  PassPrinters.cpp

  PrintSCC.cpp

  opt.cpp

 

  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)

target_link_libraries(opt PUBLIC LLVMExecutionEngine)

 

```

 

Modified opt's LLVMBuild.txt:

 

```

;===- ./tools/opt/LLVMBuild.txt --------------------------------*- Conf -*--===;

;

;                     The LLVM Compiler Infrastructure

;

; This file is distributed under the University of Illinois Open Source

; License. See LICENSE.TXT for details.

;

;===------------------------------------------------------------------------===;

;

; This is an LLVMBuild description file for the components in this subdirectory.

;

; For more information on the LLVMBuild system, please see:

;

;

;===------------------------------------------------------------------------===;

 

[component_0]

type = Tool

name = opt

parent = Tools

required_libraries =

 AsmParser

 BitReader

 BitWriter

 CodeGen

 IRReader

 IPO

 Instrumentation

 Scalar

 ObjCARC

 Passes

 ExecutionEngine

 Interpreter

 MCJIT

 Native

 NativeCodeGen

 all-targets

 

```

 

On top of that I also added these lines to the beginning of main function in opt.cpp to force linking ExecutionEngine:

 

```

  if(argc==-1){

    EngineBuilder eb;

    ExecutionEngine* ee=eb.create();

    delete ee;

  }

```

 

as well as force linking MCJIT and Interpreter by including headers in opt:

 

```

#include "llvm/ExecutionEngine/ExecutionEngine.h"

#include "llvm/ExecutionEngine/Interpreter.h"

#include "llvm/ExecutionEngine/MCJIT.h"

```

 

Moving cl::parseCommandLineOptions doesn't seem to be related to the issue, my previous assumption was wrong.

 

Those modifications works at least on my setup with the following output:

 

```

λ : >>> bin/opt -load lib/LLVMHello.dylib hw.ll -hello

WARNING: You're attempting to print out a bitcode file.

This is inadvisable as it may cause display problems. If

you REALLY want to taste LLVM bitcode first-hand, you

can force output with the `-f' option.

 

Assertion failed: (M && "Module is null?"), function Init, file /Users/naville/Development/Hikari/lib/ExecutionEngine/ExecutionEngine.cpp, line 80.

 

```

 

Which is due to i didn't initialize the EEBuilder properly, but at least the pass now loads and executes properly

 

 

Zhang

 

 

 

 

 

------------------ Original ------------------

Date:  Wed, Apr 17, 2019 04:35 AM

To:  "Viktor Was BSc"[hidden email]; "llvm-dev"[hidden email];

Subject:  Re: [llvm-dev] Opt plugin linkage

 

Hey:

I spent sometime debugging this, it seems like editing ``llvm/tools/opt.cpp`` and move ``cl::ParseCommandLineOptions(argc, argv,

    "llvm .bc -> .bc modular optimizer and analysis printer\n");`` to the beginning of main() solved it for me. I'm not sure if this is a bug on LLVM side

 

 

Zhang

 

 

------------------ Original ------------------

Date:  Wed, Apr 17, 2019 03:09 AM

To:  "llvm-dev"[hidden email];

Subject:  Re: [llvm-dev] Opt plugin linkage

 

How come the hello pass example is so totally useless as a starting point? Why is this not using any library/compontent which could conflict with opt or clang and showing how to handle this? I have no clue as to how I have to setup llvm to get this to work or why it doesn't work in the first place with the setup described in "Getting started" and "writing an llvm pass" pages etc.

Also there is basically no documentation for the custom cmake commands.

Can please somebody help me with this issue? How do I get dynamically loaded llvm pass plugins to work? Am I the only one ever having this issue?

Thanks

Viktor

On Apr 16, 2019, at 05:38, Viktor Was BSc via llvm-dev <[hidden email]> wrote:

Hi,

I have a dynamically loaded llvm pass built in-tree with ninja (generated with cmake, basically a copy of the hallo pass plugin, linux, llvm/clang version 6.0.1).

It uses the ExecutionEngine.

Building it without linking against LLVMExecutionEngine library results in an undefined symbol to the vtable of the EngineBuilder when loaded to opt. Linking the plugin with LLVMExecutionEngine results in the pass simply not being executable with giving "opt: Unkown command line argument '-passArg'."

For a minimal example add set(LLVM_LINK_COMPONENTS Core) to the CMakeLists.txt of the Hello llvm pass.

There is no error or warning at any point when linking or loading a plugin linked against some  libs.

How do I find out which llvm libs I can't link with a dynamically loaded plugin?

How can I use the EngineBuilder in my plugin with proper symbol resolution?

For reproductivity:

cmake -G "Sublime Text 2 - Ninja" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DLLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON -DLLVM_BUILD_TESTS=ON -DLLVM_BUILD_EXAMPLES=ON -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" -DLLVM_TOOL_CLANG_BUILD=ON -DLLVM_TOOL_CLANG_TOOLS_EXTRA=ON -DLLVM_OPTIMIZED_TABLEGEN=ON -DCLANG_BUILD_EXAMPLES=ON -DCLANG_PLUGIN_SUPPORT=ON

Hope someone can help me out.

Viktor



LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Opt plugin linkage

Alex L via llvm-dev
Yes I’m aware of compiling libLLVM as a huge shared library is also a possible solution. I didnt mention this as I was afraid that stuffs like library load path or something could be troublesome.
Also I’d prefer statically link the whole pass into opt without the -load mess.

Zhang

在 2019年4月18日,20:04,Viktor Was BSc <[hidden email]> 写道:

Hi John,

Thanks for the suggestion, will definitely try it out, seems like the cleanest and least invasive way to do this.

Though, I feel like this should also be possible with statically linking the ExecutionEngine into the plugin shared object.

I don't quite understand how the concrete Interpreter/MCJIT linking via llvm/ExecutionEngine/Interpreter.h and llvm/ExecutionEngine/MCJIT.h works. So far I was only using ExecutionEngine.h without Interpreter or MCJIT, so that could have been the problem why static linking didn't work.

After playing around with Zhangs solution I've found out that I get the same undefined symbol to llvm::EngineBuilder error when omitting the MCJIT header and lib (since I actually only need an interpreter), my guess is that this is due to Interpreter.h missing the getenv trick used in MCJIT.h to prevent it being optimized away by the compiler? I might take a closer look at this at some point, right now I'm just happy to finally be able to work on my opt pass.


Thanks,

Viktor


On 4/18/19 7:38 PM, John Brawn wrote:

The fundamental problem here is that opt doesn’t use ExecutionEngine (because it has no need to), so trying

to use ExecutionEngine (or any other bit of llvm that opt doesn’t use for that matter) in an opt plugin isn’t

going to work.

 

The solution I’d go with would be to build llvm with shared libraries (use –DBUILD_SHARED_LIBS=ON on the

cmake command) then link the plugin against ExecutionEngine. That shouldn’t require any changes anywhere

(when I gave it a quick try it seemed to work).

 

John

 

From: llvm-dev [[hidden email]] On Behalf Of Zhang via llvm-dev
Sent: 16 April 2019 22:04
To: Viktor Was BSc; llvm-dev
Subject: Re: [llvm-dev] Opt plugin linkage

 

Just another follow-up, seems like ExecutionEngine is still not usable without editing CMakeLists, on my setup I had to edit CMakeLists.txt as well to get the example working.

Below is the modifications I made:

 

Modified Hello.cpp for testing:

```

    bool runOnFunction(Function &F) override {

      ++HelloCounter;

      std::string errStr;

      EngineBuilder eb;

      eb.setErrorStr(&errStr);

      eb.setEngineKind(EngineKind::Kind::JIT);

      ExecutionEngine* ee=eb.create();

      errs()<<"ExecutionEngine:"<<ee<<" Error:"<<errStr<<"\n";

      delete ee;

      errs() << "Hello: ";

      errs().write_escaped(F.getName()) << '\n';

      return false;

    }

```

 

Modified opt's CMakeLists.txt:

 

```

set(LLVM_LINK_COMPONENTS

  ${LLVM_TARGETS_TO_BUILD}

  AggressiveInstCombine

  Analysis

  BitWriter

  CodeGen

  Core

  MC

  MCJIT

  Object

  OrcJIT

  Interpreter

  RuntimeDyld

  Coroutines

  IPO

  IRReader

  InstCombine

  Instrumentation

  MC

  ObjCARCOpts

  ScalarOpts

  Support

  Target

  TransformUtils

  Vectorize

  Passes

  ExecutionEngine

  )

 

# Support plugins.

set(LLVM_NO_DEAD_STRIP 1)

 

add_llvm_tool(opt

  AnalysisWrappers.cpp

  BreakpointPrinter.cpp

  Debugify.cpp

  GraphPrinters.cpp

  NewPMDriver.cpp

  PassPrinters.cpp

  PrintSCC.cpp

  opt.cpp

 

  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)

target_link_libraries(opt PUBLIC LLVMExecutionEngine)

 

```

 

Modified opt's LLVMBuild.txt:

 

```

;===- ./tools/opt/LLVMBuild.txt --------------------------------*- Conf -*--===;

;

;                     The LLVM Compiler Infrastructure

;

; This file is distributed under the University of Illinois Open Source

; License. See LICENSE.TXT for details.

;

;===------------------------------------------------------------------------===;

;

; This is an LLVMBuild description file for the components in this subdirectory.

;

; For more information on the LLVMBuild system, please see:

;

;

;===------------------------------------------------------------------------===;

 

[component_0]

type = Tool

name = opt

parent = Tools

required_libraries =

 AsmParser

 BitReader

 BitWriter

 CodeGen

 IRReader

 IPO

 Instrumentation

 Scalar

 ObjCARC

 Passes

 ExecutionEngine

 Interpreter

 MCJIT

 Native

 NativeCodeGen

 all-targets

 

```

 

On top of that I also added these lines to the beginning of main function in opt.cpp to force linking ExecutionEngine:

 

```

  if(argc==-1){

    EngineBuilder eb;

    ExecutionEngine* ee=eb.create();

    delete ee;

  }

```

 

as well as force linking MCJIT and Interpreter by including headers in opt:

 

```

#include "llvm/ExecutionEngine/ExecutionEngine.h"

#include "llvm/ExecutionEngine/Interpreter.h"

#include "llvm/ExecutionEngine/MCJIT.h"

```

 

Moving cl::parseCommandLineOptions doesn't seem to be related to the issue, my previous assumption was wrong.

 

Those modifications works at least on my setup with the following output:

 

```

λ : >>> bin/opt -load lib/LLVMHello.dylib hw.ll -hello

WARNING: You're attempting to print out a bitcode file.

This is inadvisable as it may cause display problems. If

you REALLY want to taste LLVM bitcode first-hand, you

can force output with the `-f' option.

 

Assertion failed: (M && "Module is null?"), function Init, file /Users/naville/Development/Hikari/lib/ExecutionEngine/ExecutionEngine.cpp, line 80.

 

```

 

Which is due to i didn't initialize the EEBuilder properly, but at least the pass now loads and executes properly

 

 

Zhang

 

 

 

 

 

------------------ Original ------------------

Date:  Wed, Apr 17, 2019 04:35 AM

To:  "Viktor Was BSc"[hidden email]; "llvm-dev"[hidden email];

Subject:  Re: [llvm-dev] Opt plugin linkage

 

Hey:

I spent sometime debugging this, it seems like editing ``llvm/tools/opt.cpp`` and move ``cl::ParseCommandLineOptions(argc, argv,

    "llvm .bc -> .bc modular optimizer and analysis printer\n");`` to the beginning of main() solved it for me. I'm not sure if this is a bug on LLVM side

 

 

Zhang

 

 

------------------ Original ------------------

Date:  Wed, Apr 17, 2019 03:09 AM

To:  "llvm-dev"[hidden email];

Subject:  Re: [llvm-dev] Opt plugin linkage

 

How come the hello pass example is so totally useless as a starting point? Why is this not using any library/compontent which could conflict with opt or clang and showing how to handle this? I have no clue as to how I have to setup llvm to get this to work or why it doesn't work in the first place with the setup described in "Getting started" and "writing an llvm pass" pages etc.

Also there is basically no documentation for the custom cmake commands.

Can please somebody help me with this issue? How do I get dynamically loaded llvm pass plugins to work? Am I the only one ever having this issue?

Thanks

Viktor

On Apr 16, 2019, at 05:38, Viktor Was BSc via llvm-dev <[hidden email]> wrote:

Hi,

I have a dynamically loaded llvm pass built in-tree with ninja (generated with cmake, basically a copy of the hallo pass plugin, linux, llvm/clang version 6.0.1).

It uses the ExecutionEngine.

Building it without linking against LLVMExecutionEngine library results in an undefined symbol to the vtable of the EngineBuilder when loaded to opt. Linking the plugin with LLVMExecutionEngine results in the pass simply not being executable with giving "opt: Unkown command line argument '-passArg'."

For a minimal example add set(LLVM_LINK_COMPONENTS Core) to the CMakeLists.txt of the Hello llvm pass.

There is no error or warning at any point when linking or loading a plugin linked against some  libs.

How do I find out which llvm libs I can't link with a dynamically loaded plugin?

How can I use the EngineBuilder in my plugin with proper symbol resolution?

For reproductivity:

cmake -G "Sublime Text 2 - Ninja" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DLLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON -DLLVM_BUILD_TESTS=ON -DLLVM_BUILD_EXAMPLES=ON -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" -DLLVM_TOOL_CLANG_BUILD=ON -DLLVM_TOOL_CLANG_TOOLS_EXTRA=ON -DLLVM_OPTIMIZED_TABLEGEN=ON -DCLANG_BUILD_EXAMPLES=ON -DCLANG_PLUGIN_SUPPORT=ON

Hope someone can help me out.

Viktor



LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Opt plugin linkage

Alex L via llvm-dev
In reply to this post by Alex L via llvm-dev
Hi Viktor, 

Though, I feel like this should also be possible with statically linking the ExecutionEngine into the plugin shared object.

Unfortunately it won't. In general, you don't link any LLVM libraries into opt plugins because opt already has all the symbols you need. If you were to link in the libraries, all sorts of problems arise, most of them because we have lot's of global state everywhere. With dynamic linking, most of the problems can be avoided because the dependencies won't be loaded twice.

Cheers,
Philip


I don't quite understand how the concrete Interpreter/MCJIT linking via llvm/ExecutionEngine/Interpreter.h and llvm/ExecutionEngine/MCJIT.h works. So far I was only using ExecutionEngine.h without Interpreter or MCJIT, so that could have been the problem why static linking didn't work.

After playing around with Zhangs solution I've found out that I get the same undefined symbol to llvm::EngineBuilder error when omitting the MCJIT header and lib (since I actually only need an interpreter), my guess is that this is due to Interpreter.h missing the getenv trick used in MCJIT.h to prevent it being optimized away by the compiler? I might take a closer look at this at some point, right now I'm just happy to finally be able to work on my opt pass.


Thanks,

Viktor


On 4/18/19 7:38 PM, John Brawn wrote:

The fundamental problem here is that opt doesn’t use ExecutionEngine (because it has no need to), so trying

to use ExecutionEngine (or any other bit of llvm that opt doesn’t use for that matter) in an opt plugin isn’t

going to work.

 

The solution I’d go with would be to build llvm with shared libraries (use –DBUILD_SHARED_LIBS=ON on the

cmake command) then link the plugin against ExecutionEngine. That shouldn’t require any changes anywhere

(when I gave it a quick try it seemed to work).

 

John

 

From: llvm-dev [[hidden email]] On Behalf Of Zhang via llvm-dev
Sent: 16 April 2019 22:04
To: Viktor Was BSc; llvm-dev
Subject: Re: [llvm-dev] Opt plugin linkage

 

Just another follow-up, seems like ExecutionEngine is still not usable without editing CMakeLists, on my setup I had to edit CMakeLists.txt as well to get the example working.

Below is the modifications I made:

 

Modified Hello.cpp for testing:

```

    bool runOnFunction(Function &F) override {

      ++HelloCounter;

      std::string errStr;

      EngineBuilder eb;

      eb.setErrorStr(&errStr);

      eb.setEngineKind(EngineKind::Kind::JIT);

      ExecutionEngine* ee=eb.create();

      errs()<<"ExecutionEngine:"<<ee<<" Error:"<<errStr<<"\n";

      delete ee;

      errs() << "Hello: ";

      errs().write_escaped(F.getName()) << '\n';

      return false;

    }

```

 

Modified opt's CMakeLists.txt:

 

```

set(LLVM_LINK_COMPONENTS

  ${LLVM_TARGETS_TO_BUILD}

  AggressiveInstCombine

  Analysis

  BitWriter

  CodeGen

  Core

  MC

  MCJIT

  Object

  OrcJIT

  Interpreter

  RuntimeDyld

  Coroutines

  IPO

  IRReader

  InstCombine

  Instrumentation

  MC

  ObjCARCOpts

  ScalarOpts

  Support

  Target

  TransformUtils

  Vectorize

  Passes

  ExecutionEngine

  )

 

# Support plugins.

set(LLVM_NO_DEAD_STRIP 1)

 

add_llvm_tool(opt

  AnalysisWrappers.cpp

  BreakpointPrinter.cpp

  Debugify.cpp

  GraphPrinters.cpp

  NewPMDriver.cpp

  PassPrinters.cpp

  PrintSCC.cpp

  opt.cpp

 

  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)

target_link_libraries(opt PUBLIC LLVMExecutionEngine)

 

```

 

Modified opt's LLVMBuild.txt:

 

```

;===- ./tools/opt/LLVMBuild.txt --------------------------------*- Conf -*--===;

;

;                     The LLVM Compiler Infrastructure

;

; This file is distributed under the University of Illinois Open Source

; License. See LICENSE.TXT for details.

;

;===------------------------------------------------------------------------===;

;

; This is an LLVMBuild description file for the components in this subdirectory.

;

; For more information on the LLVMBuild system, please see:

;

;

;===------------------------------------------------------------------------===;

 

[component_0]

type = Tool

name = opt

parent = Tools

required_libraries =

 AsmParser

 BitReader

 BitWriter

 CodeGen

 IRReader

 IPO

 Instrumentation

 Scalar

 ObjCARC

 Passes

 ExecutionEngine

 Interpreter

 MCJIT

 Native

 NativeCodeGen

 all-targets

 

```

 

On top of that I also added these lines to the beginning of main function in opt.cpp to force linking ExecutionEngine:

 

```

  if(argc==-1){

    EngineBuilder eb;

    ExecutionEngine* ee=eb.create();

    delete ee;

  }

```

 

as well as force linking MCJIT and Interpreter by including headers in opt:

 

```

#include "llvm/ExecutionEngine/ExecutionEngine.h"

#include "llvm/ExecutionEngine/Interpreter.h"

#include "llvm/ExecutionEngine/MCJIT.h"

```

 

Moving cl::parseCommandLineOptions doesn't seem to be related to the issue, my previous assumption was wrong.

 

Those modifications works at least on my setup with the following output:

 

```

λ : >>> bin/opt -load lib/LLVMHello.dylib hw.ll -hello

WARNING: You're attempting to print out a bitcode file.

This is inadvisable as it may cause display problems. If

you REALLY want to taste LLVM bitcode first-hand, you

can force output with the `-f' option.

 

Assertion failed: (M && "Module is null?"), function Init, file /Users/naville/Development/Hikari/lib/ExecutionEngine/ExecutionEngine.cpp, line 80.

 

```

 

Which is due to i didn't initialize the EEBuilder properly, but at least the pass now loads and executes properly

 

 

Zhang

 

 

 

 

 

------------------ Original ------------------

From:  "Zhang via llvm-dev"[hidden email];

Date:  Wed, Apr 17, 2019 04:35 AM

To:  "Viktor Was BSc"[hidden email]; "llvm-dev"[hidden email];

Subject:  Re: [llvm-dev] Opt plugin linkage

 

Hey:

I spent sometime debugging this, it seems like editing ``llvm/tools/opt.cpp`` and move ``cl::ParseCommandLineOptions(argc, argv,

    "llvm .bc -> .bc modular optimizer and analysis printer\n");`` to the beginning of main() solved it for me. I'm not sure if this is a bug on LLVM side

 

 

Zhang

 

 

------------------ Original ------------------

From:  "Viktor Was BSc via llvm-dev"[hidden email];

Date:  Wed, Apr 17, 2019 03:09 AM

To:  "llvm-dev"[hidden email];

Subject:  Re: [llvm-dev] Opt plugin linkage

 

How come the hello pass example is so totally useless as a starting point? Why is this not using any library/compontent which could conflict with opt or clang and showing how to handle this? I have no clue as to how I have to setup llvm to get this to work or why it doesn't work in the first place with the setup described in "Getting started" and "writing an llvm pass" pages etc.

Also there is basically no documentation for the custom cmake commands.

Can please somebody help me with this issue? How do I get dynamically loaded llvm pass plugins to work? Am I the only one ever having this issue?

Thanks

Viktor

On Apr 16, 2019, at 05:38, Viktor Was BSc via llvm-dev <[hidden email]> wrote:

Hi,

I have a dynamically loaded llvm pass built in-tree with ninja (generated with cmake, basically a copy of the hallo pass plugin, linux, llvm/clang version 6.0.1).

It uses the ExecutionEngine.

Building it without linking against LLVMExecutionEngine library results in an undefined symbol to the vtable of the EngineBuilder when loaded to opt. Linking the plugin with LLVMExecutionEngine results in the pass simply not being executable with giving "opt: Unkown command line argument '-passArg'."

For a minimal example add set(LLVM_LINK_COMPONENTS Core) to the CMakeLists.txt of the Hello llvm pass.

There is no error or warning at any point when linking or loading a plugin linked against some  libs.

How do I find out which llvm libs I can't link with a dynamically loaded plugin?

How can I use the EngineBuilder in my plugin with proper symbol resolution?

For reproductivity:

cmake -G "Sublime Text 2 - Ninja" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DLLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON -DLLVM_BUILD_TESTS=ON -DLLVM_BUILD_EXAMPLES=ON -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" -DLLVM_TOOL_CLANG_BUILD=ON -DLLVM_TOOL_CLANG_TOOLS_EXTRA=ON -DLLVM_OPTIMIZED_TABLEGEN=ON -DCLANG_BUILD_EXAMPLES=ON -DCLANG_PLUGIN_SUPPORT=ON

Hope someone can help me out.

Viktor



LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Opt plugin linkage

Alex L via llvm-dev

Hi Philip,

unfortunately in the case of ExecutionEngine it doesn't have the symbols needed. I was hoping to be able to do this by linking ExecutionEngine privately (target_link_libraries( pluginName PRIVATE LLVMExecutionEngine )), for testing purposes at least. How does the plugin loading work that the symbols are seemingly omitted/stripped/inaccessible?

Cheers,

Viktor


On 4/19/19 12:13 PM, Philip Pfaffe wrote:
Hi Viktor, 

Though, I feel like this should also be possible with statically linking the ExecutionEngine into the plugin shared object.

Unfortunately it won't. In general, you don't link any LLVM libraries into opt plugins because opt already has all the symbols you need. If you were to link in the libraries, all sorts of problems arise, most of them because we have lot's of global state everywhere. With dynamic linking, most of the problems can be avoided because the dependencies won't be loaded twice.

Cheers,
Philip


I don't quite understand how the concrete Interpreter/MCJIT linking via llvm/ExecutionEngine/Interpreter.h and llvm/ExecutionEngine/MCJIT.h works. So far I was only using ExecutionEngine.h without Interpreter or MCJIT, so that could have been the problem why static linking didn't work.

After playing around with Zhangs solution I've found out that I get the same undefined symbol to llvm::EngineBuilder error when omitting the MCJIT header and lib (since I actually only need an interpreter), my guess is that this is due to Interpreter.h missing the getenv trick used in MCJIT.h to prevent it being optimized away by the compiler? I might take a closer look at this at some point, right now I'm just happy to finally be able to work on my opt pass.


Thanks,

Viktor


On 4/18/19 7:38 PM, John Brawn wrote:

The fundamental problem here is that opt doesn’t use ExecutionEngine (because it has no need to), so trying

to use ExecutionEngine (or any other bit of llvm that opt doesn’t use for that matter) in an opt plugin isn’t

going to work.

 

The solution I’d go with would be to build llvm with shared libraries (use –DBUILD_SHARED_LIBS=ON on the

cmake command) then link the plugin against ExecutionEngine. That shouldn’t require any changes anywhere

(when I gave it a quick try it seemed to work).

 

John

 

From: llvm-dev [[hidden email]] On Behalf Of Zhang via llvm-dev
Sent: 16 April 2019 22:04
To: Viktor Was BSc; llvm-dev
Subject: Re: [llvm-dev] Opt plugin linkage

 

Just another follow-up, seems like ExecutionEngine is still not usable without editing CMakeLists, on my setup I had to edit CMakeLists.txt as well to get the example working.

Below is the modifications I made:

 

Modified Hello.cpp for testing:

```

    bool runOnFunction(Function &F) override {

      ++HelloCounter;

      std::string errStr;

      EngineBuilder eb;

      eb.setErrorStr(&errStr);

      eb.setEngineKind(EngineKind::Kind::JIT);

      ExecutionEngine* ee=eb.create();

      errs()<<"ExecutionEngine:"<<ee<<" Error:"<<errStr<<"\n";

      delete ee;

      errs() << "Hello: ";

      errs().write_escaped(F.getName()) << '\n';

      return false;

    }

```

 

Modified opt's CMakeLists.txt:

 

```

set(LLVM_LINK_COMPONENTS

  ${LLVM_TARGETS_TO_BUILD}

  AggressiveInstCombine

  Analysis

  BitWriter

  CodeGen

  Core

  MC

  MCJIT

  Object

  OrcJIT

  Interpreter

  RuntimeDyld

  Coroutines

  IPO

  IRReader

  InstCombine

  Instrumentation

  MC

  ObjCARCOpts

  ScalarOpts

  Support

  Target

  TransformUtils

  Vectorize

  Passes

  ExecutionEngine

  )

 

# Support plugins.

set(LLVM_NO_DEAD_STRIP 1)

 

add_llvm_tool(opt

  AnalysisWrappers.cpp

  BreakpointPrinter.cpp

  Debugify.cpp

  GraphPrinters.cpp

  NewPMDriver.cpp

  PassPrinters.cpp

  PrintSCC.cpp

  opt.cpp

 

  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)

target_link_libraries(opt PUBLIC LLVMExecutionEngine)

 

```

 

Modified opt's LLVMBuild.txt:

 

```

;===- ./tools/opt/LLVMBuild.txt --------------------------------*- Conf -*--===;

;

;                     The LLVM Compiler Infrastructure

;

; This file is distributed under the University of Illinois Open Source

; License. See LICENSE.TXT for details.

;

;===------------------------------------------------------------------------===;

;

; This is an LLVMBuild description file for the components in this subdirectory.

;

; For more information on the LLVMBuild system, please see:

;

;

;===------------------------------------------------------------------------===;

 

[component_0]

type = Tool

name = opt

parent = Tools

required_libraries =

 AsmParser

 BitReader

 BitWriter

 CodeGen

 IRReader

 IPO

 Instrumentation

 Scalar

 ObjCARC

 Passes

 ExecutionEngine

 Interpreter

 MCJIT

 Native

 NativeCodeGen

 all-targets

 

```

 

On top of that I also added these lines to the beginning of main function in opt.cpp to force linking ExecutionEngine:

 

```

  if(argc==-1){

    EngineBuilder eb;

    ExecutionEngine* ee=eb.create();

    delete ee;

  }

```

 

as well as force linking MCJIT and Interpreter by including headers in opt:

 

```

#include "llvm/ExecutionEngine/ExecutionEngine.h"

#include "llvm/ExecutionEngine/Interpreter.h"

#include "llvm/ExecutionEngine/MCJIT.h"

```

 

Moving cl::parseCommandLineOptions doesn't seem to be related to the issue, my previous assumption was wrong.

 

Those modifications works at least on my setup with the following output:

 

```

λ : >>> bin/opt -load lib/LLVMHello.dylib hw.ll -hello

WARNING: You're attempting to print out a bitcode file.

This is inadvisable as it may cause display problems. If

you REALLY want to taste LLVM bitcode first-hand, you

can force output with the `-f' option.

 

Assertion failed: (M && "Module is null?"), function Init, file /Users/naville/Development/Hikari/lib/ExecutionEngine/ExecutionEngine.cpp, line 80.

 

```

 

Which is due to i didn't initialize the EEBuilder properly, but at least the pass now loads and executes properly

 

 

Zhang

 

 

 

 

 

------------------ Original ------------------

From:  "Zhang via llvm-dev"[hidden email];

Date:  Wed, Apr 17, 2019 04:35 AM

To:  "Viktor Was BSc"[hidden email]; "llvm-dev"[hidden email];

Subject:  Re: [llvm-dev] Opt plugin linkage

 

Hey:

I spent sometime debugging this, it seems like editing ``llvm/tools/opt.cpp`` and move ``cl::ParseCommandLineOptions(argc, argv,

    "llvm .bc -> .bc modular optimizer and analysis printer\n");`` to the beginning of main() solved it for me. I'm not sure if this is a bug on LLVM side

 

 

Zhang

 

 

------------------ Original ------------------

From:  "Viktor Was BSc via llvm-dev"[hidden email];

Date:  Wed, Apr 17, 2019 03:09 AM

To:  "llvm-dev"[hidden email];

Subject:  Re: [llvm-dev] Opt plugin linkage

 

How come the hello pass example is so totally useless as a starting point? Why is this not using any library/compontent which could conflict with opt or clang and showing how to handle this? I have no clue as to how I have to setup llvm to get this to work or why it doesn't work in the first place with the setup described in "Getting started" and "writing an llvm pass" pages etc.

Also there is basically no documentation for the custom cmake commands.

Can please somebody help me with this issue? How do I get dynamically loaded llvm pass plugins to work? Am I the only one ever having this issue?

Thanks

Viktor

On Apr 16, 2019, at 05:38, Viktor Was BSc via llvm-dev <[hidden email]> wrote:

Hi,

I have a dynamically loaded llvm pass built in-tree with ninja (generated with cmake, basically a copy of the hallo pass plugin, linux, llvm/clang version 6.0.1).

It uses the ExecutionEngine.

Building it without linking against LLVMExecutionEngine library results in an undefined symbol to the vtable of the EngineBuilder when loaded to opt. Linking the plugin with LLVMExecutionEngine results in the pass simply not being executable with giving "opt: Unkown command line argument '-passArg'."

For a minimal example add set(LLVM_LINK_COMPONENTS Core) to the CMakeLists.txt of the Hello llvm pass.

There is no error or warning at any point when linking or loading a plugin linked against some  libs.

How do I find out which llvm libs I can't link with a dynamically loaded plugin?

How can I use the EngineBuilder in my plugin with proper symbol resolution?

For reproductivity:

cmake -G "Sublime Text 2 - Ninja" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DLLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON -DLLVM_BUILD_TESTS=ON -DLLVM_BUILD_EXAMPLES=ON -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" -DLLVM_TOOL_CLANG_BUILD=ON -DLLVM_TOOL_CLANG_TOOLS_EXTRA=ON -DLLVM_OPTIMIZED_TABLEGEN=ON -DCLANG_BUILD_EXAMPLES=ON -DCLANG_PLUGIN_SUPPORT=ON

Hope someone can help me out.

Viktor



LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev