Index: llvm/trunk/include/llvm/CodeGen/UnreachableBlockElim.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/UnreachableBlockElim.h +++ llvm/trunk/include/llvm/CodeGen/UnreachableBlockElim.h @@ -0,0 +1,37 @@ +//===-- UnreachableBlockElim.h - Remove unreachable blocks for codegen --===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass is an extremely simple version of the SimplifyCFG pass. Its sole +// job is to delete LLVM basic blocks that are not reachable from the entry +// node. To do this, it performs a simple depth first traversal of the CFG, +// then deletes any unvisited nodes. +// +// Note that this pass is really a hack. In particular, the instruction +// selectors for various targets should just not generate code for unreachable +// blocks. Until LLVM has a more systematic way of defining instruction +// selectors, however, we cannot really expect them to handle additional +// complexity. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_CODEGEN_UNREACHABLEBLOCKELIM_H +#define LLVM_LIB_CODEGEN_UNREACHABLEBLOCKELIM_H + +#include "llvm/IR/PassManager.h" + +namespace llvm { + +class UnreachableBlockElimPass + : public PassInfoMixin { +public: + PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); +}; +} // end namespace llvm + +#endif // LLVM_LIB_CODEGEN_UNREACHABLEBLOCKELIM_H Index: llvm/trunk/include/llvm/InitializePasses.h =================================================================== --- llvm/trunk/include/llvm/InitializePasses.h +++ llvm/trunk/include/llvm/InitializePasses.h @@ -326,7 +326,7 @@ void initializeTypeBasedAAWrapperPassPass(PassRegistry&); void initializeUnifyFunctionExitNodesPass(PassRegistry&); void initializeUnpackMachineBundlesPass(PassRegistry&); -void initializeUnreachableBlockElimPass(PassRegistry&); +void initializeUnreachableBlockElimLegacyPassPass(PassRegistry&); void initializeUnreachableMachineBlockElimPass(PassRegistry&); void initializeVerifierLegacyPassPass(PassRegistry&); void initializeVirtRegMapPass(PassRegistry&); Index: llvm/trunk/lib/CodeGen/CodeGen.cpp =================================================================== --- llvm/trunk/lib/CodeGen/CodeGen.cpp +++ llvm/trunk/lib/CodeGen/CodeGen.cpp @@ -81,7 +81,7 @@ initializeTargetPassConfigPass(Registry); initializeTwoAddressInstructionPassPass(Registry); initializeUnpackMachineBundlesPass(Registry); - initializeUnreachableBlockElimPass(Registry); + initializeUnreachableBlockElimLegacyPassPass(Registry); initializeUnreachableMachineBlockElimPass(Registry); initializeVirtRegMapPass(Registry); initializeVirtRegRewriterPass(Registry); Index: llvm/trunk/lib/CodeGen/UnreachableBlockElim.cpp =================================================================== --- llvm/trunk/lib/CodeGen/UnreachableBlockElim.cpp +++ llvm/trunk/lib/CodeGen/UnreachableBlockElim.cpp @@ -20,7 +20,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/CodeGen/Passes.h" +#include "llvm/CodeGen/UnreachableBlockElim.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/CodeGen/MachineDominators.h" @@ -28,6 +28,7 @@ #include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/Passes.h" #include "llvm/IR/CFG.h" #include "llvm/IR/Constant.h" #include "llvm/IR/Dominators.h" @@ -38,29 +39,7 @@ #include "llvm/Target/TargetInstrInfo.h" using namespace llvm; -namespace { - class UnreachableBlockElim : public FunctionPass { - bool runOnFunction(Function &F) override; - public: - static char ID; // Pass identification, replacement for typeid - UnreachableBlockElim() : FunctionPass(ID) { - initializeUnreachableBlockElimPass(*PassRegistry::getPassRegistry()); - } - - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addPreserved(); - } - }; -} -char UnreachableBlockElim::ID = 0; -INITIALIZE_PASS(UnreachableBlockElim, "unreachableblockelim", - "Remove unreachable blocks from the CFG", false, false) - -FunctionPass *llvm::createUnreachableBlockEliminationPass() { - return new UnreachableBlockElim(); -} - -bool UnreachableBlockElim::runOnFunction(Function &F) { +static bool eliminateUnreachableBlock(Function &F) { SmallPtrSet Reachable; // Mark all reachable blocks. @@ -91,6 +70,41 @@ return !DeadBlocks.empty(); } +namespace { +class UnreachableBlockElimLegacyPass : public FunctionPass { + bool runOnFunction(Function &F) override { + return eliminateUnreachableBlock(F); + } + +public: + static char ID; // Pass identification, replacement for typeid + UnreachableBlockElimLegacyPass() : FunctionPass(ID) { + initializeUnreachableBlockElimLegacyPassPass( + *PassRegistry::getPassRegistry()); + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addPreserved(); + } +}; +} +char UnreachableBlockElimLegacyPass::ID = 0; +INITIALIZE_PASS(UnreachableBlockElimLegacyPass, "unreachableblockelim", + "Remove unreachable blocks from the CFG", false, false) + +FunctionPass *llvm::createUnreachableBlockEliminationPass() { + return new UnreachableBlockElimLegacyPass(); +} + +PreservedAnalyses UnreachableBlockElimPass::run(Function &F, + FunctionAnalysisManager &AM) { + bool Changed = eliminateUnreachableBlock(F); + if (!Changed) + return PreservedAnalyses::all(); + PreservedAnalyses PA; + PA.preserve(); + return PA; +} namespace { class UnreachableMachineBlockElim : public MachineFunctionPass { Index: llvm/trunk/lib/Passes/PassBuilder.cpp =================================================================== --- llvm/trunk/lib/Passes/PassBuilder.cpp +++ llvm/trunk/lib/Passes/PassBuilder.cpp @@ -47,6 +47,7 @@ #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Analysis/TypeBasedAliasAnalysis.h" #include "llvm/CodeGen/PreISelIntrinsicLowering.h" +#include "llvm/CodeGen/UnreachableBlockElim.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/PassManager.h" Index: llvm/trunk/lib/Passes/PassRegistry.def =================================================================== --- llvm/trunk/lib/Passes/PassRegistry.def +++ llvm/trunk/lib/Passes/PassRegistry.def @@ -165,6 +165,7 @@ FUNCTION_PASS("slp-vectorizer", SLPVectorizerPass()) FUNCTION_PASS("sroa", SROA()) FUNCTION_PASS("tailcallelim", TailCallElimPass()) +FUNCTION_PASS("unreachableblockelim", UnreachableBlockElimPass()) FUNCTION_PASS("verify", VerifierPass()) FUNCTION_PASS("verify", DominatorTreeVerifierPass()) FUNCTION_PASS("verify", MemorySSAVerifierPass()) Index: llvm/trunk/test/CodeGen/X86/unreachableblockelim.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/unreachableblockelim.ll +++ llvm/trunk/test/CodeGen/X86/unreachableblockelim.ll @@ -0,0 +1,21 @@ +; RUN: opt -S < %s -unreachableblockelim | FileCheck %s +; RUN: opt -S < %s -passes=unreachableblockelim | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +declare void @abort() + +; CHECK-LABEL: @foo( +; CHECK-NOT return: +define void @foo(i32* %p) { +entry: + %p.addr = alloca i32*, align 8 + call void @abort() + unreachable + +return: ; No predecessors! + store i32* %p, i32** %p.addr, align 8 + ret void +} + Index: llvm/trunk/tools/llc/llc.cpp =================================================================== --- llvm/trunk/tools/llc/llc.cpp +++ llvm/trunk/tools/llc/llc.cpp @@ -241,7 +241,7 @@ initializeCodeGen(*Registry); initializeLoopStrengthReducePass(*Registry); initializeLowerIntrinsicsPass(*Registry); - initializeUnreachableBlockElimPass(*Registry); + initializeUnreachableBlockElimLegacyPassPass(*Registry); // Register the target printer for --version. cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion); Index: llvm/trunk/tools/opt/opt.cpp =================================================================== --- llvm/trunk/tools/opt/opt.cpp +++ llvm/trunk/tools/opt/opt.cpp @@ -364,6 +364,7 @@ initializePreISelIntrinsicLoweringLegacyPassPass(Registry); initializeGlobalMergePass(Registry); initializeInterleavedAccessPass(Registry); + initializeUnreachableBlockElimLegacyPassPass(Registry); #ifdef LINK_POLLY_INTO_TOOLS polly::initializePollyPasses(Registry);