From 2082160f33b5b531aa0ffe2f5f8d2e48553da68f Mon Sep 17 00:00:00 2001 From: Philip Reames Date: Thu, 8 Mar 2018 21:25:30 +0000 Subject: [PATCH] [NFC] Factor out a helper function for checking if a block has a potential early implicit exit. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@327065 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Analysis/ValueTracking.h | 7 +++++++ lib/Analysis/ValueTracking.cpp | 9 +++++++++ lib/Transforms/Scalar/JumpThreading.cpp | 4 +--- lib/Transforms/Utils/LoopUtils.cpp | 11 ++++------- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h index b326873523c..ced95df94d4 100644 --- a/include/llvm/Analysis/ValueTracking.h +++ b/include/llvm/Analysis/ValueTracking.h @@ -423,6 +423,13 @@ class Value; /// though division by zero might cause undefined behavior. bool isGuaranteedToTransferExecutionToSuccessor(const Instruction *I); + /// Returns true if this block does not contain a potential implicit exit. + /// This is equivelent to saying that all instructions within the basic block + /// are guaranteed to transfer execution to their successor within the basic + /// block. This has the same assumptions w.r.t. undefined behavior as the + /// instruction variant of this function. + bool isGuaranteedToTransferExecutionToSuccessor(const BasicBlock *BB); + /// Return true if this function can prove that the instruction I /// is executed for every iteration of the loop L. /// diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp index c132586d874..2ec9cc11493 100644 --- a/lib/Analysis/ValueTracking.cpp +++ b/lib/Analysis/ValueTracking.cpp @@ -3968,6 +3968,15 @@ bool llvm::isGuaranteedToTransferExecutionToSuccessor(const Instruction *I) { return true; } +bool llvm::isGuaranteedToTransferExecutionToSuccessor(const BasicBlock *BB) { + // TODO: This is slightly consdervative for invoke instruction since exiting + // via an exception *is* normal control for them. + for (auto I = BB->begin(), E = BB->end(); I != E; ++I) + if (!isGuaranteedToTransferExecutionToSuccessor(&*I)) + return false; + return true; +} + bool llvm::isGuaranteedToExecuteForEveryIteration(const Instruction *I, const Loop *L) { // The loop header is guaranteed to be executed for every iteration. diff --git a/lib/Transforms/Scalar/JumpThreading.cpp b/lib/Transforms/Scalar/JumpThreading.cpp index 8759563267b..15cc709451b 100644 --- a/lib/Transforms/Scalar/JumpThreading.cpp +++ b/lib/Transforms/Scalar/JumpThreading.cpp @@ -1019,9 +1019,7 @@ bool JumpThreadingPass::ProcessBlock(BasicBlock *BB) { // Invalidate LVI information for BB if the LVI is not provably true for // all of BB. - if (any_of(*BB, [](Instruction &I) { - return !isGuaranteedToTransferExecutionToSuccessor(&I); - })) + if (!isGuaranteedToTransferExecutionToSuccessor(BB)) LVI->eraseBlock(BB); return true; } diff --git a/lib/Transforms/Utils/LoopUtils.cpp b/lib/Transforms/Utils/LoopUtils.cpp index c9c50cd7384..01f3b2dddd3 100644 --- a/lib/Transforms/Utils/LoopUtils.cpp +++ b/lib/Transforms/Utils/LoopUtils.cpp @@ -1491,10 +1491,8 @@ void llvm::computeLoopSafetyInfo(LoopSafetyInfo *SafetyInfo, Loop *CurLoop) { SafetyInfo->MayThrow = false; SafetyInfo->HeaderMayThrow = false; // Iterate over header and compute safety info. - for (BasicBlock::iterator I = Header->begin(), E = Header->end(); - (I != E) && !SafetyInfo->HeaderMayThrow; ++I) - SafetyInfo->HeaderMayThrow |= - !isGuaranteedToTransferExecutionToSuccessor(&*I); + SafetyInfo->HeaderMayThrow = + !isGuaranteedToTransferExecutionToSuccessor(Header); SafetyInfo->MayThrow = SafetyInfo->HeaderMayThrow; // Iterate over loop instructions and compute safety info. @@ -1505,9 +1503,8 @@ void llvm::computeLoopSafetyInfo(LoopSafetyInfo *SafetyInfo, Loop *CurLoop) { for (Loop::block_iterator BB = std::next(CurLoop->block_begin()), BBE = CurLoop->block_end(); (BB != BBE) && !SafetyInfo->MayThrow; ++BB) - for (BasicBlock::iterator I = (*BB)->begin(), E = (*BB)->end(); - (I != E) && !SafetyInfo->MayThrow; ++I) - SafetyInfo->MayThrow |= !isGuaranteedToTransferExecutionToSuccessor(&*I); + SafetyInfo->MayThrow |= + !isGuaranteedToTransferExecutionToSuccessor(*BB); // Compute funclet colors if we might sink/hoist in a function with a funclet // personality routine. -- 2.11.0