mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[PM] Port UnreachableBlockElim to the new Pass Manager
Differential Revision: http://reviews.llvm.org/D22124 llvm-svn: 274824
This commit is contained in:
parent
545f49f4b4
commit
3d33c761b3
37
include/llvm/CodeGen/UnreachableBlockElim.h
Normal file
37
include/llvm/CodeGen/UnreachableBlockElim.h
Normal file
@ -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<UnreachableBlockElimPass> {
|
||||||
|
public:
|
||||||
|
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||||
|
};
|
||||||
|
} // end namespace llvm
|
||||||
|
|
||||||
|
#endif // LLVM_LIB_CODEGEN_UNREACHABLEBLOCKELIM_H
|
@ -326,7 +326,7 @@ void initializeTwoAddressInstructionPassPass(PassRegistry&);
|
|||||||
void initializeTypeBasedAAWrapperPassPass(PassRegistry&);
|
void initializeTypeBasedAAWrapperPassPass(PassRegistry&);
|
||||||
void initializeUnifyFunctionExitNodesPass(PassRegistry&);
|
void initializeUnifyFunctionExitNodesPass(PassRegistry&);
|
||||||
void initializeUnpackMachineBundlesPass(PassRegistry&);
|
void initializeUnpackMachineBundlesPass(PassRegistry&);
|
||||||
void initializeUnreachableBlockElimPass(PassRegistry&);
|
void initializeUnreachableBlockElimLegacyPassPass(PassRegistry&);
|
||||||
void initializeUnreachableMachineBlockElimPass(PassRegistry&);
|
void initializeUnreachableMachineBlockElimPass(PassRegistry&);
|
||||||
void initializeVerifierLegacyPassPass(PassRegistry&);
|
void initializeVerifierLegacyPassPass(PassRegistry&);
|
||||||
void initializeVirtRegMapPass(PassRegistry&);
|
void initializeVirtRegMapPass(PassRegistry&);
|
||||||
|
@ -81,7 +81,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
|
|||||||
initializeTargetPassConfigPass(Registry);
|
initializeTargetPassConfigPass(Registry);
|
||||||
initializeTwoAddressInstructionPassPass(Registry);
|
initializeTwoAddressInstructionPassPass(Registry);
|
||||||
initializeUnpackMachineBundlesPass(Registry);
|
initializeUnpackMachineBundlesPass(Registry);
|
||||||
initializeUnreachableBlockElimPass(Registry);
|
initializeUnreachableBlockElimLegacyPassPass(Registry);
|
||||||
initializeUnreachableMachineBlockElimPass(Registry);
|
initializeUnreachableMachineBlockElimPass(Registry);
|
||||||
initializeVirtRegMapPass(Registry);
|
initializeVirtRegMapPass(Registry);
|
||||||
initializeVirtRegRewriterPass(Registry);
|
initializeVirtRegRewriterPass(Registry);
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/CodeGen/Passes.h"
|
#include "llvm/CodeGen/UnreachableBlockElim.h"
|
||||||
#include "llvm/ADT/DepthFirstIterator.h"
|
#include "llvm/ADT/DepthFirstIterator.h"
|
||||||
#include "llvm/ADT/SmallPtrSet.h"
|
#include "llvm/ADT/SmallPtrSet.h"
|
||||||
#include "llvm/CodeGen/MachineDominators.h"
|
#include "llvm/CodeGen/MachineDominators.h"
|
||||||
@ -28,6 +28,7 @@
|
|||||||
#include "llvm/CodeGen/MachineLoopInfo.h"
|
#include "llvm/CodeGen/MachineLoopInfo.h"
|
||||||
#include "llvm/CodeGen/MachineModuleInfo.h"
|
#include "llvm/CodeGen/MachineModuleInfo.h"
|
||||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||||
|
#include "llvm/CodeGen/Passes.h"
|
||||||
#include "llvm/IR/CFG.h"
|
#include "llvm/IR/CFG.h"
|
||||||
#include "llvm/IR/Constant.h"
|
#include "llvm/IR/Constant.h"
|
||||||
#include "llvm/IR/Dominators.h"
|
#include "llvm/IR/Dominators.h"
|
||||||
@ -38,29 +39,7 @@
|
|||||||
#include "llvm/Target/TargetInstrInfo.h"
|
#include "llvm/Target/TargetInstrInfo.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
namespace {
|
static bool eliminateUnreachableBlock(Function &F) {
|
||||||
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<DominatorTreeWrapperPass>();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
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) {
|
|
||||||
SmallPtrSet<BasicBlock*, 8> Reachable;
|
SmallPtrSet<BasicBlock*, 8> Reachable;
|
||||||
|
|
||||||
// Mark all reachable blocks.
|
// Mark all reachable blocks.
|
||||||
@ -91,6 +70,41 @@ bool UnreachableBlockElim::runOnFunction(Function &F) {
|
|||||||
return !DeadBlocks.empty();
|
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<DominatorTreeWrapperPass>();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
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<DominatorTreeAnalysis>();
|
||||||
|
return PA;
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class UnreachableMachineBlockElim : public MachineFunctionPass {
|
class UnreachableMachineBlockElim : public MachineFunctionPass {
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||||
#include "llvm/Analysis/TypeBasedAliasAnalysis.h"
|
#include "llvm/Analysis/TypeBasedAliasAnalysis.h"
|
||||||
#include "llvm/CodeGen/PreISelIntrinsicLowering.h"
|
#include "llvm/CodeGen/PreISelIntrinsicLowering.h"
|
||||||
|
#include "llvm/CodeGen/UnreachableBlockElim.h"
|
||||||
#include "llvm/IR/Dominators.h"
|
#include "llvm/IR/Dominators.h"
|
||||||
#include "llvm/IR/IRPrintingPasses.h"
|
#include "llvm/IR/IRPrintingPasses.h"
|
||||||
#include "llvm/IR/PassManager.h"
|
#include "llvm/IR/PassManager.h"
|
||||||
|
@ -165,6 +165,7 @@ FUNCTION_PASS("sink", SinkingPass())
|
|||||||
FUNCTION_PASS("slp-vectorizer", SLPVectorizerPass())
|
FUNCTION_PASS("slp-vectorizer", SLPVectorizerPass())
|
||||||
FUNCTION_PASS("sroa", SROA())
|
FUNCTION_PASS("sroa", SROA())
|
||||||
FUNCTION_PASS("tailcallelim", TailCallElimPass())
|
FUNCTION_PASS("tailcallelim", TailCallElimPass())
|
||||||
|
FUNCTION_PASS("unreachableblockelim", UnreachableBlockElimPass())
|
||||||
FUNCTION_PASS("verify", VerifierPass())
|
FUNCTION_PASS("verify", VerifierPass())
|
||||||
FUNCTION_PASS("verify<domtree>", DominatorTreeVerifierPass())
|
FUNCTION_PASS("verify<domtree>", DominatorTreeVerifierPass())
|
||||||
FUNCTION_PASS("verify<memoryssa>", MemorySSAVerifierPass())
|
FUNCTION_PASS("verify<memoryssa>", MemorySSAVerifierPass())
|
||||||
|
21
test/CodeGen/X86/unreachableblockelim.ll
Normal file
21
test/CodeGen/X86/unreachableblockelim.ll
Normal file
@ -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
|
||||||
|
}
|
||||||
|
|
@ -241,7 +241,7 @@ int main(int argc, char **argv) {
|
|||||||
initializeCodeGen(*Registry);
|
initializeCodeGen(*Registry);
|
||||||
initializeLoopStrengthReducePass(*Registry);
|
initializeLoopStrengthReducePass(*Registry);
|
||||||
initializeLowerIntrinsicsPass(*Registry);
|
initializeLowerIntrinsicsPass(*Registry);
|
||||||
initializeUnreachableBlockElimPass(*Registry);
|
initializeUnreachableBlockElimLegacyPassPass(*Registry);
|
||||||
|
|
||||||
// Register the target printer for --version.
|
// Register the target printer for --version.
|
||||||
cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
|
cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
|
||||||
|
@ -364,6 +364,7 @@ int main(int argc, char **argv) {
|
|||||||
initializePreISelIntrinsicLoweringLegacyPassPass(Registry);
|
initializePreISelIntrinsicLoweringLegacyPassPass(Registry);
|
||||||
initializeGlobalMergePass(Registry);
|
initializeGlobalMergePass(Registry);
|
||||||
initializeInterleavedAccessPass(Registry);
|
initializeInterleavedAccessPass(Registry);
|
||||||
|
initializeUnreachableBlockElimLegacyPassPass(Registry);
|
||||||
|
|
||||||
#ifdef LINK_POLLY_INTO_TOOLS
|
#ifdef LINK_POLLY_INTO_TOOLS
|
||||||
polly::initializePollyPasses(Registry);
|
polly::initializePollyPasses(Registry);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user