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()) << '\n';
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\n";
54       for(auto it : opCodeMap){
55         errs() <<"   total opcode now use "<<it.first <<" "<<it.second <<"\n";
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 

结果如下图:

 

posted @ 2021-03-26 01:03  转换无极限  阅读(693)  评论(0编辑  收藏  举报