Commit e741fabc authored by Philip Reames's avatar Philip Reames
Browse files

[SCEV] Move getIndexExpressionsFromGEP to delinearize [NFC]

parent 4eaaf053
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include "llvm/Support/raw_ostream.h"

namespace llvm {
class GetElementPtrInst;
class ScalarEvolution;
class SCEV;

@@ -110,6 +111,20 @@ void delinearize(ScalarEvolution &SE, const SCEV *Expr,
                 SmallVectorImpl<const SCEV *> &Subscripts,
                 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
    : public PassInfoMixin<DelinearizationPrinterPass> {
  explicit DelinearizationPrinterPass(raw_ostream &OS);
+0 −13
Original line number Diff line number Diff line
@@ -1104,19 +1104,6 @@ public:
  bool invalidate(Function &F, const PreservedAnalyses &PA,
                  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
  /// operating on.
  const DataLayout &getDataLayout() const {
+38 −0
Original line number Diff line number Diff line
@@ -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 {

class Delinearization : public FunctionPass {
+2 −2
Original line number Diff line number Diff line
@@ -3339,8 +3339,8 @@ bool DependenceInfo::tryDelinearizeFixedSize(
    return false;

  SmallVector<int, 4> SrcSizes, DstSizes;
  SE->getIndexExpressionsFromGEP(SrcGEP, SrcSubscripts, SrcSizes);
  SE->getIndexExpressionsFromGEP(DstGEP, DstSubscripts, DstSizes);
  getIndexExpressionsFromGEP(*SE, SrcGEP, SrcSubscripts, SrcSizes);
  getIndexExpressionsFromGEP(*SE, DstGEP, DstSubscripts, DstSizes);

  // Check that the two size arrays are non-empty and equal in length and
  // value.
+0 −37
Original line number Diff line number Diff line
@@ -12201,43 +12201,6 @@ const SCEV *ScalarEvolution::getElementSize(Instruction *Inst) {
  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
//===----------------------------------------------------------------------===//