【问题标题】:LLVM IR: get the return value of the callsiteLLVM IR:获取调用点的返回值
【发布时间】:2019-03-25 16:12:11
【问题描述】:

这是一个关于分析 LLVM IR 的快速问题。所以基本上我正在尝试获取 LLVM IR 函数调用语句的返回值,如下所示:

%47  =   call i256 @test(i256 %46)

我想访问%47

这是我用来访问参数的代码。

      else if (funcName.contains("test")) {
        Value *op = CI->getOperand(0);
        if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(op))
          // get the first function parameter
          op = GEP->getPointerOperand();
      }

非常令人惊讶的发现是,我在文档中找不到诸如“获取返回值”之类的东西:http://llvm.org/doxygen/classllvm_1_1CallInst.html

有人可以在这里点亮一些灯吗?非常感谢。

【问题讨论】:

  • 您到底想在这里得到什么?函数在运行时将作为常量返回的实际返回值?显然,直到运行时您才能知道这一点(除非调用是恒定折叠的,在这种情况下,CallInst 不再存在)。还是将评估为返回值的指令?这只是CallInst 本身。
  • @sepp2k 感谢您的回复。所以我想得到一个变量%47Value实例。
  • 那是CallInst
  • 我有一个类似于你问的用例,获取 %47 的值并将其作为参数传递给另一个接受 i32 类型的函数。问题是如果我们只使用 CallInst,参数将类似于 call%47 i32,它与接受 i32 类型的新函数不兼容。 LLVM 是 SSA,但这样的场景是一个有趣的问题

标签: llvm llvm-ir


【解决方案1】:

CIcall 指令)它的返回值。它有一个继承Value的类型。

如果你想做1 + %47,举个例子,你可以像这样做一个加法:Value * Add = BinaryOperation::Create(Instruction::Add, CI, ConstantInt::get(i256, 1), ...);加法指令反过来就是它的结果,Add-&gt;getType() == i256因为它是两个值的和两者都具有i256 类型。

【讨论】:

  • 如果我不想插入指令,还有其他方法可以获取函数的返回值吗?我想要的只是函数的返回值
  • 由于 llvm 是 SSA,我想我可以简单地将值传递给另一个检测函数,但类型不兼容。新的函数参数是 i32 类型。如果我按原样传递,它会创建类似这样的调用 %i32 与新函数的 i32 参数类型不兼容
  • 指令的值。如果您不插入指令,则该值不会进入程序的域。如果您想知道函数的返回值,则必须调用该函数,并且在 SSA 中。调用指令返回值,看到了吗?或者你的真正目标是在编译时推理函数可能返回的内容,如果调用但不调用它?
  • 可以传值,需要强制转换。如何施放取决于你。例如,某些语言对整数进行符号扩展,因此 true 变为 32 位 -1,其他语言进行零扩展,因此 true 变为 1。 CastInst::Create() 可以让你做任何事,只要你决定什么样的演员表是合适的。
【解决方案2】:

如果您需要“返回值”名称的字符串,作为不同的答案,您可以在派生自Value 类的Instruction 对象上使用inst.getName()inst.getNameOrAsOperand()

【讨论】:

    最近更新 更多