LLVM Pass 简介(4)

这里介绍LLVM或者所有编译器中非常重要的一种结构,def-use链,或者叫DU-chain。说是DU,实际上除了def-use,还有use-def的存在。

通常,我们可能有Value类的一个实例,并且我们想确定哪些使用者使用了该Value。我们将具有特定值的所有用户的列表称为def-use链。
另外,通常有一个User Class实例,需要知道它使用了哪些值。用户使用的所有值的列表称为use-def链。 Instruction类的实例是常见的User,
因此我们可能要遍历特定指令使用的所有值
另外,通常有一个User Class实例,需要知道它使用了哪些值。用户使用的所有值的列表称use-def链。
Instruction类的实例是常见的User,因此我们可能要遍历特定指令使用的所有值。

source from:https://llvm.org/docs/ProgrammersManual.html#iterating-over-def-use-use-def-chains

def是定值,use是使用点。DU是查找该点的使用点,UD是确定该点用了哪些其他点,其实就是得到它的操作数,如果这个是一个函数调用的话,就是找到函数调用的参数列表。

编程手册中给的一个例子,介绍如何使用函数F的使用点:

Function *F = ...;

for (User *U : F->users()) {
  if (Instruction *Inst = dyn_cast<Instruction>(U)) {
    errs() << "F is used in instruction:
";
    errs() << *Inst << "
";
  }

而对于UD,是这样的case:

Instruction *pi = ...;

for (Use &U : pi->operands()) {
  Value *v = U.get();
  // ...
}

下边是一个DCE的代码,进行死代码删除的功能,来源于《LLVM CodeBook》一书,代码虽然有bug,但是作为DU的阅读代码非常不错:

 1 // Hello4 - Dead code Elimination
 2 //
 3 //source code :https://ch4r1l4.github.io/2019/05/04/LLVM-%E5%88%9D%E6%8E%A2-2-Optimization-Pass-%E7%BC%96%E5%86%99/
 4 namespace {
 5   struct Hello4 : public FunctionPass {
 6     static char ID; // Pass identification, replacement for typeid
 7     Hello4() : FunctionPass(ID) {}
 8     using BasicBlockListType = SymbolTableList<BasicBlock>;
 9 
10     bool runOnFunction(Function &F) override {
11       errs()<<"in runOnFunction
";
12       SmallPtrSet<Instruction*, 32> Alive;
13       SmallVector<Instruction*, 32> Worklist;
14       for(Instruction & I:instructions(F)){
15           if(isa<TerminatorInst>(I) || isa<DbgInfoIntrinsic>(I)
16               || isa<LandingPadInst>(I) || I.mayHaveSideEffects()){
17               Alive.insert(&I);
18               Worklist.push_back(&I);
19           }
20       }
21       while(!Worklist.empty()){
22           Instruction* Curr = Worklist.pop_back_val();
23           for( Use &OI : Curr->operands()) {
24               if (Instruction* Inst = dyn_cast<Instruction>(OI))
25                   if(Alive.insert(Inst).second)
26                       Worklist.push_back(Inst);
27           }
28       }
29       for(Instruction &I : instructions(F)){
30           if(!Alive.count(&I)){
31               Worklist.push_back(&I);
32               I.dropAllReferences();
33           }
34       }
35       for(Instruction* I : Worklist){
36           I->dump();
37           I->eraseFromParent();
38       }
39       return !Worklist.empty();
40       
41       return false;
42     }
43 
44 
45     // We don't modify the program, so we preserve all analyses.
46     void getAnalysisUsage(AnalysisUsage &AU) const override {
47       AU.setPreservesAll();
48     }
49     std::map<std::string, uint> opCodeMap;
50   };
51 }
52 
53 char Hello4::ID = 0;
54 static RegisterPass<Hello4> Ms("hello4", "remove dead code", false, false);
原文地址:https://www.cnblogs.com/jourluohua/p/14556253.html