xref: /aosp_15_r20/external/llvm/lib/IR/Operator.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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 Worker Type *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 Worker Type *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 Worker bool 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