1
0
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:
Wei Mi 2016-07-08 03:32:49 +00:00
parent 545f49f4b4
commit 3d33c761b3
9 changed files with 102 additions and 27 deletions

View 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

View File

@ -326,7 +326,7 @@ void initializeTwoAddressInstructionPassPass(PassRegistry&);
void initializeTypeBasedAAWrapperPassPass(PassRegistry&);
void initializeUnifyFunctionExitNodesPass(PassRegistry&);
void initializeUnpackMachineBundlesPass(PassRegistry&);
void initializeUnreachableBlockElimPass(PassRegistry&);
void initializeUnreachableBlockElimLegacyPassPass(PassRegistry&);
void initializeUnreachableMachineBlockElimPass(PassRegistry&);
void initializeVerifierLegacyPassPass(PassRegistry&);
void initializeVirtRegMapPass(PassRegistry&);

View File

@ -81,7 +81,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
initializeTargetPassConfigPass(Registry);
initializeTwoAddressInstructionPassPass(Registry);
initializeUnpackMachineBundlesPass(Registry);
initializeUnreachableBlockElimPass(Registry);
initializeUnreachableBlockElimLegacyPassPass(Registry);
initializeUnreachableMachineBlockElimPass(Registry);
initializeVirtRegMapPass(Registry);
initializeVirtRegRewriterPass(Registry);

View File

@ -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<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) {
static bool eliminateUnreachableBlock(Function &F) {
SmallPtrSet<BasicBlock*, 8> Reachable;
// Mark all reachable blocks.
@ -91,6 +70,41 @@ bool UnreachableBlockElim::runOnFunction(Function &F) {
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 {
class UnreachableMachineBlockElim : public MachineFunctionPass {

View File

@ -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"

View File

@ -165,6 +165,7 @@ FUNCTION_PASS("sink", SinkingPass())
FUNCTION_PASS("slp-vectorizer", SLPVectorizerPass())
FUNCTION_PASS("sroa", SROA())
FUNCTION_PASS("tailcallelim", TailCallElimPass())
FUNCTION_PASS("unreachableblockelim", UnreachableBlockElimPass())
FUNCTION_PASS("verify", VerifierPass())
FUNCTION_PASS("verify<domtree>", DominatorTreeVerifierPass())
FUNCTION_PASS("verify<memoryssa>", MemorySSAVerifierPass())

View 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
}

View File

@ -241,7 +241,7 @@ int main(int argc, char **argv) {
initializeCodeGen(*Registry);
initializeLoopStrengthReducePass(*Registry);
initializeLowerIntrinsicsPass(*Registry);
initializeUnreachableBlockElimPass(*Registry);
initializeUnreachableBlockElimLegacyPassPass(*Registry);
// Register the target printer for --version.
cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);

View File

@ -364,6 +364,7 @@ int main(int argc, char **argv) {
initializePreISelIntrinsicLoweringLegacyPassPass(Registry);
initializeGlobalMergePass(Registry);
initializeInterleavedAccessPass(Registry);
initializeUnreachableBlockElimLegacyPassPass(Registry);
#ifdef LINK_POLLY_INTO_TOOLS
polly::initializePollyPasses(Registry);