version:llvm20.15
LoopInstrument.cpp
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Passes/PassPlugin.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
namespace {
struct LoopInstrumentPass : PassInfoMixin<LoopInstrumentPass> {
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM) {
auto &LI = FAM.getResult<LoopAnalysis>(F);
for (Loop *L : LI) {
unsigned NumBlocks = L->getNumBlocks();
errs() << "Function: " << F.getName()
<< ", Loop with " << NumBlocks
<< " basic blocks found.\n";
// Iterate through all basic blocks in this loop
for (BasicBlock *BB : L->blocks()) {
errs() << " BasicBlock: " << BB->getName() << "\n";
// Iterate through all instructions in the basic block
for (Instruction &I : *BB) {
errs() << " Instruction: " << I << "\n";
}
}
}
errs().flush();
return PreservedAnalyses::all();
}
};
} // namespace
// 插件入口点
extern "C" LLVM_ATTRIBUTE_WEAK ::llvm::PassPluginLibraryInfo
llvmGetPassPluginInfo() {
return {
LLVM_PLUGIN_API_VERSION,
"LoopInstrument",
"0.1",
[](PassBuilder &PB) {
PB.registerPipelineParsingCallback(
[](StringRef Name, FunctionPassManager &FPM,
ArrayRef<PassBuilder::PipelineElement>) {
if (Name == "loopinst") {
FPM.addPass(LoopInstrumentPass());
return true;
}
return false;
});
}
};
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.13)
project(LoopInstrument)
find_package(LLVM REQUIRED CONFIG)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard to conform to")
include_directories(${LLVM_INCLUDE_DIRS})
add_definitions(${LLVM_DEFINITIONS})
add_library(LoopInstrument MODULE LoopInstrument.cpp)
# LLVM libraries needed
target_link_libraries(LoopInstrument PRIVATE
LLVMCore
LLVMIRReader
LLVMPasses
)
# Let LLVM know it's a plugin
set_target_properties(LoopInstrument PROPERTIES
COMPILE_FLAGS "-fno-rtti"
)
test
#!/bin/bash
set -e
clang -O1 -emit-llvm -S test.c -o test.ll
opt -load-pass-plugin ./lib*.so -passes=loopinst -S test.ll -o instrument.ll
clang instrument.ll