LLVM运行PassManager(非遗留)

时间:2017-07-31 08:27:03

标签: c++ llvm llvm-ir llvm-c++-api

如何运行非传统PassManager?我尝试过以下操作,但在尝试使run函数中的分析管理器失效时会抛出一些异常。我还应该做些什么来进行初始化吗?

llvm::AnalysisManager<Module> mm;
PassBuilder builder;
auto pm = builder.buildModuleOptimizationPipeline(PassBuilder::OptimizationLevel::O3);
pm.run(module, mm );

1 个答案:

答案 0 :(得分:0)

这些代码片段说明了如何运行和设置以运行现代自定义功能,以及如何在一些.c / .cpp文件中传递模块以及完整的makefile文件。这适用于最近(2018年3月)的LLVM 6。它不使用旧版通行证管理器。 HelloWorld.cpp:

#include <llvm/Pass.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/Module.h>
#include <llvm/Support/raw_ostream.h>

namespace {

  struct Hello : public llvm::FunctionPass {
    static char ID;
    Hello() : llvm::FunctionPass{ID} {}

    bool runOnFunction(llvm::Function &F) override {
      llvm::errs() << "Hello ";
      llvm::errs().write_escaped(F.getName()) << "\n";
      return false;
    }
  };

  struct Hello2 : public llvm::ModulePass {
    static char ID;

    Hello2() : llvm::ModulePass{ID} {}

    bool runOnModule(llvm::Module &M) override {
      llvm::errs() << "Name of the module ", llvm::errs().write_escaped(M.getName()) << "\n";
      for(auto iter = M.getFunctionList().begin(); iter != M.getFunctionList().end(); ++iter) {
    llvm::errs() << "Function name:" << iter->getName() << "\n";
      }
      return false;
    }
  };
}

char Hello::ID = 0;
static llvm::RegisterPass<Hello> X("Hello", 
                   "Hello World Pass",
                   false,   
                   false
                   );

char Hello2::ID = 1;
static llvm::RegisterPass<Hello2> Y("Hello2", 
                    "Hello World2 pass",
                    false,  
                    false
);

对应的makefile:

LLVM_VERSION=
LLVM_INCLUDEDIR = `llvm-config-6.0 --includedir`
LLVM_FLAGS = `llvm-config-6.0 --cxxflags --ldflags --system-libs --libs all`
CXX = clang++-6.0
CXXFLAGS = -g -std=c++11 -O3 -I $(LLVM_INCLUDEDIR) -I $(LLVM_INCLUDEDIR)
Hello.so:
    $(CXX) -fPIC $(CXXFLAGS) HelloWorld.cpp $(LLVM_FLAGS) -shared -o Hello.so
Hello: Hello.so

testfile:
    clang++-6.0 -emit-llvm -c test.cpp -o test.bc

runFunctionPassOnTestFile: Hello testfile
    opt-6.0 -load ./Hello.so -Hello < test.bc > /dev/null

runModulePassOnTestfile: Hello testfile
    opt-6.0 -load ./Hello.so -Hello2 < test.bc > /dev/null

clean:
    rm *.o *.so *.out *~
DBG:
@echo LLVM INCLUDE DIRS $(LLVM_INCLUDEDIR) $(test)

一个简单的文件,用于测试所有内容,即test.cpp:

#include <stdio.h>
#include <stdlib.h>

int a = 4;

int c = 5;

int d = 6;

int e = 7;

int bar() { int *a = (int*) malloc(4); e = 1; return 1;}

int foo() { return 2; }

int barfoo() { return 3; }

int main() {
  printf("Testing testing\n");
  return 0;
}