zoukankan      html  css  js  c++  java
  • LLVM Pass 简介(2)

    本节介绍一段对LLVM 的Function进行遍历的过程,遍历过程中统计每个Function内的BasicBlock数目和指令数目,同时统计所有的operand出现的次数。

    因为涉及到IR的东西,UserManual手册为: https://llvm.org/docs/LangRef.html 。真的建议初学者都去简单的扫一遍这个文档,看下目录也好,网上的很多介绍文档和博客上边都给了很多错误的东西。

     1 #include "llvm/ADT/Statistic.h"
     2 #include "llvm/IR/Function.h"
     3 #include "llvm/Pass.h"
     4 #include "llvm/Support/raw_ostream.h"
     5 #include <map>
     6 #include <string>
     7 #include "llvm/IR/Instructions.h"
     8 #include "llvm/IR/InstVisitor.h"
     9 #include "llvm/ADT/DepthFirstIterator.h"
    10 #include "llvm/ADT/SmallPtrSet.h"
    11 #include "llvm/ADT/SmallVector.h"
    12 #include "llvm/IR/InstIterator.h"
    13 #include "llvm/IR/Instructions.h"
    14 #include "llvm/IR/IntrinsicInst.h"
    15 using namespace llvm;
    16 #define DEBUG_TYPE "hello"
    17 
    18 STATISTIC(HelloCounter, "Counts number of functions greeted");
    19 namespace {
    20   // Hello2 - The second implementation with getAnalysisUsage implemented.
    21   struct Hello2 : public FunctionPass {
    22     static char ID; // Pass identification, replacement for typeid
    23     Hello2() : FunctionPass(ID) {}
    24     using BasicBlockListType = SymbolTableList<BasicBlock>;
    25     bool runOnFunction(Function &F) override {
    26       ++HelloCounter;
    27       errs() << "now process funcName: ";
    28       errs().write_escaped(F.getName()) << '
    ';
    29       //we just what to show how to Traverse
    30       //BBsize = F.size();
    31       //when you just want get all instructions, you can use llvm::instructions(F)
    32       uint BBsize = 0;
    33       uint instSize = 0;
    34       BasicBlockListType::const_iterator bbEnd = F.end();
    35       for(BasicBlockListType::const_iterator bbIter=F.begin(); bbIter!=bbEnd; ++bbIter){
    36         BBsize += 1;
    37         SymbolTableList<Instruction>::const_iterator instIter = bbIter->begin();
    38         SymbolTableList<Instruction>::const_iterator instEnd  = bbIter->end();
    39         for(; instIter != instEnd; ++instIter){
    40           instSize ++;
    41           std::string opcName(instIter->getOpcodeName());
    42           std::map<std::string, uint>::iterator itFind =
    43             opCodeMap.find(opcName);
    44           if(itFind != opCodeMap.end() ){
    45             opCodeMap[opcName]++;
    46           }
    47           else{
    48             opCodeMap[opcName] = 1;
    49           }
    50         }
    51       }
    52       //
    53       errs() << "    has "<< BBsize <<" BasicBlocks "<<instSize <<" insts
    ";
    54       for(auto it : opCodeMap){
    55         errs() <<"   total opcode now use "<<it.first <<" "<<it.second <<"
    ";
    56       }
    57       return false;
    58     }
    59 
    60     // We don't modify the program, so we preserve all analyses.
    61     void getAnalysisUsage(AnalysisUsage &AU) const override {
    62       AU.setPreservesAll();
    63     }
    64     std::map<std::string, uint> opCodeMap;
    65   };
    66 }
    67 
    68 char Hello2::ID = 0;
    69 static RegisterPass<Hello2>
    70 Y("hello2", "Hello World Pass (with getAnalysisUsage implemented)");

    使用上一节的测试hello.c 这次需要将命令换为 ./bin/opt -load lib/LLVMHello.so -hello2 < hello.bc > /dev/null 

    结果如下图:

  • 相关阅读:
    java常量池概念【转】
    IntelliJ IDEA 2016 汉化说明:
    intellij idea 添加动态 user library(java.lang.VerifyError)【转】
    IntelliJ IDEA 12 创建Web项目 教程 超详细版【转】
    IntelliJ IDEA 12详细开发教程(一)思想的转变与新手入门【转】
    接口请求时,charles修改请求参数
    monkey测试工具
    操作DOM
    操作表单
    jQuery扩展
  • 原文地址:https://www.cnblogs.com/jourluohua/p/14556184.html
Copyright © 2011-2022 走看看