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