Skip to content

Commit cf9dae1

Browse files
committed
[NFC] [DA] Refactoring getIndexExpressionsFromGEP
Summary: This patch moves the getIndexExpressionsFromGEP function from polly into ScalarEvolution so that both polly and DependenceAnalysis can use it for the purpose of subscript delinearization when the array sizes are not parametric. Authored By: bmahjour Reviewer: Meinersbur, sebpop, fhahn, dmgreen, grosser, etiotto, bollu Reviewed By: Meinersbur Subscribers: hiraditya, arphaman, Whitney, ppc-slack, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D73995
1 parent c93112d commit cf9dae1

File tree

5 files changed

+61
-68
lines changed

5 files changed

+61
-68
lines changed

llvm/include/llvm/Analysis/ScalarEvolution.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -998,6 +998,19 @@ class ScalarEvolution {
998998
SmallVectorImpl<const SCEV *> &Subscripts,
999999
SmallVectorImpl<const SCEV *> &Sizes);
10001000

1001+
/// Gathers the individual index expressions from a GEP instruction.
1002+
///
1003+
/// This function optimistically assumes the GEP references into a fixed size
1004+
/// array. If this is actually true, this function returns a list of array
1005+
/// subscript expressions in \p Subscripts and a list of integers describing
1006+
/// the size of the individual array dimensions in \p Sizes. Both lists have
1007+
/// either equal length or the size list is one element shorter in case there
1008+
/// is no known size available for the outermost array dimension. Returns true
1009+
/// if successful and false otherwise.
1010+
bool getIndexExpressionsFromGEP(const GetElementPtrInst *GEP,
1011+
SmallVectorImpl<const SCEV *> &Subscripts,
1012+
SmallVectorImpl<int> &Sizes);
1013+
10011014
/// Split this SCEVAddRecExpr into two vectors of SCEVs representing the
10021015
/// subscripts and sizes of an array access.
10031016
///

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11409,6 +11409,51 @@ void ScalarEvolution::delinearize(const SCEV *Expr,
1140911409
});
1141011410
}
1141111411

11412+
bool ScalarEvolution::getIndexExpressionsFromGEP(
11413+
const GetElementPtrInst *GEP, SmallVectorImpl<const SCEV *> &Subscripts,
11414+
SmallVectorImpl<int> &Sizes) {
11415+
assert(Subscripts.empty() && Sizes.empty() &&
11416+
"Expected output lists to be empty on entry to this function.");
11417+
assert(GEP && "getIndexExpressionsFromGEP called with a null GEP");
11418+
Type *Ty = GEP->getPointerOperandType();
11419+
bool DroppedFirstDim = false;
11420+
for (unsigned i = 1; i < GEP->getNumOperands(); i++) {
11421+
const SCEV *Expr = getSCEV(GEP->getOperand(i));
11422+
if (i == 1) {
11423+
if (auto *PtrTy = dyn_cast<PointerType>(Ty)) {
11424+
Ty = PtrTy->getElementType();
11425+
} else if (auto *ArrayTy = dyn_cast<ArrayType>(Ty)) {
11426+
Ty = ArrayTy->getElementType();
11427+
} else {
11428+
Subscripts.clear();
11429+
Sizes.clear();
11430+
return false;
11431+
}
11432+
if (auto *Const = dyn_cast<SCEVConstant>(Expr))
11433+
if (Const->getValue()->isZero()) {
11434+
DroppedFirstDim = true;
11435+
continue;
11436+
}
11437+
Subscripts.push_back(Expr);
11438+
continue;
11439+
}
11440+
11441+
auto *ArrayTy = dyn_cast<ArrayType>(Ty);
11442+
if (!ArrayTy) {
11443+
Subscripts.clear();
11444+
Sizes.clear();
11445+
return false;
11446+
}
11447+
11448+
Subscripts.push_back(Expr);
11449+
if (!(DroppedFirstDim && i == 2))
11450+
Sizes.push_back(ArrayTy->getNumElements());
11451+
11452+
Ty = ArrayTy->getElementType();
11453+
}
11454+
return !Subscripts.empty();
11455+
}
11456+
1141211457
//===----------------------------------------------------------------------===//
1141311458
// SCEVCallbackVH Class Implementation
1141411459
//===----------------------------------------------------------------------===//

polly/include/polly/Support/ScopHelper.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -502,22 +502,6 @@ bool canSynthesize(const llvm::Value *V, const Scop &S,
502502
/// case this function returns nullptr.
503503
llvm::BasicBlock *getUseBlock(const llvm::Use &U);
504504

505-
/// Derive the individual index expressions from a GEP instruction.
506-
///
507-
/// This function optimistically assumes the GEP references into a fixed size
508-
/// array. If this is actually true, this function returns a list of array
509-
/// subscript expressions as SCEV as well as a list of integers describing
510-
/// the size of the individual array dimensions. Both lists have either equal
511-
/// length or the size list is one element shorter in case there is no known
512-
/// size available for the outermost array dimension.
513-
///
514-
/// @param GEP The GetElementPtr instruction to analyze.
515-
///
516-
/// @return A tuple with the subscript expressions and the dimension sizes.
517-
std::tuple<std::vector<const llvm::SCEV *>, std::vector<int>>
518-
getIndexExpressionsFromGEP(llvm::GetElementPtrInst *GEP,
519-
llvm::ScalarEvolution &SE);
520-
521505
// If the loop is nonaffine/boxed, return the first non-boxed surrounding loop
522506
// for Polly. If the loop is affine, return the loop itself.
523507
//

polly/lib/Analysis/ScopBuilder.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1629,9 +1629,9 @@ bool ScopBuilder::buildAccessMultiDimFixed(MemAccInst Inst, ScopStmt *Stmt) {
16291629
if (!GEP)
16301630
return false;
16311631

1632-
std::vector<const SCEV *> Subscripts;
1633-
std::vector<int> Sizes;
1634-
std::tie(Subscripts, Sizes) = getIndexExpressionsFromGEP(GEP, SE);
1632+
SmallVector<const SCEV *, 4> Subscripts;
1633+
SmallVector<int, 4> Sizes;
1634+
SE.getIndexExpressionsFromGEP(GEP, Subscripts, Sizes);
16351635
auto *BasePtr = GEP->getOperand(0);
16361636

16371637
if (auto *BasePtrCast = dyn_cast<BitCastInst>(BasePtr))

polly/lib/Support/ScopHelper.cpp

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -668,55 +668,6 @@ llvm::BasicBlock *polly::getUseBlock(const llvm::Use &U) {
668668
return UI->getParent();
669669
}
670670

671-
std::tuple<std::vector<const SCEV *>, std::vector<int>>
672-
polly::getIndexExpressionsFromGEP(GetElementPtrInst *GEP, ScalarEvolution &SE) {
673-
std::vector<const SCEV *> Subscripts;
674-
std::vector<int> Sizes;
675-
676-
Type *Ty = GEP->getPointerOperandType();
677-
678-
bool DroppedFirstDim = false;
679-
680-
for (unsigned i = 1; i < GEP->getNumOperands(); i++) {
681-
682-
const SCEV *Expr = SE.getSCEV(GEP->getOperand(i));
683-
684-
if (i == 1) {
685-
if (auto *PtrTy = dyn_cast<PointerType>(Ty)) {
686-
Ty = PtrTy->getElementType();
687-
} else if (auto *ArrayTy = dyn_cast<ArrayType>(Ty)) {
688-
Ty = ArrayTy->getElementType();
689-
} else {
690-
Subscripts.clear();
691-
Sizes.clear();
692-
break;
693-
}
694-
if (auto *Const = dyn_cast<SCEVConstant>(Expr))
695-
if (Const->getValue()->isZero()) {
696-
DroppedFirstDim = true;
697-
continue;
698-
}
699-
Subscripts.push_back(Expr);
700-
continue;
701-
}
702-
703-
auto *ArrayTy = dyn_cast<ArrayType>(Ty);
704-
if (!ArrayTy) {
705-
Subscripts.clear();
706-
Sizes.clear();
707-
break;
708-
}
709-
710-
Subscripts.push_back(Expr);
711-
if (!(DroppedFirstDim && i == 2))
712-
Sizes.push_back(ArrayTy->getNumElements());
713-
714-
Ty = ArrayTy->getElementType();
715-
}
716-
717-
return std::make_tuple(Subscripts, Sizes);
718-
}
719-
720671
llvm::Loop *polly::getFirstNonBoxedLoopFor(llvm::Loop *L, llvm::LoopInfo &LI,
721672
const BoxedLoopsSetTy &BoxedLoops) {
722673
while (BoxedLoops.count(L))

0 commit comments

Comments
 (0)