はIR

2012-03-13 5 views
2

私は、次のコードを使用することにより、IRにおける配列アクセスを特定しようとしている中で配列型を特定しますは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命令を識別しますが、それは最初のオペランドがありますかどうかを識別しないことは配列型でありますか否か。私のコードの問題点を教えてください。

答えて

4

GEP(getelementptr命令)の最初のオペランドは、配列ではなくポインタです。そのポインタは配列を指しているかもしれませんし、そうでないかもしれません(下記参照)。だから、このポインタが何を指しているのかを調べる必要があります。実際にはC/C++には多くの「配列」は、そう、あなたが期待する配列型を取得することはできませんポインタこと、しかし、

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

注:

はここでサンプルBasicBlockPass訪問者です。例えば

、あなたはこのコードをコンパイルする場合:

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が配列としてを扱うですが、コンパイラはポインタとしてそれを考えると、配列型は見えません。 GEPの最初のオペランドがへのポインタのため、上に貼り付けたパスは配列を認識しません。