[SCEV] Move getIndexExpressionsFromGEP to delinearize [NFC]

This commit is contained in:
Philip Reames 2021-09-08 16:29:29 -07:00
parent 4eaaf05394
commit e741fabc22
5 changed files with 55 additions and 52 deletions

View File

@ -21,6 +21,7 @@
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
namespace llvm { namespace llvm {
class GetElementPtrInst;
class ScalarEvolution; class ScalarEvolution;
class SCEV; class SCEV;
@ -110,6 +111,20 @@ void delinearize(ScalarEvolution &SE, const SCEV *Expr,
SmallVectorImpl<const SCEV *> &Subscripts, SmallVectorImpl<const SCEV *> &Subscripts,
SmallVectorImpl<const SCEV *> &Sizes, const SCEV *ElementSize); SmallVectorImpl<const SCEV *> &Sizes, const SCEV *ElementSize);
/// Gathers the individual index expressions from a GEP instruction.
///
/// 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.
bool getIndexExpressionsFromGEP(ScalarEvolution &SE,
const GetElementPtrInst *GEP,
SmallVectorImpl<const SCEV *> &Subscripts,
SmallVectorImpl<int> &Sizes);
struct DelinearizationPrinterPass struct DelinearizationPrinterPass
: public PassInfoMixin<DelinearizationPrinterPass> { : public PassInfoMixin<DelinearizationPrinterPass> {
explicit DelinearizationPrinterPass(raw_ostream &OS); explicit DelinearizationPrinterPass(raw_ostream &OS);

View File

@ -1104,19 +1104,6 @@ public:
bool invalidate(Function &F, const PreservedAnalyses &PA, bool invalidate(Function &F, const PreservedAnalyses &PA,
FunctionAnalysisManager::Invalidator &Inv); FunctionAnalysisManager::Invalidator &Inv);
/// Gathers the individual index expressions from a GEP instruction.
///
/// 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.
bool getIndexExpressionsFromGEP(const GetElementPtrInst *GEP,
SmallVectorImpl<const SCEV *> &Subscripts,
SmallVectorImpl<int> &Sizes);
/// Return the DataLayout associated with the module this SCEV instance is /// Return the DataLayout associated with the module this SCEV instance is
/// operating on. /// operating on.
const DataLayout &getDataLayout() const { const DataLayout &getDataLayout() const {

View File

@ -485,6 +485,44 @@ void llvm::delinearize(ScalarEvolution &SE, const SCEV *Expr,
}); });
} }
bool llvm::getIndexExpressionsFromGEP(ScalarEvolution &SE,
const GetElementPtrInst *GEP,
SmallVectorImpl<const SCEV *> &Subscripts,
SmallVectorImpl<int> &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");
Type *Ty = nullptr;
bool DroppedFirstDim = false;
for (unsigned i = 1; i < GEP->getNumOperands(); i++) {
const SCEV *Expr = SE.getSCEV(GEP->getOperand(i));
if (i == 1) {
Ty = GEP->getSourceElementType();
if (auto *Const = dyn_cast<SCEVConstant>(Expr))
if (Const->getValue()->isZero()) {
DroppedFirstDim = true;
continue;
}
Subscripts.push_back(Expr);
continue;
}
auto *ArrayTy = dyn_cast<ArrayType>(Ty);
if (!ArrayTy) {
Subscripts.clear();
Sizes.clear();
return false;
}
Subscripts.push_back(Expr);
if (!(DroppedFirstDim && i == 2))
Sizes.push_back(ArrayTy->getNumElements());
Ty = ArrayTy->getElementType();
}
return !Subscripts.empty();
}
namespace { namespace {
class Delinearization : public FunctionPass { class Delinearization : public FunctionPass {

View File

@ -3339,8 +3339,8 @@ bool DependenceInfo::tryDelinearizeFixedSize(
return false; return false;
SmallVector<int, 4> SrcSizes, DstSizes; SmallVector<int, 4> SrcSizes, DstSizes;
SE->getIndexExpressionsFromGEP(SrcGEP, SrcSubscripts, SrcSizes); getIndexExpressionsFromGEP(*SE, SrcGEP, SrcSubscripts, SrcSizes);
SE->getIndexExpressionsFromGEP(DstGEP, DstSubscripts, DstSizes); getIndexExpressionsFromGEP(*SE, DstGEP, DstSubscripts, DstSizes);
// Check that the two size arrays are non-empty and equal in length and // Check that the two size arrays are non-empty and equal in length and
// value. // value.

View File

@ -12201,43 +12201,6 @@ const SCEV *ScalarEvolution::getElementSize(Instruction *Inst) {
return getSizeOfExpr(ETy, Ty); return getSizeOfExpr(ETy, Ty);
} }
bool ScalarEvolution::getIndexExpressionsFromGEP(
const GetElementPtrInst *GEP, SmallVectorImpl<const SCEV *> &Subscripts,
SmallVectorImpl<int> &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");
Type *Ty = nullptr;
bool DroppedFirstDim = false;
for (unsigned i = 1; i < GEP->getNumOperands(); i++) {
const SCEV *Expr = getSCEV(GEP->getOperand(i));
if (i == 1) {
Ty = GEP->getSourceElementType();
if (auto *Const = dyn_cast<SCEVConstant>(Expr))
if (Const->getValue()->isZero()) {
DroppedFirstDim = true;
continue;
}
Subscripts.push_back(Expr);
continue;
}
auto *ArrayTy = dyn_cast<ArrayType>(Ty);
if (!ArrayTy) {
Subscripts.clear();
Sizes.clear();
return false;
}
Subscripts.push_back(Expr);
if (!(DroppedFirstDim && i == 2))
Sizes.push_back(ArrayTy->getNumElements());
Ty = ArrayTy->getElementType();
}
return !Subscripts.empty();
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// SCEVCallbackVH Class Implementation // SCEVCallbackVH Class Implementation
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//