Writing an llvm pass within source tree

I was trying to write an LLVM pass within source tree using the new pass manager. While trying to build opt using ninja opt I encounter the following error:

Linking CXX shared library lib/libLLVMPasses.so.16git
FAILED: lib/libLLVMPasses.so.16git 
: && /usr/bin/c++ -fPIC -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wno-misleading-indentation -fdiagnostics-color -g  -Wl,-z,defs -Wl,-z,nodelete   -Wl,-rpath-link,/home/user3/Desktop/llvm-project/build/./lib -shared -Wl,-soname,libLLVMPasses.so.16git -o lib/libLLVMPasses.so.16git lib/Passes/CMakeFiles/LLVMPasses.dir/OptimizationLevel.cpp.o lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilder.cpp.o lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilderBindings.cpp.o lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilderPipelines.cpp.o lib/Passes/CMakeFiles/LLVMPasses.dir/PassPlugin.cpp.o lib/Passes/CMakeFiles/LLVMPasses.dir/StandardInstrumentations.cpp.o  -Wl,-rpath,"\$ORIGIN/../lib"  lib/libLLVMCoroutines.so.16git  lib/libLLVMipo.so.16git  lib/libLLVMObjCARCOpts.so.16git  lib/libLLVMTarget.so.16git  lib/libLLVMVectorize.so.16git  lib/libLLVMInstrumentation.so.16git  lib/libLLVMScalarOpts.so.16git  lib/libLLVMAggressiveInstCombine.so.16git  lib/libLLVMInstCombine.so.16git  lib/libLLVMTransformUtils.so.16git  lib/libLLVMAnalysis.so.16git  lib/libLLVMCore.so.16git  lib/libLLVMSupport.so.16git  -Wl,-rpath-link,/home/user3/Desktop/llvm-project/build/lib && :
/usr/bin/ld: lib/Passes/CMakeFiles/LLVMPasses.dir/PassBuilder.cpp.o: in function `llvm::detail::PassModel<llvm::Function, llvm::CountIRPass, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&)':
/home/user3/Desktop/llvm-project/llvm/include/llvm/IR/PassManagerInternal.h:88: undefined reference to `llvm::CountIRPass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&)'
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

Here CountIRPass is the class which contains run function for my Pass.
Kindly help. I have attached the code for reference:

  1. CountIR.cpp
#include "llvm/Transforms/CountIR/CountIR.h"
#include "llvm/Support/raw_ostream.h"
// #include "llvm/ADT/Statistic.h"
// #include "llvm/Support/Debug.h"

using namespace llvm;

#define DEBUG_TYPE "countir"

// STATISTIC(NumOfInst, "Number of instructions");
// STATISTIC(NumOfBB, "Number of basic blocks");

PreservedAnalyses CountIRPass::run(Function &F, FunctionAnalysisManager &FAM) {

  int NumOfBB = 0;
  int NumOfInst = 0;
  for (auto &BB : F) {
    ++NumOfBB;
    for (auto &Inst : BB) {
      ++NumOfInst;
    }
  }
  errs() << "NumOfInst: " << NumOfInst << "\n";
  errs() << "NumOfBB: " << NumOfBB << "\n";
  return PreservedAnalyses::all();
}

2.CountIR.h:

#ifndef Count_IR_H
#define Count_IR_H

#include "llvm/IR/PassManager.h"

namespace llvm {
class CountIRPass : public PassInfoMixin<CountIRPass> {
public:
  PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
  static bool isRequired() { return true; }
};
} // namespace llvm

#endif

3.CMakeLists.txt:

add_llvm_component_library(LLVMCountIR
  CountIR.cpp  
  LINK_COMPONENTS
  Core
  Support
  )

The CMakeLists.txt and CountIR.cpp are located at path llvm/lib/Transforms/CountIR/
The CountIR.h file is located at path llvm/Transforms/CountIR/

I have added #include "llvm/Transforms/CountIR/CountIR.h" to llvm/lib/Passes/PassBuilder.cpp and FUNCTION_PASS("countir",CountIRPass()) to llvm/lib/Passes/PassRegistry.def file.
I also added the following line: add_subdirectory(CountIR) to CMakeLists.txt at path : llvm/lib/Transforms
These are all the changes I have made. KIndly help me figure out a way to resolve this error.

This looks like a CMake issue.

I doubt add_llvm_component_group is what you want to use here. Instead, I would use add_llvm_pass_plugin - that’s assuming that you want to build a static pass plugin. Here’s a short guideline from llvm-tutor with a link to a relevant section in the LLVM docs.

Hope this helps,
-Andrzej

1 Like

Did you add CountIR as a dependency in llvm/lib/Passes/CMakeLists.txt?

1 Like

I had missed it… Thankyou. The error was resolved after I made the changes. The book I was following didn’t mention this step.