From 8fbafc9f4e92e9e05174770e94b7190deb2a1b2e Mon Sep 17 00:00:00 2001 From: Mehdi Amini Date: Wed, 13 Apr 2016 05:25:08 +0000 Subject: [PATCH] Refactor the InternalizePass into a helper class, and expose it through a public free function (NFC) There is really no reason to require to instanciate a pass manager to internalize. From: Mehdi Amini git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@266167 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Transforms/IPO/Internalize.h | 27 ++++ lib/LTO/LTOInternalize.cpp | 8 +- lib/Transforms/IPO/Internalize.cpp | 155 +++++++++++++--------- test/LTO/X86/disable-verify.ll | 3 +- 4 files changed, 119 insertions(+), 74 deletions(-) create mode 100644 include/llvm/Transforms/IPO/Internalize.h diff --git a/include/llvm/Transforms/IPO/Internalize.h b/include/llvm/Transforms/IPO/Internalize.h new file mode 100644 index 00000000000..b51584ae37c --- /dev/null +++ b/include/llvm/Transforms/IPO/Internalize.h @@ -0,0 +1,27 @@ +//====- llvm/Transforms/IPO/Internalize.h - Internalization API -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_INTERNALIZE_H +#define LLVM_INTERNALIZE_H + +#include "llvm/IR/GlobalValue.h" + +#include + +namespace llvm { +class Module; +class CallGraph; + +bool internalizeModule( + Module &TheModule, + const std::function &MustPreserveGV, + CallGraph *CG = nullptr); +} + +#endif // LLVM_INTERNALIZE_H diff --git a/lib/LTO/LTOInternalize.cpp b/lib/LTO/LTOInternalize.cpp index c3c95e7b1e9..f4a4f6bc67c 100644 --- a/lib/LTO/LTOInternalize.cpp +++ b/lib/LTO/LTOInternalize.cpp @@ -18,7 +18,7 @@ #include "llvm/IR/Mangler.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetSubtargetInfo.h" -#include "llvm/Transforms/IPO.h" +#include "llvm/Transforms/IPO/Internalize.h" using namespace llvm; @@ -170,9 +170,5 @@ void llvm::LTOInternalize( LLVMCompilerUsed->setSection("llvm.metadata"); } - legacy::PassManager passes; - passes.add(createInternalizePass(MustPreserveSymbols)); - - // apply scope restrictions - passes.run(TheModule); + internalizeModule(TheModule, MustPreserveSymbols); } diff --git a/lib/Transforms/IPO/Internalize.cpp b/lib/Transforms/IPO/Internalize.cpp index f2b848b98ff..eac4c7b0ad5 100644 --- a/lib/Transforms/IPO/Internalize.cpp +++ b/lib/Transforms/IPO/Internalize.cpp @@ -19,6 +19,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Transforms/IPO/Internalize.h" #include "llvm/Transforms/IPO.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" @@ -37,25 +38,25 @@ using namespace llvm; #define DEBUG_TYPE "internalize" -STATISTIC(NumAliases , "Number of aliases internalized"); +STATISTIC(NumAliases, "Number of aliases internalized"); STATISTIC(NumFunctions, "Number of functions internalized"); -STATISTIC(NumGlobals , "Number of global vars internalized"); +STATISTIC(NumGlobals, "Number of global vars internalized"); // APIFile - A file which contains a list of symbols that should not be marked // external. static cl::opt -APIFile("internalize-public-api-file", cl::value_desc("filename"), - cl::desc("A file containing list of symbol names to preserve")); + APIFile("internalize-public-api-file", cl::value_desc("filename"), + cl::desc("A file containing list of symbol names to preserve")); // APIList - A list of symbols that should not be marked internal. static cl::list -APIList("internalize-public-api-list", cl::value_desc("list"), - cl::desc("A list of symbol names to preserve"), - cl::CommaSeparated); + APIList("internalize-public-api-list", cl::value_desc("list"), + cl::desc("A list of symbol names to preserve"), cl::CommaSeparated); namespace { + // Helper to load an API list to preserve from file and expose it as a functor -// to the Internalize Pass +// for internalization. class PreserveAPIList { public: PreserveAPIList() { @@ -70,31 +71,63 @@ public: private: // Contains the set of symbols loaded from file - StringSet<> ExternalNames; + StringSet<> ExternalNames; - void LoadFile(StringRef Filename) { - // Load the APIFile... - std::ifstream In(Filename.data()); - if (!In.good()) { - errs() << "WARNING: Internalize couldn't load file '" << Filename - << "'! Continuing as if it's empty.\n"; - return; // Just continue as if the file were empty - } - while (In) { - std::string Symbol; - In >> Symbol; - if (!Symbol.empty()) - ExternalNames.insert(Symbol); - } + void LoadFile(StringRef Filename) { + // Load the APIFile... + std::ifstream In(Filename.data()); + if (!In.good()) { + errs() << "WARNING: Internalize couldn't load file '" << Filename + << "'! Continuing as if it's empty.\n"; + return; // Just continue as if the file were empty } + while (In) { + std::string Symbol; + In >> Symbol; + if (!Symbol.empty()) + ExternalNames.insert(Symbol); + } + } }; -} -namespace { +// Internalization exposed as a pass class InternalizePass : public ModulePass { - // Client supply callback to control wheter a symbol must be preserved. + // Client supplied callback to control wheter a symbol must be preserved. std::function MustPreserveGV; +public: + static char ID; // Pass identification, replacement for typeid + + InternalizePass() : ModulePass(ID), MustPreserveGV(PreserveAPIList()) {} + + InternalizePass(std::function MustPreserveGV) + : ModulePass(ID), MustPreserveGV(std::move(MustPreserveGV)) { + initializeInternalizePassPass(*PassRegistry::getPassRegistry()); + } + + bool runOnModule(Module &M) override { + CallGraphWrapperPass *CGPass = + getAnalysisIfAvailable(); + CallGraph *CG = CGPass ? &CGPass->getCallGraph() : nullptr; + return internalizeModule(M, MustPreserveGV, CG); + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesCFG(); + AU.addPreserved(); + } +}; +} // end anonymous namespace + +char InternalizePass::ID = 0; +INITIALIZE_PASS(InternalizePass, "internalize", "Internalize Global Symbols", + false, false) + +// Helper class to perform internalization. +class Internalizer { + // Client supplied callback to control wheter a symbol must be preserved. + const std::function &MustPreserveGV; + // Set of symbols private to the compiler that this pass should not touch. StringSet<> AlwaysPreserved; @@ -123,40 +156,26 @@ class InternalizePass : public ModulePass { return MustPreserveGV(GV); } - bool maybeInternalize(GlobalValue &GV, - const std::set &ExternalComdats); - void checkComdatVisibility(GlobalValue &GV, - std::set &ExternalComdats); + bool maybeInternalize(GlobalValue &GV, + const std::set &ExternalComdats); + void checkComdatVisibility(GlobalValue &GV, + std::set &ExternalComdats); - public: - static char ID; // Pass identification, replacement for typeid - explicit InternalizePass(); - InternalizePass(std::function MustPreserveGV); - bool runOnModule(Module &M) override; +public: + Internalizer(const std::function &MustPreserveGV) + : MustPreserveGV(MustPreserveGV) {} - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.setPreservesCFG(); - AU.addPreserved(); - } - }; -} // end anonymous namespace - -char InternalizePass::ID = 0; -INITIALIZE_PASS(InternalizePass, "internalize", - "Internalize Global Symbols", false, false) - -InternalizePass::InternalizePass() - : ModulePass(ID), MustPreserveGV(PreserveAPIList()) {} - -InternalizePass::InternalizePass( - std::function MustPreserveGV) - : ModulePass(ID), MustPreserveGV(std::move(MustPreserveGV)) { - initializeInternalizePassPass(*PassRegistry::getPassRegistry()); -} + /// Run the internalizer on \p TheModule, returns true if any changes was + /// made. + /// + /// If the CallGraph \p CG is supplied, it will be updated when + /// internalizing a function (by removing any edge from the "external node") + bool internalizeModule(Module &TheModule, CallGraph *CG = nullptr); +}; // Internalize GV if it is possible to do so, i.e. it is not externally visible // and is not a member of an externally visible comdat. -bool InternalizePass::maybeInternalize( +bool Internalizer::maybeInternalize( GlobalValue &GV, const std::set &ExternalComdats) { if (Comdat *C = GV.getComdat()) { if (ExternalComdats.count(C)) @@ -183,7 +202,7 @@ bool InternalizePass::maybeInternalize( // If GV is part of a comdat and is externally visible, keep track of its // comdat so that we don't internalize any of its members. -void InternalizePass::checkComdatVisibility( +void Internalizer::checkComdatVisibility( GlobalValue &GV, std::set &ExternalComdats) { Comdat *C = GV.getComdat(); if (!C) @@ -193,9 +212,7 @@ void InternalizePass::checkComdatVisibility( ExternalComdats.insert(C); } -bool InternalizePass::runOnModule(Module &M) { - CallGraphWrapperPass *CGPass = getAnalysisIfAvailable(); - CallGraph *CG = CGPass ? &CGPass->getCallGraph() : nullptr; +bool Internalizer::internalizeModule(Module &M, CallGraph *CG) { CallGraphNode *ExternalNode = CG ? CG->getExternalCallingNode() : nullptr; SmallPtrSet Used; @@ -258,8 +275,8 @@ bool InternalizePass::runOnModule(Module &M) { // Mark all global variables with initializers that are not in the api as // internal as well. - for (Module::global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) { + for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; + ++I) { if (!maybeInternalize(*I, ExternalComdats)) continue; @@ -268,8 +285,8 @@ bool InternalizePass::runOnModule(Module &M) { } // Mark all aliases that are not in the api as internal as well. - for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); - I != E; ++I) { + for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; + ++I) { if (!maybeInternalize(*I, ExternalComdats)) continue; @@ -286,12 +303,18 @@ bool InternalizePass::runOnModule(Module &M) { return true; } -ModulePass *llvm::createInternalizePass() { - return new InternalizePass(PreserveAPIList()); +/// Public API below + +bool llvm::internalizeModule( + Module &TheModule, + const std::function &MustPreserveGV, + CallGraph *CG) { + return Internalizer(MustPreserveGV).internalizeModule(TheModule, CG); } +ModulePass *llvm::createInternalizePass() { return new InternalizePass(); } + ModulePass *llvm::createInternalizePass( std::function MustPreserveGV) { return new InternalizePass(std::move(MustPreserveGV)); } - diff --git a/test/LTO/X86/disable-verify.ll b/test/LTO/X86/disable-verify.ll index d8b20d4e361..e66ebac05ce 100644 --- a/test/LTO/X86/disable-verify.ll +++ b/test/LTO/X86/disable-verify.ll @@ -6,10 +6,9 @@ target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.10.0" ; -disable-verify should disable verification from the optimization pipeline. -; CHECK: Pass Arguments: -internalize +; CHECK: Pass Arguments: ; CHECK-NOT: -verify -; VERIFY: Pass Arguments: -internalize ; VERIFY: Pass Arguments: {{.*}} -verify {{.*}} -verify define void @f() {