1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00

[IPO/GlobalDCE] Port to the new pass manager.

Differential Revision:  http://reviews.llvm.org/D19782

llvm-svn: 268425
This commit is contained in:
Davide Italiano 2016-05-03 19:39:15 +00:00
parent 2316521069
commit 84e14ec542
8 changed files with 81 additions and 32 deletions

View File

@ -142,7 +142,7 @@ void initializeForceFunctionAttrsLegacyPassPass(PassRegistry&);
void initializeGCMachineCodeAnalysisPass(PassRegistry&);
void initializeGCModuleInfoPass(PassRegistry&);
void initializeGVNLegacyPassPass(PassRegistry&);
void initializeGlobalDCEPass(PassRegistry&);
void initializeGlobalDCELegacyPassPass(PassRegistry&);
void initializeGlobalOptLegacyPassPass(PassRegistry&);
void initializeGlobalsAAWrapperPassPass(PassRegistry&);
void initializeIPCPPass(PassRegistry&);

View File

@ -0,0 +1,46 @@
//===-- GlobalDCE.h - DCE unreachable internal functions ------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This transform is designed to eliminate unreachable internal globals from the
// program. It uses an aggressive algorithm, searching out globals that are
// known to be alive. After it finds all of the globals which are needed, it
// deletes whatever is left over. This allows it to delete recursive chunks of
// the program which are unreachable.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TRANSFORMS_IPO_GLOBALDCE_H
#define LLVM_TRANSFORMS_IPO_GLOBALDCE_H
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
#include <unordered_map>
namespace llvm {
/// Pass to remove unused function declarations.
class GlobalDCEPass : public PassInfoMixin<GlobalDCEPass> {
public:
PreservedAnalyses run(Module &M);
private:
SmallPtrSet<GlobalValue*, 32> AliveGlobals;
SmallPtrSet<Constant *, 8> SeenConstants;
std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
/// Mark the specific global value as needed, and
/// recursively mark anything that it uses as also needed.
void GlobalIsNeeded(GlobalValue *GV);
void MarkUsedGlobalsAsNeeded(Constant *C);
bool RemoveUnusedGlobalValue(GlobalValue &GV);
};
}
#endif // LLVM_TRANSFORMS_IPO_GLOBALDCE_H

View File

@ -104,7 +104,7 @@ void LTOCodeGenerator::initializeLTOPasses() {
initializeInstructionCombiningPassPass(R);
initializeSimpleInlinerPass(R);
initializePruneEHPass(R);
initializeGlobalDCEPass(R);
initializeGlobalDCELegacyPassPass(R);
initializeArgPromotionPass(R);
initializeJumpThreadingPass(R);
initializeSROALegacyPassPass(R);

View File

@ -47,6 +47,7 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/IPO/ForceFunctionAttrs.h"
#include "llvm/Transforms/IPO/FunctionAttrs.h"
#include "llvm/Transforms/IPO/GlobalDCE.h"
#include "llvm/Transforms/IPO/GlobalOpt.h"
#include "llvm/Transforms/IPO/InferFunctionAttrs.h"
#include "llvm/Transforms/IPO/Internalize.h"

View File

@ -36,6 +36,7 @@ MODULE_ALIAS_ANALYSIS("globals-aa", GlobalsAA())
#define MODULE_PASS(NAME, CREATE_PASS)
#endif
MODULE_PASS("forceattrs", ForceFunctionAttrsPass())
MODULE_PASS("globaldce", GlobalDCEPass())
MODULE_PASS("globalopt", GlobalOptPass())
MODULE_PASS("inferattrs", InferFunctionAttrsPass())
MODULE_PASS("internalize", InternalizePass())

View File

@ -15,6 +15,7 @@
//
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/IPO/GlobalDCE.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/IR/Constants.h"
@ -34,31 +35,38 @@ STATISTIC(NumFunctions, "Number of functions removed");
STATISTIC(NumVariables, "Number of global variables removed");
namespace {
struct GlobalDCE : public ModulePass {
class GlobalDCELegacyPass : public ModulePass {
public:
static char ID; // Pass identification, replacement for typeid
GlobalDCE() : ModulePass(ID) {
initializeGlobalDCEPass(*PassRegistry::getPassRegistry());
GlobalDCELegacyPass() : ModulePass(ID) {
initializeGlobalDCELegacyPassPass(*PassRegistry::getPassRegistry());
}
// run - Do the GlobalDCE pass on the specified module, optionally updating
// the specified callgraph to reflect the changes.
//
bool runOnModule(Module &M) override;
bool runOnModule(Module &M) override {
if (skipModule(M))
return false;
auto PA = Impl.run(M);
return !PA.areAllPreserved();
}
private:
SmallPtrSet<GlobalValue*, 32> AliveGlobals;
SmallPtrSet<Constant *, 8> SeenConstants;
std::unordered_multimap<Comdat *, GlobalValue *> ComdatMembers;
/// GlobalIsNeeded - mark the specific global value as needed, and
/// recursively mark anything that it uses as also needed.
void GlobalIsNeeded(GlobalValue *GV);
void MarkUsedGlobalsAsNeeded(Constant *C);
bool RemoveUnusedGlobalValue(GlobalValue &GV);
GlobalDCEPass Impl;
};
}
char GlobalDCELegacyPass::ID = 0;
INITIALIZE_PASS(GlobalDCELegacyPass, "globaldce",
"Dead Global Elimination", false, false)
// Public interface to the GlobalDCEPass.
ModulePass *llvm::createGlobalDCEPass() {
return new GlobalDCELegacyPass();
}
/// Returns true if F contains only a single "ret" instruction.
static bool isEmptyFunction(Function *F) {
BasicBlock &Entry = F->getEntryBlock();
@ -68,16 +76,7 @@ static bool isEmptyFunction(Function *F) {
return RI.getReturnValue() == nullptr;
}
char GlobalDCE::ID = 0;
INITIALIZE_PASS(GlobalDCE, "globaldce",
"Dead Global Elimination", false, false)
ModulePass *llvm::createGlobalDCEPass() { return new GlobalDCE(); }
bool GlobalDCE::runOnModule(Module &M) {
if (skipModule(M))
return false;
PreservedAnalyses GlobalDCEPass::run(Module &M) {
bool Changed = false;
// Remove empty functions from the global ctors list.
@ -188,12 +187,14 @@ bool GlobalDCE::runOnModule(Module &M) {
SeenConstants.clear();
ComdatMembers.clear();
return Changed;
if (Changed)
return PreservedAnalyses::none();
return PreservedAnalyses::all();
}
/// GlobalIsNeeded - the specific global value as needed, and
/// recursively mark anything that it uses as also needed.
void GlobalDCE::GlobalIsNeeded(GlobalValue *G) {
void GlobalDCEPass::GlobalIsNeeded(GlobalValue *G) {
// If the global is already in the set, no need to reprocess it.
if (!AliveGlobals.insert(G).second)
return;
@ -231,7 +232,7 @@ void GlobalDCE::GlobalIsNeeded(GlobalValue *G) {
}
}
void GlobalDCE::MarkUsedGlobalsAsNeeded(Constant *C) {
void GlobalDCEPass::MarkUsedGlobalsAsNeeded(Constant *C) {
if (GlobalValue *GV = dyn_cast<GlobalValue>(C))
return GlobalIsNeeded(GV);
@ -251,7 +252,7 @@ void GlobalDCE::MarkUsedGlobalsAsNeeded(Constant *C) {
// so, nuke it. This will reduce the reference count on the global value, which
// might make it deader.
//
bool GlobalDCE::RemoveUnusedGlobalValue(GlobalValue &GV) {
bool GlobalDCEPass::RemoveUnusedGlobalValue(GlobalValue &GV) {
if (GV.use_empty())
return false;
GV.removeDeadConstantUsers();

View File

@ -29,7 +29,7 @@ void llvm::initializeIPO(PassRegistry &Registry) {
initializeDAEPass(Registry);
initializeDAHPass(Registry);
initializeForceFunctionAttrsLegacyPassPass(Registry);
initializeGlobalDCEPass(Registry);
initializeGlobalDCELegacyPassPass(Registry);
initializeGlobalOptLegacyPassPass(Registry);
initializeIPCPPass(Registry);
initializeAlwaysInlinerPass(Registry);

View File

@ -1,4 +1,4 @@
; RUN: opt < %s -globaldce -S | FileCheck %s
; RUN: opt < %s -passes=globaldce -S | FileCheck %s
; CHECK-NOT: global
@X = external global i32