diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/LTO/LTOCodeGenerator.cpp | 12 | ||||
-rw-r--r-- | lib/LTO/LTOModule.cpp | 26 | ||||
-rw-r--r-- | lib/Transforms/IPO/IPO.cpp | 2 | ||||
-rw-r--r-- | lib/Transforms/IPO/Internalize.cpp | 64 | ||||
-rw-r--r-- | lib/Transforms/IPO/PassManagerBuilder.cpp | 2 |
5 files changed, 43 insertions, 63 deletions
diff --git a/lib/LTO/LTOCodeGenerator.cpp b/lib/LTO/LTOCodeGenerator.cpp index c55eccb..3c9a378 100644 --- a/lib/LTO/LTOCodeGenerator.cpp +++ b/lib/LTO/LTOCodeGenerator.cpp @@ -313,7 +313,6 @@ bool LTOCodeGenerator::determineTarget(std::string &errMsg) { void LTOCodeGenerator:: applyRestriction(GlobalValue &GV, std::vector<const char*> &MustPreserveList, - std::vector<const char*> &DSOList, SmallPtrSet<GlobalValue*, 8> &AsmUsed, Mangler &Mangler) { SmallString<64> Buffer; @@ -323,8 +322,6 @@ applyRestriction(GlobalValue &GV, return; if (MustPreserveSymbols.count(Buffer)) MustPreserveList.push_back(GV.getName().data()); - if (DSOSymbols.count(Buffer)) - DSOList.push_back(GV.getName().data()); if (AsmUndefinedRefs.count(Buffer)) AsmUsed.insert(&GV); } @@ -352,18 +349,17 @@ void LTOCodeGenerator::applyScopeRestrictions() { // mark which symbols can not be internalized Mangler Mangler(TargetMach); std::vector<const char*> MustPreserveList; - std::vector<const char*> DSOList; SmallPtrSet<GlobalValue*, 8> AsmUsed; for (Module::iterator f = mergedModule->begin(), e = mergedModule->end(); f != e; ++f) - applyRestriction(*f, MustPreserveList, DSOList, AsmUsed, Mangler); + applyRestriction(*f, MustPreserveList, AsmUsed, Mangler); for (Module::global_iterator v = mergedModule->global_begin(), e = mergedModule->global_end(); v != e; ++v) - applyRestriction(*v, MustPreserveList, DSOList, AsmUsed, Mangler); + applyRestriction(*v, MustPreserveList, AsmUsed, Mangler); for (Module::alias_iterator a = mergedModule->alias_begin(), e = mergedModule->alias_end(); a != e; ++a) - applyRestriction(*a, MustPreserveList, DSOList, AsmUsed, Mangler); + applyRestriction(*a, MustPreserveList, AsmUsed, Mangler); GlobalVariable *LLVMCompilerUsed = mergedModule->getGlobalVariable("llvm.compiler.used"); @@ -391,7 +387,7 @@ void LTOCodeGenerator::applyScopeRestrictions() { LLVMCompilerUsed->setSection("llvm.metadata"); } - passes.add(createInternalizePass(MustPreserveList, DSOList)); + passes.add(createInternalizePass(MustPreserveList)); // apply scope restrictions passes.run(*mergedModule); diff --git a/lib/LTO/LTOModule.cpp b/lib/LTO/LTOModule.cpp index db9b9c9..91240aa 100644 --- a/lib/LTO/LTOModule.cpp +++ b/lib/LTO/LTOModule.cpp @@ -38,6 +38,7 @@ #include "llvm/Support/TargetSelect.h" #include "llvm/Support/system_error.h" #include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/Transforms/Utils/GlobalStatus.h" using namespace llvm; LTOModule::LTOModule(llvm::Module *m, llvm::TargetMachine *t) @@ -162,6 +163,8 @@ LTOModule *LTOModule::makeLTOModule(MemoryBuffer *buffer, TargetMachine *target = march->createTargetMachine(TripleStr, CPU, FeatureStr, options); + m->MaterializeAllPermanently(); + LTOModule *Ret = new LTOModule(m.take(), target); if (Ret->parseSymbols(errMsg)) { delete Ret; @@ -333,6 +336,25 @@ void LTOModule::addDefinedFunctionSymbol(const Function *f) { addDefinedSymbol(f, true); } +static bool canBeHidden(const GlobalValue *GV) { + GlobalValue::LinkageTypes L = GV->getLinkage(); + + if (L == GlobalValue::LinkOnceODRAutoHideLinkage) + return true; + + if (L != GlobalValue::LinkOnceODRLinkage) + return false; + + if (GV->hasUnnamedAddr()) + return true; + + GlobalStatus GS; + if (GlobalStatus::analyzeGlobal(GV, GS)) + return false; + + return !GS.IsCompared; +} + /// addDefinedSymbol - Add a defined symbol to the list. void LTOModule::addDefinedSymbol(const GlobalValue *def, bool isFunction) { // ignore all llvm.* symbols @@ -372,12 +394,12 @@ void LTOModule::addDefinedSymbol(const GlobalValue *def, bool isFunction) { attr |= LTO_SYMBOL_SCOPE_HIDDEN; else if (def->hasProtectedVisibility()) attr |= LTO_SYMBOL_SCOPE_PROTECTED; + else if (canBeHidden(def)) + attr |= LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN; else if (def->hasExternalLinkage() || def->hasWeakLinkage() || def->hasLinkOnceLinkage() || def->hasCommonLinkage() || def->hasLinkerPrivateWeakLinkage()) attr |= LTO_SYMBOL_SCOPE_DEFAULT; - else if (def->hasLinkOnceODRAutoHideLinkage()) - attr |= LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN; else attr |= LTO_SYMBOL_SCOPE_INTERNAL; diff --git a/lib/Transforms/IPO/IPO.cpp b/lib/Transforms/IPO/IPO.cpp index 5f26bac..5d563d8 100644 --- a/lib/Transforms/IPO/IPO.cpp +++ b/lib/Transforms/IPO/IPO.cpp @@ -98,7 +98,7 @@ void LLVMAddInternalizePass(LLVMPassManagerRef PM, unsigned AllButMain) { std::vector<const char *> Export; if (AllButMain) Export.push_back("main"); - unwrap(PM)->add(createInternalizePass(Export, None)); + unwrap(PM)->add(createInternalizePass(Export)); } void LLVMAddStripDeadPrototypesPass(LLVMPassManagerRef PM) { diff --git a/lib/Transforms/IPO/Internalize.cpp b/lib/Transforms/IPO/Internalize.cpp index e615918..64e2ced 100644 --- a/lib/Transforms/IPO/Internalize.cpp +++ b/lib/Transforms/IPO/Internalize.cpp @@ -11,18 +11,11 @@ // If the function or variable is not in the list of external names given to // the pass it is marked as internal. // -// This transformation would not be legal or profitable in a regular -// compilation, but it gets extra information from the linker about what is safe -// or profitable. +// This transformation would not be legal in a regular compilation, but it gets +// extra information from the linker about what is safe. // -// As an example of a normally illegal transformation: Internalizing a function -// with external linkage. Only if we are told it is only used from within this -// module, it is safe to do it. -// -// On the profitability side: It is always legal to internalize a linkonce_odr -// whose address is not used. Doing so normally would introduce code bloat, but -// if we are told by the linker that the only use of this would be for a -// DSO symbol table, it is profitable to hide it. +// For example: Internalizing a function with external linkage. Only if we are +// told it is only used from within this module, it is safe to do it. // //===----------------------------------------------------------------------===// @@ -58,20 +51,13 @@ APIList("internalize-public-api-list", cl::value_desc("list"), cl::desc("A list of symbol names to preserve"), cl::CommaSeparated); -static cl::list<std::string> -DSOList("internalize-dso-list", cl::value_desc("list"), - cl::desc("A list of symbol names need for a dso symbol table"), - cl::CommaSeparated); - namespace { class InternalizePass : public ModulePass { std::set<std::string> ExternalNames; - std::set<std::string> DSONames; public: static char ID; // Pass identification, replacement for typeid explicit InternalizePass(); - explicit InternalizePass(ArrayRef<const char *> ExportList, - ArrayRef<const char *> DSOList); + explicit InternalizePass(ArrayRef<const char *> ExportList); void LoadFile(const char *Filename); virtual bool runOnModule(Module &M); @@ -92,21 +78,15 @@ InternalizePass::InternalizePass() if (!APIFile.empty()) // If a filename is specified, use it. LoadFile(APIFile.c_str()); ExternalNames.insert(APIList.begin(), APIList.end()); - DSONames.insert(DSOList.begin(), DSOList.end()); } -InternalizePass::InternalizePass(ArrayRef<const char *> ExportList, - ArrayRef<const char *> DSOList) +InternalizePass::InternalizePass(ArrayRef<const char *> ExportList) : ModulePass(ID){ initializeInternalizePassPass(*PassRegistry::getPassRegistry()); for(ArrayRef<const char *>::const_iterator itr = ExportList.begin(); itr != ExportList.end(); itr++) { ExternalNames.insert(*itr); } - for(ArrayRef<const char *>::const_iterator itr = DSOList.begin(); - itr != DSOList.end(); itr++) { - DSONames.insert(*itr); - } } void InternalizePass::LoadFile(const char *Filename) { @@ -126,8 +106,7 @@ void InternalizePass::LoadFile(const char *Filename) { } static bool shouldInternalize(const GlobalValue &GV, - const std::set<std::string> &ExternalNames, - const std::set<std::string> &DSONames) { + const std::set<std::string> &ExternalNames) { // Function must be defined here if (GV.isDeclaration()) return false; @@ -144,23 +123,7 @@ static bool shouldInternalize(const GlobalValue &GV, if (ExternalNames.count(GV.getName())) return false; - // Not needed for the symbol table? - if (!DSONames.count(GV.getName())) - return true; - - // Not a linkonce. Someone can depend on it being on the symbol table. - if (!GV.hasLinkOnceLinkage()) - return false; - - // The address is not important, we can hide it. - if (GV.hasUnnamedAddr()) - return true; - - GlobalStatus GS; - if (GlobalStatus::analyzeGlobal(&GV, GS)) - return false; - - return !GS.IsCompared; + return true; } bool InternalizePass::runOnModule(Module &M) { @@ -189,7 +152,7 @@ bool InternalizePass::runOnModule(Module &M) { // Mark all functions not in the api as internal. // FIXME: maybe use private linkage? for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { - if (!shouldInternalize(*I, ExternalNames, DSONames)) + if (!shouldInternalize(*I, ExternalNames)) continue; I->setLinkage(GlobalValue::InternalLinkage); @@ -226,7 +189,7 @@ bool InternalizePass::runOnModule(Module &M) { // FIXME: maybe use private linkage? for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { - if (!shouldInternalize(*I, ExternalNames, DSONames)) + if (!shouldInternalize(*I, ExternalNames)) continue; I->setLinkage(GlobalValue::InternalLinkage); @@ -238,7 +201,7 @@ 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) { - if (!shouldInternalize(*I, ExternalNames, DSONames)) + if (!shouldInternalize(*I, ExternalNames)) continue; I->setLinkage(GlobalValue::InternalLinkage); @@ -254,7 +217,6 @@ ModulePass *llvm::createInternalizePass() { return new InternalizePass(); } -ModulePass *llvm::createInternalizePass(ArrayRef<const char *> ExportList, - ArrayRef<const char *> DSOList) { - return new InternalizePass(ExportList, DSOList); +ModulePass *llvm::createInternalizePass(ArrayRef<const char *> ExportList) { + return new InternalizePass(ExportList); } diff --git a/lib/Transforms/IPO/PassManagerBuilder.cpp b/lib/Transforms/IPO/PassManagerBuilder.cpp index 0017c1b..1386201 100644 --- a/lib/Transforms/IPO/PassManagerBuilder.cpp +++ b/lib/Transforms/IPO/PassManagerBuilder.cpp @@ -277,7 +277,7 @@ void PassManagerBuilder::populateLTOPassManager(PassManagerBase &PM, // for a main function. If main is defined, mark all other functions // internal. if (Internalize) - PM.add(createInternalizePass("main", None)); + PM.add(createInternalizePass("main")); // Propagate constants at call sites into the functions they call. This // opens opportunities for globalopt (and inlining) by substituting function |