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 Type *GEPOperator::getResultElementType() const {
     16   if (auto *I = dyn_cast<GetElementPtrInst>(this))
     17     return I->getResultElementType();
     18   return cast<GetElementPtrConstantExpr>(this)->getResultElementType();
     19 }
     20 
     21 bool GEPOperator::accumulateConstantOffset(const DataLayout &DL,
     22                                            APInt &Offset) const {
     23   assert(Offset.getBitWidth() ==
     24              DL.getPointerSizeInBits(getPointerAddressSpace()) &&
     25          "The offset must have exactly as many bits as our pointer.");
     26 
     27   for (gep_type_iterator GTI = gep_type_begin(this), GTE = gep_type_end(this);
     28        GTI != GTE; ++GTI) {
     29     ConstantInt *OpC = dyn_cast<ConstantInt>(GTI.getOperand());
     30     if (!OpC)
     31       return false;
     32     if (OpC->isZero())
     33       continue;
     34 
     35     // Handle a struct index, which adds its field offset to the pointer.
     36     if (StructType *STy = dyn_cast<StructType>(*GTI)) {
     37       unsigned ElementIdx = OpC->getZExtValue();
     38       const StructLayout *SL = DL.getStructLayout(STy);
     39       Offset += APInt(Offset.getBitWidth(), SL->getElementOffset(ElementIdx));
     40       continue;
     41     }
     42 
     43     // For array or vector indices, scale the index by the size of the type.
     44     APInt Index = OpC->getValue().sextOrTrunc(Offset.getBitWidth());
     45     Offset += Index * APInt(Offset.getBitWidth(),
     46                             DL.getTypeAllocSize(GTI.getIndexedType()));
     47   }
     48   return true;
     49 }
     50 }
     51