如何找到"" LLVM中值的定义点?

时间:2014-12-12 03:39:50

标签: llvm static-analysis llvm-ir

LLVM对其IR使用静态单一赋值(SSA)形式,这意味着每个Value都有一个定义点。那么最简单(也是最通用)的方式是什么?"" Value的定义点,无需检查每个用途并确定我们Value的使用方式?在下面的代码中,我感兴趣的是用作函数参数的Value的定义点。

protected: void getValueDefs( Function * F ) {
    for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
      ImmutableCallSite CS( cast<Value>(I) );
      if ( !CS || isa<IntrinsicInst>(I) ) continue;
      for ( User::const_op_iterator Ab = CS.arg_begin(), Ae = CS.arg_end(); Ab != Ae; ++Ab ) {
          for ( User *U : Ab->get()->users() ) {
              if (Instruction *Inst = dyn_cast<Instruction>(U)) {
                  /* How to do the check here?? */
              }
          }
      }
   }
}

1 个答案:

答案 0 :(得分:1)

编写它有点奇怪。我可能会做这样的事情:

void scanFunc(Function &F) {

  for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
    for (BasicBlock::iterator BBI = BB->begin(), BBE = BB->end(); BBI != BBE;
         ++BBI) {
      if (CallInst *CI = dyn_cast<CallInst>(BBI)) {
        dbgs() << "Call: ";
        CI->dump();
        dbgs() << "\n";
        ImmutableCallSite CS(CI);
        for (ImmutableCallSite::arg_iterator I = CS.arg_begin(),
                                             E = CS.arg_end();
             I != E; ++I) {
          if (Instruction *Inst = dyn_cast<Instruction>(*I)) {
            // Do stuff                                                                                                                                                   
            dbgs() << "\tInst: ";
            Inst->dump();
            dbgs() << "\n";

          }
        }
      }
    }
  }
}

但基本上,如果是指令,则是值的定义。这就是IR的工作原理。否则,它可能是一个常数等。如果你采用这个代码:

int a (int b) {
  return b + 4;
}

int b (int c) {
  return a(c) + a(c-1);
}

int d (int e, int f, int g) {
  int h = a(4);
  int i = b(5);
  int j = b(6);

  return h + i + j + e + f + g;
}

并将其编译为IR并在其上运行此代码,您将看到:

Call:   %call = call i32 @_Z1ai(i32 %0)

    Inst:   %0 = load i32* %c.addr, align 4

Call:   %call1 = call i32 @_Z1ai(i32 %sub)

    Inst:   %sub = sub nsw i32 %1, 1

Call:   %call = call i32 @_Z1ai(i32 4)

Call:   %call1 = call i32 @_Z1bi(i32 5)

Call:   %call2 = call i32 @_Z1bi(i32 6)