美文网首页LLVM
llvm学习日记十三:PassManager 注册pass

llvm学习日记十三:PassManager 注册pass

作者: 鸣人的大哥 | 来源:发表于2019-12-09 11:42 被阅读0次

参考:http://www.alonemonkey.com/2016/12/21/learning-llvm/

一、目的:

实现clang编译时执行我们注册的pass

二、使用pass

把上一小节的pass稍加修改

  • 创建头文件:include/llvm/Transforms/CountOpcode/CountOpcode.h
#include "llvm/IR/Function.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"
#include <map>

#define DEBUG_TYPE "opcodecounter"

namespace llvm {
    Pass *createCountOpcode(bool flag);
}
  • cpp文件:lib/Transforms/CountOpcode/CountOpcode.cpp
#include "llvm/Transforms/CountOpcode/CountOpcode.h"
using namespace llvm;
namespace {
    struct CountOpcode : public FunctionPass {
        std::map<std::string,int> opcodeCounter;
        static char ID;
        bool flag;
        CountOpcode() : FunctionPass(ID){}
        CountOpcode(bool flag) : FunctionPass(ID) {
            this->flag = flag;
        }
        virtual bool runOnFunction(Function &F) {
            errs()<<"FunctionName:"<<F.getName()<<"\n";
            for(Function::iterator bb = F.begin(),e = F.end();bb!=e;++bb){
                for(BasicBlock::iterator i = bb->begin(),ie = bb->end();i!=ie;++i){
                    if(opcodeCounter.find(i->getOpcodeName()) == opcodeCounter.end()){
                        opcodeCounter[i->getOpcodeName()] =1;
                    }else{
                        opcodeCounter[i->getOpcodeName()] +=1;
                    }
                }
            }
            std::map<std::string,int>::iterator ib = opcodeCounter.begin();
            std::map<std::string,int>::iterator ie = opcodeCounter.end();
            while (ib != ie) {
                errs() << ib->first << " : " << ib->second << "\n";
                ib++;
            }
            errs()<<"\n";
            opcodeCounter.clear();
            return true;
        }       
    };   
}
char CountOpcode::ID = 0;
static RegisterPass<CountOpcode> X("opcodeCounter", "Count opcode number", true, true);
// INITIALIZE_PASS(CountOpcode, "opcodeCounter", "Count opcode number", true, true)
Pass *llvm::createCountOpcode(bool flag) { return new CountOpcode();}
  • 创建LLVMBuild.txt : lib/Transforms/CountOpcode/LLVMBuild.txt
[component_0]
type = Library
name = CountOpcode
parent = Transforms
library_name = CountOpcode
  • 创建CMakeLists.txt : lib/Transforms/CountOpcode/CMakeLists.txt

add_llvm_library( LLVMCountOpcode
  CountOpcode.cpp

  DEPENDS
  intrinsics_gen
  )

  • lib/Transforms/CMakeLists.txt
add_subdirectory(CountOpcode)
  • lib/Transforms/LLVMBuild.txt 加上我们的pass
[common]
subdirectories = AggressiveInstCombine Coroutines IPO InstCombine Instrumentation Scalar Utils Vectorize ObjCARC CountOpcode

上面步骤编译后可以使用opt加载

三、PassManager 注册

  • lib/Transforms/IPO/PassManagerBuilder.cpp 添加头文件:
#include "llvm/Transforms/CountOpcode/CountOpcode.h"
  • lib/Transforms/IPO/PassManagerBuilder.cpp 添加:
static cl::opt<bool> CountOpcode("opcodeCounter", cl::init(false),
                           cl::desc("Count opcode number"));

如下图:


image.png
  • 函数populateModulePassManager 添加:
MPM.add(createCountOpcode(CountOpcode));
  • lib/Transforms/IPO/LLVMBuild.txt 添加:
required_libraries = AggressiveInstCombine Analysis BitReader BitWriter Core InstCombine IRReader Linker Object ProfileData Scalar Support TransformUtils Vectorize Instrumentation CountOpcode

最后我们直接编译就行。

四、clang执行:

我试过了修改IR的pass和不修改IR的pass,在llvm9.0 里边这样添加的注册,都被默认执行了,不需要-mllvm 参数去调用。


image.png

相关文章

网友评论

    本文标题:llvm学习日记十三:PassManager 注册pass

    本文链接:https://www.haomeiwen.com/subject/xcpcgctx.html