首页 > 解决方案 > 有没有办法区分llvm ir中的指针类型?

问题描述

我正在尝试优化 llvm ir 中的代码,意识到 Types - isPointerTy 不区分 *i8、*i16、*i32、*i64。打印出它们的类型值显然会给出不同的值。下面是我用来检测问题的代码。

在 C 中:

...
if (CallInst *CI = dyn_cast<CallInst>(UsrI)) {
   if (CI->getCalledFunction()->getReturnType() ->isPointerTy()){
      outs() << "Calling func with ptr return = " << CI->getCalledFunction()->getName() << "\n";
      outs() << CI->getCalledFunction()->getReturnType() << "\n";
   }
}
...

在 llvm 中:

...
if.end:
    %test3 = call i64* @malloc64(i64 %mul)
    %call = call i32* @malloc32(i64 %mul) #4
    %test = call i16* @malloc16(i64 %mul)
    %test2 = call i8* @malloc8(i64 %mul)
...
declare i8* @malloc8(i64)
declare i16* @malloc16(i64)
declare i16* @malloc16(i64)
declare i16* @malloc16(i64)

显示输出为

使用 ptr 返回调用 func = malloc8 0x1c56e90 使用 ptr 返回调用 func = malloc16
0x1c56e20 使用 ptr 返回调用 func = malloc32 0x1c56db0使用 ptr 返回 调用 func = malloc64 0x1c56d40





我尝试检查许多 llvm 文档,但我错过了一些东西。任何关于我如何检查确切指针类型的建议将不胜感激。

标签: llvm

解决方案


isPointerTy方法不区分不同的类型,它只是告诉一个类型true是否false是指针。

解决问题的一种方法是查看它的底层指针类型(指针指向的类型)。

您可以这样做:

Type *returnType = CI->getCalledFunction()->getReturnType();
if (PointerType *pointerType = dyn_cast<PointerType>(returnType)) {
  llvm::Type *pointeeType = pointerType->getElementType();
  /// the pointee type now holds one of i8, i16, i32, or i64
  if (IntegerType *intType = dyn_cast<IntegerType>(pointeeType)) {
    outs() << intType->getBitWidth() << "\n";
  }
}

第二行试图将一般投射Type *到更特殊的位置PointerType *。如果不是 a ,则dyn_cast返回有效指针或a 。nullptrreturnTypePointerType

然后,您可以访问指针类型(通过getElementType)并可以进行进一步检查。在您的示例中,所有基础类型都是IntegerTypes,区分它们的方法是检查它们的位宽。

我想这应该会有所帮助:)


推荐阅读