1 //===-- Operator.cpp - Implement the LLVM operators -----------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements the non-inline methods for the LLVM Operator classes. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/IR/Operator.h" 15 #include "llvm/IR/DataLayout.h" 16 #include "llvm/IR/GetElementPtrTypeIterator.h" 17 #include "llvm/IR/Instructions.h" 18 #include "llvm/IR/Type.h" 19 20 #include "ConstantsContext.h" 21 22 namespace llvm { getSourceElementType() const23Type *GEPOperator::getSourceElementType() const { 24 if (auto *I = dyn_cast<GetElementPtrInst>(this)) 25 return I->getSourceElementType(); 26 return cast<GetElementPtrConstantExpr>(this)->getSourceElementType(); 27 } 28 getResultElementType() const29Type *GEPOperator::getResultElementType() const { 30 if (auto *I = dyn_cast<GetElementPtrInst>(this)) 31 return I->getResultElementType(); 32 return cast<GetElementPtrConstantExpr>(this)->getResultElementType(); 33 } 34 accumulateConstantOffset(const DataLayout & DL,APInt & Offset) const35bool GEPOperator::accumulateConstantOffset(const DataLayout &DL, 36 APInt &Offset) const { 37 assert(Offset.getBitWidth() == 38 DL.getIndexSizeInBits(getPointerAddressSpace()) && 39 "The offset bit width does not match DL specification."); 40 41 for (gep_type_iterator GTI = gep_type_begin(this), GTE = gep_type_end(this); 42 GTI != GTE; ++GTI) { 43 ConstantInt *OpC = dyn_cast<ConstantInt>(GTI.getOperand()); 44 if (!OpC) 45 return false; 46 if (OpC->isZero()) 47 continue; 48 49 // Handle a struct index, which adds its field offset to the pointer. 50 if (StructType *STy = GTI.getStructTypeOrNull()) { 51 unsigned ElementIdx = OpC->getZExtValue(); 52 const StructLayout *SL = DL.getStructLayout(STy); 53 Offset += APInt(Offset.getBitWidth(), SL->getElementOffset(ElementIdx)); 54 continue; 55 } 56 57 // For array or vector indices, scale the index by the size of the type. 58 APInt Index = OpC->getValue().sextOrTrunc(Offset.getBitWidth()); 59 Offset += Index * APInt(Offset.getBitWidth(), 60 DL.getTypeAllocSize(GTI.getIndexedType())); 61 } 62 return true; 63 } 64 } 65