如何判断LLVM IR中的指令是否为调用指令?

时间:2019-03-31 04:30:28

标签: llvm-ir

我是llvm中的新手,我正在尝试查找IR中的所有函数调用指令。 我的代码如下所示:

  for (BasicBlock &BB : F) {
    for (Instruction &inst : BB) {

      errs() << "\n => " << inst << "\n";

      // if (dyn_cast<CallInst>(&inst) || dyn_cast<InvokeInst>(&inst)) {
      if(inst.getOpcode() == Instruction::Call || inst.getOpcode() == Instruction::Invoke) { 
        errs() << "\n callinst => " << inst << "\n";
      }
    }
  }

但这无法找到函数调用指令。 例如:

for this instruction: call void @func2(i32* %num)
the code can not find it.
And I did some experiment for this instucion:
inst.getOpcodeName() == "call"
inst.getOpcode() == 56
but:
Instruction::Call == 54
Instruction::UserOp1 == 56

我有一些问题:

  1. 如何在llvm IR中查找函数调用?
  2. Instruction :: UserOp1的用途是什么?
  3. 为什么上面的例子如此困惑?

1 个答案:

答案 0 :(得分:1)

实际上,您的代码是正确的。截至llvm镜像中的最新提交,调用指令的操作码不再是54,而是56。在2018年11月13日,它被更改为55,在2019年2月8日,它被更改为56。

https://github.com/llvm-mirror/llvm/commit/ca8cb6852b59f4cbfc311415aab0d5a7ce0616b4#diff-3ac5806b20ed80b3be17bac3cdb4f799

https://github.com/llvm-mirror/llvm/commit/e3696113b639c8bf0b72d6c27dd76d6fdd8ebf61#diff-3ac5806b20ed80b3be17bac3cdb4f799

UserOp1的操作码现在为58。

对您的问题:

1)识别呼叫指令以及任何其他类型的指令的正确方法是使用isa<>()函数。模板参数是您要识别的类型,函数参数是您的指令指针。在您的示例中,您可以将if条件更改为:

if(isa<CallInst>(&inst) || isa<InvokeInst>(&inst)) {

与比较操作码相比,您更愿意这样做的原因非常明显。如您所见,可以添加新指令并可以更改操作码。因此,比较操作码变得非常不兼容。如果类型匹配,则使用“ isa”函数将始终返回true,而与操作码无关。请在以下位置检查此功能的文档:http://llvm.org/docs/ProgrammersManual.html#the-isa-cast-and-dyn-cast-templates

2)UserOp1是仅在内部内部使用的指令类型。据我所知,llvm框架在一些函数中也使用它来处理一些极端情况。您永远无法向IR读取或写入“ UserOp1”(或UserOp2)指令。您不必关心这种类型。另请参见此处:How to use UserOp1/UserOp2 instruction?

3)您可能正在使用最新版本的框架,这就是为什么您获得56的呼叫说明输出的原因。您可能会感到困惑,因为您将此输出与稍微过时的Instructions.def文件进行了比较,该文件将调用指令映射到操作码54。