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

问题描述 投票:1回答:1

我是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. 为什么上面的例子如此困惑?
llvm-ir
1个回答
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的操作码。

© www.soinside.com 2019 - 2024. All rights reserved.