diff options
| author | Johannes Doerfert <doerfert@cs.uni-saarland.de> | 2016-05-19 12:34:57 +0000 |
|---|---|---|
| committer | Johannes Doerfert <doerfert@cs.uni-saarland.de> | 2016-05-19 12:34:57 +0000 |
| commit | ffd222f2d671d5e15b10d17a19bab21f16891a5d (patch) | |
| tree | b2cc1050ce29afaab5a0f3a55a69b8be2fdd47dc /polly/lib | |
| parent | 60dd9e134688da14357b515258c3194253c9a3eb (diff) | |
| download | bcm5719-llvm-ffd222f2d671d5e15b10d17a19bab21f16891a5d.tar.gz bcm5719-llvm-ffd222f2d671d5e15b10d17a19bab21f16891a5d.zip | |
Propagate the DetectionContext to the SCoP [NFC]
The SCoP now holds a reference to the ScopDetection::DetectionContext
which allows to simplify the type of various methods and remove code.
llvm-svn: 270053
Diffstat (limited to 'polly/lib')
| -rw-r--r-- | polly/lib/Analysis/ScopDetection.cpp | 28 | ||||
| -rw-r--r-- | polly/lib/Analysis/ScopInfo.cpp | 219 |
2 files changed, 92 insertions, 155 deletions
diff --git a/polly/lib/Analysis/ScopDetection.cpp b/polly/lib/Analysis/ScopDetection.cpp index cf71b8905ed..bfc9a99ff86 100644 --- a/polly/lib/Analysis/ScopDetection.cpp +++ b/polly/lib/Analysis/ScopDetection.cpp @@ -1493,13 +1493,6 @@ bool ScopDetection::runOnFunction(llvm::Function &F) { return false; } -bool ScopDetection::isNonAffineSubRegion(const Region *SubR, - const Region *ScopR) const { - const DetectionContext *DC = getDetectionContext(ScopR); - assert(DC && "ScopR is no valid region!"); - return DC->NonAffineSubRegionSet.count(SubR); -} - const ScopDetection::DetectionContext * ScopDetection::getDetectionContext(const Region *R) const { auto DCMIt = DetectionContextMap.find(getBBPairForRegion(R)); @@ -1508,27 +1501,6 @@ ScopDetection::getDetectionContext(const Region *R) const { return &DCMIt->second; } -const ScopDetection::BoxedLoopsSetTy * -ScopDetection::getBoxedLoops(const Region *R) const { - const DetectionContext *DC = getDetectionContext(R); - assert(DC && "ScopR is no valid region!"); - return &DC->BoxedLoopsSet; -} - -const MapInsnToMemAcc * -ScopDetection::getInsnToMemAccMap(const Region *R) const { - const DetectionContext *DC = getDetectionContext(R); - assert(DC && "ScopR is no valid region!"); - return &DC->InsnToMemAcc; -} - -const InvariantLoadsSetTy * -ScopDetection::getRequiredInvariantLoads(const Region *R) const { - const DetectionContext *DC = getDetectionContext(R); - assert(DC && "ScopR is no valid region!"); - return &DC->RequiredILS; -} - const RejectLog *ScopDetection::lookupRejectionLog(const Region *R) const { const DetectionContext *DC = getDetectionContext(R); return DC ? &DC->Log : nullptr; diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp index b12af38937c..6c2612ae135 100644 --- a/polly/lib/Analysis/ScopInfo.cpp +++ b/polly/lib/Analysis/ScopInfo.cpp @@ -1402,15 +1402,14 @@ void ScopStmt::buildDomain() { Domain = isl_set_set_tuple_id(Domain, Id); } -void ScopStmt::deriveAssumptionsFromGEP(GetElementPtrInst *GEP, - ScopDetection &SD) { +void ScopStmt::deriveAssumptionsFromGEP(GetElementPtrInst *GEP, LoopInfo &LI) { isl_ctx *Ctx = Parent.getIslCtx(); isl_local_space *LSpace = isl_local_space_from_space(getDomainSpace()); Type *Ty = GEP->getPointerOperandType(); ScalarEvolution &SE = *Parent.getSE(); // The set of loads that are required to be invariant. - auto &ScopRIL = *SD.getRequiredInvariantLoads(&Parent.getRegion()); + auto &ScopRIL = Parent.getRequiredInvariantLoads(); std::vector<const SCEV *> Subscripts; std::vector<int> Sizes; @@ -1430,7 +1429,7 @@ void ScopStmt::deriveAssumptionsFromGEP(GetElementPtrInst *GEP, auto *Expr = Subscripts[i + IndexOffset]; auto Size = Sizes[i]; - auto *Scope = SD.getLI()->getLoopFor(getEntryBlock()); + auto *Scope = LI.getLoopFor(getEntryBlock()); InvariantLoadsSetTy AccessILS; if (!isAffineExpr(&Parent.getRegion(), Scope, Expr, SE, &AccessILS)) continue; @@ -1468,7 +1467,7 @@ void ScopStmt::deriveAssumptionsFromGEP(GetElementPtrInst *GEP, isl_set_free(NotExecuted); } -void ScopStmt::deriveAssumptions(ScopDetection &SD) { +void ScopStmt::deriveAssumptions(LoopInfo &LI) { for (auto *MA : *this) { if (!MA->isArrayKind()) continue; @@ -1477,7 +1476,7 @@ void ScopStmt::deriveAssumptions(ScopDetection &SD) { auto *GEP = dyn_cast_or_null<GetElementPtrInst>(Acc.getPointerOperand()); if (GEP) - deriveAssumptionsFromGEP(GEP, SD); + deriveAssumptionsFromGEP(GEP, LI); } } @@ -1503,14 +1502,14 @@ ScopStmt::ScopStmt(Scop &parent, BasicBlock &bb) BaseName = getIslCompatibleName("Stmt_", &bb, ""); } -void ScopStmt::init(ScopDetection &SD) { +void ScopStmt::init(LoopInfo &LI) { assert(!Domain && "init must be called only once"); buildDomain(); collectSurroundingLoops(); buildAccessRelations(); - deriveAssumptions(SD); + deriveAssumptions(LI); if (DetectReductions) checkForReductions(); @@ -1996,10 +1995,10 @@ void Scop::addUserContext() { isl_space_free(Space); } -void Scop::buildInvariantEquivalenceClasses(ScopDetection &SD) { +void Scop::buildInvariantEquivalenceClasses() { DenseMap<std::pair<const SCEV *, Type *>, LoadInst *> EquivClasses; - const InvariantLoadsSetTy &RIL = *SD.getRequiredInvariantLoads(&getRegion()); + const InvariantLoadsSetTy &RIL = getRequiredInvariantLoads(); for (LoadInst *LInst : RIL) { const SCEV *PointerSCEV = SE->getSCEV(LInst->getPointerOperand()); @@ -2267,10 +2266,9 @@ __isl_give isl_set *Scop::getDomainConditions(BasicBlock *BB) const { return getDomainConditions(BBR->getEntry()); } -bool Scop::buildDomains(Region *R, ScopDetection &SD, DominatorTree &DT, - LoopInfo &LI) { +bool Scop::buildDomains(Region *R, DominatorTree &DT, LoopInfo &LI) { - bool IsOnlyNonAffineRegion = SD.isNonAffineSubRegion(R, R); + bool IsOnlyNonAffineRegion = isNonAffineSubRegion(R); auto *EntryBB = R->getEntry(); auto *L = IsOnlyNonAffineRegion ? nullptr : LI.getLoopFor(EntryBB); int LD = getRelativeLoopDepth(L); @@ -2290,10 +2288,10 @@ bool Scop::buildDomains(Region *R, ScopDetection &SD, DominatorTree &DT, if (IsOnlyNonAffineRegion) return !containsErrorBlock(R->getNode(), *R, LI, DT); - if (!buildDomainsWithBranchConstraints(R, SD, DT, LI)) + if (!buildDomainsWithBranchConstraints(R, DT, LI)) return false; - if (!propagateDomainConstraints(R, SD, DT, LI)) + if (!propagateDomainConstraints(R, DT, LI)) return false; // Error blocks and blocks dominated by them have been assumed to never be @@ -2308,15 +2306,14 @@ bool Scop::buildDomains(Region *R, ScopDetection &SD, DominatorTree &DT, // with an empty set. Additionally, we will record for each block under which // parameter combination it would be reached via an error block in its // InvalidDomain. This information is needed during load hoisting. - if (!propagateInvalidStmtDomains(R, SD, DT, LI)) + if (!propagateInvalidStmtDomains(R, DT, LI)) return false; return true; } -static Loop * -getFirstNonBoxedLoopFor(BasicBlock *BB, LoopInfo &LI, - const ScopDetection::BoxedLoopsSetTy &BoxedLoops) { +static Loop *getFirstNonBoxedLoopFor(BasicBlock *BB, LoopInfo &LI, + const BoxedLoopsSetTy &BoxedLoops) { auto *L = LI.getLoopFor(BB); while (BoxedLoops.count(L)) L = L->getParentLoop(); @@ -2373,9 +2370,9 @@ static __isl_give isl_set *adjustDomainDimensions(Scop &S, return Dom; } -bool Scop::propagateInvalidStmtDomains(Region *R, ScopDetection &SD, - DominatorTree &DT, LoopInfo &LI) { - auto &BoxedLoops = *SD.getBoxedLoops(&getRegion()); +bool Scop::propagateInvalidStmtDomains(Region *R, DominatorTree &DT, + LoopInfo &LI) { + auto &BoxedLoops = getBoxedLoops(); ReversePostOrderTraversal<Region *> RTraversal(R); for (auto *RN : RTraversal) { @@ -2384,8 +2381,8 @@ bool Scop::propagateInvalidStmtDomains(Region *R, ScopDetection &SD, // subregions. if (RN->isSubRegion()) { Region *SubRegion = RN->getNodeAs<Region>(); - if (!SD.isNonAffineSubRegion(SubRegion, &getRegion())) { - propagateInvalidStmtDomains(SubRegion, SD, DT, LI); + if (!isNonAffineSubRegion(SubRegion)) { + propagateInvalidStmtDomains(SubRegion, DT, LI); continue; } } @@ -2459,8 +2456,7 @@ bool Scop::propagateInvalidStmtDomains(Region *R, ScopDetection &SD, void Scop::propagateDomainConstraintsToRegionExit( BasicBlock *BB, Loop *BBLoop, - SmallPtrSetImpl<BasicBlock *> &FinishedExitBlocks, ScopDetection &SD, - LoopInfo &LI) { + SmallPtrSetImpl<BasicBlock *> &FinishedExitBlocks, LoopInfo &LI) { // Check if the block @p BB is the entry of a region. If so we propagate it's // domain to the exit block of the region. Otherwise we are done. @@ -2470,7 +2466,7 @@ void Scop::propagateDomainConstraintsToRegionExit( if (!BBReg || BBReg->getEntry() != BB || !R.contains(ExitBB)) return; - auto &BoxedLoops = *SD.getBoxedLoops(&getRegion()); + auto &BoxedLoops = getBoxedLoops(); // Do not propagate the domain if there is a loop backedge inside the region // that would prevent the exit block from beeing executed. auto *L = BBLoop; @@ -2506,10 +2502,8 @@ void Scop::propagateDomainConstraintsToRegionExit( FinishedExitBlocks.insert(ExitBB); } -bool Scop::buildDomainsWithBranchConstraints(Region *R, ScopDetection &SD, - DominatorTree &DT, LoopInfo &LI) { - auto &BoxedLoops = *SD.getBoxedLoops(&getRegion()); - +bool Scop::buildDomainsWithBranchConstraints(Region *R, DominatorTree &DT, + LoopInfo &LI) { // To create the domain for each block in R we iterate over all blocks and // subregions in R and propagate the conditions under which the current region // element is executed. To this end we iterate in reverse post order over R as @@ -2529,8 +2523,8 @@ bool Scop::buildDomainsWithBranchConstraints(Region *R, ScopDetection &SD, // subregions. if (RN->isSubRegion()) { Region *SubRegion = RN->getNodeAs<Region>(); - if (!SD.isNonAffineSubRegion(SubRegion, &getRegion())) { - if (!buildDomainsWithBranchConstraints(SubRegion, SD, DT, LI)) + if (!isNonAffineSubRegion(SubRegion)) { + if (!buildDomainsWithBranchConstraints(SubRegion, DT, LI)) return false; continue; } @@ -2553,8 +2547,7 @@ bool Scop::buildDomainsWithBranchConstraints(Region *R, ScopDetection &SD, auto *BBLoop = getRegionNodeLoop(RN, LI); // Propagate the domain from BB directly to blocks that have a superset // domain, at the moment only region exit nodes of regions that start in BB. - propagateDomainConstraintsToRegionExit(BB, BBLoop, FinishedExitBlocks, SD, - LI); + propagateDomainConstraintsToRegionExit(BB, BBLoop, FinishedExitBlocks, LI); // If all successors of BB have been set a domain through the propagation // above we do not need to build condition sets but can just skip this @@ -2607,6 +2600,7 @@ bool Scop::buildDomainsWithBranchConstraints(Region *R, ScopDetection &SD, continue; } + auto &BoxedLoops = getBoxedLoops(); auto *SuccBBLoop = getFirstNonBoxedLoopFor(SuccBB, LI, BoxedLoops); CondSet = adjustDomainDimensions(*this, CondSet, BBLoop, SuccBBLoop); @@ -2640,7 +2634,6 @@ bool Scop::buildDomainsWithBranchConstraints(Region *R, ScopDetection &SD, __isl_give isl_set *Scop::getPredecessorDomainConstraints(BasicBlock *BB, isl_set *Domain, - ScopDetection &SD, DominatorTree &DT, LoopInfo &LI) { // If @p BB is the ScopEntry we are done @@ -2648,7 +2641,7 @@ __isl_give isl_set *Scop::getPredecessorDomainConstraints(BasicBlock *BB, return isl_set_universe(isl_set_get_space(Domain)); // The set of boxed loops (loops in non-affine subregions) for this SCoP. - auto &BoxedLoops = *SD.getBoxedLoops(&getRegion()); + auto &BoxedLoops = getBoxedLoops(); // The region info of this function. auto &RI = *R.getRegionInfo(); @@ -2698,8 +2691,8 @@ __isl_give isl_set *Scop::getPredecessorDomainConstraints(BasicBlock *BB, return PredDom; } -bool Scop::propagateDomainConstraints(Region *R, ScopDetection &SD, - DominatorTree &DT, LoopInfo &LI) { +bool Scop::propagateDomainConstraints(Region *R, DominatorTree &DT, + LoopInfo &LI) { // Iterate over the region R and propagate the domain constrains from the // predecessors to the current node. In contrast to the // buildDomainsWithBranchConstraints function, this one will pull the domain @@ -2716,8 +2709,8 @@ bool Scop::propagateDomainConstraints(Region *R, ScopDetection &SD, // subregions. if (RN->isSubRegion()) { Region *SubRegion = RN->getNodeAs<Region>(); - if (!SD.isNonAffineSubRegion(SubRegion, &getRegion())) { - if (!propagateDomainConstraints(SubRegion, SD, DT, LI)) + if (!isNonAffineSubRegion(SubRegion)) { + if (!propagateDomainConstraints(SubRegion, DT, LI)) return false; continue; } @@ -2728,7 +2721,7 @@ bool Scop::propagateDomainConstraints(Region *R, ScopDetection &SD, assert(Domain); // Under the union of all predecessor conditions we can reach this block. - auto *PredDom = getPredecessorDomainConstraints(BB, Domain, SD, DT, LI); + auto *PredDom = getPredecessorDomainConstraints(BB, Domain, DT, LI); Domain = isl_set_coalesce(isl_set_intersect(Domain, PredDom)); Domain = isl_set_align_params(Domain, getParamSpace()); @@ -3058,22 +3051,23 @@ static Loop *getLoopSurroundingRegion(Region &R, LoopInfo &LI) { return L ? (R.contains(L) ? L->getParentLoop() : L) : nullptr; } -Scop::Scop(Region &R, ScalarEvolution &ScalarEvolution, LoopInfo &LI) +Scop::Scop(Region &R, ScalarEvolution &ScalarEvolution, LoopInfo &LI, + const ScopDetection::DetectionContext &DC) : SE(&ScalarEvolution), R(R), IsOptimized(false), HasSingleExitEdge(R.getExitingBlock()), HasErrorBlock(false), - MaxLoopDepth(0), IslCtx(isl_ctx_alloc(), isl_ctx_free), Context(nullptr), - Affinator(this, LI), AssumedContext(nullptr), InvalidContext(nullptr), - Schedule(nullptr) { + MaxLoopDepth(0), DC(DC), IslCtx(isl_ctx_alloc(), isl_ctx_free), + Context(nullptr), Affinator(this, LI), AssumedContext(nullptr), + InvalidContext(nullptr), Schedule(nullptr) { if (IslOnErrorAbort) isl_options_set_on_error(getIslCtx(), ISL_ON_ERROR_ABORT); buildContext(); } -void Scop::init(AliasAnalysis &AA, AssumptionCache &AC, ScopDetection &SD, - DominatorTree &DT, LoopInfo &LI) { - buildInvariantEquivalenceClasses(SD); +void Scop::init(AliasAnalysis &AA, AssumptionCache &AC, DominatorTree &DT, + LoopInfo &LI) { + buildInvariantEquivalenceClasses(); - if (!buildDomains(&R, SD, DT, LI)) + if (!buildDomains(&R, DT, LI)) return; addUserAssumptions(AC, DT, LI); @@ -3086,7 +3080,7 @@ void Scop::init(AliasAnalysis &AA, AssumptionCache &AC, ScopDetection &SD, // The ScopStmts now have enough information to initialize themselves. for (ScopStmt &Stmt : Stmts) - Stmt.init(SD); + Stmt.init(LI); // Check early for profitability. Afterwards it cannot change anymore, // only the runtime context could become infeasible. @@ -3095,7 +3089,7 @@ void Scop::init(AliasAnalysis &AA, AssumptionCache &AC, ScopDetection &SD, return; } - buildSchedule(SD, LI); + buildSchedule(LI); updateAccessDimensionality(); realignParams(); @@ -3109,8 +3103,8 @@ void Scop::init(AliasAnalysis &AA, AssumptionCache &AC, ScopDetection &SD, simplifyContexts(); buildAliasChecks(AA); - hoistInvariantLoads(SD); - verifyInvariantLoads(SD); + hoistInvariantLoads(); + verifyInvariantLoads(); simplifySCoP(true, DT, LI); // Check late for a feasible runtime context because profitability did not @@ -3450,8 +3444,8 @@ bool Scop::isHoistableAccess(MemoryAccess *Access, return true; } -void Scop::verifyInvariantLoads(ScopDetection &SD) { - auto &RIL = *SD.getRequiredInvariantLoads(&getRegion()); +void Scop::verifyInvariantLoads() { + auto &RIL = getRequiredInvariantLoads(); for (LoadInst *LI : RIL) { assert(LI && getRegion().contains(LI)); ScopStmt *Stmt = getStmtFor(LI); @@ -3462,7 +3456,7 @@ void Scop::verifyInvariantLoads(ScopDetection &SD) { } } -void Scop::hoistInvariantLoads(ScopDetection &SD) { +void Scop::hoistInvariantLoads() { if (!PollyInvariantLoadHoisting) return; @@ -4041,10 +4035,10 @@ void Scop::addScopStmt(BasicBlock *BB, Region *R) { } } -void Scop::buildSchedule(ScopDetection &SD, LoopInfo &LI) { +void Scop::buildSchedule(LoopInfo &LI) { Loop *L = getLoopSurroundingRegion(getRegion(), LI); LoopStackTy LoopStack({LoopStackElementTy(L, nullptr, 0)}); - buildSchedule(getRegion().getNode(), LoopStack, SD, LI); + buildSchedule(getRegion().getNode(), LoopStack, LI); assert(LoopStack.size() == 1 && LoopStack.back().L == L); Schedule = LoopStack[0].Schedule; } @@ -4073,8 +4067,7 @@ void Scop::buildSchedule(ScopDetection &SD, LoopInfo &LI) { /// sub-regions or blocks that are outside the last loop on the @p LoopStack. /// These region-nodes are then queue and only traverse after the all nodes /// within the current loop have been processed. -void Scop::buildSchedule(Region *R, LoopStackTy &LoopStack, ScopDetection &SD, - LoopInfo &LI) { +void Scop::buildSchedule(Region *R, LoopStackTy &LoopStack, LoopInfo &LI) { Loop *OuterScopLoop = getLoopSurroundingRegion(getRegion(), LI); ReversePostOrderTraversal<Region *> RTraversal(R); @@ -4114,19 +4107,18 @@ void Scop::buildSchedule(Region *R, LoopStackTy &LoopStack, ScopDetection &SD, } LoopStack.push_back({L, nullptr, 0}); } - buildSchedule(RN, LoopStack, SD, LI); + buildSchedule(RN, LoopStack, LI); } return; } -void Scop::buildSchedule(RegionNode *RN, LoopStackTy &LoopStack, - ScopDetection &SD, LoopInfo &LI) { +void Scop::buildSchedule(RegionNode *RN, LoopStackTy &LoopStack, LoopInfo &LI) { if (RN->isSubRegion()) { auto *LocalRegion = RN->getNodeAs<Region>(); - if (!SD.isNonAffineSubRegion(LocalRegion, &getRegion())) { - buildSchedule(LocalRegion, LoopStack, SD, LI); + if (!isNonAffineSubRegion(LocalRegion)) { + buildSchedule(LocalRegion, LoopStack, LI); return; } } @@ -4270,10 +4262,7 @@ void ScopInfo::buildEscapingDependences(Instruction *Inst) { } } -bool ScopInfo::buildAccessMultiDimFixed( - MemAccInst Inst, Loop *L, Region *R, - const ScopDetection::BoxedLoopsSetTy *BoxedLoops, - const InvariantLoadsSetTy &ScopRIL) { +bool ScopInfo::buildAccessMultiDimFixed(MemAccInst Inst, Loop *L, Region *R) { Value *Val = Inst.getValueOperand(); Type *ElementType = Val->getType(); Value *Address = Inst.getPointerOperand(); @@ -4317,6 +4306,7 @@ bool ScopInfo::buildAccessMultiDimFixed( std::vector<const SCEV *> SizesSCEV; + const InvariantLoadsSetTy &ScopRIL = scop->getRequiredInvariantLoads(); for (auto *Subscript : Subscripts) { InvariantLoadsSetTy AccessILS; if (!isAffineExpr(R, L, Subscript, *SE, &AccessILS)) @@ -4339,10 +4329,7 @@ bool ScopInfo::buildAccessMultiDimFixed( return true; } -bool ScopInfo::buildAccessMultiDimParam( - MemAccInst Inst, Loop *L, Region *R, - const ScopDetection::BoxedLoopsSetTy *BoxedLoops, - const InvariantLoadsSetTy &ScopRIL, const MapInsnToMemAcc &InsnToMemAcc) { +bool ScopInfo::buildAccessMultiDimParam(MemAccInst Inst, Loop *L, Region *R) { if (!PollyDelinearize) return false; @@ -4360,6 +4347,7 @@ bool ScopInfo::buildAccessMultiDimParam( assert(BasePointer && "Could not find base pointer"); AccessFunction = SE->getMinusSCEV(AccessFunction, BasePointer); + auto &InsnToMemAcc = scop->getInsnToMemAccMap(); auto AccItr = InsnToMemAcc.find(Inst); if (AccItr == InsnToMemAcc.end()) return false; @@ -4384,10 +4372,7 @@ bool ScopInfo::buildAccessMultiDimParam( return true; } -bool ScopInfo::buildAccessMemIntrinsic( - MemAccInst Inst, Loop *L, Region *R, - const ScopDetection::BoxedLoopsSetTy *BoxedLoops, - const InvariantLoadsSetTy &ScopRIL) { +bool ScopInfo::buildAccessMemIntrinsic(MemAccInst Inst, Loop *L, Region *R) { auto *MemIntr = dyn_cast_or_null<MemIntrinsic>(Inst); if (MemIntr == nullptr) @@ -4398,6 +4383,7 @@ bool ScopInfo::buildAccessMemIntrinsic( // Check if the length val is actually affine or if we overapproximate it InvariantLoadsSetTy AccessILS; + const InvariantLoadsSetTy &ScopRIL = scop->getRequiredInvariantLoads(); bool LengthIsAffine = isAffineExpr(R, L, LengthVal, *SE, &AccessILS); for (LoadInst *LInst : AccessILS) if (!ScopRIL.count(LInst)) @@ -4449,10 +4435,7 @@ bool ScopInfo::buildAccessMemIntrinsic( return true; } -bool ScopInfo::buildAccessCallInst( - MemAccInst Inst, Loop *L, Region *R, - const ScopDetection::BoxedLoopsSetTy *BoxedLoops, - const InvariantLoadsSetTy &ScopRIL) { +bool ScopInfo::buildAccessCallInst(MemAccInst Inst, Loop *L, Region *R) { auto *CI = dyn_cast_or_null<CallInst>(Inst); if (CI == nullptr) @@ -4495,10 +4478,7 @@ bool ScopInfo::buildAccessCallInst( return true; } -void ScopInfo::buildAccessSingleDim( - MemAccInst Inst, Loop *L, Region *R, - const ScopDetection::BoxedLoopsSetTy *BoxedLoops, - const InvariantLoadsSetTy &ScopRIL) { +void ScopInfo::buildAccessSingleDim(MemAccInst Inst, Loop *L, Region *R) { Value *Address = Inst.getPointerOperand(); Value *Val = Inst.getValueOperand(); Type *ElementType = Val->getType(); @@ -4514,18 +4494,18 @@ void ScopInfo::buildAccessSingleDim( // Check if the access depends on a loop contained in a non-affine subregion. bool isVariantInNonAffineLoop = false; - if (BoxedLoops) { - SetVector<const Loop *> Loops; - findLoops(AccessFunction, Loops); - for (const Loop *L : Loops) - if (BoxedLoops->count(L)) - isVariantInNonAffineLoop = true; - } + SetVector<const Loop *> Loops; + auto &BoxedLoops = scop->getBoxedLoops(); + findLoops(AccessFunction, Loops); + for (const Loop *L : Loops) + if (BoxedLoops.count(L)) + isVariantInNonAffineLoop = true; InvariantLoadsSetTy AccessILS; bool IsAffine = !isVariantInNonAffineLoop && isAffineExpr(R, L, AccessFunction, *SE, &AccessILS); + const InvariantLoadsSetTy &ScopRIL = scop->getRequiredInvariantLoads(); for (LoadInst *LInst : AccessILS) if (!ScopRIL.count(LInst)) IsAffine = false; @@ -4537,45 +4517,41 @@ void ScopInfo::buildAccessSingleDim( {AccessFunction}, {}, Val); } -void ScopInfo::buildMemoryAccess( - MemAccInst Inst, Loop *L, Region *R, - const ScopDetection::BoxedLoopsSetTy *BoxedLoops, - const InvariantLoadsSetTy &ScopRIL, const MapInsnToMemAcc &InsnToMemAcc) { +void ScopInfo::buildMemoryAccess(MemAccInst Inst, Loop *L, Region *R) { - if (buildAccessMemIntrinsic(Inst, L, R, BoxedLoops, ScopRIL)) + if (buildAccessMemIntrinsic(Inst, L, R)) return; - if (buildAccessCallInst(Inst, L, R, BoxedLoops, ScopRIL)) + if (buildAccessCallInst(Inst, L, R)) return; - if (buildAccessMultiDimFixed(Inst, L, R, BoxedLoops, ScopRIL)) + if (buildAccessMultiDimFixed(Inst, L, R)) return; - if (buildAccessMultiDimParam(Inst, L, R, BoxedLoops, ScopRIL, InsnToMemAcc)) + if (buildAccessMultiDimParam(Inst, L, R)) return; - buildAccessSingleDim(Inst, L, R, BoxedLoops, ScopRIL); + buildAccessSingleDim(Inst, L, R); } -void ScopInfo::buildAccessFunctions(Region &R, Region &SR, - const MapInsnToMemAcc &InsnToMemAcc) { +void ScopInfo::buildAccessFunctions(Region &R, Region &SR) { - if (SD->isNonAffineSubRegion(&SR, &R)) { + if (scop->isNonAffineSubRegion(&SR)) { for (BasicBlock *BB : SR.blocks()) - buildAccessFunctions(R, *BB, InsnToMemAcc, &SR); + buildAccessFunctions(R, *BB, &SR); return; } for (auto I = SR.element_begin(), E = SR.element_end(); I != E; ++I) if (I->isSubRegion()) - buildAccessFunctions(R, *I->getNodeAs<Region>(), InsnToMemAcc); + buildAccessFunctions(R, *I->getNodeAs<Region>()); else - buildAccessFunctions(R, *I->getNodeAs<BasicBlock>(), InsnToMemAcc); + buildAccessFunctions(R, *I->getNodeAs<BasicBlock>()); } void ScopInfo::buildStmts(Region &R, Region &SR) { - if (SD->isNonAffineSubRegion(&SR, &R)) { + if (scop->isNonAffineSubRegion(&SR)) { scop->addScopStmt(nullptr, &SR); return; } @@ -4588,7 +4564,6 @@ void ScopInfo::buildStmts(Region &R, Region &SR) { } void ScopInfo::buildAccessFunctions(Region &R, BasicBlock &BB, - const MapInsnToMemAcc &InsnToMemAcc, Region *NonAffineSubRegion, bool IsExitBlock) { // We do not build access functions for error blocks, as they may contain @@ -4598,12 +4573,6 @@ void ScopInfo::buildAccessFunctions(Region &R, BasicBlock &BB, Loop *L = LI->getLoopFor(&BB); - // The set of loops contained in non-affine subregions that are part of R. - const ScopDetection::BoxedLoopsSetTy *BoxedLoops = SD->getBoxedLoops(&R); - - // The set of loads that are required to be invariant. - auto &ScopRIL = *SD->getRequiredInvariantLoads(&R); - for (Instruction &Inst : BB) { PHINode *PHI = dyn_cast<PHINode>(&Inst); if (PHI) @@ -4613,12 +4582,8 @@ void ScopInfo::buildAccessFunctions(Region &R, BasicBlock &BB, if (!PHI && IsExitBlock) break; - // TODO: At this point we only know that elements of ScopRIL have to be - // invariant and will be hoisted for the SCoP to be processed. Though, - // there might be other invariant accesses that will be hoisted and - // that would allow to make a non-affine access affine. if (auto MemInst = MemAccInst::dyn_cast(Inst)) - buildMemoryAccess(MemInst, L, &R, BoxedLoops, ScopRIL, InsnToMemAcc); + buildMemoryAccess(MemInst, L, &R); if (isIgnoredIntrinsic(&Inst)) continue; @@ -4727,8 +4692,8 @@ void ScopInfo::ensureValueRead(Value *V, BasicBlock *UserBB) { // Do not build scalar dependences for required invariant loads as we will // hoist them later on anyway or drop the SCoP if we cannot. - auto *ScopRIL = SD->getRequiredInvariantLoads(&ScopRegion); - if (ScopRIL->count(dyn_cast<LoadInst>(V))) + auto &ScopRIL = scop->getRequiredInvariantLoads(); + if (ScopRIL.count(dyn_cast<LoadInst>(V))) return; // Determine the ScopStmt containing the value's definition and use. There is @@ -4810,10 +4775,10 @@ void ScopInfo::addPHIReadAccess(PHINode *PHI) { } void ScopInfo::buildScop(Region &R, AssumptionCache &AC) { - scop.reset(new Scop(R, *SE, *LI)); + scop.reset(new Scop(R, *SE, *LI, *SD->getDetectionContext(&R))); buildStmts(R, R); - buildAccessFunctions(R, R, *SD->getInsnToMemAccMap(&R)); + buildAccessFunctions(R, R); // In case the region does not have an exiting block we will later (during // code generation) split the exit block. This will move potential PHI nodes @@ -4823,7 +4788,7 @@ void ScopInfo::buildScop(Region &R, AssumptionCache &AC) { // accesses. Note that we do not model anything in the exit block if we have // an exiting block in the region, as there will not be any splitting later. if (!R.getExitingBlock()) - buildAccessFunctions(R, *R.getExit(), *SD->getInsnToMemAccMap(&R), nullptr, + buildAccessFunctions(R, *R.getExit(), nullptr, /* IsExitBlock */ true); // Create memory accesses for global reads since all arrays are now known. @@ -4833,7 +4798,7 @@ void ScopInfo::buildScop(Region &R, AssumptionCache &AC) { addArrayAccess(MemAccInst(GlobalRead), MemoryAccess::READ, BP, BP->getType(), false, {AF}, {}, GlobalRead); - scop->init(*AA, AC, *SD, *DT, *LI); + scop->init(*AA, AC, *DT, *LI); } void ScopInfo::print(raw_ostream &OS, const Module *) const { |

