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

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

一、目的:

写入opt和clang的命令参数,可以直接参数指定调用

二、使用pass

把上一小节的pass稍加修改

  • 创建头文件:include/llvm/Transforms/CountOpcode/CountOpcode.h
#include "llvm/IR/Function.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Instructions.h"
#include "llvm/InitializePasses.h"

#define DEBUG_TYPE "opcodecounter"

namespace llvm {
    FunctionPass *createCountOpcodePass();
//    void initializeCountOpcodePass(PassRegistry &Registry);
}
  • cpp文件:lib/Transforms/CountOpcode/CountOpcode.cpp
#include "llvm/Transforms/CountOpcode/CountOpcode.h"

using namespace llvm;

static cl::opt<bool> EnableCountOpcode("opcodeCounter2", cl::init(false),
                                 cl::desc("Count opcode number"));

namespace llvm {
    struct CountOpcode : public FunctionPass {
        std::map<std::string,int> opcodeCounter;
        static char ID;
        CountOpcode() : FunctionPass(ID){}
        virtual bool runOnFunction(Function &F) {
            if(!EnableCountOpcode){
                return false;
            }
            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 false;
        }
        
    };
    FunctionPass * createCountOpcodePass(){
        return new CountOpcode();
    }

}

char CountOpcode::ID = 0;
//static RegisterPass<CountOpcode> X("opcodeCounter", "Count opcode number", false, false);
INITIALIZE_PASS(CountOpcode, "opcodeCounter", "Count opcode number", false, false)

  • 创建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
  • PassManager 注册
  • lib/Transforms/IPO/PassManagerBuilder.cpp 添加头文件:
#include "llvm/Transforms/CountOpcode/CountOpcode.h"
  • lib/Transforms/IPO/PassManagerBuilder.cpp 函数 populateModulePassManager 添加:
MPM.add(createCountOpcode());
  • lib/Transforms/IPO/LLVMBuild.txt 添加:
required_libraries = AggressiveInstCombine Analysis BitReader BitWriter Core InstCombine IRReader Linker Object ProfileData Scalar Support TransformUtils Vectorize Instrumentation CountOpcode
  • 相关头文件修改:
    llvm/LinkAllPasses.h 头文件添加:
    #include "llvm/Transforms/CountOpcode/CountOpcode.h"
    (void) llvm::createCountOpcodePass();
    llvm/InitializePasses.h 头文件添加:
    void initializeCountOpcodePass(PassRegistry&);
  • opt命令参数添加:
    initializeCountOpcodePass(Registry);

最后分别编译opt和clang。

  • 编译可能的问题:
  1. 最终链接找不到新pass的符号,需要在链接flag配置新创建pass库的路径:
    ld: symbol(s) not found for architecture x86_64
    如下配置链接库:
    image.png

四、opt 和 clang执行:

  • opt 参数与运行结果:


    image.png
image.png
  • clang 参数与运行结果:


    image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • mean to add the formatted="false" attribute?.[ 46% 47325/...
    ProZoom阅读 7,590评论 0 3
  • 近来,ollvm在国内移动安全,尤其是安全加固上的使用越来越广泛,ollvm的混淆和反混淆也被视为比较高等的知识之...
    that_is_this阅读 8,130评论 4 0
  • Swift介绍 Swift是一种高性能的语言,拥有整洁现代的语法。swift可以和C、OC的代码和框架无缝衔接,并...
    sea_biscute阅读 11,389评论 2 22
  • http://www.starming.com/index.php?v=index&view=107 http:/...
    111浪子111阅读 8,360评论 0 11
  • PS: Clang为LLVM提供的C语言编译器,默认参数可以生成本机可执行的二进制程序。-S和-c参数与GCC一样...
    HAPPYers阅读 10,102评论 0 2