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