From ef3682a4fbfc3ff1a593adf95740ad8ab0d1d487 Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Wed, 14 May 2008 20:01:01 +0000 Subject: [PATCH] Simplify internalize pass. Add test case. Patch by Matthijs Kooijman! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51114 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Transforms/IPO.h | 13 ++++-- lib/Transforms/IPO/Internalize.cpp | 40 ++++++++++--------- .../Internalize/2008-05-09-AllButMain.ll | 27 +++++++++++++ .../2008-05-09-AllButMain.ll.apifile | 2 + test/Transforms/Internalize/dg.exp | 3 ++ 5 files changed, 62 insertions(+), 23 deletions(-) create mode 100644 test/Transforms/Internalize/2008-05-09-AllButMain.ll create mode 100644 test/Transforms/Internalize/2008-05-09-AllButMain.ll.apifile create mode 100644 test/Transforms/Internalize/dg.exp diff --git a/include/llvm/Transforms/IPO.h b/include/llvm/Transforms/IPO.h index 7d98dfe6045..71b3fa7b08c 100644 --- a/include/llvm/Transforms/IPO.h +++ b/include/llvm/Transforms/IPO.h @@ -102,12 +102,17 @@ Pass *createPruneEHPass(); //===----------------------------------------------------------------------===// /// createInternalizePass - This pass loops over all of the functions in the -/// input module, looking for a main function. If a list of symbols is -/// specified with the -internalize-public-api-* command line options, those -/// symbols are internalized. Otherwise if InternalizeEverything is set and -/// the main function is found, all other globals are marked as internal. +/// 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. /// ModulePass *createInternalizePass(bool InternalizeEverything); + +/// createInternalizePass - This pass loops over all of the functions in the +/// input module, internalizing all globals (functions and variables) not in the +/// given exportList. ModulePass *createInternalizePass(const std::vector &exportList); //===----------------------------------------------------------------------===// diff --git a/lib/Transforms/IPO/Internalize.cpp b/lib/Transforms/IPO/Internalize.cpp index 453b4945e73..e1c6fe971f2 100644 --- a/lib/Transforms/IPO/Internalize.cpp +++ b/lib/Transforms/IPO/Internalize.cpp @@ -43,7 +43,9 @@ APIList("internalize-public-api-list", cl::value_desc("list"), namespace { class VISIBILITY_HIDDEN InternalizePass : public ModulePass { std::set ExternalNames; - bool DontInternalize; + /// 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 InternalizeEverything = true); @@ -57,19 +59,16 @@ char InternalizePass::ID = 0; static RegisterPass X("internalize", "Internalize Global Symbols"); -InternalizePass::InternalizePass(bool InternalizeEverything) - : ModulePass((intptr_t)&ID), DontInternalize(false){ - if (!APIFile.empty()) // If a filename is specified, use it +InternalizePass::InternalizePass(bool AllButMain) + : ModulePass((intptr_t)&ID), AllButMain(AllButMain){ + if (!APIFile.empty()) // If a filename is specified, use it. LoadFile(APIFile.c_str()); - else if (!APIList.empty()) // Else, if a list is specified, use it. + if (!APIList.empty()) // If a list is specified, use it as well. ExternalNames.insert(APIList.begin(), APIList.end()); - else if (!InternalizeEverything) - // Finally, if we're allowed to, internalize all but main. - DontInternalize = true; } InternalizePass::InternalizePass(const std::vector&exportList) - : ModulePass((intptr_t)&ID), DontInternalize(false){ + : ModulePass((intptr_t)&ID), AllButMain(false){ for(std::vector::const_iterator itr = exportList.begin(); itr != exportList.end(); itr++) { ExternalNames.insert(*itr); @@ -80,8 +79,9 @@ void InternalizePass::LoadFile(const char *Filename) { // Load the APIFile... std::ifstream In(Filename); if (!In.good()) { - cerr << "WARNING: Internalize couldn't load file '" << Filename << "'!\n"; - return; // Do not internalize anything... + cerr << "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; @@ -92,13 +92,14 @@ void InternalizePass::LoadFile(const char *Filename) { } bool InternalizePass::runOnModule(Module &M) { - if (DontInternalize) 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. - // 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... @@ -109,7 +110,7 @@ bool InternalizePass::runOnModule(Module &M) { bool Changed = false; - // Found a main function, mark all functions not named main as internal. + // Mark all functions not in the api as internal. for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (!I->isDeclaration() && // Function must be defined here !I->hasInternalLinkage() && // Can't already have internal linkage @@ -134,7 +135,8 @@ bool InternalizePass::runOnModule(Module &M) { ExternalNames.insert("llvm.noinline"); ExternalNames.insert("llvm.global.annotations"); - // Mark all global variables with initializers as internal as well. + // 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) if (!I->isDeclaration() && !I->hasInternalLinkage() && diff --git a/test/Transforms/Internalize/2008-05-09-AllButMain.ll b/test/Transforms/Internalize/2008-05-09-AllButMain.ll new file mode 100644 index 00000000000..a7c7a1c6316 --- /dev/null +++ b/test/Transforms/Internalize/2008-05-09-AllButMain.ll @@ -0,0 +1,27 @@ +; No arguments means internalize all but main +; RUN: llvm-as < %s | opt -internalize | llvm-dis | grep internal | count 4 +; Internalize all but foo and j +; RUN: llvm-as < %s | opt -internalize -internalize-public-api-list foo -internalize-public-api-list j | llvm-dis | grep internal | count 3 +; Non existent files should be treated as if they were empty (so internalize all but main) +; RUN: llvm-as < %s | opt -internalize -internalize-public-api-file /nonexistent/file | llvm-dis | grep internal | count 4 +; RUN: llvm-as < %s | opt -internalize -internalize-public-api-list bar -internalize-public-api-list foo -internalize-public-api-file /nonexistent/file | llvm-dis | grep internal | count 3 +; -file and -list options should be merged, the .apifile contains foo and j +; RUN: llvm-as < %s | opt -internalize -internalize-public-api-list bar -internalize-public-api-file %s.apifile | llvm-dis | grep internal | count 2 + +@i = weak global i32 0 ; [#uses=0] +@j = weak global i32 0 ; [#uses=0] + +define void @main(...) { +entry: + ret void +} + +define void @foo(...) { +entry: + ret void +} + +define void @bar(...) { +entry: + ret void +} diff --git a/test/Transforms/Internalize/2008-05-09-AllButMain.ll.apifile b/test/Transforms/Internalize/2008-05-09-AllButMain.ll.apifile new file mode 100644 index 00000000000..f6c58b80c1c --- /dev/null +++ b/test/Transforms/Internalize/2008-05-09-AllButMain.ll.apifile @@ -0,0 +1,2 @@ +foo +j diff --git a/test/Transforms/Internalize/dg.exp b/test/Transforms/Internalize/dg.exp new file mode 100644 index 00000000000..879685ca879 --- /dev/null +++ b/test/Transforms/Internalize/dg.exp @@ -0,0 +1,3 @@ +load_lib llvm.exp + +RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] -- 2.34.1