llvm - 识别 IR 中的数组类型

标签 llvm

我一直在尝试通过使用以下代码来识别 IR 中的数组访问:

  for (BasicBlock::iterator ii = BB->begin(), ii2; ii != BB->end(); ii++) {
     Instruction *I=ii;             
    if(GetElementPtrInst *getElePntr = dyn_cast<GetElementPtrInst>(&*I))
    {                   

        Value *valAlloc = (getElePntr->getOperand(0));

        if(getElePntr->getOperand(0)->getType()->isArrayTy())
            {
                errs()<<"\tarray found";
            }
    }  
 }  

此代码识别 getElementPtr 指令,但不识别其第一个操作数是否为数组类型。请让我知道我的代码有什么问题。

最佳答案

GEP(getelementptr 指令)的第一个操作数是指针,而不是数组。该指针可能指向一个数组,也可能不指向(见下文)。所以你需要看看这个指针指向什么。

这是一个示例 BasicBlockPass 访问者:

virtual bool runOnBasicBlock(BasicBlock &BB) {
    for (BasicBlock::iterator ii = BB.begin(), ii_e = BB.end(); ii != ii_e; ++ii) {
        if (GetElementPtrInst *gep = dyn_cast<GetElementPtrInst>(&*ii)) {
            // Dump the GEP instruction
            gep->dump();
            Value* firstOperand = gep->getOperand(0);
            Type* type = firstOperand->getType();

            // Figure out whether the first operand points to an array
            if (PointerType *pointerType = dyn_cast<PointerType>(type)) {
                Type* elementType = pointerType->getElementType();
                errs() << "The element type is: " << *elementType << "\n";

                if (elementType->isArrayTy()) {
                    errs() << "  .. points to an array!\n";
                }
            }
        }
    }

    return false;
}

但是请注意,C/C++ 中的许多“数组”实际上是指针,因此您可能无法获得预期的数组类型。

例如,如果你编译这段代码:

int main(int argc, char **argv) {
  return (int)argv[1][8];
}

你得到 IR:

define i32 @main(i32 %argc, i8** %argv) nounwind uwtable {
  %1 = alloca i32, align 4
  %2 = alloca i32, align 4
  %3 = alloca i8**, align 8
  store i32 0, i32* %1
  store i32 %argc, i32* %2, align 4
  store i8** %argv, i8*** %3, align 8
  %4 = load i8*** %3, align 8
  %5 = getelementptr inbounds i8** %4, i64 1
  %6 = load i8** %5
  %7 = getelementptr inbounds i8* %6, i64 8
  %8 = load i8* %7
  %9 = sext i8 %8 to i32
  ret i32 %9
}

尽管 argv视为 一个数组,但编译器将其视为一个指针,因此看不到数组类型。我上面粘贴的 pass 在这里无法识别数组,因为 GEP 的第一个操作数是指向指针的指针。

关于llvm - 识别 IR 中的数组类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9682705/

相关文章:

c++ - 链接@_Znam 和@_Znwm

windows - Windows 上 LLVM 汇编语言中的 Hello World

c++ - 将 c 代码的中间表示解析回 c

c++ - LLVM:如何找出使用的是哪种类型?

c++ - 将 LLVM getOrInsertFunction 链接到 LLVM 传递中的外部 C++ 函数

c++ - LLVM如何无一异常(exception)地使用C++的标准容器?

c - 如何正确销毁 LLVM 模块和 LLVM ExecutionEngine?

xcode - "too many errors emitted stopping now"- 如何增加或取消限制?

haskell - 为 'lambda' , 'define' 生成 LLVM 代码

gcc - LLVM 与 GCC MIPS 代码生成,任何基准?