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

标签 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";
      }
    }
  }

但这对查找函数调用指令不起作用。
例如,对于此指令:
call void @func2(i32* %num)

代码找不到它。

我为此指令做了一些实验:
inst.getOpcodeName() == "call"
inst.getOpcode() == 56

但:
Instruction::Call == 54
Instruction::UserOp1 == 56

我有一些问题:
  • 如何在llvm IR中找到函数调用?
  • Instruction::UserOp1 的用途是什么?
  • 为什么上面的例子如此困惑?
  • 最佳答案

    实际上,您的代码是正确的。截止到llvm镜像最新的commit,call指令的opcode已经不是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 框架也在一些函数中使用它来处理一些极端情况。您永远无法读取或写入 'UserOp1'(或 UserOp2)指令到 IR。你不需要关心这种类型。另见此处:How to use UserOp1/UserOp2 instruction?

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

    关于llvm-ir - 如何判断LLVM IR中的指令是否为调用指令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55437876/

    相关文章:

    c++ - 带有类型比较的 LLVM 测试示例问题

    c++ - 如何将参数传递给我在 LLVM 传递中使用 CallInst::Create(...) 调用的外部函数?

    c++ - 如何使用 `llvm::ilist_iterator<NodeTy>::operator pointer() const` 方法?

    c++ - 在 llvm ir 中增加一个 ptr

    llvm - 将 std::string 转换为 llvm::MemoryBuffer

    c++ - LLVM IR : Branch instruction with variable BasicBlock target?

    LLVM 将 if/else 插入现有的基本 block

    llvm - `ConstantInt::getTrue (LLVMContext &Context)` 和 `ConstantInt::getTrue (Type *Ty)` 有什么区别?

    c++ - 获取 llvm::Function 静态地址