一起学习LLVM(三)

                                    学习LLVM常用的API操作

 

  • 常用的结构:

---关于函数和指令以及block和指令的操作;

  • 引用的各自类型:

---Dynamic casts

---Instanceof-of casts

  • 修改CFG的几种方式

---修改基本块或者指令

 

 

一、Runtime type inference(RTTI):

LLVM有五种运行时的value的类型操作,其中有三种是比较常用的:

1.isa<T>(V):知道V这个值的动态类型,如果V是T的一个引用则返回True,否则返回True.

比如:以下主要是判断对应的指令是不是PHINode类型:

 

Count_Phis() : FunctionPass(ID) {}
    virtual bool runOnFunction(Function &F) {
      errs() << "Function " << F.getName() << '\n';
      for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
        if (isa<PHINode>(*I)) {
          errs() << *I << "\n";
        }
      }
      return false;
    }
  };

2.cast<T>(V):类型的检查。

3.V'=dyn_cast<T>(V):把V转换为V',否则失败。

把为PHINode的指令转换为PN类型:

 

 virtual bool runOnFunction(Function &F) {
      errs() << "Function " << F.getName() << '\n';
      for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
        if (PHINode *PN = dyn_cast<PHINode>(&*I)) {
          errs() << *PN << "\n";
          int numArgs = PN->getNumIncomingValues();
          errs() << "  - has " << numArgs << " parameters\n";
          for (int arg = 0; arg < numArgs; arg++) {
            errs() << "    Argument " << arg << ":\n";
            errs() << "    " << PN->getIncomingBlock(arg)->getName() << ": " <<
              *(PN->getIncomingValue(arg)) << "\n";
          }
        }
      }
      return false;
    }

 

 

二、对代码结构进行转换:

1.增加/删除指令;指令是BasicBlock中以List的形式存在,无法单独存在,必须是某个BasicBlock中,通常我们通过写Pass进行优化和反优化大部分就是操作的指令。

 

2.增加/删除基本块;基本块(BasicBlock)是Function中以List的形式存放的,无法单独存在,里面有很多的指令存在,分为普通指令和TerminatorInst指令。

 

3.增加删除函数;函数是无数个基本块组成,使用列表组成,有且仅有一个EntryBlcok,是列表中得第一个BasicBlock。

 

举例:SmallVector<PHINode*, 16> Worklist,收集到PHINode结点的指令,再调用 PN->replaceAllUsesWith(PN->getIncomingValue(0)); PN->eraseFromParent()在迭代器外进行删除,不能够在迭代器内部进行删除操作。

 

virtual bool runOnFunction(Function &F) {
      bool cutInstruction = false;
      errs() << "Function " << F.getName() << '\n';
      SmallVector<PHINode*, 16> Worklist;
      for (Function::iterator B = F.begin(), EB = F.end(); B != EB; ++B) {
        for (BasicBlock::iterator I = B->begin(), EI = B->end(); I != EI; ++I) {
          if (PHINode *PN = dyn_cast<PHINode>(I)) {
            if (PN->hasConstantValue()) {
              // store for later elimination:
              Worklist.push_back(PN);
              cutInstruction = true;
            }
          } else {
            continue;
          }
        }
      }
      // Eliminate the uses:
      while (!Worklist.empty()) {
        PHINode* PN = Worklist.pop_back_val();
        PN->replaceAllUsesWith(PN->getIncomingValue(0));
        PN->eraseFromParent();
      }
      return cutInstruction;
    }

三、总结:

通过本节可以学习到Runtime type inference(RTTI)三种常见的基本类型操作,以及理解LLVM中指令(instructions)、基本块(BasicBlock)、以及函数(Function)之间的关系和对于它们的基本操作。

 

参考:http://llvm.org/docs/ProgrammersManual.html

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值