Pass scope and LoopInfo to SCEVValidator. NFC.
authorMichael Kruse <llvm@meinersbur.de>
Thu, 3 Mar 2016 22:10:47 +0000 (22:10 +0000)
committerMichael Kruse <llvm@meinersbur.de>
Thu, 3 Mar 2016 22:10:47 +0000 (22:10 +0000)
The scope will be required in the following fix. This commit separates
the large changes that do not change behaviour from the small, but
functional change.

llvm-svn: 262664

polly/include/polly/ScopDetection.h
polly/include/polly/ScopInfo.h
polly/include/polly/Support/SCEVAffinator.h
polly/include/polly/Support/SCEVValidator.h
polly/lib/Analysis/ScopDetection.cpp
polly/lib/Analysis/ScopInfo.cpp
polly/lib/Support/SCEVAffinator.cpp
polly/lib/Support/SCEVValidator.cpp

index b91a4e0..d033a98 100644 (file)
@@ -438,9 +438,10 @@ private:
   /// non-affine.
   ///
   /// @param S           The expression to be checked.
+  /// @param Scope       The loop nest in which @p S is used.
   /// @param Context     The context of scop detection.
   /// @param BaseAddress The base address of the expression @p S (if any).
-  bool isAffine(const SCEV *S, DetectionContext &Context,
+  bool isAffine(const SCEV *S, Loop *Scope, DetectionContext &Context,
                 Value *BaseAddress = nullptr) const;
 
   /// @brief Check if the control flow in a basic block is valid.
@@ -516,6 +517,9 @@ public:
   /// This was added to give the DOT printer easy access to this information.
   RegionInfo *getRI() const { return RI; }
 
+  /// @brief Get the LoopInfo stored in this pass.
+  LoopInfo *getLI() const { return LI; }
+
   /// @brief Is the region is the maximum region of a Scop?
   ///
   /// @param R The Region to test if it is maximum.
index 5c18971..ffb79c3 100644 (file)
@@ -1411,7 +1411,7 @@ private:
   InvariantEquivClassesTy InvariantEquivClasses;
 
   /// @brief Scop constructor; invoked from ScopInfo::buildScop.
-  Scop(Region &R, ScalarEvolution &SE, unsigned MaxLoopDepth);
+  Scop(Region &R, ScalarEvolution &SE, LoopInfo &LI, unsigned MaxLoopDepth);
 
   /// @brief Get or create the access function set in a BasicBlock
   AccFuncSetType &getOrCreateAccessFunctions(const BasicBlock *BB) {
index c982349..e462c95 100644 (file)
@@ -46,7 +46,7 @@ class ScopStmt;
 /// Translate a SCEV to an isl_pw_aff.
 struct SCEVAffinator : public llvm::SCEVVisitor<SCEVAffinator, isl_pw_aff *> {
 public:
-  SCEVAffinator(Scop *S);
+  SCEVAffinator(Scop *S, llvm::LoopInfo &LI);
   ~SCEVAffinator();
 
   /// @brief Translate a SCEV to an isl_pw_aff.
@@ -81,6 +81,7 @@ private:
   unsigned NumIterators;
   const llvm::Region &R;
   llvm::ScalarEvolution &SE;
+  llvm::LoopInfo &LI;
   llvm::BasicBlock *BB;
 
   /// @brief Target data for element size computing.
index 99bb972..4e1351c 100644 (file)
@@ -51,19 +51,20 @@ void findValues(const llvm::SCEV *Expr, llvm::SetVector<llvm::Value *> &Values);
 ///                   region count as dependence.
 bool hasScalarDepsInsideRegion(const llvm::SCEV *S, const llvm::Region *R,
                                llvm::Loop *Scope, bool AllowLoops);
-bool isAffineExpr(const llvm::Region *R, const llvm::SCEV *Expression,
-                  llvm::ScalarEvolution &SE, const llvm::Value *BaseAddress = 0,
+bool isAffineExpr(const llvm::Region *R, llvm::Loop *Scope,
+                  const llvm::SCEV *Expression, llvm::ScalarEvolution &SE,
+                  const llvm::Value *BaseAddress = 0,
                   InvariantLoadsSetTy *ILS = nullptr);
 
 /// @brief Check if @p V describes an affine parameter constraint in @p R.
 bool isAffineParamConstraint(llvm::Value *V, const llvm::Region *R,
-                             llvm::ScalarEvolution &SE,
+                             llvm::Loop *Scope, llvm::ScalarEvolution &SE,
                              std::vector<const llvm::SCEV *> &Params,
                              bool OrExpr = false);
 
 std::vector<const llvm::SCEV *>
-getParamsInAffineExpr(const llvm::Region *R, const llvm::SCEV *Expression,
-                      llvm::ScalarEvolution &SE,
+getParamsInAffineExpr(const llvm::Region *R, llvm::Loop *Scope,
+                      const llvm::SCEV *Expression, llvm::ScalarEvolution &SE,
                       const llvm::Value *BaseAddress = 0);
 
 /// @brief Extract the constant factors from the multiplication @p M.
index 47bf547..548b874 100644 (file)
@@ -322,11 +322,12 @@ bool ScopDetection::onlyValidRequiredInvariantLoads(
   return true;
 }
 
-bool ScopDetection::isAffine(const SCEV *S, DetectionContext &Context,
+bool ScopDetection::isAffine(const SCEV *S, Loop *Scope,
+                             DetectionContext &Context,
                              Value *BaseAddress) const {
 
   InvariantLoadsSetTy AccessILS;
-  if (!isAffineExpr(&Context.CurRegion, S, *SE, BaseAddress, &AccessILS))
+  if (!isAffineExpr(&Context.CurRegion, Scope, S, *SE, BaseAddress, &AccessILS))
     return false;
 
   if (!onlyValidRequiredInvariantLoads(AccessILS, Context))
@@ -341,7 +342,7 @@ bool ScopDetection::isValidSwitch(BasicBlock &BB, SwitchInst *SI,
   Loop *L = LI->getLoopFor(&BB);
   const SCEV *ConditionSCEV = SE->getSCEVAtScope(Condition, L);
 
-  if (isAffine(ConditionSCEV, Context))
+  if (isAffine(ConditionSCEV, L, Context))
     return true;
 
   if (!IsLoopBranch && AllowNonAffineSubRegions &&
@@ -401,7 +402,7 @@ bool ScopDetection::isValidBranch(BasicBlock &BB, BranchInst *BI,
   const SCEV *LHS = SE->getSCEVAtScope(ICmp->getOperand(0), L);
   const SCEV *RHS = SE->getSCEVAtScope(ICmp->getOperand(1), L);
 
-  if (isAffine(LHS, Context) && isAffine(RHS, Context))
+  if (isAffine(LHS, L, Context) && isAffine(RHS, L, Context))
     return true;
 
   if (!IsLoopBranch && AllowNonAffineSubRegions &&
@@ -537,7 +538,7 @@ bool ScopDetection::isValidIntrinsicInst(IntrinsicInst &II,
       return false;
 
     // Bail if the length is not affine.
-    if (!isAffine(SE->getSCEVAtScope(cast<MemIntrinsic>(II).getLength(), L),
+    if (!isAffine(SE->getSCEVAtScope(cast<MemIntrinsic>(II).getLength(), L), L,
                   Context))
       return false;
 
@@ -721,7 +722,7 @@ bool ScopDetection::hasValidArraySizes(DetectionContext &Context,
   Value *BaseValue = BasePointer->getValue();
   Region &CurRegion = Context.CurRegion;
   for (const SCEV *DelinearizedSize : Sizes) {
-    if (!isAffine(DelinearizedSize, Context, nullptr)) {
+    if (!isAffine(DelinearizedSize, Scope, Context, nullptr)) {
       Sizes.clear();
       break;
     }
@@ -749,7 +750,7 @@ bool ScopDetection::hasValidArraySizes(DetectionContext &Context,
       const Instruction *Insn = Pair.first;
       const SCEV *AF = Pair.second;
 
-      if (!isAffine(AF, Context, BaseValue)) {
+      if (!isAffine(AF, Scope, Context, BaseValue)) {
         invalid<ReportNonAffineAccess>(Context, /*Assert=*/true, AF, Insn,
                                        BaseValue);
         if (!KeepGoing)
@@ -780,9 +781,10 @@ bool ScopDetection::computeAccessFunctions(
     bool IsNonAffine = false;
     TempMemoryAccesses.insert(std::make_pair(Insn, MemAcc(Insn, Shape)));
     MemAcc *Acc = &TempMemoryAccesses.find(Insn)->second;
+    auto *Scope = LI->getLoopFor(Insn->getParent());
 
     if (!AF) {
-      if (isAffine(Pair.second, Context, BaseValue))
+      if (isAffine(Pair.second, Scope, Context, BaseValue))
         Acc->DelinearizedSubscripts.push_back(Pair.second);
       else
         IsNonAffine = true;
@@ -792,7 +794,7 @@ bool ScopDetection::computeAccessFunctions(
       if (Acc->DelinearizedSubscripts.size() == 0)
         IsNonAffine = true;
       for (const SCEV *S : Acc->DelinearizedSubscripts)
-        if (!isAffine(S, Context, BaseValue))
+        if (!isAffine(S, Scope, Context, BaseValue))
           IsNonAffine = true;
     }
 
@@ -898,7 +900,8 @@ bool ScopDetection::isValidAccess(Instruction *Inst, const SCEV *AF,
     if (Context.BoxedLoopsSet.count(L))
       IsVariantInNonAffineLoop = true;
 
-  bool IsAffine = !IsVariantInNonAffineLoop && isAffine(AF, Context, BV);
+  auto *Scope = LI->getLoopFor(Inst->getParent());
+  bool IsAffine = !IsVariantInNonAffineLoop && isAffine(AF, Scope, Context, BV);
   // Do not try to delinearize memory intrinsics and force them to be affine.
   if (isa<MemIntrinsic>(Inst) && !IsAffine) {
     return invalid<ReportNonAffineAccess>(Context, /*Assert=*/true, AF, Inst,
index 4e94035..a6c14c6 100644 (file)
@@ -1318,8 +1318,10 @@ void ScopStmt::deriveAssumptionsFromGEP(GetElementPtrInst *GEP,
     auto *Expr = Subscripts[i + IndexOffset];
     auto Size = Sizes[i];
 
+    auto *Scope = SD.getLI()->getLoopFor(getEntryBlock());
     InvariantLoadsSetTy AccessILS;
-    if (!isAffineExpr(&Parent.getRegion(), Expr, SE, nullptr, &AccessILS))
+    if (!isAffineExpr(&Parent.getRegion(), Scope, Expr, SE, nullptr,
+                      &AccessILS))
       continue;
 
     bool NonAffine = false;
@@ -1783,9 +1785,10 @@ void Scop::addUserAssumptions(AssumptionCache &AC, DominatorTree &DT,
     if (!DT.dominates(CI->getParent(), R->getEntry()))
       continue;
 
+    auto *L = LI.getLoopFor(CI->getParent());
     auto *Val = CI->getArgOperand(0);
     std::vector<const SCEV *> Params;
-    if (!isAffineParamConstraint(Val, R, *SE, Params)) {
+    if (!isAffineParamConstraint(Val, R, L, *SE, Params)) {
       emitOptimizationRemarkAnalysis(F.getContext(), DEBUG_TYPE, F,
                                      CI->getDebugLoc(),
                                      "Non-affine user assumption ignored.");
@@ -1794,7 +1797,6 @@ void Scop::addUserAssumptions(AssumptionCache &AC, DominatorTree &DT,
 
     addParams(Params);
 
-    auto *L = LI.getLoopFor(CI->getParent());
     SmallVector<isl_set *, 2> ConditionSets;
     buildConditionSets(*this, Val, nullptr, L, Context, ConditionSets);
     assert(ConditionSets.size() == 2);
@@ -2765,11 +2767,12 @@ static unsigned getMaxLoopDepthInRegion(const Region &R, LoopInfo &LI,
   return MaxLD - MinLD + 1;
 }
 
-Scop::Scop(Region &R, ScalarEvolution &ScalarEvolution, unsigned MaxLoopDepth)
+Scop::Scop(Region &R, ScalarEvolution &ScalarEvolution, LoopInfo &LI,
+           unsigned MaxLoopDepth)
     : SE(&ScalarEvolution), R(R), IsOptimized(false),
       HasSingleExitEdge(R.getExitingBlock()), HasErrorBlock(false),
       MaxLoopDepth(MaxLoopDepth), IslCtx(isl_ctx_alloc(), isl_ctx_free),
-      Context(nullptr), Affinator(this), AssumedContext(nullptr),
+      Context(nullptr), Affinator(this, LI), AssumedContext(nullptr),
       InvalidContext(nullptr), Schedule(nullptr) {
   isl_options_set_on_error(getIslCtx(), ISL_ON_ERROR_ABORT);
   buildContext();
@@ -3855,7 +3858,7 @@ bool ScopInfo::buildAccessMultiDimFixed(
 
   for (auto *Subscript : Subscripts) {
     InvariantLoadsSetTy AccessILS;
-    if (!isAffineExpr(R, Subscript, *SE, nullptr, &AccessILS))
+    if (!isAffineExpr(R, L, Subscript, *SE, nullptr, &AccessILS))
       return false;
 
     for (LoadInst *LInst : AccessILS)
@@ -3934,7 +3937,7 @@ bool ScopInfo::buildAccessMemIntrinsic(
 
   // Check if the length val is actually affine or if we overapproximate it
   InvariantLoadsSetTy AccessILS;
-  bool LengthIsAffine = isAffineExpr(R, LengthVal, *SE, nullptr, &AccessILS);
+  bool LengthIsAffine = isAffineExpr(R, L, LengthVal, *SE, nullptr, &AccessILS);
   for (LoadInst *LInst : AccessILS)
     if (!ScopRIL.count(LInst))
       LengthIsAffine = false;
@@ -4044,9 +4047,9 @@ void ScopInfo::buildAccessSingleDim(
   }
 
   InvariantLoadsSetTy AccessILS;
-  bool IsAffine =
-      !isVariantInNonAffineLoop &&
-      isAffineExpr(R, AccessFunction, *SE, BasePointer->getValue(), &AccessILS);
+  bool IsAffine = !isVariantInNonAffineLoop &&
+                  isAffineExpr(R, L, AccessFunction, *SE,
+                               BasePointer->getValue(), &AccessILS);
 
   for (LoadInst *LInst : AccessILS)
     if (!ScopRIL.count(LInst))
@@ -4317,7 +4320,7 @@ void ScopInfo::addPHIReadAccess(PHINode *PHI) {
 
 void ScopInfo::buildScop(Region &R, AssumptionCache &AC) {
   unsigned MaxLoopDepth = getMaxLoopDepthInRegion(R, *LI, *SD);
-  scop.reset(new Scop(R, *SE, MaxLoopDepth));
+  scop.reset(new Scop(R, *SE, *LI, MaxLoopDepth));
 
   buildStmts(R, R);
   buildAccessFunctions(R, R, *SD->getInsnToMemAccMap(&R));
index e94df79..084fcf0 100644 (file)
@@ -24,8 +24,8 @@
 using namespace llvm;
 using namespace polly;
 
-SCEVAffinator::SCEVAffinator(Scop *S)
-    : S(S), Ctx(S->getIslCtx()), R(S->getRegion()), SE(*S->getSE()),
+SCEVAffinator::SCEVAffinator(Scop *S, LoopInfo &LI)
+    : S(S), Ctx(S->getIslCtx()), R(S->getRegion()), SE(*S->getSE()), LI(LI),
       TD(R.getEntry()->getParent()->getParent()->getDataLayout()) {}
 
 SCEVAffinator::~SCEVAffinator() {
@@ -44,7 +44,8 @@ __isl_give isl_pw_aff *SCEVAffinator::getPwAff(const SCEV *Expr,
   } else
     NumIterators = 0;
 
-  S->addParams(getParamsInAffineExpr(&R, Expr, SE));
+  auto *Scope = LI.getLoopFor(BB);
+  S->addParams(getParamsInAffineExpr(&R, Scope, Expr, SE));
 
   return visit(Expr);
 }
index 492264b..2413990 100644 (file)
@@ -124,14 +124,15 @@ struct SCEVValidator
     : public SCEVVisitor<SCEVValidator, class ValidatorResult> {
 private:
   const Region *R;
+  Loop *Scope;
   ScalarEvolution &SE;
   const Value *BaseAddress;
   InvariantLoadsSetTy *ILS;
 
 public:
-  SCEVValidator(const Region *R, ScalarEvolution &SE, const Value *BaseAddress,
-                InvariantLoadsSetTy *ILS)
-      : R(R), SE(SE), BaseAddress(BaseAddress), ILS(ILS) {}
+  SCEVValidator(const Region *R, Loop *Scope, ScalarEvolution &SE,
+                const Value *BaseAddress, InvariantLoadsSetTy *ILS)
+      : R(R), Scope(Scope), SE(SE), BaseAddress(BaseAddress), ILS(ILS) {}
 
   class ValidatorResult visitConstant(const SCEVConstant *Constant) {
     return ValidatorResult(SCEVType::INT);
@@ -576,12 +577,13 @@ bool hasScalarDepsInsideRegion(const SCEV *Expr, const Region *R,
   return SCEVInRegionDependences::hasDependences(Expr, R, Scope, AllowLoops);
 }
 
-bool isAffineExpr(const Region *R, const SCEV *Expr, ScalarEvolution &SE,
-                  const Value *BaseAddress, InvariantLoadsSetTy *ILS) {
+bool isAffineExpr(const Region *R, llvm::Loop *Scope, const SCEV *Expr,
+                  ScalarEvolution &SE, const Value *BaseAddress,
+                  InvariantLoadsSetTy *ILS) {
   if (isa<SCEVCouldNotCompute>(Expr))
     return false;
 
-  SCEVValidator Validator(R, SE, BaseAddress, ILS);
+  SCEVValidator Validator(R, Scope, SE, BaseAddress, ILS);
   DEBUG({
     dbgs() << "\n";
     dbgs() << "Expr: " << *Expr << "\n";
@@ -600,13 +602,14 @@ bool isAffineExpr(const Region *R, const SCEV *Expr, ScalarEvolution &SE,
   return Result.isValid();
 }
 
-static bool isAffineParamExpr(Value *V, const Region *R, ScalarEvolution &SE,
+static bool isAffineParamExpr(Value *V, const Region *R, Loop *Scope,
+                              ScalarEvolution &SE,
                               std::vector<const SCEV *> &Params) {
   auto *E = SE.getSCEV(V);
   if (isa<SCEVCouldNotCompute>(E))
     return false;
 
-  SCEVValidator Validator(R, SE, nullptr, nullptr);
+  SCEVValidator Validator(R, Scope, SE, nullptr, nullptr);
   ValidatorResult Result = Validator.visit(E);
   if (!Result.isConstant())
     return false;
@@ -617,17 +620,20 @@ static bool isAffineParamExpr(Value *V, const Region *R, ScalarEvolution &SE,
   return true;
 }
 
-bool isAffineParamConstraint(Value *V, const Region *R, ScalarEvolution &SE,
+bool isAffineParamConstraint(Value *V, const Region *R, llvm::Loop *Scope,
+                             ScalarEvolution &SE,
                              std::vector<const SCEV *> &Params, bool OrExpr) {
   if (auto *ICmp = dyn_cast<ICmpInst>(V)) {
-    return isAffineParamConstraint(ICmp->getOperand(0), R, SE, Params, true) &&
-           isAffineParamConstraint(ICmp->getOperand(1), R, SE, Params, true);
+    return isAffineParamConstraint(ICmp->getOperand(0), R, Scope, SE, Params,
+                                   true) &&
+           isAffineParamConstraint(ICmp->getOperand(1), R, Scope, SE, Params,
+                                   true);
   } else if (auto *BinOp = dyn_cast<BinaryOperator>(V)) {
     auto Opcode = BinOp->getOpcode();
     if (Opcode == Instruction::And || Opcode == Instruction::Or)
-      return isAffineParamConstraint(BinOp->getOperand(0), R, SE, Params,
+      return isAffineParamConstraint(BinOp->getOperand(0), R, Scope, SE, Params,
                                      false) &&
-             isAffineParamConstraint(BinOp->getOperand(1), R, SE, Params,
+             isAffineParamConstraint(BinOp->getOperand(1), R, Scope, SE, Params,
                                      false);
     /* Fall through */
   }
@@ -635,10 +641,10 @@ bool isAffineParamConstraint(Value *V, const Region *R, ScalarEvolution &SE,
   if (!OrExpr)
     return false;
 
-  return isAffineParamExpr(V, R, SE, Params);
+  return isAffineParamExpr(V, R, Scope, SE, Params);
 }
 
-std::vector<const SCEV *> getParamsInAffineExpr(const Region *R,
+std::vector<const SCEV *> getParamsInAffineExpr(const Region *R, Loop *Scope,
                                                 const SCEV *Expr,
                                                 ScalarEvolution &SE,
                                                 const Value *BaseAddress) {
@@ -646,7 +652,7 @@ std::vector<const SCEV *> getParamsInAffineExpr(const Region *R,
     return std::vector<const SCEV *>();
 
   InvariantLoadsSetTy ILS;
-  SCEVValidator Validator(R, SE, BaseAddress, &ILS);
+  SCEVValidator Validator(R, Scope, SE, BaseAddress, &ILS);
   ValidatorResult Result = Validator.visit(Expr);
   assert(Result.isValid() && "Requested parameters for an invalid SCEV!");