【问题标题】:How to verify if LLVM "ret" instruction returns void?如何验证 LLVM“ret”指令是否返回 void?
【发布时间】:2017-09-29 21:48:02
【问题描述】:

我有以下sn-p的代码:

static LLVMContext TempContext;
Type * RetTy = Type::getVoidTy(TempContext)
for (Instruction *I : ListOfInstructions) {
  if (isa<ReturnInst>(I)) {
    RetTy = I->getOperand(0)->getType();
    break
  }
}

我试图在哪里捕获指令的RetTy,无论是否无效,所以我可以在

上使用它
getOrInsertFunction("TempF", FunctionType::get(RetTy, ArgsTys,false));

只要 ret 指令不是ret void,此代码就可以工作。

我尝试添加第二个if 来检查void 的情况,但这似乎不起作用,并且在FunctionType::get(...) 函数中的执行停止,打印回溯。

for (Instruction *I : ListOfInstructions) {
  if (isa<ReturnInst>(I)) {
    if ( I->getOperand(0)->getType() != Type::getVoidTy(TempContext)) {
      RetTy = I->getOperand(0)->getType();
      break
    }
  }
}                                            

请注意,同时删除 for 循环并继续执行,因为函数 FunctionType::get(...) 可以很好地处理 RetTy 的初始化 Type * RetTy = Type::getVoidTy(TempContext) "void" 值。但是当 llvm 函数返回非 void 值时,我无法捕获。


我如何知道 I 指令何时是返回指令并且它在 LLVM IR 中返回 Void?

【问题讨论】:

    标签: c++ compiler-construction llvm llvm-ir


    【解决方案1】:

    您当前代码的问题是ret void 没有操作数,因此调用getOperand(0) 会访问无效数据。

    将你的 if 替换为:

    if (ReturnInst *ri = dyn_cast<ReturnInst>(I))
    {
      if (ri->getNumOperands() == 0)
      {
        errs() << "VOID: " << *ri << "\n";
      }
      else
      {
        errs() << "NON-VOID: " << *ri << "\n";
      }
    }
    

    现在,此代码将输出VOID: ret void,正确检测到指令。

    作为替代方案,您可以使用任何指令检索函数的返回类型,方法是依赖函数I-&gt;getFunction()-&gt;getReturnType() 包含的指令;但是,这会假设函数格式正确且 ReturnInst 与其类型匹配,并且指令是函数的一部分。

    【讨论】:

    • 我在阅读文档时没有看到这一点。现在,您突出显示了它,我看到IRBuilder 调用ReturnInst::Create 方法初始化TerminatorInst(在InstrTypes.h 中),NumOps 参数设置为0。谢谢您的回答。
    猜你喜欢
    • 2017-09-04
    • 2020-02-05
    • 2015-01-12
    • 1970-01-01
    • 2016-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多