mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-19 02:25:01 +00:00
IR: Refactor GEP range checks, reuse them for other parts of folding
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194341 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -1897,6 +1897,37 @@ static bool isInBoundsIndices(ArrayRef<IndexTy> Idxs) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Test whether a given ConstantInt is in-range for a SequentialType.
|
||||||
|
static bool isIndexInRangeOfSequentialType(const SequentialType *STy,
|
||||||
|
const ConstantInt *CI) {
|
||||||
|
if (const PointerType *PTy = dyn_cast<PointerType>(STy))
|
||||||
|
// Only handle pointers to sized types, not pointers to functions.
|
||||||
|
return PTy->getElementType()->isSized();
|
||||||
|
|
||||||
|
uint64_t NumElements = 0;
|
||||||
|
// Determine the number of elements in our sequential type.
|
||||||
|
if (const ArrayType *ATy = dyn_cast<ArrayType>(STy))
|
||||||
|
NumElements = ATy->getNumElements();
|
||||||
|
else if (const VectorType *VTy = dyn_cast<VectorType>(STy))
|
||||||
|
NumElements = VTy->getNumElements();
|
||||||
|
|
||||||
|
assert((isa<ArrayType>(STy) || NumElements > 0) &&
|
||||||
|
"didn't expect non-array type to have zero elements!");
|
||||||
|
|
||||||
|
// We cannot bounds check the index if it doesn't fit in an int64_t.
|
||||||
|
if (CI->getValue().getActiveBits() > 64)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// A negative index or an index past the end of our sequential type is
|
||||||
|
// considered out-of-range.
|
||||||
|
int64_t IndexVal = CI->getSExtValue();
|
||||||
|
if (IndexVal < 0 || (NumElements > 0 && (uint64_t)IndexVal >= NumElements))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Otherwise, it is in-range.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename IndexTy>
|
template<typename IndexTy>
|
||||||
static Constant *ConstantFoldGetElementPtrImpl(Constant *C,
|
static Constant *ConstantFoldGetElementPtrImpl(Constant *C,
|
||||||
bool inBounds,
|
bool inBounds,
|
||||||
@@ -1958,26 +1989,14 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C,
|
|||||||
//
|
//
|
||||||
// The following prohibits such a GEP from being formed by checking to see
|
// The following prohibits such a GEP from being formed by checking to see
|
||||||
// if the index is in-range with respect to an array or vector.
|
// if the index is in-range with respect to an array or vector.
|
||||||
bool IsSequentialAccessInRange = false;
|
bool PerformFold = false;
|
||||||
if (LastTy && isa<SequentialType>(LastTy)) {
|
if (Idx0->isNullValue())
|
||||||
uint64_t NumElements = 0;
|
PerformFold = true;
|
||||||
if (ArrayType *ATy = dyn_cast<ArrayType>(LastTy))
|
else if (SequentialType *STy = dyn_cast_or_null<SequentialType>(LastTy))
|
||||||
NumElements = ATy->getNumElements();
|
if (ConstantInt *CI = dyn_cast<ConstantInt>(Idx0))
|
||||||
else if (VectorType *VTy = dyn_cast<VectorType>(LastTy))
|
PerformFold = isIndexInRangeOfSequentialType(STy, CI);
|
||||||
NumElements = VTy->getNumElements();
|
|
||||||
|
|
||||||
if (NumElements > 0) {
|
if (PerformFold) {
|
||||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(Idx0)) {
|
|
||||||
int64_t Idx0Val = CI->getSExtValue();
|
|
||||||
if (Idx0Val >= 0 && (uint64_t)Idx0Val < NumElements)
|
|
||||||
IsSequentialAccessInRange = true;
|
|
||||||
}
|
|
||||||
} else if (PointerType *PTy = dyn_cast<PointerType>(LastTy))
|
|
||||||
// Only handle pointers to sized types, not pointers to functions.
|
|
||||||
if (PTy->getElementType()->isSized())
|
|
||||||
IsSequentialAccessInRange = true;
|
|
||||||
}
|
|
||||||
if (IsSequentialAccessInRange || Idx0->isNullValue()) {
|
|
||||||
SmallVector<Value*, 16> NewIndices;
|
SmallVector<Value*, 16> NewIndices;
|
||||||
NewIndices.reserve(Idxs.size() + CE->getNumOperands());
|
NewIndices.reserve(Idxs.size() + CE->getNumOperands());
|
||||||
for (unsigned i = 1, e = CE->getNumOperands()-1; i != e; ++i)
|
for (unsigned i = 1, e = CE->getNumOperands()-1; i != e; ++i)
|
||||||
@@ -2037,8 +2056,8 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check to see if any array indices are not within the corresponding
|
// Check to see if any array indices are not within the corresponding
|
||||||
// notional array bounds. If so, try to determine if they can be factored
|
// notional array or vector bounds. If so, try to determine if they can be
|
||||||
// out into preceding dimensions.
|
// factored out into preceding dimensions.
|
||||||
bool Unknown = false;
|
bool Unknown = false;
|
||||||
SmallVector<Constant *, 8> NewIdxs;
|
SmallVector<Constant *, 8> NewIdxs;
|
||||||
Type *Ty = C->getType();
|
Type *Ty = C->getType();
|
||||||
@@ -2046,16 +2065,20 @@ static Constant *ConstantFoldGetElementPtrImpl(Constant *C,
|
|||||||
for (unsigned i = 0, e = Idxs.size(); i != e;
|
for (unsigned i = 0, e = Idxs.size(); i != e;
|
||||||
Prev = Ty, Ty = cast<CompositeType>(Ty)->getTypeAtIndex(Idxs[i]), ++i) {
|
Prev = Ty, Ty = cast<CompositeType>(Ty)->getTypeAtIndex(Idxs[i]), ++i) {
|
||||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(Idxs[i])) {
|
if (ConstantInt *CI = dyn_cast<ConstantInt>(Idxs[i])) {
|
||||||
if (ArrayType *ATy = dyn_cast<ArrayType>(Ty))
|
if (isa<ArrayType>(Ty) || isa<VectorType>(Ty))
|
||||||
if (ATy->getNumElements() <= INT64_MAX &&
|
if (CI->getSExtValue() > 0 &&
|
||||||
ATy->getNumElements() != 0 &&
|
!isIndexInRangeOfSequentialType(cast<SequentialType>(Ty), CI)) {
|
||||||
CI->getSExtValue() >= (int64_t)ATy->getNumElements()) {
|
|
||||||
if (isa<SequentialType>(Prev)) {
|
if (isa<SequentialType>(Prev)) {
|
||||||
// It's out of range, but we can factor it into the prior
|
// It's out of range, but we can factor it into the prior
|
||||||
// dimension.
|
// dimension.
|
||||||
NewIdxs.resize(Idxs.size());
|
NewIdxs.resize(Idxs.size());
|
||||||
ConstantInt *Factor = ConstantInt::get(CI->getType(),
|
uint64_t NumElements = 0;
|
||||||
ATy->getNumElements());
|
if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty))
|
||||||
|
NumElements = ATy->getNumElements();
|
||||||
|
else
|
||||||
|
NumElements = cast<VectorType>(Ty)->getNumElements();
|
||||||
|
|
||||||
|
ConstantInt *Factor = ConstantInt::get(CI->getType(), NumElements);
|
||||||
NewIdxs[i] = ConstantExpr::getSRem(CI, Factor);
|
NewIdxs[i] = ConstantExpr::getSRem(CI, Factor);
|
||||||
|
|
||||||
Constant *PrevIdx = cast<Constant>(Idxs[i-1]);
|
Constant *PrevIdx = cast<Constant>(Idxs[i-1]);
|
||||||
|
Reference in New Issue
Block a user