【问题标题】:Backtrack operations and operands in LLVMLLVM 中的回溯操作和操作数
【发布时间】:2016-09-16 07:54:37
【问题描述】:

我正在努力分析使用过的指令。鉴于我发现 感兴趣的指令,我想回溯所有使用过的操作和 变量。例如,在 LLVM IR 中给出以下循环。

%i.01 = phi i32 [ 0, %0 ], [ %4, %2 ]
%3 = icmp eq i32 %i.01, 0
%bar.foobar.i = select i1 %3, void ()* @bar, void ()* @foobar
tail call void %bar.foobar.i() #2
%4 = add nuw nsw i32 %i.01, 1
%exitcond = icmp eq i32 %4, 10
br i1 %exitcond, label %1, label %2

例如,我对最后一个分支中涉及的所有数据感兴趣。条件在使用ICompInst 之前计算一条指令,其中涉及变量%4 和常量10%4 在使用加法之前计算一步。等等等等……

鉴于我找到了感兴趣的指令,在本例中为 BranchInst,我想开始回溯。

if(BranchInst* BI = dyn_cast<BranchInst>(&I)) {
  if(BI->isConditional()) {
    backtrack(BI, &I);
  }
}

要实现这样的算法,我有两个问题。有了分支指令,如何获得开始回溯的条件? 其次,如何确定条件是否在先前的指令中使用?为了更容易理解,我有以下伪代码:

void backtrack(BranchInst* BI, Instruction* I) {
  Value* condition = BI->getCondition();
  Instruction* prevInst = I;

  do {
    prevInst = prev(prevInst);
    if(prevInst->prevInst(condition)) {
      backTrackOperand(prevInst->getOperand(0), prevInst);
      backTrackOperand(prevInst->getOperand(1), prevInst);
      break;
    }
  } while(1);  
}

void backTrackOperand(Value* operand, Instruction* I) {
  Instruction* prevInst = I;

  do {
    prevInst = prev(prevInst);
    if(prevInst->usesOperand(operand)) {
      ...
    }
  }
}

那么我该如何实现函数getCondition()computesCondition()usesOperand()呢?

【问题讨论】:

    标签: llvm llvm-clang llvm-ir


    【解决方案1】:
    • getCondition() 是 getOperand(0)。
    • 我在您的代码中没有看到 computesCondition()?
    • usesOperand() 类似于llvm::find_if(prevInst-&gt;operands(), [&amp;] (Uses &amp;U) { return isa&lt;Instruction&gt;(&amp;U) &amp;&amp; cast&lt;Instruction&gt;(&amp;U) == I; });。但也请注意,从条件或任何值中,您可以轻松找到所有用途。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-18
      • 1970-01-01
      相关资源
      最近更新 更多