From 4253bd8faf4df1ed9d0353704ca44d2afe3350ba Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 26 Oct 2012 18:47:48 +0000 Subject: [PATCH] Change the internalize pass to internalize all symbols when given an empty list of externals. This makes sense since a shared library with no symbols can still be useful if it has static constructors. llvm-svn: 166795 --- llvm/include/llvm/LinkAllPasses.h | 2 +- llvm/include/llvm/Transforms/IPO.h | 15 ++------- llvm/lib/Transforms/IPO/IPO.cpp | 5 ++- llvm/lib/Transforms/IPO/Internalize.cpp | 38 +++++----------------- llvm/lib/Transforms/IPO/PassManagerBuilder.cpp | 7 ++-- llvm/test/Other/link-opts.ll | 13 ++++++++ .../Internalize/2008-05-09-AllButMain.ll | 9 ++--- .../Internalize/2009-01-05-InternalizeAliases.ll | 2 +- 8 files changed, 41 insertions(+), 50 deletions(-) create mode 100644 llvm/test/Other/link-opts.ll diff --git a/llvm/include/llvm/LinkAllPasses.h b/llvm/include/llvm/LinkAllPasses.h index 8652acd..13693d0 100644 --- a/llvm/include/llvm/LinkAllPasses.h +++ b/llvm/include/llvm/LinkAllPasses.h @@ -82,7 +82,7 @@ namespace { (void) llvm::createIPSCCPPass(); (void) llvm::createIndVarSimplifyPass(); (void) llvm::createInstructionCombiningPass(); - (void) llvm::createInternalizePass(false); + (void) llvm::createInternalizePass(); (void) llvm::createLCSSAPass(); (void) llvm::createLICMPass(); (void) llvm::createLazyValueInfoPass(); diff --git a/llvm/include/llvm/Transforms/IPO.h b/llvm/include/llvm/Transforms/IPO.h index 08d3bbd..fc1cd59 100644 --- a/llvm/include/llvm/Transforms/IPO.h +++ b/llvm/include/llvm/Transforms/IPO.h @@ -104,23 +104,14 @@ Pass *createPruneEHPass(); //===----------------------------------------------------------------------===// /// createInternalizePass - This pass loops over all of the functions in the -/// input module, internalizing all globals (functions and variables) not part -/// of the api. If a list of symbols is specified with the -/// -internalize-public-api-* command line options, those symbols are not -/// internalized and all others are. Otherwise if AllButMain is set and the -/// main function is found, all other globals are marked as internal. If no api -/// is supplied and AllButMain is not set, or no main function is found, nothing -/// is internalized. -/// -ModulePass *createInternalizePass(bool AllButMain); - -/// createInternalizePass - This pass loops over all of the functions in the /// input module, internalizing all globals (functions and variables) not in the /// given exportList. /// /// Note that commandline options that are used with the above function are not -/// used now! Also, when exportList is empty, nothing is internalized. +/// used now! ModulePass *createInternalizePass(const std::vector &exportList); +/// createInternalizePass - Same as above, but with an empty exportList. +ModulePass *createInternalizePass(); //===----------------------------------------------------------------------===// /// createDeadArgEliminationPass - This pass removes arguments from functions diff --git a/llvm/lib/Transforms/IPO/IPO.cpp b/llvm/lib/Transforms/IPO/IPO.cpp index 86c76f0..5d563d8 100644 --- a/llvm/lib/Transforms/IPO/IPO.cpp +++ b/llvm/lib/Transforms/IPO/IPO.cpp @@ -95,7 +95,10 @@ void LLVMAddIPSCCPPass(LLVMPassManagerRef PM) { } void LLVMAddInternalizePass(LLVMPassManagerRef PM, unsigned AllButMain) { - unwrap(PM)->add(createInternalizePass(AllButMain != 0)); + std::vector Export; + if (AllButMain) + Export.push_back("main"); + unwrap(PM)->add(createInternalizePass(Export)); } void LLVMAddStripDeadPrototypesPass(LLVMPassManagerRef PM) { diff --git a/llvm/lib/Transforms/IPO/Internalize.cpp b/llvm/lib/Transforms/IPO/Internalize.cpp index fb5869e..aa629cc 100644 --- a/llvm/lib/Transforms/IPO/Internalize.cpp +++ b/llvm/lib/Transforms/IPO/Internalize.cpp @@ -7,9 +7,9 @@ // //===----------------------------------------------------------------------===// // -// This pass loops over all of the functions in the input module, looking for a -// main function. If a main function is found, all other functions and all -// global variables with initializers are marked as internal. +// This pass loops over all of the functions and variables in the input module. +// If the function or variable is not in the list of external names given to +// the pass it is marked as internal. // //===----------------------------------------------------------------------===// @@ -45,12 +45,9 @@ APIList("internalize-public-api-list", cl::value_desc("list"), namespace { class InternalizePass : public ModulePass { std::set ExternalNames; - /// If no api symbols were specified and a main function is defined, - /// assume the main function is the only API - bool AllButMain; public: static char ID; // Pass identification, replacement for typeid - explicit InternalizePass(bool AllButMain = true); + explicit InternalizePass(); explicit InternalizePass(const std::vector & exportList); void LoadFile(const char *Filename); virtual bool runOnModule(Module &M); @@ -66,8 +63,8 @@ char InternalizePass::ID = 0; INITIALIZE_PASS(InternalizePass, "internalize", "Internalize Global Symbols", false, false) -InternalizePass::InternalizePass(bool AllButMain) - : ModulePass(ID), AllButMain(AllButMain){ +InternalizePass::InternalizePass() + : ModulePass(ID) { initializeInternalizePassPass(*PassRegistry::getPassRegistry()); if (!APIFile.empty()) // If a filename is specified, use it. LoadFile(APIFile.c_str()); @@ -76,7 +73,7 @@ InternalizePass::InternalizePass(bool AllButMain) } InternalizePass::InternalizePass(const std::vector&exportList) - : ModulePass(ID), AllButMain(false){ + : ModulePass(ID){ initializeInternalizePassPass(*PassRegistry::getPassRegistry()); for(std::vector::const_iterator itr = exportList.begin(); itr != exportList.end(); itr++) { @@ -103,23 +100,6 @@ void InternalizePass::LoadFile(const char *Filename) { bool InternalizePass::runOnModule(Module &M) { CallGraph *CG = getAnalysisIfAvailable(); CallGraphNode *ExternalNode = CG ? CG->getExternalCallingNode() : 0; - - if (ExternalNames.empty()) { - // Return if we're not in 'all but main' mode and have no external api - if (!AllButMain) - return false; - // If no list or file of symbols was specified, check to see if there is a - // "main" symbol defined in the module. If so, use it, otherwise do not - // internalize the module, it must be a library or something. - // - Function *MainFunc = M.getFunction("main"); - if (MainFunc == 0 || MainFunc->isDeclaration()) - return false; // No main found, must be a library... - - // Preserve main, internalize all else. - ExternalNames.insert(MainFunc->getName()); - } - bool Changed = false; // Never internalize functions which code-gen might insert. @@ -189,8 +169,8 @@ bool InternalizePass::runOnModule(Module &M) { return Changed; } -ModulePass *llvm::createInternalizePass(bool AllButMain) { - return new InternalizePass(AllButMain); +ModulePass *llvm::createInternalizePass() { + return new InternalizePass(); } ModulePass *llvm::createInternalizePass(const std::vector &el) { diff --git a/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp b/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp index 1d8f1e5..e3bc94e 100644 --- a/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp +++ b/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp @@ -245,8 +245,11 @@ void PassManagerBuilder::populateLTOPassManager(PassManagerBase &PM, // Now that composite has been compiled, scan through the module, looking // for a main function. If main is defined, mark all other functions // internal. - if (Internalize) - PM.add(createInternalizePass(true)); + if (Internalize) { + std::vector E; + E.push_back("main"); + PM.add(createInternalizePass(E)); + } // Propagate constants at call sites into the functions they call. This // opens opportunities for globalopt (and inlining) by substituting function diff --git a/llvm/test/Other/link-opts.ll b/llvm/test/Other/link-opts.ll new file mode 100644 index 0000000..8e58ac8 --- /dev/null +++ b/llvm/test/Other/link-opts.ll @@ -0,0 +1,13 @@ +;RUN: opt -S -std-link-opts < %s | FileCheck %s +; Simple test to check that -std-link-opts keeps only the main function. + +; CHECK-NOT: define +; CHECK: define void @main +; CHECK-NOT: define +define void @main() { + ret void +} + +define void @foo() { + ret void +} diff --git a/llvm/test/Transforms/Internalize/2008-05-09-AllButMain.ll b/llvm/test/Transforms/Internalize/2008-05-09-AllButMain.ll index 1101f99..c07abb0 100644 --- a/llvm/test/Transforms/Internalize/2008-05-09-AllButMain.ll +++ b/llvm/test/Transforms/Internalize/2008-05-09-AllButMain.ll @@ -1,10 +1,11 @@ -; No arguments means internalize all but main +; No arguments means internalize everything ; RUN: opt < %s -internalize -S | FileCheck --check-prefix=NOARGS %s ; Internalize all but foo and j ; RUN: opt < %s -internalize -internalize-public-api-list foo -internalize-public-api-list j -S | FileCheck --check-prefix=LIST %s -; Non existent files should be treated as if they were empty (so internalize all but main) +; Non existent files should be treated as if they were empty (so internalize +; everything) ; RUN: opt < %s -internalize -internalize-public-api-file /nonexistent/file 2> /dev/null -S | FileCheck --check-prefix=EMPTYFILE %s ; RUN: opt < %s -S -internalize -internalize-public-api-list bar -internalize-public-api-list foo -internalize-public-api-file /nonexistent/file 2> /dev/null | FileCheck --check-prefix=LIST2 %s @@ -26,9 +27,9 @@ ; MERGE: @j = global @j = global i32 0 -; NOARGS: define void @main +; NOARGS: define internal void @main ; LIST: define internal void @main -; EMPTYFILE: define void @main +; EMPTYFILE: define internal void @main ; LIST2: define internal void @main ; MERGE: define internal void @main define void @main() { diff --git a/llvm/test/Transforms/Internalize/2009-01-05-InternalizeAliases.ll b/llvm/test/Transforms/Internalize/2009-01-05-InternalizeAliases.ll index 7b18a04..47cf3f0 100644 --- a/llvm/test/Transforms/Internalize/2009-01-05-InternalizeAliases.ll +++ b/llvm/test/Transforms/Internalize/2009-01-05-InternalizeAliases.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -internalize -S | grep internal | count 3 +; RUN: opt < %s -internalize -internalize-public-api-list main -S | grep internal | count 3 @A = global i32 0 @B = alias i32* @A -- 2.7.4