diff options
Diffstat (limited to 'polly/lib')
-rw-r--r-- | polly/lib/Analysis/ScopDetection.cpp | 23 | ||||
-rw-r--r-- | polly/lib/Analysis/ScopInfo.cpp | 25 | ||||
-rw-r--r-- | polly/lib/Support/SCEVAffinator.cpp | 7 | ||||
-rw-r--r-- | polly/lib/Support/SCEVValidator.cpp | 38 |
4 files changed, 53 insertions, 40 deletions
diff --git a/polly/lib/Analysis/ScopDetection.cpp b/polly/lib/Analysis/ScopDetection.cpp index 47bf54786fb..548b8747c20 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<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, diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp index 4e940350f24..a6c14c6224f 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<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)); diff --git a/polly/lib/Support/SCEVAffinator.cpp b/polly/lib/Support/SCEVAffinator.cpp index e94df79d19d..084fcf0de00 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 492264bcb57..24139908c5d 100644 --- a/polly/lib/Support/SCEVValidator.cpp +++ b/polly/lib/Support/SCEVValidator.cpp @@ -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!"); |