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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166795 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rafael Espindola 2012-10-26 18:47:48 +00:00
parent 276c43f022
commit e5551ed9ce
8 changed files with 41 additions and 50 deletions

View File

@ -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();

View File

@ -103,24 +103,15 @@ Pass *createAlwaysInlinerPass(bool InsertLifetime);
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<const char *> &exportList);
/// createInternalizePass - Same as above, but with an empty exportList.
ModulePass *createInternalizePass();
//===----------------------------------------------------------------------===//
/// createDeadArgEliminationPass - This pass removes arguments from functions

View File

@ -95,7 +95,10 @@ void LLVMAddIPSCCPPass(LLVMPassManagerRef PM) {
}
void LLVMAddInternalizePass(LLVMPassManagerRef PM, unsigned AllButMain) {
unwrap(PM)->add(createInternalizePass(AllButMain != 0));
std::vector<const char *> Export;
if (AllButMain)
Export.push_back("main");
unwrap(PM)->add(createInternalizePass(Export));
}
void LLVMAddStripDeadPrototypesPass(LLVMPassManagerRef PM) {

View File

@ -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<std::string> 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 <const char *>& 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<const char *>&exportList)
: ModulePass(ID), AllButMain(false){
: ModulePass(ID){
initializeInternalizePassPass(*PassRegistry::getPassRegistry());
for(std::vector<const char *>::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<CallGraph>();
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 <const char *> &el) {

View File

@ -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<const char*> 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

13
test/Other/link-opts.ll Normal file
View File

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

View File

@ -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() {

View File

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