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