summaryrefslogtreecommitdiff
path: root/lib/Transforms
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2013-10-31 20:51:58 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2013-10-31 20:51:58 +0000
commit7e667c56cf7e27ff521ceb86518beab32bfb630d (patch)
tree70a76ad0c4af2d93a15e630ebd9864665253a72f /lib/Transforms
parentf7ba4897302bf930f7ec4682a296ff4cd736a0e3 (diff)
downloadllvm-7e667c56cf7e27ff521ceb86518beab32bfb630d.tar.gz
llvm-7e667c56cf7e27ff521ceb86518beab32bfb630d.tar.bz2
llvm-7e667c56cf7e27ff521ceb86518beab32bfb630d.tar.xz
Use LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN instead of the "dso list".
There are two ways one could implement hiding of linkonce_odr symbols in LTO: * LLVM tells the linker which symbols can be hidden if not used from native files. * The linker tells LLVM which symbols are not used from other object files, but will be put in the dso symbol table if present. GOLD's API is the second option. It was implemented almost 1:1 in llvm by passing the list down to internalize. LLVM already had partial support for the first option. It is also very similar to how ld64 handles hiding these symbols when *not* doing LTO. This patch then * removes the APIs for the DSO list. * marks LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN all linkonce_odr unnamed_addr global values and other linkonce_odr whose address is not used. * makes the gold plugin responsible for handling the API mismatch. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193800 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/IPO/IPO.cpp2
-rw-r--r--lib/Transforms/IPO/Internalize.cpp64
-rw-r--r--lib/Transforms/IPO/PassManagerBuilder.cpp2
3 files changed, 15 insertions, 53 deletions
diff --git a/lib/Transforms/IPO/IPO.cpp b/lib/Transforms/IPO/IPO.cpp
index 5f26bac2c8..5d563d8bbf 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 e61591870b..64e2cedfb1 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 0017c1b822..1386201094 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