mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-15 12:39:19 +00:00
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:
parent
e699370f3b
commit
ef74443c97
@ -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
|
||||
///
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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<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 <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.
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user