mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
[CFG] Move reachable from entry checks into basic block variant
These checks are not specific to the instruction based variant of isPotentiallyReachable(), they are equally valid for the basic block based variant. Move them there, to make sure that switching between the instruction and basic block variants cannot introduce regressions.
This commit is contained in:
parent
a6e815c9bd
commit
fffdcaf76a
@ -77,9 +77,10 @@ bool isPotentiallyReachable(
|
|||||||
/// Determine whether there is a path from From to To within a single function.
|
/// Determine whether there is a path from From to To within a single function.
|
||||||
/// Returns false only if we can prove that once 'From' has been reached then
|
/// Returns false only if we can prove that once 'From' has been reached then
|
||||||
/// 'To' can not be executed. Conservatively returns true.
|
/// 'To' can not be executed. Conservatively returns true.
|
||||||
bool isPotentiallyReachable(const BasicBlock *From, const BasicBlock *To,
|
bool isPotentiallyReachable(
|
||||||
const DominatorTree *DT = nullptr,
|
const BasicBlock *From, const BasicBlock *To,
|
||||||
const LoopInfo *LI = nullptr);
|
const SmallPtrSetImpl<BasicBlock *> *ExclusionSet = nullptr,
|
||||||
|
const DominatorTree *DT = nullptr, const LoopInfo *LI = nullptr);
|
||||||
|
|
||||||
/// Determine whether there is at least one path from a block in
|
/// Determine whether there is at least one path from a block in
|
||||||
/// 'Worklist' to 'StopBB', returning true if uncertain.
|
/// 'Worklist' to 'StopBB', returning true if uncertain.
|
||||||
|
@ -208,16 +208,29 @@ bool llvm::isPotentiallyReachableFromMany(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool llvm::isPotentiallyReachable(const BasicBlock *A, const BasicBlock *B,
|
bool llvm::isPotentiallyReachable(
|
||||||
const DominatorTree *DT, const LoopInfo *LI) {
|
const BasicBlock *A, const BasicBlock *B,
|
||||||
|
const SmallPtrSetImpl<BasicBlock *> *ExclusionSet, const DominatorTree *DT,
|
||||||
|
const LoopInfo *LI) {
|
||||||
assert(A->getParent() == B->getParent() &&
|
assert(A->getParent() == B->getParent() &&
|
||||||
"This analysis is function-local!");
|
"This analysis is function-local!");
|
||||||
|
|
||||||
|
if (DT) {
|
||||||
|
if (DT->isReachableFromEntry(A) && !DT->isReachableFromEntry(B))
|
||||||
|
return false;
|
||||||
|
if (!ExclusionSet || ExclusionSet->empty()) {
|
||||||
|
if (A->isEntryBlock() && DT->isReachableFromEntry(B))
|
||||||
|
return true;
|
||||||
|
if (B->isEntryBlock() && DT->isReachableFromEntry(A))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SmallVector<BasicBlock*, 32> Worklist;
|
SmallVector<BasicBlock*, 32> Worklist;
|
||||||
Worklist.push_back(const_cast<BasicBlock*>(A));
|
Worklist.push_back(const_cast<BasicBlock*>(A));
|
||||||
|
|
||||||
return isPotentiallyReachableFromMany(Worklist, const_cast<BasicBlock *>(B),
|
return isPotentiallyReachableFromMany(Worklist, const_cast<BasicBlock *>(B),
|
||||||
nullptr, DT, LI);
|
ExclusionSet, DT, LI);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool llvm::isPotentiallyReachable(
|
bool llvm::isPotentiallyReachable(
|
||||||
@ -227,8 +240,6 @@ bool llvm::isPotentiallyReachable(
|
|||||||
assert(A->getParent()->getParent() == B->getParent()->getParent() &&
|
assert(A->getParent()->getParent() == B->getParent()->getParent() &&
|
||||||
"This analysis is function-local!");
|
"This analysis is function-local!");
|
||||||
|
|
||||||
SmallVector<BasicBlock*, 32> Worklist;
|
|
||||||
|
|
||||||
if (A->getParent() == B->getParent()) {
|
if (A->getParent() == B->getParent()) {
|
||||||
// The same block case is special because it's the only time we're looking
|
// The same block case is special because it's the only time we're looking
|
||||||
// within a single block to see which instruction comes first. Once we
|
// within a single block to see which instruction comes first. Once we
|
||||||
@ -252,30 +263,18 @@ bool llvm::isPotentiallyReachable(
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Otherwise, continue doing the normal per-BB CFG walk.
|
// Otherwise, continue doing the normal per-BB CFG walk.
|
||||||
|
SmallVector<BasicBlock*, 32> Worklist;
|
||||||
Worklist.append(succ_begin(BB), succ_end(BB));
|
Worklist.append(succ_begin(BB), succ_end(BB));
|
||||||
|
|
||||||
if (Worklist.empty()) {
|
if (Worklist.empty()) {
|
||||||
// We've proven that there's no path!
|
// We've proven that there's no path!
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Worklist.push_back(const_cast<BasicBlock*>(A->getParent()));
|
return isPotentiallyReachableFromMany(
|
||||||
|
Worklist, const_cast<BasicBlock *>(B->getParent()), ExclusionSet,
|
||||||
|
DT, LI);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DT) {
|
return isPotentiallyReachable(
|
||||||
if (DT->isReachableFromEntry(A->getParent()) &&
|
A->getParent(), B->getParent(), ExclusionSet, DT, LI);
|
||||||
!DT->isReachableFromEntry(B->getParent()))
|
|
||||||
return false;
|
|
||||||
if (!ExclusionSet || ExclusionSet->empty()) {
|
|
||||||
if (A->getParent()->isEntryBlock() &&
|
|
||||||
DT->isReachableFromEntry(B->getParent()))
|
|
||||||
return true;
|
|
||||||
if (B->getParent()->isEntryBlock() &&
|
|
||||||
DT->isReachableFromEntry(A->getParent()))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return isPotentiallyReachableFromMany(
|
|
||||||
Worklist, const_cast<BasicBlock *>(B->getParent()), ExclusionSet, DT, LI);
|
|
||||||
}
|
}
|
||||||
|
@ -1098,7 +1098,7 @@ Instruction *InstCombinerImpl::foldOpIntoPhi(Instruction &I, PHINode *PN) {
|
|||||||
// If the incoming non-constant value is in I's block, we will remove one
|
// If the incoming non-constant value is in I's block, we will remove one
|
||||||
// instruction, but insert another equivalent one, leading to infinite
|
// instruction, but insert another equivalent one, leading to infinite
|
||||||
// instcombine.
|
// instcombine.
|
||||||
if (isPotentiallyReachable(I.getParent(), NonConstBB, &DT, LI))
|
if (isPotentiallyReachable(I.getParent(), NonConstBB, nullptr, &DT, LI))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user