zoukankan      html  css  js  c++  java
  • 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);
  • 相关阅读:
    理解SVG坐标系统和变换: transform属性
    在svg文间画图过程中放大缩小图片后,坐标偏移问题
    理解SVG的缩放 偏移的计算公式
    svg 实践之屏幕坐标与svg元素坐标转换
    Winform 程序打包及安装
    使用bootstrap table小记(表格组件)
    MVC实现多级联动
    微信公众号开发之网页中及时获取当前用户Openid及注意事项
    微信公众号开发之网页授权获取用户基本信息
    微信公众号开发之自动消息回复和自定义菜单
  • 原文地址:https://www.cnblogs.com/jourluohua/p/14556253.html
Copyright © 2011-2022 走看看