LLVM get constant integer back from Value*

2019-01-18 09:53发布

问题:

I create a llvm::Value* from a integer constant like this:

llvm::Value* constValue = llvm::ConstantInt::get( llvmContext , llvm::APInt( node->someInt() ));

now i want to retrieve the compile-time constant value back;

int constIntValue = constValue->???

The examples shown in LLVM Programmer manual seem to imply that cast<> will accept a pointer when using the type (rather than the type plus pointer) template parameter, however i'm pretty sure thats failing as from 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*&)’

What would be the correct approach here?

回答1:

Given llvm::Value* foo and you know that foo is actually a ConstantInt, I believe that the idiomatic LLVM code approach is to use dyn_cast as follows:

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
}

If you're absolutely sure that foo is a ConstantInt and are ready to be hit with an assertion failure if it isn't, you can use cast instead of dyn_cast.


P.S. Do note that cast and dyn_cast are part of LLVM's own implementation of RTTI. dyn_cast acts somewhat similarly to the standard C++ dynamic_cast, though there are differences in implementation and performance (as can be read here).



回答2:

Eli's answer is great, but it's missing the final part, which is getting the integer back. The full picture should look like this:

if (ConstantInt* CI = dyn_cast<ConstantInt>(Val)) {
  if (CI->getBitWidth() <= 32) {
    constIntValue = CI->getSExtValue();
  }
}

Of course, you can also change it to <= 64 if constIntValue is a 64-bit integer, etc.

And as Eli wrote, if you are confident the value is indeed of type ConstInt, you can use cast<ConstantInt> instead of dyn_cast.



标签: c++ llvm