Craig Topper | c98f883 | 2017-03-20 05:08:38 +0000 | [diff] [blame] | 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 | |
David Blaikie | 60310f2 | 2015-05-08 00:42:26 +0000 | [diff] [blame] | 14 | #include "llvm/IR/Operator.h" |
Craig Topper | b5c2bfa | 2017-03-20 05:08:41 +0000 | [diff] [blame] | 15 | #include "llvm/IR/DataLayout.h" |
David Blaikie | 6f0d522 | 2015-05-21 21:17:12 +0000 | [diff] [blame] | 16 | #include "llvm/IR/GetElementPtrTypeIterator.h" |
David Blaikie | 60310f2 | 2015-05-08 00:42:26 +0000 | [diff] [blame] | 17 | #include "llvm/IR/Instructions.h" |
| 18 | #include "llvm/IR/Type.h" |
| 19 | |
| 20 | #include "ConstantsContext.h" |
| 21 | |
| 22 | namespace llvm { |
| 23 | Type *GEPOperator::getSourceElementType() const { |
| 24 | if (auto *I = dyn_cast<GetElementPtrInst>(this)) |
| 25 | return I->getSourceElementType(); |
| 26 | return cast<GetElementPtrConstantExpr>(this)->getSourceElementType(); |
| 27 | } |
David Blaikie | 6f0d522 | 2015-05-21 21:17:12 +0000 | [diff] [blame] | 28 | |
Eduard Burtescu | 19eb031 | 2016-01-19 17:28:00 +0000 | [diff] [blame] | 29 | Type *GEPOperator::getResultElementType() const { |
| 30 | if (auto *I = dyn_cast<GetElementPtrInst>(this)) |
| 31 | return I->getResultElementType(); |
| 32 | return cast<GetElementPtrConstantExpr>(this)->getResultElementType(); |
| 33 | } |
| 34 | |
David Blaikie | 6f0d522 | 2015-05-21 21:17:12 +0000 | [diff] [blame] | 35 | bool GEPOperator::accumulateConstantOffset(const DataLayout &DL, |
| 36 | APInt &Offset) const { |
| 37 | assert(Offset.getBitWidth() == |
Elena Demikhovsky | 945b7e5 | 2018-02-14 06:58:08 +0000 | [diff] [blame] | 38 | DL.getIndexSizeInBits(getPointerAddressSpace()) && |
| 39 | "The offset bit width does not match DL specification."); |
David Blaikie | 6f0d522 | 2015-05-21 21:17:12 +0000 | [diff] [blame] | 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. |
Peter Collingbourne | ab85225b | 2016-12-02 02:24:42 +0000 | [diff] [blame] | 50 | if (StructType *STy = GTI.getStructTypeOrNull()) { |
David Blaikie | 6f0d522 | 2015-05-21 21:17:12 +0000 | [diff] [blame] | 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 | } |
Alexander Kornienko | f00654e | 2015-06-23 09:49:53 +0000 | [diff] [blame] | 64 | } |