From ef74443c9748e09ad9cc7e4b1a842db56bfb7e32 Mon Sep 17 00:00:00 2001 From: Johannes Doerfert Date: Mon, 23 May 2016 12:42:38 +0000 Subject: [PATCH] Duplicate part of the Region interface in the Scop class [NFC] This allows to use the SCoP directly for various queries, thus to hide the underlying region more often. llvm-svn: 270426 --- polly/include/polly/CodeGen/BlockGenerators.h | 2 +- polly/include/polly/ScopInfo.h | 18 +++++++++++++++ polly/lib/Analysis/ScopInfo.cpp | 22 ++++++++---------- polly/lib/CodeGen/BlockGenerators.cpp | 23 ++++++++----------- polly/lib/CodeGen/CodeGeneration.cpp | 4 ++-- polly/lib/CodeGen/IslNodeBuilder.cpp | 5 ++-- polly/lib/CodeGen/Utils.cpp | 12 +++++----- 7 files changed, 49 insertions(+), 37 deletions(-) diff --git a/polly/include/polly/CodeGen/BlockGenerators.h b/polly/include/polly/CodeGen/BlockGenerators.h index fc6c91adee94..1fb374d52787 100644 --- a/polly/include/polly/CodeGen/BlockGenerators.h +++ b/polly/include/polly/CodeGen/BlockGenerators.h @@ -426,7 +426,7 @@ protected: /// If a scalar value was used outside the SCoP we need to promote the value /// stored in the memory cell allocated for that scalar and combine it with /// the original value in the non-optimized SCoP. - void createScalarFinalization(Region &R); + void createScalarFinalization(Scop &S); /// @brief Try to synthesize a new value /// diff --git a/polly/include/polly/ScopInfo.h b/polly/include/polly/ScopInfo.h index 8135790d88b3..15b55b3d7439 100644 --- a/polly/include/polly/ScopInfo.h +++ b/polly/include/polly/ScopInfo.h @@ -1882,6 +1882,24 @@ public: /// @brief Check if @p I is contained in the SCoP. bool contains(const Instruction *I) const { return R.contains(I); } + /// @brief Return the unique exit block of the SCoP. + BasicBlock *getExit() const { return R.getExit(); } + + /// @brief Return the unique exiting block of the SCoP if any. + BasicBlock *getExitingBlock() const { return R.getExitingBlock(); } + + /// @brief Return the unique entry block of the SCoP. + BasicBlock *getEntry() const { return R.getEntry(); } + + /// @brief Return the unique entering block of the SCoP if any. + BasicBlock *getEnteringBlock() const { return R.getEnteringBlock(); } + + /// @brief Return true if @p BB is the exit block of the SCoP. + bool isExit(BasicBlock *BB) const { return getExit() == BB; } + + /// @brief Return a range of all basic blocks in the SCoP. + Region::block_range blocks() const { return R.blocks(); } + /// @brief Get the maximum depth of the loop. /// /// @return The maximum depth of the loop. diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp index bfc0f0f8a0f1..d2e6df3e452b 100644 --- a/polly/lib/Analysis/ScopInfo.cpp +++ b/polly/lib/Analysis/ScopInfo.cpp @@ -3074,24 +3074,24 @@ bool Scop::buildAliasGroups(AliasAnalysis &AA) { return true; } -/// @brief Get the smallest loop that contains @p R but is not in @p R. -static Loop *getLoopSurroundingRegion(Region &R, LoopInfo &LI) { +/// @brief Get the smallest loop that contains @p S but is not in @p S. +static Loop *getLoopSurroundingScop(Scop &S, LoopInfo &LI) { // Start with the smallest loop containing the entry and expand that // loop until it contains all blocks in the region. If there is a loop // containing all blocks in the region check if it is itself contained // and if so take the parent loop as it will be the smallest containing // the region but not contained by it. - Loop *L = LI.getLoopFor(R.getEntry()); + Loop *L = LI.getLoopFor(S.getEntry()); while (L) { bool AllContained = true; - for (auto *BB : R.blocks()) + for (auto *BB : S.blocks()) AllContained &= L->contains(BB); if (AllContained) break; L = L->getParentLoop(); } - return L ? (R.contains(L) ? L->getParentLoop() : L) : nullptr; + return L ? (S.contains(L) ? L->getParentLoop() : L) : nullptr; } Scop::Scop(Region &R, ScalarEvolution &ScalarEvolution, LoopInfo &LI, @@ -4086,7 +4086,7 @@ void Scop::addScopStmt(BasicBlock *BB, Region *R) { } void Scop::buildSchedule(LoopInfo &LI) { - Loop *L = getLoopSurroundingRegion(getRegion(), LI); + Loop *L = getLoopSurroundingScop(*this, LI); LoopStackTy LoopStack({LoopStackElementTy(L, nullptr, 0)}); buildSchedule(getRegion().getNode(), LoopStack, LI); assert(LoopStack.size() == 1 && LoopStack.back().L == L); @@ -4118,7 +4118,7 @@ void Scop::buildSchedule(LoopInfo &LI) { /// 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, LoopInfo &LI) { - Loop *OuterScopLoop = getLoopSurroundingRegion(getRegion(), LI); + Loop *OuterScopLoop = getLoopSurroundingScop(*this, LI); ReversePostOrderTraversal RTraversal(R); std::deque WorkList(RTraversal.begin(), RTraversal.end()); @@ -4284,8 +4284,6 @@ void ScopInfo::buildScalarDependences(Instruction *Inst) { } void ScopInfo::buildEscapingDependences(Instruction *Inst) { - Region *R = &scop->getRegion(); - // Check for uses of this instruction outside the scop. Because we do not // iterate over such instructions and therefore did not "ensure" the existence // of a write, we must determine such use here. @@ -4303,8 +4301,8 @@ void ScopInfo::buildEscapingDependences(Instruction *Inst) { // generation inserts new basic blocks before the PHI such that its incoming // blocks are not in the scop anymore. if (!scop->contains(UseParent) || - (isa(UI) && UserParent == R->getExit() && - R->getExitingBlock())) { + (isa(UI) && scop->isExit(UserParent) && + scop->hasSingleExitEdge())) { // At least one escaping use found. ensureValueWrite(Inst); break; @@ -4837,7 +4835,7 @@ void ScopInfo::buildScop(Region &R, AssumptionCache &AC) { // To handle these PHI nodes later we will now model their operands as scalar // 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()) + if (!scop->hasSingleExitEdge()) buildAccessFunctions(R, *R.getExit(), nullptr, /* IsExitBlock */ true); diff --git a/polly/lib/CodeGen/BlockGenerators.cpp b/polly/lib/CodeGen/BlockGenerators.cpp index 8df0e830b9a9..7b07f42c7a1c 100644 --- a/polly/lib/CodeGen/BlockGenerators.cpp +++ b/polly/lib/CodeGen/BlockGenerators.cpp @@ -449,17 +449,16 @@ void BlockGenerator::generateScalarStores(ScopStmt &Stmt, LoopToScevMapT <S, } void BlockGenerator::createScalarInitialization(Scop &S) { - Region &R = S.getRegion(); - BasicBlock *ExitBB = R.getExit(); + BasicBlock *ExitBB = S.getExit(); // The split block __just before__ the region and optimized region. - BasicBlock *SplitBB = R.getEnteringBlock(); + BasicBlock *SplitBB = S.getEnteringBlock(); BranchInst *SplitBBTerm = cast(SplitBB->getTerminator()); assert(SplitBBTerm->getNumSuccessors() == 2 && "Bad region entering block!"); // Get the start block of the __optimized__ region. BasicBlock *StartBB = SplitBBTerm->getSuccessor(0); - if (StartBB == R.getEntry()) + if (StartBB == S.getEntry()) StartBB = SplitBBTerm->getSuccessor(1); Builder.SetInsertPoint(StartBB->getTerminator()); @@ -508,11 +507,11 @@ void BlockGenerator::createScalarInitialization(Scop &S) { } } -void BlockGenerator::createScalarFinalization(Region &R) { +void BlockGenerator::createScalarFinalization(Scop &S) { // The exit block of the __unoptimized__ region. - BasicBlock *ExitBB = R.getExitingBlock(); + BasicBlock *ExitBB = S.getExitingBlock(); // The merge block __just after__ the region and the optimized region. - BasicBlock *MergeBB = R.getExit(); + BasicBlock *MergeBB = S.getExit(); // The exit block of the __optimized__ region. BasicBlock *OptExitBB = *(pred_begin(MergeBB)); @@ -583,10 +582,8 @@ void BlockGenerator::createExitPHINodeMerges(Scop &S) { if (S.hasSingleExitEdge()) return; - Region &R = S.getRegion(); - - auto *ExitBB = R.getExitingBlock(); - auto *MergeBB = R.getExit(); + auto *ExitBB = S.getExitingBlock(); + auto *MergeBB = S.getExit(); auto *AfterMergeBB = MergeBB->getSingleSuccessor(); BasicBlock *OptExitBB = *(pred_begin(MergeBB)); if (OptExitBB == ExitBB) @@ -633,7 +630,7 @@ void BlockGenerator::finalizeSCoP(Scop &S) { findOutsideUsers(S); createScalarInitialization(S); createExitPHINodeMerges(S); - createScalarFinalization(S.getRegion()); + createScalarFinalization(S); } VectorBlockGenerator::VectorBlockGenerator(BlockGenerator &BlockGen, @@ -1117,7 +1114,7 @@ void RegionGenerator::copyStmt(ScopStmt &Stmt, LoopToScevMapT <S, // the same Region object, such that we cannot change the exit of one and not // the other. BasicBlock *ExitBB = R->getExit(); - if (!S->hasSingleExitEdge() && ExitBB == S->getRegion().getExit()) + if (!S->hasSingleExitEdge() && ExitBB == S->getExit()) ExitBB = *(++pred_begin(ExitBB)); // Iterate over all blocks in the region in a breadth-first search. diff --git a/polly/lib/CodeGen/CodeGeneration.cpp b/polly/lib/CodeGen/CodeGeneration.cpp index 729de9bec580..4eb1122f2145 100644 --- a/polly/lib/CodeGen/CodeGeneration.cpp +++ b/polly/lib/CodeGen/CodeGeneration.cpp @@ -143,7 +143,7 @@ public: simplifyRegion(R, DT, LI, RI); assert(R->isSimple()); - BasicBlock *EnteringBB = S.getRegion().getEnteringBlock(); + BasicBlock *EnteringBB = S.getEnteringBlock(); assert(EnteringBB); PollyIRBuilder Builder = createPollyIRBuilder(EnteringBB, Annotator); @@ -182,7 +182,7 @@ public: assert(MergeBlock); markBlockUnreachable(*StartBlock, Builder); markBlockUnreachable(*ExitingBlock, Builder); - auto *ExitingBB = R->getExitingBlock(); + auto *ExitingBB = S.getExitingBlock(); assert(ExitingBB); DT->changeImmediateDominator(MergeBlock, ExitingBB); DT->eraseNode(ExitingBlock); diff --git a/polly/lib/CodeGen/IslNodeBuilder.cpp b/polly/lib/CodeGen/IslNodeBuilder.cpp index c98463164ab1..47722e33c54b 100644 --- a/polly/lib/CodeGen/IslNodeBuilder.cpp +++ b/polly/lib/CodeGen/IslNodeBuilder.cpp @@ -314,7 +314,7 @@ void IslNodeBuilder::getReferencesInSubtree(__isl_keep isl_ast_node *For, /// are considered local. This leaves only loops that are before the scop, but /// do not contain the scop itself. Loops.remove_if([this](const Loop *L) { - return S.contains(L) || L->contains(S.getRegion().getEntry()); + return S.contains(L) || L->contains(S.getEntry()); }); } @@ -1196,8 +1196,7 @@ void IslNodeBuilder::addParameters(__isl_take isl_set *Context) { // scop itself, but as the number of such scops may be arbitrarily large we do // not generate code for them here, but only at the point of code generation // where these values are needed. - Region &R = S.getRegion(); - Loop *L = LI.getLoopFor(R.getEntry()); + Loop *L = LI.getLoopFor(S.getEntry()); while (L != nullptr && S.contains(L)) L = L->getParentLoop(); diff --git a/polly/lib/CodeGen/Utils.cpp b/polly/lib/CodeGen/Utils.cpp index 743a0cceec0f..890d90192e2a 100644 --- a/polly/lib/CodeGen/Utils.cpp +++ b/polly/lib/CodeGen/Utils.cpp @@ -78,7 +78,7 @@ static BasicBlock *splitEdge(BasicBlock *Prev, BasicBlock *Succ, BasicBlock *polly::executeScopConditionally(Scop &S, Pass *P, Value *RTC) { Region &R = S.getRegion(); - PollyIRBuilder Builder(R.getEntry()); + PollyIRBuilder Builder(S.getEntry()); DominatorTree &DT = P->getAnalysis().getDomTree(); RegionInfo &RI = P->getAnalysis().getRegionInfo(); LoopInfo &LI = P->getAnalysis().getLoopInfo(); @@ -96,8 +96,8 @@ BasicBlock *polly::executeScopConditionally(Scop &S, Pass *P, Value *RTC) { // / \ // // Create a fork block. - BasicBlock *EnteringBB = R.getEnteringBlock(); - BasicBlock *EntryBB = R.getEntry(); + BasicBlock *EnteringBB = S.getEnteringBlock(); + BasicBlock *EntryBB = S.getEntry(); assert(EnteringBB && "Must be a simple region"); BasicBlock *SplitBlock = splitEdge(EnteringBB, EntryBB, ".split_new_and_old", &DT, &LI, &RI); @@ -116,8 +116,8 @@ BasicBlock *polly::executeScopConditionally(Scop &S, Pass *P, Value *RTC) { RI.setRegionFor(SplitBlock, PrevRegion); // Create a join block - BasicBlock *ExitingBB = R.getExitingBlock(); - BasicBlock *ExitBB = R.getExit(); + BasicBlock *ExitingBB = S.getExitingBlock(); + BasicBlock *ExitBB = S.getExit(); assert(ExitingBB && "Must be a simple region"); BasicBlock *MergeBlock = splitEdge(ExitingBB, ExitBB, ".merge_new_and_old", &DT, &LI, &RI); @@ -149,7 +149,7 @@ BasicBlock *polly::executeScopConditionally(Scop &S, Pass *P, Value *RTC) { BasicBlock::Create(F->getContext(), "polly.exiting", F); SplitBlock->getTerminator()->eraseFromParent(); Builder.SetInsertPoint(SplitBlock); - Builder.CreateCondBr(RTC, StartBlock, R.getEntry()); + Builder.CreateCondBr(RTC, StartBlock, S.getEntry()); if (Loop *L = LI.getLoopFor(SplitBlock)) { L->addBasicBlockToLoop(StartBlock, LI); L->addBasicBlockToLoop(ExitingBlock, LI);