0

I just start learning LLVM and follow the start-up website quick-start-writing-hello-world to write my first HelloPass.

However, it doesn't work as expected.

The llvm version is 16.0.6

Here are my steps.

The cmakelist is a bit different from the doc, because I don't include my project into the LLVM source. And I follow Developing LLVM passes out of source.

The project structure: . ├── CMakeLists.txt ├── helloPass │ ├── CMakeLists.txt │ └── hello.cpp

In CMakeLists.txt:

cmake_minimum_required(VERSION 3.25)
project(llvm_kernel CXX C)

set(CMAKE_CXX_STANDARD 17)
set(LLVM_PATH /usr/lib/llvm-16)
set(CMAKE_C_COMPILER /usr/bin/clang)
set(CMAKE_CXX_COMPILER /usr/bin/clang++)

find_package(LLVM REQUIRED CONFIG)

separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
add_definitions(${LLVM_DEFINITIONS_LIST})

include_directories(${LLVM_PATH}/include)

add_subdirectory(helloPass)

In helloPass/CMakeLists.txt:

cmake_minimum_required(VERSION 3.25)

add_library(HelloPass MODULE hello.cpp)

set_target_properties(HelloPass PROPERTIES
        COMPILE_FLAGS "-fno-rtti"
)

In helloPass/hello.cpp

#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"

#include "llvm/IR/LegacyPassManager.h"

using namespace llvm;

namespace {
    struct Hello : public FunctionPass {
        static char ID;

        Hello() : FunctionPass(ID) {}

        bool runOnFunction(Function &F) override {
            errs() << "Hello: ";
            errs().write_escaped(F.getName()) << '\n';
            return false;
        }
    }; // end of struct Hello
}  // end of anonymous namespace

char Hello::ID = 0;
static RegisterPass<Hello> X("hello", "Hello World Pass",
                             false /* Only looks at CFG */,
                             false /* Analysis Pass */);

And the following is just to build the project like :

mkdir build && cd build
cmake ..
make

Now the libHelloPass.so is generated. It works fine till here. But it fails in the invocation.

I try to use opt to load the helloPass as the documentation Running a pass with opt¶ said but it fails with "opt: unknown pass name 'hello'". The opt command is like: opt -load build/helloPass/libHelloPass.so -p hello test.bc > /dev/null. I do a bit modification here followed the doc Invoking opt.

I also tried just list all passes but not found a pass called "hello" but only a "helloworld", which is not defined by me. opt -load build/helloPass/libHelloPass.so --print-passes | grep hello

Anyone can help me about this?

I have checked the paths of llvm-related tools like opt, clang, clang++, which are all located at /usr/lib/llvm-16/bin

2
  • I tried this on LLVM-12, it surprisingly works! I still don't know what the problem is. I have tried build from the source code for llvm-16, but it still fails. One important thing is that HelloPass is included in the source code located at lib/Transforms/Hello, and after build whole llvm, the shared library LLVMHello.so is located at {build_dir}/lib. However it also fails to load the hello pass! Commented Dec 27, 2023 at 8:05
  • Can you try this: opt -load-pass-plugin build/helloPass/libHelloPass.so -passes="hello"? Commented Dec 27, 2023 at 8:23

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.