[LLVM] pass example

//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&);
}

猜你喜欢

转载自blog.csdn.net/adream307/article/details/80990331