From: Michael Kruse Date: Thu, 3 Mar 2016 22:10:47 +0000 (+0000) Subject: Pass scope and LoopInfo to SCEVValidator. NFC. X-Git-Tag: llvmorg-3.9.0-rc1~12522 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=09eb4451d2a94995fe985d21ec802b7bb262479c;p=platform%2Fupstream%2Fllvm.git Pass scope and LoopInfo to SCEVValidator. NFC. 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 --- diff --git a/polly/include/polly/ScopDetection.h b/polly/include/polly/ScopDetection.h index b91a4e0..d033a98 100644 --- a/polly/include/polly/ScopDetection.h +++ b/polly/include/polly/ScopDetection.h @@ -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. diff --git a/polly/include/polly/ScopInfo.h b/polly/include/polly/ScopInfo.h index 5c18971..ffb79c3 100644 --- a/polly/include/polly/ScopInfo.h +++ b/polly/include/polly/ScopInfo.h @@ -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) { diff --git a/polly/include/polly/Support/SCEVAffinator.h b/polly/include/polly/Support/SCEVAffinator.h index c982349..e462c95 100644 --- a/polly/include/polly/Support/SCEVAffinator.h +++ b/polly/include/polly/Support/SCEVAffinator.h @@ -46,7 +46,7 @@ class ScopStmt; /// Translate a SCEV to an isl_pw_aff. struct SCEVAffinator : public llvm::SCEVVisitor { 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. diff --git a/polly/include/polly/Support/SCEVValidator.h b/polly/include/polly/Support/SCEVValidator.h index 99bb972..4e1351c 100644 --- a/polly/include/polly/Support/SCEVValidator.h +++ b/polly/include/polly/Support/SCEVValidator.h @@ -51,19 +51,20 @@ void findValues(const llvm::SCEV *Expr, llvm::SetVector &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 &Params, bool OrExpr = false); std::vector -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. diff --git a/polly/lib/Analysis/ScopDetection.cpp b/polly/lib/Analysis/ScopDetection.cpp index 47bf547..548b874 100644 --- a/polly/lib/Analysis/ScopDetection.cpp +++ b/polly/lib/Analysis/ScopDetection.cpp @@ -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(II).getLength(), L), + if (!isAffine(SE->getSCEVAtScope(cast(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(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(Inst) && !IsAffine) { return invalid(Context, /*Assert=*/true, AF, Inst, diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp index 4e94035..a6c14c6 100644 --- a/polly/lib/Analysis/ScopInfo.cpp +++ b/polly/lib/Analysis/ScopInfo.cpp @@ -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 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 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)); diff --git a/polly/lib/Support/SCEVAffinator.cpp b/polly/lib/Support/SCEVAffinator.cpp index e94df79..084fcf0 100644 --- a/polly/lib/Support/SCEVAffinator.cpp +++ b/polly/lib/Support/SCEVAffinator.cpp @@ -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); } diff --git a/polly/lib/Support/SCEVValidator.cpp b/polly/lib/Support/SCEVValidator.cpp index 492264b..2413990 100644 --- a/polly/lib/Support/SCEVValidator.cpp +++ b/polly/lib/Support/SCEVValidator.cpp @@ -124,14 +124,15 @@ struct SCEVValidator : public SCEVVisitor { 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(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 &Params) { auto *E = SE.getSCEV(V); if (isa(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 &Params, bool OrExpr) { if (auto *ICmp = dyn_cast(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(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 getParamsInAffineExpr(const Region *R, +std::vector getParamsInAffineExpr(const Region *R, Loop *Scope, const SCEV *Expr, ScalarEvolution &SE, const Value *BaseAddress) { @@ -646,7 +652,7 @@ std::vector getParamsInAffineExpr(const Region *R, return std::vector(); 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!");