1 //===-- Operator.cpp - Implement the LLVM operators -----------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements the non-inline methods for the LLVM Operator classes.
11 //===----------------------------------------------------------------------===//
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"
19 #include "ConstantsContext.h"
22 Type
*GEPOperator::getSourceElementType() const {
23 if (auto *I
= dyn_cast
<GetElementPtrInst
>(this))
24 return I
->getSourceElementType();
25 return cast
<GetElementPtrConstantExpr
>(this)->getSourceElementType();
28 Type
*GEPOperator::getResultElementType() const {
29 if (auto *I
= dyn_cast
<GetElementPtrInst
>(this))
30 return I
->getResultElementType();
31 return cast
<GetElementPtrConstantExpr
>(this)->getResultElementType();
34 bool 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.");
40 for (gep_type_iterator GTI
= gep_type_begin(this), GTE
= gep_type_end(this);
42 ConstantInt
*OpC
= dyn_cast
<ConstantInt
>(GTI
.getOperand());
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
));
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()));