David Blaikie | 60310f2 | 2015-05-08 00:42:26 +0000 | [diff] [blame] | 1 | #include "llvm/IR/Operator.h" |
David Blaikie | 6f0d522 | 2015-05-21 21:17:12 +0000 | [diff] [blame] | 2 | #include "llvm/IR/GetElementPtrTypeIterator.h" |
David Blaikie | 60310f2 | 2015-05-08 00:42:26 +0000 | [diff] [blame] | 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 | } |
David Blaikie | 6f0d522 | 2015-05-21 21:17:12 +0000 | [diff] [blame] | 14 | |
Eduard Burtescu | 19eb031 | 2016-01-19 17:28:00 +0000 | [diff] [blame] | 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 | |
David Blaikie | 6f0d522 | 2015-05-21 21:17:12 +0000 | [diff] [blame] | 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. |
Peter Collingbourne | ab85225b | 2016-12-02 02:24:42 +0000 | [diff] [blame] | 36 | if (StructType *STy = GTI.getStructTypeOrNull()) { |
David Blaikie | 6f0d522 | 2015-05-21 21:17:12 +0000 | [diff] [blame] | 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 | } |
Alexander Kornienko | f00654e | 2015-06-23 09:49:53 +0000 | [diff] [blame] | 50 | } |