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
This commit is contained in:
Johannes Doerfert 2016-05-23 12:42:38 +00:00
parent e699370f3b
commit ef74443c97
7 changed files with 49 additions and 37 deletions

View File

@ -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
///

View File

@ -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.

View File

@ -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<Region *> RTraversal(R);
std::deque<RegionNode *> 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<PHINode>(UI) && UserParent == R->getExit() &&
R->getExitingBlock())) {
(isa<PHINode>(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);

View File

@ -449,17 +449,16 @@ void BlockGenerator::generateScalarStores(ScopStmt &Stmt, LoopToScevMapT &LTS,
}
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<BranchInst>(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 &LTS,
// 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.

View File

@ -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);

View File

@ -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();

View File

@ -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<DominatorTreeWrapperPass>().getDomTree();
RegionInfo &RI = P->getAnalysis<RegionInfoPass>().getRegionInfo();
LoopInfo &LI = P->getAnalysis<LoopInfoWrapperPass>().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);