-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[delinearize] use SCEV exprs in getIndexExpressionsFromGEP #162888
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-llvm-analysis Author: Sebastian Pop (sebpop) Changesclean up interface of getIndexExpressionsFromGEP to get SCEV expressions instead of int for Sizes of the arrays. Full diff: https://github.com/llvm/llvm-project/pull/162888.diff 5 Files Affected:
diff --git a/llvm/include/llvm/Analysis/Delinearization.h b/llvm/include/llvm/Analysis/Delinearization.h
index 434cfb61699d6..9c729b5cf18c8 100644
--- a/llvm/include/llvm/Analysis/Delinearization.h
+++ b/llvm/include/llvm/Analysis/Delinearization.h
@@ -145,15 +145,15 @@ bool delinearizeFixedSizeArray(ScalarEvolution &SE, const SCEV *Expr,
///
/// This function optimistically assumes the GEP references into a fixed size
/// array. If this is actually true, this function returns a list of array
-/// subscript expressions in \p Subscripts and a list of integers describing
-/// the size of the individual array dimensions in \p Sizes. Both lists have
-/// either equal length or the size list is one element shorter in case there
-/// is no known size available for the outermost array dimension. Returns true
-/// if successful and false otherwise.
+/// subscript expressions in \p Subscripts and a list of SCEV expressions
+/// describing the size of the individual array dimensions in \p Sizes. Both
+/// lists have either equal length or the size list is one element shorter in
+/// case there is no known size available for the outermost array dimension.
+/// Returns true if successful and false otherwise.
bool getIndexExpressionsFromGEP(ScalarEvolution &SE,
const GetElementPtrInst *GEP,
SmallVectorImpl<const SCEV *> &Subscripts,
- SmallVectorImpl<int> &Sizes);
+ SmallVectorImpl<const SCEV *> &Sizes);
/// Implementation of fixed size array delinearization. Try to delinearize
/// access function for a fixed size multi-dimensional array, by deriving
@@ -164,7 +164,7 @@ bool getIndexExpressionsFromGEP(ScalarEvolution &SE,
bool tryDelinearizeFixedSizeImpl(ScalarEvolution *SE, Instruction *Inst,
const SCEV *AccessFn,
SmallVectorImpl<const SCEV *> &Subscripts,
- SmallVectorImpl<int> &Sizes);
+ SmallVectorImpl<const SCEV *> &Sizes);
struct DelinearizationPrinterPass
: public PassInfoMixin<DelinearizationPrinterPass> {
diff --git a/llvm/lib/Analysis/Delinearization.cpp b/llvm/lib/Analysis/Delinearization.cpp
index 4064b25d9d4e7..f438a9bd9ecdd 100644
--- a/llvm/lib/Analysis/Delinearization.cpp
+++ b/llvm/lib/Analysis/Delinearization.cpp
@@ -659,7 +659,7 @@ bool llvm::delinearizeFixedSizeArray(ScalarEvolution &SE, const SCEV *Expr,
bool llvm::getIndexExpressionsFromGEP(ScalarEvolution &SE,
const GetElementPtrInst *GEP,
SmallVectorImpl<const SCEV *> &Subscripts,
- SmallVectorImpl<int> &Sizes) {
+ SmallVectorImpl<const SCEV *> &Sizes) {
assert(Subscripts.empty() && Sizes.empty() &&
"Expected output lists to be empty on entry to this function.");
assert(GEP && "getIndexExpressionsFromGEP called with a null GEP");
@@ -690,7 +690,8 @@ bool llvm::getIndexExpressionsFromGEP(ScalarEvolution &SE,
Subscripts.push_back(Expr);
if (!(DroppedFirstDim && i == 2))
- Sizes.push_back(ArrayTy->getNumElements());
+ Sizes.push_back(SE.getConstant(Expr->getType(),
+ ArrayTy->getNumElements()));
Ty = ArrayTy->getElementType();
}
@@ -706,7 +707,7 @@ bool llvm::getIndexExpressionsFromGEP(ScalarEvolution &SE,
bool llvm::tryDelinearizeFixedSizeImpl(
ScalarEvolution *SE, Instruction *Inst, const SCEV *AccessFn,
- SmallVectorImpl<const SCEV *> &Subscripts, SmallVectorImpl<int> &Sizes) {
+ SmallVectorImpl<const SCEV *> &Subscripts, SmallVectorImpl<const SCEV *> &Sizes) {
Value *SrcPtr = getLoadStorePointerOperand(Inst);
// Check the simple case where the array dimensions are fixed size.
diff --git a/llvm/lib/Analysis/DependenceAnalysis.cpp b/llvm/lib/Analysis/DependenceAnalysis.cpp
index 8d20b0e10305b..7dd0bea75c847 100644
--- a/llvm/lib/Analysis/DependenceAnalysis.cpp
+++ b/llvm/lib/Analysis/DependenceAnalysis.cpp
@@ -3504,8 +3504,8 @@ bool DependenceInfo::tryDelinearizeFixedSize(
"expected src and dst scev unknowns to be equal");
});
- SmallVector<int, 4> SrcSizes;
- SmallVector<int, 4> DstSizes;
+ SmallVector<const SCEV *, 4> SrcSizes;
+ SmallVector<const SCEV *, 4> DstSizes;
if (!tryDelinearizeFixedSizeImpl(SE, Src, SrcAccessFn, SrcSubscripts,
SrcSizes) ||
!tryDelinearizeFixedSizeImpl(SE, Dst, DstAccessFn, DstSubscripts,
@@ -3513,7 +3513,7 @@ bool DependenceInfo::tryDelinearizeFixedSize(
return false;
// Check that the two size arrays are non-empty and equal in length and
- // value.
+ // value. SCEV expressions are uniqued, so we can compare pointers.
if (SrcSizes.size() != DstSizes.size() ||
!std::equal(SrcSizes.begin(), SrcSizes.end(), DstSizes.begin())) {
SrcSubscripts.clear();
@@ -3535,7 +3535,7 @@ bool DependenceInfo::tryDelinearizeFixedSize(
// iff the subscripts are positive and are less than the range of the
// dimension.
if (!DisableDelinearizationChecks) {
- auto AllIndicesInRange = [&](SmallVector<int, 4> &DimensionSizes,
+ auto AllIndicesInRange = [&](SmallVector<const SCEV *, 4> &DimensionSizes,
SmallVectorImpl<const SCEV *> &Subscripts,
Value *Ptr) {
size_t SSize = Subscripts.size();
@@ -3548,17 +3548,14 @@ bool DependenceInfo::tryDelinearizeFixedSize(
});
return false;
}
- if (auto *SType = dyn_cast<IntegerType>(S->getType())) {
- const SCEV *Range = SE->getConstant(
- ConstantInt::get(SType, DimensionSizes[I - 1], false));
- if (!isKnownLessThan(S, Range)) {
- LLVM_DEBUG({
- dbgs() << "Check failed: !isKnownLessThan(S, Range)\n";
- dbgs() << " S: " << *S << "\n"
- << " Range: " << *Range << "\n";
- });
- return false;
- }
+ const SCEV *Range = DimensionSizes[I - 1];
+ if (!isKnownLessThan(S, Range)) {
+ LLVM_DEBUG({
+ dbgs() << "Check failed: !isKnownLessThan(S, Range)\n";
+ dbgs() << " S: " << *S << "\n"
+ << " Range: " << *Range << "\n";
+ });
+ return false;
}
}
return true;
diff --git a/llvm/lib/Analysis/LoopCacheAnalysis.cpp b/llvm/lib/Analysis/LoopCacheAnalysis.cpp
index 050c32707596a..74bcce8f51a4c 100644
--- a/llvm/lib/Analysis/LoopCacheAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopCacheAnalysis.cpp
@@ -356,15 +356,14 @@ CacheCostTy IndexedReference::computeRefCost(const Loop &L,
bool IndexedReference::tryDelinearizeFixedSize(
const SCEV *AccessFn, SmallVectorImpl<const SCEV *> &Subscripts) {
- SmallVector<int, 4> ArraySizes;
+ SmallVector<const SCEV *, 4> ArraySizes;
if (!tryDelinearizeFixedSizeImpl(&SE, &StoreOrLoadInst, AccessFn, Subscripts,
ArraySizes))
return false;
// Populate Sizes with scev expressions to be used in calculations later.
for (auto Idx : seq<unsigned>(1, Subscripts.size()))
- Sizes.push_back(
- SE.getConstant(Subscripts[Idx]->getType(), ArraySizes[Idx - 1]));
+ Sizes.push_back(ArraySizes[Idx - 1]);
LLVM_DEBUG({
dbgs() << "Delinearized subscripts of fixed-size array\n"
diff --git a/polly/lib/Analysis/ScopBuilder.cpp b/polly/lib/Analysis/ScopBuilder.cpp
index 67a4c43455809..ec77b15ddd768 100644
--- a/polly/lib/Analysis/ScopBuilder.cpp
+++ b/polly/lib/Analysis/ScopBuilder.cpp
@@ -1463,7 +1463,7 @@ bool ScopBuilder::buildAccessMultiDimFixed(MemAccInst Inst, ScopStmt *Stmt) {
return false;
SmallVector<const SCEV *, 4> Subscripts;
- SmallVector<int, 4> Sizes;
+ SmallVector<const SCEV *, 4> Sizes;
getIndexExpressionsFromGEP(SE, GEP, Subscripts, Sizes);
auto *BasePtr = GEP->getOperand(0);
@@ -1475,8 +1475,6 @@ bool ScopBuilder::buildAccessMultiDimFixed(MemAccInst Inst, ScopStmt *Stmt) {
if (BasePtr != BasePointer->getValue())
return false;
- std::vector<const SCEV *> SizesSCEV;
-
const InvariantLoadsSetTy &ScopRIL = scop->getRequiredInvariantLoads();
Loop *SurroundingLoop = Stmt->getSurroundingLoop();
@@ -1494,11 +1492,9 @@ bool ScopBuilder::buildAccessMultiDimFixed(MemAccInst Inst, ScopStmt *Stmt) {
if (Sizes.empty())
return false;
+ std::vector<const SCEV *> SizesSCEV;
SizesSCEV.push_back(nullptr);
-
- for (auto V : Sizes)
- SizesSCEV.push_back(SE.getSCEV(
- ConstantInt::get(IntegerType::getInt64Ty(BasePtr->getContext()), V)));
+ SizesSCEV.insert(SizesSCEV.end(), Sizes.begin(), Sizes.end());
addArrayAccess(Stmt, Inst, AccType, BasePointer->getValue(), ElementType,
true, Subscripts, SizesSCEV, Val);
|
You can test this locally with the following command:git-clang-format --diff origin/main HEAD --extensions h,cpp -- llvm/include/llvm/Analysis/Delinearization.h llvm/lib/Analysis/Delinearization.cpp llvm/lib/Analysis/DependenceAnalysis.cpp llvm/lib/Analysis/LoopCacheAnalysis.cpp polly/lib/Analysis/ScopBuilder.cpp
View the diff from clang-format here.diff --git a/llvm/lib/Analysis/Delinearization.cpp b/llvm/lib/Analysis/Delinearization.cpp
index f438a9bd9..d2a300c8a 100644
--- a/llvm/lib/Analysis/Delinearization.cpp
+++ b/llvm/lib/Analysis/Delinearization.cpp
@@ -690,8 +690,8 @@ bool llvm::getIndexExpressionsFromGEP(ScalarEvolution &SE,
Subscripts.push_back(Expr);
if (!(DroppedFirstDim && i == 2))
- Sizes.push_back(SE.getConstant(Expr->getType(),
- ArrayTy->getNumElements()));
+ Sizes.push_back(
+ SE.getConstant(Expr->getType(), ArrayTy->getNumElements()));
Ty = ArrayTy->getElementType();
}
@@ -707,7 +707,8 @@ bool llvm::getIndexExpressionsFromGEP(ScalarEvolution &SE,
bool llvm::tryDelinearizeFixedSizeImpl(
ScalarEvolution *SE, Instruction *Inst, const SCEV *AccessFn,
- SmallVectorImpl<const SCEV *> &Subscripts, SmallVectorImpl<const SCEV *> &Sizes) {
+ SmallVectorImpl<const SCEV *> &Subscripts,
+ SmallVectorImpl<const SCEV *> &Sizes) {
Value *SrcPtr = getLoadStorePointerOperand(Inst);
// Check the simple case where the array dimensions are fixed size.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally LGTM. Please apply clang-format.
std::vector<const SCEV *> SizesSCEV; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the declaration needs to be moved.
Sizes.push_back(SE.getConstant(Expr->getType(), | ||
ArrayTy->getNumElements())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as #156342 (comment), maybe using DataLayout::getIndexSize
is better.
clean up interface of getIndexExpressionsFromGEP to get SCEV expressions instead of int for Sizes of the arrays.
This intends to simplify the code in #156342 by avoiding conversions from SCEV to int and back to SCEV.