summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/IPO/Internalize.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2013-10-03 18:29:09 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2013-10-03 18:29:09 +0000
commitcda2911caaf64f11905dcc0757a1b291943bbe9a (patch)
tree479d25f058fde301d3cbf8a362335a011fd66585 /llvm/lib/Transforms/IPO/Internalize.cpp
parent3d78fe8fa02e75c4416b36c5537fdff614fee040 (diff)
downloadbcm5719-llvm-cda2911caaf64f11905dcc0757a1b291943bbe9a.tar.gz
bcm5719-llvm-cda2911caaf64f11905dcc0757a1b291943bbe9a.zip
Optimize linkonce_odr unnamed_addr functions during LTO.
Generalize the API so we can distinguish symbols that are needed just for a DSO symbol table from those that are used from some native .o. The symbols that are only wanted for the dso symbol table can be dropped if llvm can prove every other dso has a copy (linkonce_odr) and the address is not important (unnamed_addr). llvm-svn: 191922
Diffstat (limited to 'llvm/lib/Transforms/IPO/Internalize.cpp')
-rw-r--r--llvm/lib/Transforms/IPO/Internalize.cpp46
1 files changed, 37 insertions, 9 deletions
diff --git a/llvm/lib/Transforms/IPO/Internalize.cpp b/llvm/lib/Transforms/IPO/Internalize.cpp
index f2feacc0b63..f20a7bd92f4 100644
--- a/llvm/lib/Transforms/IPO/Internalize.cpp
+++ b/llvm/lib/Transforms/IPO/Internalize.cpp
@@ -44,13 +44,20 @@ 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);
+ explicit InternalizePass(ArrayRef<const char *> ExportList,
+ ArrayRef<const char *> DSOList);
void LoadFile(const char *Filename);
virtual bool runOnModule(Module &M);
@@ -71,15 +78,21 @@ 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)
+InternalizePass::InternalizePass(ArrayRef<const char *> ExportList,
+ ArrayRef<const char *> DSOList)
: 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) {
@@ -99,7 +112,8 @@ void InternalizePass::LoadFile(const char *Filename) {
}
static bool shouldInternalize(const GlobalValue &GV,
- const std::set<std::string> &ExternalNames) {
+ const std::set<std::string> &ExternalNames,
+ const std::set<std::string> &DSONames) {
// Function must be defined here
if (GV.isDeclaration())
return false;
@@ -116,7 +130,20 @@ static bool shouldInternalize(const GlobalValue &GV,
if (ExternalNames.count(GV.getName()))
return false;
- return true;
+ // 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;
+
+ // FIXME: Check if the address is used.
+ return false;
}
bool InternalizePass::runOnModule(Module &M) {
@@ -145,7 +172,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))
+ if (!shouldInternalize(*I, ExternalNames, DSONames))
continue;
I->setLinkage(GlobalValue::InternalLinkage);
@@ -182,7 +209,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))
+ if (!shouldInternalize(*I, ExternalNames, DSONames))
continue;
I->setLinkage(GlobalValue::InternalLinkage);
@@ -194,7 +221,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))
+ if (!shouldInternalize(*I, ExternalNames, DSONames))
continue;
I->setLinkage(GlobalValue::InternalLinkage);
@@ -210,6 +237,7 @@ ModulePass *llvm::createInternalizePass() {
return new InternalizePass();
}
-ModulePass *llvm::createInternalizePass(ArrayRef<const char *> ExportList) {
- return new InternalizePass(ExportList);
+ModulePass *llvm::createInternalizePass(ArrayRef<const char *> ExportList,
+ ArrayRef<const char *> DSOList) {
+ return new InternalizePass(ExportList, DSOList);
}
OpenPOWER on IntegriCloud