A new Pass as a Plugin can't be run

I’m trying to write a Pass as a plugin in the new fashion, not legacy. The funtionality of the Pass is to print how many instructions in every basic block. After finishing building .so file, I call it on a demo.ll with opt. However, it shows

Statistics are disabled. Build with asserts or with -DLLVM_FORCE_ENABLE_STATS

I build this tiny project with cmake. The following is top-level CMakeLists.txt and source file. Does anyone have idea why this Pass couldn’t be run? Any reference link and material would be helpful. Thanks.

#include "CountIR.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Support/Debug.h"

#define DEBUG_TYPE "countir"

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

llvm::PreservedAnalyses CountIRPass::run(
        llvm::Function& F,llvm::FunctionAnalysisManager& AM){
            for(llvm::BasicBlock& BB: F){
                ++NumOfBB;
                for(llvm::Instruction& I:BB){
                    (void)I;
                    ++NumOfInst;
                }
            }
            return llvm::PreservedAnalyses::all();
}

bool PipelineParsingCB(llvm::StringRef Name,llvm::FunctionPassManager& FPM,llvm::ArrayRef<llvm::PassBuilder::PipelineElement>){
    if(Name=="countir"){
        FPM.addPass(CountIRPass());
        return true;
    }
    return false;
}

void RegisterCB(llvm::PassBuilder& PB){

    PB.registerPipelineParsingCallback(PipelineParsingCB);
}

//return the Pass entity from a function.
extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK llvmGetPassPluginInfo(){
    return {LLVM_PLUGIN_API_VERSION,"CountIR","v0.1",RegisterCB};
}
cmake_minimum_required(VERSION 3.4.3)

project(countirpass)

#set(LLVM_EXPORTED_SYMBOL_FILE ON)

set(LLVM_FORCE_ENABLE_STATS ON)

find_package(LLVM REQUIRED CONFIG)

message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")

message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")

list(APPEND CMAKE_MODULE_PATH ${LLVM_DIR})

include(ChooseMSVCCRT)

include(AddLLVM)

include_directories("${LLVM_INCLUDE_DIR}")

add_definitions("${LLVM_DEFINITIONS}")

link_directories("${LLVM_LIBRARY_DIR}")

include_directories(BEFORE include)

add_subdirectory(lib)

Your pass is likely running, but you’re not seeing any statistical
output (via the -stats argument) because LLVM itself was built
with statistical output disabled. You’d need a debug version of LLVM
or to build it yourself with -DLLVM_FORCE_ENABLE_STATS specified
during CMake configuration.

You can verify this by changing your STATISTIC declarations to
ALWAYS_ENABLED_STATISTIC.

Thanks very much for your reply. Is any approaches that I can see the output without rebuilding LLVM? @jvstech

Yes. As I mentioned, change these

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

to this instead:

ALWAYS_ENABLED_STATISTIC(NumOfInst,"Number of instructions.");
ALWAYS_ENABLED_STATISTIC(NumOfBB,"Number of basic blocks.");

By the way, in addition to changing the use of the STATISTIC macro, you can simplify your whole pass by assigning values directly to the underlying llvm::Statistic variables:

#include "llvm/IR/InstIterator.h"

...

llvm::PreservedAnalyses CountIRPass::run(
    llvm::Function &F, llvm::FunctionAnalysisManager &AM) {
  NumOfBB = F.size();
  NumOfInst = std::distance(llvm::inst_begin(F), llvm::inst_end(F));
  return llvm::PreservedAnalyses::all();
}
...

Just wanted to point that out in case you hadn’t seen llvm::inst_begin()/llvm::inst_end()/llvm::instructions() or any of the other stuff from InstIterator.h.

Thank you very much. Your replies really help me a lot! :grin:

Hello Viurx, have you solved this problem? I change STATISTIC to ALWAYS_ENABLED_STATISTIC, but the problem still exists.

#include "CountIR.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Support/Debug.h"

using namespace llvm;

#define DEBUG_TYPE "countir"

ALWAYS_ENABLED_STATISTIC(NumOfInst, "Number of instructions.");//change
ALWAYS_ENABLED_STATISTIC(NumOfBB, "Number of basic blocks.");//change

Should I modify other code? Any help will be appreciated!

Sorry for this late reply. Due to lack of reference concerning new pass, I have given up this new style and turned to legacy style. For this issue you mentioned, it ,probably, can be fixed by building LLVM in Debug type.

Thanks a lot, by rebuilding llvm with Debug type, the pass can print stats info.