aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/LTO/LTOCodeGenerator.cpp12
-rw-r--r--lib/LTO/LTOModule.cpp26
-rw-r--r--lib/Transforms/IPO/IPO.cpp2
-rw-r--r--lib/Transforms/IPO/Internalize.cpp64
-rw-r--r--lib/Transforms/IPO/PassManagerBuilder.cpp2
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