From fffdcaf76a4991c2684426706af8e59f00b18c2c Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 15 May 2021 13:05:18 +0200 Subject: [PATCH] [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. --- include/llvm/Analysis/CFG.h | 7 +-- lib/Analysis/CFG.cpp | 47 +++++++++---------- .../InstCombine/InstructionCombining.cpp | 2 +- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/include/llvm/Analysis/CFG.h b/include/llvm/Analysis/CFG.h index a36ceb484f1..f2c10c7e6ed 100644 --- a/include/llvm/Analysis/CFG.h +++ b/include/llvm/Analysis/CFG.h @@ -77,9 +77,10 @@ bool isPotentiallyReachable( /// 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 /// 'To' can not be executed. Conservatively returns true. -bool isPotentiallyReachable(const BasicBlock *From, const BasicBlock *To, - const DominatorTree *DT = nullptr, - const LoopInfo *LI = nullptr); +bool isPotentiallyReachable( + const BasicBlock *From, const BasicBlock *To, + const SmallPtrSetImpl *ExclusionSet = nullptr, + const DominatorTree *DT = nullptr, const LoopInfo *LI = nullptr); /// Determine whether there is at least one path from a block in /// 'Worklist' to 'StopBB', returning true if uncertain. diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index 650103fbc61..ec25ee161e2 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -208,16 +208,29 @@ bool llvm::isPotentiallyReachableFromMany( return false; } -bool llvm::isPotentiallyReachable(const BasicBlock *A, const BasicBlock *B, - const DominatorTree *DT, const LoopInfo *LI) { +bool llvm::isPotentiallyReachable( + const BasicBlock *A, const BasicBlock *B, + const SmallPtrSetImpl *ExclusionSet, const DominatorTree *DT, + const LoopInfo *LI) { assert(A->getParent() == B->getParent() && "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 Worklist; Worklist.push_back(const_cast(A)); return isPotentiallyReachableFromMany(Worklist, const_cast(B), - nullptr, DT, LI); + ExclusionSet, DT, LI); } bool llvm::isPotentiallyReachable( @@ -227,8 +240,6 @@ bool llvm::isPotentiallyReachable( assert(A->getParent()->getParent() == B->getParent()->getParent() && "This analysis is function-local!"); - SmallVector Worklist; - if (A->getParent() == B->getParent()) { // 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 @@ -252,30 +263,18 @@ bool llvm::isPotentiallyReachable( return false; // Otherwise, continue doing the normal per-BB CFG walk. + SmallVector Worklist; Worklist.append(succ_begin(BB), succ_end(BB)); - if (Worklist.empty()) { // We've proven that there's no path! return false; } - } else { - Worklist.push_back(const_cast(A->getParent())); + + return isPotentiallyReachableFromMany( + Worklist, const_cast(B->getParent()), ExclusionSet, + DT, LI); } - if (DT) { - if (DT->isReachableFromEntry(A->getParent()) && - !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(B->getParent()), ExclusionSet, DT, LI); + return isPotentiallyReachable( + A->getParent(), B->getParent(), ExclusionSet, DT, LI); } diff --git a/lib/Transforms/InstCombine/InstructionCombining.cpp b/lib/Transforms/InstCombine/InstructionCombining.cpp index fc10757dc1e..e5f01ae59f7 100644 --- a/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -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 // instruction, but insert another equivalent one, leading to infinite // instcombine. - if (isPotentiallyReachable(I.getParent(), NonConstBB, &DT, LI)) + if (isPotentiallyReachable(I.getParent(), NonConstBB, nullptr, &DT, LI)) return nullptr; }