//CMakeLists.txt
project(PassTest)
set(CMAKE_CXX_STANDARD 11)
SET(LLVM_HOME /opt/llvm)
find_package(LLVM)
add_definitions(${LLVM_DEFINITIONS})
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
include_directories(${LLVM_INCLUDE_DIRS})
llvm_map_components_to_libnames(llvm_libs support core irreader)
add_executable(PassTest main.cpp TestPassSupport.h InitializeTestPasses.h PrintFnName.h PrintFnName.cpp)
target_link_libraries(PassTest ${llvm_libs})
//main.cpp
#include <llvm/IR/LLVMContext.h>
#include <llvm/IRReader/IRReader.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/IR/LegacyPassManager.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/Module.h>
#include <llvm/ADT/Statistic.h>
#include "PrintFnName.h"
int main(int argc, char * argv[]) {
llvm::LLVMContext context;
llvm::SMDiagnostic err;
std::unique_ptr<llvm::Module> module = llvm::parseIRFile(argv[1], err, context);
llvm::legacy::PassManager pm;
llvm::EnableStatistics();
pm.add(test::createPrintFnNamePass());
pm.run(*module);
llvm::PrintStatistics(llvm::errs());
return 0;
}
//PrintFnName.h
#pragma once
#include <llvm/Pass.h>
namespace test{
llvm::Pass *createPrintFnNamePass();
}
//PrintFnName.cpp
#include <llvm/ADT/Statistic.h>
#include <llvm/IR/Constants.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/LegacyPassManager.h>
#include <llvm/IR/Module.h>
#include <llvm/IRReader/IRReader.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/Support/raw_ostream.h>
#include "PrintFnName.h"
#include "InitializeTestPasses.h"
#include "TestPassSupport.h"
#define DEBUG_TYPE "PrintFnName"
STATISTIC(numPrintFnName, "number of print function name");
namespace {
class PrintFnName : public llvm::FunctionPass {
public:
PrintFnName();
bool runOnFunction(llvm::Function &F) override;
void getAnalysisUsage(llvm::AnalysisUsage &AU) const override;
public:
static char ID;
};
}
char PrintFnName::ID = 0;
PrintFnName::PrintFnName():llvm::FunctionPass(ID) {
test::initializePrintFnNamePass(*llvm::PassRegistry::getPassRegistry());
}
bool PrintFnName::runOnFunction(llvm::Function &F) {
bool change = false;
llvm::outs() << F.getName() << "\n";
++numPrintFnName;
return change;
}
void PrintFnName::getAnalysisUsage(llvm::AnalysisUsage &AU) const {
//AU.addRequired<delateFnName>()
}
INITIALIZE_TEST_PASS(PrintFnName,"PrintFnName", "Print Function Name", false, false)
llvm::Pass* test::createPrintFnNamePass() {
return new PrintFnName;
}
static auto X = std::make_shared<llvm::Pass*>(test::createPrintFnNamePass());
//TestPassSupport.h
#pragma once
#include <llvm/Pass.h>
#include <llvm/PassInfo.h>
#include <llvm/PassRegistry.h>
#include <llvm/Support/Threading.h>
#define INITIALIZE_TEST_PASS(passName, arg, name, cfg, analysis) \
static void *initialize##passName##PassOnce(llvm::PassRegistry &Registry) { \
llvm::PassInfo *PI = \
new llvm::PassInfo(name, arg, &passName::ID, llvm::PassInfo::NormalCtor_t(llvm::callDefaultCtor<passName>), cfg, analysis); \
Registry.registerPass(*PI, true); \
return PI; \
} \
static llvm::once_flag Initialize##passName##PassFlag; \
void test::initialize##passName##Pass(llvm::PassRegistry &Registry) { \
llvm::call_once(Initialize##passName##PassFlag, initialize##passName##PassOnce, std::ref(Registry)); \
}
//InitializeTestPasses.h
#pragma once
#include <llvm/PassRegistry.h>
namespace test{
void initializePrintFnNamePass(llvm::PassRegistry&);
}