Identify array type in IR

社会主义新天地 提交于 2019-12-07 15:00:37

问题


I have been trying to identify array access in IR by making use of following code:

  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";
            }
    }  
 }  

This code identifies getElementPtr instruction but it does not identify whether it's first operand is an array type or not. Please let me know what is the problem with my code.


回答1:


The first operand of a GEP (getelementptr instruction) is a pointer, not an array. That pointer may point to an array, or it may not (see below). So you need to look what this pointer points to.

Here's a sample BasicBlockPass visitor:

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;
}

Note, however, that many "arrays" in C/C++ are actually pointers so you may not get the array type where you expect.

For example, if you compile this code:

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

You get the 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
}

Although argv is treated as an array, the compiler thinks of it as a pointer, so there is no array type in sight. The pass I pasted above won't recognize an array here, because the first operand of the GEP is a pointer to a pointer.



来源:https://stackoverflow.com/questions/9682705/identify-array-type-in-ir

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!