1*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Operator.h" 2*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/GetElementPtrTypeIterator.h" 3*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Instructions.h" 4*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Type.h" 5*9880d681SAndroid Build Coastguard Worker 6*9880d681SAndroid Build Coastguard Worker #include "ConstantsContext.h" 7*9880d681SAndroid Build Coastguard Worker 8*9880d681SAndroid Build Coastguard Worker namespace llvm { getSourceElementType() const9*9880d681SAndroid Build Coastguard WorkerType *GEPOperator::getSourceElementType() const { 10*9880d681SAndroid Build Coastguard Worker if (auto *I = dyn_cast<GetElementPtrInst>(this)) 11*9880d681SAndroid Build Coastguard Worker return I->getSourceElementType(); 12*9880d681SAndroid Build Coastguard Worker return cast<GetElementPtrConstantExpr>(this)->getSourceElementType(); 13*9880d681SAndroid Build Coastguard Worker } 14*9880d681SAndroid Build Coastguard Worker getResultElementType() const15*9880d681SAndroid Build Coastguard WorkerType *GEPOperator::getResultElementType() const { 16*9880d681SAndroid Build Coastguard Worker if (auto *I = dyn_cast<GetElementPtrInst>(this)) 17*9880d681SAndroid Build Coastguard Worker return I->getResultElementType(); 18*9880d681SAndroid Build Coastguard Worker return cast<GetElementPtrConstantExpr>(this)->getResultElementType(); 19*9880d681SAndroid Build Coastguard Worker } 20*9880d681SAndroid Build Coastguard Worker accumulateConstantOffset(const DataLayout & DL,APInt & Offset) const21*9880d681SAndroid Build Coastguard Workerbool GEPOperator::accumulateConstantOffset(const DataLayout &DL, 22*9880d681SAndroid Build Coastguard Worker APInt &Offset) const { 23*9880d681SAndroid Build Coastguard Worker assert(Offset.getBitWidth() == 24*9880d681SAndroid Build Coastguard Worker DL.getPointerSizeInBits(getPointerAddressSpace()) && 25*9880d681SAndroid Build Coastguard Worker "The offset must have exactly as many bits as our pointer."); 26*9880d681SAndroid Build Coastguard Worker 27*9880d681SAndroid Build Coastguard Worker for (gep_type_iterator GTI = gep_type_begin(this), GTE = gep_type_end(this); 28*9880d681SAndroid Build Coastguard Worker GTI != GTE; ++GTI) { 29*9880d681SAndroid Build Coastguard Worker ConstantInt *OpC = dyn_cast<ConstantInt>(GTI.getOperand()); 30*9880d681SAndroid Build Coastguard Worker if (!OpC) 31*9880d681SAndroid Build Coastguard Worker return false; 32*9880d681SAndroid Build Coastguard Worker if (OpC->isZero()) 33*9880d681SAndroid Build Coastguard Worker continue; 34*9880d681SAndroid Build Coastguard Worker 35*9880d681SAndroid Build Coastguard Worker // Handle a struct index, which adds its field offset to the pointer. 36*9880d681SAndroid Build Coastguard Worker if (StructType *STy = dyn_cast<StructType>(*GTI)) { 37*9880d681SAndroid Build Coastguard Worker unsigned ElementIdx = OpC->getZExtValue(); 38*9880d681SAndroid Build Coastguard Worker const StructLayout *SL = DL.getStructLayout(STy); 39*9880d681SAndroid Build Coastguard Worker Offset += APInt(Offset.getBitWidth(), SL->getElementOffset(ElementIdx)); 40*9880d681SAndroid Build Coastguard Worker continue; 41*9880d681SAndroid Build Coastguard Worker } 42*9880d681SAndroid Build Coastguard Worker 43*9880d681SAndroid Build Coastguard Worker // For array or vector indices, scale the index by the size of the type. 44*9880d681SAndroid Build Coastguard Worker APInt Index = OpC->getValue().sextOrTrunc(Offset.getBitWidth()); 45*9880d681SAndroid Build Coastguard Worker Offset += Index * APInt(Offset.getBitWidth(), 46*9880d681SAndroid Build Coastguard Worker DL.getTypeAllocSize(GTI.getIndexedType())); 47*9880d681SAndroid Build Coastguard Worker } 48*9880d681SAndroid Build Coastguard Worker return true; 49*9880d681SAndroid Build Coastguard Worker } 50*9880d681SAndroid Build Coastguard Worker } 51