LLVM从Value*获得常量整数

lur*_*her 24 c++ llvm

我从一个整数常量创建一个llvm :: Value*,如下所示:

llvm::Value* constValue = llvm::ConstantInt::get( llvmContext , llvm::APInt( node->someInt() ));
Run Code Online (Sandbox Code Playgroud)

现在我想要检索编译时常量值;

int constIntValue = constValue->???
Run Code Online (Sandbox Code Playgroud)

LLVM Programmer手册中显示的示例似乎暗示当使用类型(而不是类型加指针)模板参数时,强制转换<>将接受指针,但是我很确定从2.8开始失败:

llvm::Value* foo = 0;
llvm::ConstantInt* intValue = & llvm::cast< llvm::ConstantInt , llvm::Value >(foo );

//build error:
//error: no matching function for call to ‘cast(llvm::Value*&)’
Run Code Online (Sandbox Code Playgroud)

这里的正确方法是什么?

Oak*_*Oak 34

Eli的答案很棒,但它缺少最后一部分,即整数回归.全貌应如下所示:

if (ConstantInt* CI = dyn_cast<ConstantInt>(Val)) {
  if (CI->getBitWidth() <= 32) {
    constIntValue = CI->getSExtValue();
  }
}
Run Code Online (Sandbox Code Playgroud)

当然,您也可以将其更改为<= 64if constIntValue是64位整数等.

正如Eli所写,如果你确信价值确实是类型ConstInt,你可以用cast<ConstantInt>而不是dyn_cast.


Eli*_*sky 27

鉴于llvm::Value* foo并且你知道它foo实际上是一个ConstantInt,我相信惯用的LLVM代码方法是使用dyn_cast如下:

if (llvm::ConstantInt* CI = dyn_cast<llvm::ConstantInt>(foo)) {
  // foo indeed is a ConstantInt, we can use CI here
}
else {
  // foo was not actually a ConstantInt
}
Run Code Online (Sandbox Code Playgroud)

如果你完全确定foo是a ConstantInt并准备好被断言失败,如果不是,你可以使用cast而不是dyn_cast.


PS请注意cast并且dyn_cast是LLVM自己的RTTI实现的一部分.虽然在实现和性能方面存在差异(可以在这里阅读),但它的dyn_cast行为与标准C++有些相似.dynamic_cast