diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2013-10-31 20:51:58 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2013-10-31 20:51:58 +0000 |
commit | 7e667c56cf7e27ff521ceb86518beab32bfb630d (patch) | |
tree | 70a76ad0c4af2d93a15e630ebd9864665253a72f /tools | |
parent | f7ba4897302bf930f7ec4682a296ff4cd736a0e3 (diff) | |
download | external_llvm-7e667c56cf7e27ff521ceb86518beab32bfb630d.zip external_llvm-7e667c56cf7e27ff521ceb86518beab32bfb630d.tar.gz external_llvm-7e667c56cf7e27ff521ceb86518beab32bfb630d.tar.bz2 |
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 'tools')
-rw-r--r-- | tools/gold/gold-plugin.cpp | 21 | ||||
-rw-r--r-- | tools/llvm-lto/llvm-lto.cpp | 28 | ||||
-rw-r--r-- | tools/lto/lto.cpp | 4 | ||||
-rw-r--r-- | tools/lto/lto.exports | 1 |
4 files changed, 41 insertions, 13 deletions
diff --git a/tools/gold/gold-plugin.cpp b/tools/gold/gold-plugin.cpp index 360ec07..0e3bad2 100644 --- a/tools/gold/gold-plugin.cpp +++ b/tools/gold/gold-plugin.cpp @@ -15,6 +15,7 @@ #include "llvm/Config/config.h" // plugin-api.h requires HAVE_STDINT_H #include "plugin-api.h" #include "llvm-c/lto.h" +#include "llvm/ADT/StringSet.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/Support/Errno.h" #include "llvm/Support/FileSystem.h" @@ -67,6 +68,7 @@ namespace { std::list<claimed_file> Modules; std::vector<std::string> Cleanup; lto_code_gen_t code_gen = NULL; + StringSet<> CannotBeHidden; } namespace options { @@ -297,6 +299,9 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, sym.version = NULL; int scope = attrs & LTO_SYMBOL_SCOPE_MASK; + bool CanBeHidden = scope == LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN; + if (!CanBeHidden) + CannotBeHidden.insert(sym.name); switch (scope) { case LTO_SYMBOL_SCOPE_HIDDEN: sym.visibility = LDPV_HIDDEN; @@ -306,6 +311,7 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, break; case 0: // extern case LTO_SYMBOL_SCOPE_DEFAULT: + case LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN: sym.visibility = LDPV_DEFAULT; break; default: @@ -364,6 +370,14 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, return LDPS_OK; } +static bool mustPreserve(const claimed_file &F, int i) { + if (F.syms[i].resolution == LDPR_PREVAILING_DEF) + return true; + if (F.syms[i].resolution == LDPR_PREVAILING_DEF_IRONLY_EXP) + return CannotBeHidden.count(F.syms[i].name); + return false; +} + /// all_symbols_read_hook - gold informs us that all symbols have been read. /// At this point, we use get_symbols to see if any of our definitions have /// been overridden by a native object file. Then, perform optimization and @@ -386,16 +400,11 @@ static ld_plugin_status all_symbols_read_hook(void) { continue; (*get_symbols)(I->handle, I->syms.size(), &I->syms[0]); for (unsigned i = 0, e = I->syms.size(); i != e; i++) { - if (I->syms[i].resolution == LDPR_PREVAILING_DEF) { + if (mustPreserve(*I, i)) { lto_codegen_add_must_preserve_symbol(code_gen, I->syms[i].name); if (options::generate_api_file) api_file << I->syms[i].name << "\n"; - } else if (I->syms[i].resolution == LDPR_PREVAILING_DEF_IRONLY_EXP) { - lto_codegen_add_dso_symbol(code_gen, I->syms[i].name); - - if (options::generate_api_file) - api_file << I->syms[i].name << " dso only\n"; } } } diff --git a/tools/llvm-lto/llvm-lto.cpp b/tools/llvm-lto/llvm-lto.cpp index bce903f..0fc68ae 100644 --- a/tools/llvm-lto/llvm-lto.cpp +++ b/tools/llvm-lto/llvm-lto.cpp @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/StringSet.h" #include "llvm/CodeGen/CommandFlags.h" #include "llvm/LTO/LTOCodeGenerator.h" #include "llvm/LTO/LTOModule.h" @@ -55,6 +56,12 @@ DSOSymbols("dso-symbol", cl::desc("Symbol to put in the symtab in the resulting dso"), cl::ZeroOrMore); +namespace { +struct ModuleInfo { + std::vector<bool> CanBeHidden; +}; +} + int main(int argc, char **argv) { // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(); @@ -99,6 +106,12 @@ int main(int argc, char **argv) { CodeGen.setDebugInfo(LTO_DEBUG_MODEL_DWARF); CodeGen.setTargetOptions(Options); + llvm::StringSet<llvm::MallocAllocator> DSOSymbolsSet; + for (unsigned i = 0; i < DSOSymbols.size(); ++i) + DSOSymbolsSet.insert(DSOSymbols[i]); + + std::vector<std::string> KeptDSOSyms; + for (unsigned i = BaseArg; i < InputFilenames.size(); ++i) { std::string error; OwningPtr<LTOModule> Module(LTOModule::makeLTOModule(InputFilenames[i].c_str(), @@ -115,6 +128,17 @@ int main(int argc, char **argv) { << "': " << error << "\n"; return 1; } + + unsigned NumSyms = Module->getSymbolCount(); + for (unsigned I = 0; I < NumSyms; ++I) { + StringRef Name = Module->getSymbolName(I); + if (!DSOSymbolsSet.count(Name)) + continue; + lto_symbol_attributes Attrs = Module->getSymbolAttributes(I); + unsigned Scope = Attrs & LTO_SYMBOL_SCOPE_MASK; + if (Scope != LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN) + KeptDSOSyms.push_back(Name); + } } // Add all the exported symbols to the table of symbols to preserve. @@ -122,8 +146,8 @@ int main(int argc, char **argv) { CodeGen.addMustPreserveSymbol(ExportedSymbols[i].c_str()); // Add all the dso symbols to the table of symbols to expose. - for (unsigned i = 0; i < DSOSymbols.size(); ++i) - CodeGen.addDSOSymbol(DSOSymbols[i].c_str()); + for (unsigned i = 0; i < KeptDSOSyms.size(); ++i) + CodeGen.addMustPreserveSymbol(KeptDSOSyms[i].c_str()); if (!OutputFilename.empty()) { size_t len = 0; diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp index a3acd4c..7bfddcd 100644 --- a/tools/lto/lto.cpp +++ b/tools/lto/lto.cpp @@ -260,10 +260,6 @@ void lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg, cg->addMustPreserveSymbol(symbol); } -void lto_codegen_add_dso_symbol(lto_code_gen_t cg, const char *symbol) { - cg->addDSOSymbol(symbol); -} - /// lto_codegen_write_merged_modules - Writes a new file at the specified path /// that contains the merged contents of all modules added so far. Returns true /// on error (check lto_get_error_message() for details). diff --git a/tools/lto/lto.exports b/tools/lto/lto.exports index c0e220b..46d0d74 100644 --- a/tools/lto/lto.exports +++ b/tools/lto/lto.exports @@ -15,7 +15,6 @@ lto_module_is_object_file_for_target lto_module_is_object_file_in_memory lto_module_is_object_file_in_memory_for_target lto_module_dispose -lto_codegen_add_dso_symbol lto_codegen_add_module lto_codegen_add_must_preserve_symbol lto_codegen_compile |