summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2016-12-02 02:24:42 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2016-12-02 02:24:42 +0000
commitab85225be49b2abf5112823d84525e91d469d6bd (patch)
tree409fc728e31d6bd0afc63bdb4ba06b7c96f6a816 /llvm/lib/IR
parent6afcab35887245f36751790ba33debaf74b0d2ee (diff)
downloadbcm5719-llvm-ab85225be49b2abf5112823d84525e91d469d6bd.tar.gz
bcm5719-llvm-ab85225be49b2abf5112823d84525e91d469d6bd.zip
IR: Change the gep_type_iterator API to avoid always exposing the "current" type.
Instead, expose whether the current type is an array or a struct, if an array what the upper bound is, and if a struct the struct type itself. This is in preparation for a later change which will make PointerType derive from Type rather than SequentialType. Differential Revision: https://reviews.llvm.org/D26594 llvm-svn: 288458
Diffstat (limited to 'llvm/lib/IR')
-rw-r--r--llvm/lib/IR/ConstantFold.cpp33
-rw-r--r--llvm/lib/IR/Constants.cpp13
-rw-r--r--llvm/lib/IR/DataLayout.cpp9
-rw-r--r--llvm/lib/IR/Operator.cpp2
4 files changed, 20 insertions, 37 deletions
diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp
index 37bab3a0d28..60f6fbb6f65 100644
--- a/llvm/lib/IR/ConstantFold.cpp
+++ b/llvm/lib/IR/ConstantFold.cpp
@@ -2019,22 +2019,8 @@ static bool isInBoundsIndices(ArrayRef<IndexTy> Idxs) {
}
/// Test whether a given ConstantInt is in-range for a SequentialType.
-static bool isIndexInRangeOfSequentialType(SequentialType *STy,
- const ConstantInt *CI) {
- // And indices are valid when indexing along a pointer
- if (isa<PointerType>(STy))
- return true;
-
- uint64_t NumElements = 0;
- // Determine the number of elements in our sequential type.
- if (auto *ATy = dyn_cast<ArrayType>(STy))
- NumElements = ATy->getNumElements();
- else if (auto *VTy = dyn_cast<VectorType>(STy))
- NumElements = VTy->getNumElements();
-
- assert((isa<ArrayType>(STy) || NumElements > 0) &&
- "didn't expect non-array type to have zero elements!");
-
+static bool isIndexInRangeOfArrayType(uint64_t NumElements,
+ const ConstantInt *CI) {
// We cannot bounds check the index if it doesn't fit in an int64_t.
if (CI->getValue().getActiveBits() > 64)
return false;
@@ -2089,10 +2075,10 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C,
// getelementptr instructions into a single instruction.
//
if (CE->getOpcode() == Instruction::GetElementPtr) {
- Type *LastTy = nullptr;
+ gep_type_iterator LastI = gep_type_end(CE);
for (gep_type_iterator I = gep_type_begin(CE), E = gep_type_end(CE);
I != E; ++I)
- LastTy = *I;
+ LastI = I;
// We cannot combine indices if doing so would take us outside of an
// array or vector. Doing otherwise could trick us if we evaluated such a
@@ -2115,9 +2101,11 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C,
bool PerformFold = false;
if (Idx0->isNullValue())
PerformFold = true;
- else if (SequentialType *STy = dyn_cast_or_null<SequentialType>(LastTy))
+ else if (LastI.isSequential())
if (ConstantInt *CI = dyn_cast<ConstantInt>(Idx0))
- PerformFold = isIndexInRangeOfSequentialType(STy, CI);
+ PerformFold =
+ !LastI.isBoundedSequential() ||
+ isIndexInRangeOfArrayType(LastI.getSequentialNumElements(), CI);
if (PerformFold) {
SmallVector<Value*, 16> NewIndices;
@@ -2228,7 +2216,10 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C,
Unknown = true;
continue;
}
- if (isIndexInRangeOfSequentialType(STy, CI))
+ if (isIndexInRangeOfArrayType(isa<ArrayType>(STy)
+ ? cast<ArrayType>(STy)->getNumElements()
+ : cast<VectorType>(STy)->getNumElements(),
+ CI))
// It's in range, skip to the next index.
continue;
if (!isa<SequentialType>(Prev)) {
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index 0e5fa248caa..b6af6ed111a 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -1073,19 +1073,14 @@ bool ConstantExpr::isGEPWithNoNotionalOverIndexing() const {
gep_type_iterator GEPI = gep_type_begin(this), E = gep_type_end(this);
User::const_op_iterator OI = std::next(this->op_begin());
- // Skip the first index, as it has no static limit.
- ++GEPI;
- ++OI;
-
// The remaining indices must be compile-time known integers within the
// bounds of the corresponding notional static array types.
for (; GEPI != E; ++GEPI, ++OI) {
ConstantInt *CI = dyn_cast<ConstantInt>(*OI);
- if (!CI) return false;
- if (ArrayType *ATy = dyn_cast<ArrayType>(*GEPI))
- if (CI->getValue().getActiveBits() > 64 ||
- CI->getZExtValue() >= ATy->getNumElements())
- return false;
+ if (GEPI.isBoundedSequential() &&
+ (CI->getValue().getActiveBits() > 64 ||
+ CI->getZExtValue() >= GEPI.getSequentialNumElements()))
+ return false;
}
// All the indices checked out.
diff --git a/llvm/lib/IR/DataLayout.cpp b/llvm/lib/IR/DataLayout.cpp
index 3de1889996e..d15a34c0b93 100644
--- a/llvm/lib/IR/DataLayout.cpp
+++ b/llvm/lib/IR/DataLayout.cpp
@@ -737,15 +737,12 @@ int64_t DataLayout::getIndexedOffsetInType(Type *ElemTy,
ArrayRef<Value *> Indices) const {
int64_t Result = 0;
- // We can use 0 as the address space as we don't need
- // to get pointer types back from gep_type_iterator.
- unsigned AS = 0;
generic_gep_type_iterator<Value* const*>
- GTI = gep_type_begin(ElemTy, AS, Indices),
- GTE = gep_type_end(ElemTy, AS, Indices);
+ GTI = gep_type_begin(ElemTy, Indices),
+ GTE = gep_type_end(ElemTy, Indices);
for (; GTI != GTE; ++GTI) {
Value *Idx = GTI.getOperand();
- if (auto *STy = dyn_cast<StructType>(*GTI)) {
+ if (StructType *STy = GTI.getStructTypeOrNull()) {
assert(Idx->getType()->isIntegerTy(32) && "Illegal struct idx");
unsigned FieldNo = cast<ConstantInt>(Idx)->getZExtValue();
diff --git a/llvm/lib/IR/Operator.cpp b/llvm/lib/IR/Operator.cpp
index 8a94053a72c..2fba24d99b3 100644
--- a/llvm/lib/IR/Operator.cpp
+++ b/llvm/lib/IR/Operator.cpp
@@ -33,7 +33,7 @@ bool GEPOperator::accumulateConstantOffset(const DataLayout &DL,
continue;
// Handle a struct index, which adds its field offset to the pointer.
- if (StructType *STy = dyn_cast<StructType>(*GTI)) {
+ if (StructType *STy = GTI.getStructTypeOrNull()) {
unsigned ElementIdx = OpC->getZExtValue();
const StructLayout *SL = DL.getStructLayout(STy);
Offset += APInt(Offset.getBitWidth(), SL->getElementOffset(ElementIdx));
OpenPOWER on IntegriCloud