[llvm] r355846 - [Utils] Extract EliminateUnreachableBlocks (NFC)
Brian Gesiak via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 11 10:51:58 PDT 2019
Author: modocache
Date: Mon Mar 11 10:51:57 2019
New Revision: 355846
URL: http://llvm.org/viewvc/llvm-project?rev=355846&view=rev
Log:
[Utils] Extract EliminateUnreachableBlocks (NFC)
Summary:
Extract the functionality of eliminating unreachable basic blocks
within a function, previously encapsulated within the
-unreachableblockelim pass, and make it available as a function within
BlockUtils.h. No functional change intended other than making the logic
reusable.
Exposing this logic makes it easier to implement
https://reviews.llvm.org/D59068, which fixes coroutines bug
https://bugs.llvm.org/show_bug.cgi?id=40979.
Reviewers: mkazantsev, wmi, davidxl, silvas, davide
Reviewed By: davide
Subscribers: llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D59069
Modified:
llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h
llvm/trunk/lib/CodeGen/UnreachableBlockElim.cpp
llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp
llvm/trunk/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp
Modified: llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h?rev=355846&r1=355845&r2=355846&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h Mon Mar 11 10:51:57 2019
@@ -62,6 +62,12 @@ void DeleteDeadBlocks(ArrayRef <BasicBlo
DomTreeUpdater *DTU = nullptr,
bool KeepOneInputPHIs = false);
+/// Delete all basic blocks from \p F that are not reachable from its entry
+/// node. If \p KeepOneInputPHIs is true, one-input Phis in successors of
+/// blocks being deleted will be preserved.
+bool EliminateUnreachableBlocks(Function &F, DomTreeUpdater *DTU = nullptr,
+ bool KeepOneInputPHIs = false);
+
/// We know that BB has one predecessor. If there are any single-entry PHI nodes
/// in it, fold them away. This handles the case when all entries to the PHI
/// nodes in a block are guaranteed equal, such as when the block has exactly
Modified: llvm/trunk/lib/CodeGen/UnreachableBlockElim.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/UnreachableBlockElim.cpp?rev=355846&r1=355845&r2=355846&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/UnreachableBlockElim.cpp (original)
+++ llvm/trunk/lib/CodeGen/UnreachableBlockElim.cpp Mon Mar 11 10:51:57 2019
@@ -40,31 +40,10 @@
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
using namespace llvm;
-static bool eliminateUnreachableBlock(Function &F) {
- df_iterator_default_set<BasicBlock*> Reachable;
-
- // Mark all reachable blocks.
- for (BasicBlock *BB : depth_first_ext(&F, Reachable))
- (void)BB/* Mark all reachable blocks */;
-
- // Collect all dead blocks.
- std::vector<BasicBlock*> DeadBlocks;
- for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
- if (!Reachable.count(&*I)) {
- BasicBlock *BB = &*I;
- DeadBlocks.push_back(BB);
- }
-
- // Delete the dead blocks.
- DeleteDeadBlocks(DeadBlocks);
-
- return !DeadBlocks.empty();
-}
-
namespace {
class UnreachableBlockElimLegacyPass : public FunctionPass {
bool runOnFunction(Function &F) override {
- return eliminateUnreachableBlock(F);
+ return llvm::EliminateUnreachableBlocks(F);
}
public:
@@ -89,7 +68,7 @@ FunctionPass *llvm::createUnreachableBlo
PreservedAnalyses UnreachableBlockElimPass::run(Function &F,
FunctionAnalysisManager &AM) {
- bool Changed = eliminateUnreachableBlock(F);
+ bool Changed = llvm::EliminateUnreachableBlocks(F);
if (!Changed)
return PreservedAnalyses::all();
PreservedAnalyses PA;
Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=355846&r1=355845&r2=355846&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Mon Mar 11 10:51:57 2019
@@ -110,6 +110,28 @@ void llvm::DeleteDeadBlocks(ArrayRef <Ba
BB->eraseFromParent();
}
+bool llvm::EliminateUnreachableBlocks(Function &F, DomTreeUpdater *DTU,
+ bool KeepOneInputPHIs) {
+ df_iterator_default_set<BasicBlock*> Reachable;
+
+ // Mark all reachable blocks.
+ for (BasicBlock *BB : depth_first_ext(&F, Reachable))
+ (void)BB/* Mark all reachable blocks */;
+
+ // Collect all dead blocks.
+ std::vector<BasicBlock*> DeadBlocks;
+ for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
+ if (!Reachable.count(&*I)) {
+ BasicBlock *BB = &*I;
+ DeadBlocks.push_back(BB);
+ }
+
+ // Delete the dead blocks.
+ DeleteDeadBlocks(DeadBlocks, DTU, KeepOneInputPHIs);
+
+ return !DeadBlocks.empty();
+}
+
void llvm::FoldSingleEntryPHINodes(BasicBlock *BB,
MemoryDependenceResults *MemDep) {
if (!isa<PHINode>(BB->begin())) return;
Modified: llvm/trunk/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp?rev=355846&r1=355845&r2=355846&view=diff
==============================================================================
--- llvm/trunk/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp (original)
+++ llvm/trunk/unittests/Transforms/Utils/BasicBlockUtilsTest.cpp Mon Mar 11 10:51:57 2019
@@ -25,6 +25,64 @@ static std::unique_ptr<Module> parseIR(L
return Mod;
}
+TEST(BasicBlockUtils, EliminateUnreachableBlocks) {
+ LLVMContext C;
+
+ std::unique_ptr<Module> M = parseIR(
+ C,
+ "define i32 @has_unreachable(i1 %cond) {\n"
+ "entry:\n"
+ " br i1 %cond, label %bb0, label %bb1\n"
+ "bb0:\n"
+ " br label %bb1\n"
+ "bb1:\n"
+ " %phi = phi i32 [ 0, %entry ], [ 1, %bb0 ]"
+ " ret i32 %phi\n"
+ "bb2:\n"
+ " ret i32 42\n"
+ "}\n"
+ "\n"
+ );
+
+ auto *F = M->getFunction("has_unreachable");
+ DominatorTree DT(*F);
+ DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
+
+ EXPECT_EQ(F->size(), (size_t)4);
+ bool Result = EliminateUnreachableBlocks(*F, &DTU);
+ EXPECT_TRUE(Result);
+ EXPECT_EQ(F->size(), (size_t)3);
+ EXPECT_TRUE(DT.verify());
+}
+
+TEST(BasicBlockUtils, NoUnreachableBlocksToEliminate) {
+ LLVMContext C;
+
+ std::unique_ptr<Module> M = parseIR(
+ C,
+ "define i32 @no_unreachable(i1 %cond) {\n"
+ "entry:\n"
+ " br i1 %cond, label %bb0, label %bb1\n"
+ "bb0:\n"
+ " br label %bb1\n"
+ "bb1:\n"
+ " %phi = phi i32 [ 0, %entry ], [ 1, %bb0 ]"
+ " ret i32 %phi\n"
+ "}\n"
+ "\n"
+ );
+
+ auto *F = M->getFunction("no_unreachable");
+ DominatorTree DT(*F);
+ DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
+
+ EXPECT_EQ(F->size(), (size_t)3);
+ bool Result = EliminateUnreachableBlocks(*F, &DTU);
+ EXPECT_FALSE(Result);
+ EXPECT_EQ(F->size(), (size_t)3);
+ EXPECT_TRUE(DT.verify());
+}
+
TEST(BasicBlockUtils, SplitBlockPredecessors) {
LLVMContext C;
More information about the llvm-commits
mailing list