Line data Source code
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 :
14 : #include "llvm/IR/Operator.h"
15 : #include "llvm/IR/DataLayout.h"
16 : #include "llvm/IR/GetElementPtrTypeIterator.h"
17 : #include "llvm/IR/Instructions.h"
18 : #include "llvm/IR/Type.h"
19 :
20 : #include "ConstantsContext.h"
21 :
22 : namespace llvm {
23 101313567 : Type *GEPOperator::getSourceElementType() const {
24 : if (auto *I = dyn_cast<GetElementPtrInst>(this))
25 14139159 : return I->getSourceElementType();
26 87174408 : return cast<GetElementPtrConstantExpr>(this)->getSourceElementType();
27 : }
28 :
29 16630660 : Type *GEPOperator::getResultElementType() const {
30 : if (auto *I = dyn_cast<GetElementPtrInst>(this))
31 1157 : return I->getResultElementType();
32 16629503 : return cast<GetElementPtrConstantExpr>(this)->getResultElementType();
33 : }
34 :
35 13769682 : bool GEPOperator::accumulateConstantOffset(const DataLayout &DL,
36 : APInt &Offset) const {
37 : assert(Offset.getBitWidth() ==
38 : DL.getIndexSizeInBits(getPointerAddressSpace()) &&
39 : "The offset bit width does not match DL specification.");
40 :
41 40790423 : for (gep_type_iterator GTI = gep_type_begin(this), GTE = gep_type_end(this);
42 67811164 : GTI != GTE; ++GTI) {
43 : ConstantInt *OpC = dyn_cast<ConstantInt>(GTI.getOperand());
44 : if (!OpC)
45 180955 : return false;
46 27020741 : if (OpC->isZero())
47 17970635 : continue;
48 :
49 : // Handle a struct index, which adds its field offset to the pointer.
50 242646 : if (StructType *STy = GTI.getStructTypeOrNull()) {
51 242646 : unsigned ElementIdx = OpC->getZExtValue();
52 242646 : const StructLayout *SL = DL.getStructLayout(STy);
53 485292 : Offset += APInt(Offset.getBitWidth(), SL->getElementOffset(ElementIdx));
54 242646 : continue;
55 : }
56 :
57 : // For array or vector indices, scale the index by the size of the type.
58 9050106 : APInt Index = OpC->getValue().sextOrTrunc(Offset.getBitWidth());
59 27150318 : Offset += Index * APInt(Offset.getBitWidth(),
60 9050106 : DL.getTypeAllocSize(GTI.getIndexedType()));
61 : }
62 13588727 : return true;
63 : }
64 : }
|