<div dir="ltr">On Thu, Oct 3, 2013 at 11:29 AM, Rafael Espindola <span dir="ltr"><<a href="mailto:rafael.espindola@gmail.com" target="_blank">rafael.espindola@gmail.com</a>></span> wrote:<br><div class="gmail_extra">
<div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Author: rafael<br>
Date: Thu Oct  3 13:29:09 2013<br>
New Revision: 191922<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=191922&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=191922&view=rev</a><br>
Log:<br>
Optimize linkonce_odr unnamed_addr functions during LTO.<br>
<br>
Generalize the API so we can distinguish symbols that are needed just for a DSO<br>
symbol table from those that are used from some native .o.<br>
<br>
The symbols that are only wanted for the dso symbol table can be dropped if<br>
llvm can prove every other dso has a copy (linkonce_odr) and the address is not<br>
important (unnamed_addr).<br>
<br>
Modified:<br>
    llvm/trunk/include/llvm-c/lto.h<br>
    llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h<br>
    llvm/trunk/include/llvm/Transforms/IPO.h<br>
    llvm/trunk/lib/LTO/LTOCodeGenerator.cpp<br>
    llvm/trunk/lib/Transforms/IPO/IPO.cpp<br>
    llvm/trunk/lib/Transforms/IPO/Internalize.cpp<br>
    llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp<br>
    llvm/trunk/test/LTO/cfi_endproc.ll<br>
    llvm/trunk/test/Transforms/Internalize/lists.ll<br>
    llvm/trunk/tools/gold/gold-plugin.cpp<br>
    llvm/trunk/tools/llvm-lto/llvm-lto.cpp<br>
    llvm/trunk/tools/lto/lto.cpp<br>
<br>
Modified: llvm/trunk/include/llvm-c/lto.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/lto.h?rev=191922&r1=191921&r2=191922&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/lto.h?rev=191922&r1=191921&r2=191922&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/include/llvm-c/lto.h (original)<br>
+++ llvm/trunk/include/llvm-c/lto.h Thu Oct  3 13:29:09 2013<br>
@@ -29,7 +29,7 @@<br>
  * @{<br>
  */<br>
<br>
-#define LTO_API_VERSION 4<br>
+#define LTO_API_VERSION 5<br>
<br>
 typedef enum {<br>
     LTO_SYMBOL_ALIGNMENT_MASK              = 0x0000001F, /* log2 of alignment */<br>
@@ -253,13 +253,21 @@ lto_codegen_set_assembler_args(lto_code_<br>
                                int nargs);<br>
<br>
 /**<br>
- * Adds to a list of all global symbols that must exist in the final<br>
- * generated code.  If a function is not listed, it might be<br>
- * inlined into every usage and optimized away.<br>
+ * Tells LTO optimization passes that this symbol must be preserved<br>
+ * because it is referenced by native code or a command line option.<br>
  */<br>
 extern void<br>
 lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg, const char* symbol);<br>
<br>
+<br>
+/**<br>
+ * Tells LTO optimization passes that a dynamic shared library is being<br>
+ * built and this symbol may be exported. Unless IR semantics allow the symbol<br>
+ * to be made local to the library, it should remain so it can be exported by<br>
+ * the shared library.<br>
+ */<br>
+extern void lto_codegen_add_dso_symbol(lto_code_gen_t cg, const char *symbol);<br>
+<br>
 /**<br>
  * Writes a new object file at the specified path that contains the<br>
  * merged contents of all modules added so far.<br>
<br>
Modified: llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h?rev=191922&r1=191921&r2=191922&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h?rev=191922&r1=191921&r2=191922&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h (original)<br>
+++ llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h Thu Oct  3 13:29:09 2013<br>
@@ -73,6 +73,10 @@ struct LTOCodeGenerator {<br>
<br>
   void addMustPreserveSymbol(const char *sym) { MustPreserveSymbols[sym] = 1; }<br>
<br>
+  void addDSOSymbol(const char* Sym) {<br>
+    DSOSymbols[Sym] = 1;<br>
+  }<br>
+<br>
   // To pass options to the driver and optimization passes. These options are<br>
   // not necessarily for debugging purpose (The function name is misleading).<br>
   // This function should be called before LTOCodeGenerator::compilexxx(),<br>
@@ -126,6 +130,7 @@ private:<br>
   void applyScopeRestrictions();<br>
   void applyRestriction(llvm::GlobalValue &GV,<br>
                         std::vector<const char*> &MustPreserveList,<br>
+                        std::vector<const char*> &SymtabList,<br>
                         llvm::SmallPtrSet<llvm::GlobalValue*, 8> &AsmUsed,<br>
                         llvm::Mangler &Mangler);<br>
   bool determineTarget(std::string &errMsg);<br>
@@ -138,6 +143,7 @@ private:<br>
   bool EmitDwarfDebugInfo;<br>
   bool ScopeRestrictionsDone;<br>
   lto_codegen_model CodeModel;<br>
+  StringSet DSOSymbols;<br>
   StringSet MustPreserveSymbols;<br>
   StringSet AsmUndefinedRefs;<br>
   llvm::MemoryBuffer *NativeObjectFile;<br>
<br>
Modified: llvm/trunk/include/llvm/Transforms/IPO.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/IPO.h?rev=191922&r1=191921&r2=191922&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/IPO.h?rev=191922&r1=191921&r2=191922&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/include/llvm/Transforms/IPO.h (original)<br>
+++ llvm/trunk/include/llvm/Transforms/IPO.h Thu Oct  3 13:29:09 2013<br>
@@ -104,12 +104,32 @@ Pass *createPruneEHPass();<br>
<br>
 //===----------------------------------------------------------------------===//<br>
 /// createInternalizePass - This pass loops over all of the functions in the<br>
-/// input module, internalizing all globals (functions and variables) not in the<br>
-/// given exportList.<br>
+/// input module, internalizing all globals (functions and variables) it can.<br>
+////<br>
+/// The symbols in \p ExportList are never internalized.<br>
+///<br>
+/// The symbol in DSOList are internalized if it is safe to drop them from<br>
+/// the symbol table.<br>
+///<br>
+/// For example of the difference, consider a dynamic library being built from<br>
+/// two translation units. The first one compiled to a native object<br>
+/// (ELF/MachO/COFF) and second one compiled to IL. Translation unit A has a<br>
+/// copy of linkonce_odr unnamed_addr function F. The translation unit B has a<br>
+/// copy of the linkonce_odr unnamed_addr functions F and G.<br>
+///<br>
+/// Assume the linker decides to keep the copy of F in B. This means that LLVM<br>
+/// must produce F in the object file it passes to the linker, otherwise we<br>
+/// will have an undefined reference. For G the situation is different. The<br>
+/// linker puts the function in the DSOList, since it is only wanted for the<br>
+/// symbol table. With this information internalize can now reason that since<br>
+/// the function is a linkonce_odr and its address is not important, it can be<br>
+/// omitted. Any other shared library needing this function will have a copy of<br>
+/// it.<br>
 ///<br>
 /// Note that commandline options that are used with the above function are not<br>
 /// used now!<br>
-ModulePass *createInternalizePass(ArrayRef<const char *> ExportList);<br>
+ModulePass *createInternalizePass(ArrayRef<const char *> ExportList,<br>
+                                  ArrayRef<const char *> DSOList);<br>
 /// createInternalizePass - Same as above, but with an empty exportList.<br>
 ModulePass *createInternalizePass();<br>
<br>
<br>
Modified: llvm/trunk/lib/LTO/LTOCodeGenerator.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTOCodeGenerator.cpp?rev=191922&r1=191921&r2=191922&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTOCodeGenerator.cpp?rev=191922&r1=191921&r2=191922&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/LTO/LTOCodeGenerator.cpp (original)<br>
+++ llvm/trunk/lib/LTO/LTOCodeGenerator.cpp Thu Oct  3 13:29:09 2013<br>
@@ -310,6 +310,7 @@ bool LTOCodeGenerator::determineTarget(s<br>
 void LTOCodeGenerator::<br>
 applyRestriction(GlobalValue &GV,<br>
                  std::vector<const char*> &MustPreserveList,<br>
+                 std::vector<const char*> &DSOList,<br>
                  SmallPtrSet<GlobalValue*, 8> &AsmUsed,<br>
                  Mangler &Mangler) {<br>
   SmallString<64> Buffer;<br>
@@ -319,6 +320,8 @@ applyRestriction(GlobalValue &GV,<br>
     return;<br>
   if (MustPreserveSymbols.count(Buffer))<br>
     MustPreserveList.push_back(GV.getName().data());<br>
+  if (DSOSymbols.count(Buffer))<br>
+    DSOList.push_back(GV.getName().data());<br>
   if (AsmUndefinedRefs.count(Buffer))<br>
     AsmUsed.insert(&GV);<br>
 }<br>
@@ -348,17 +351,18 @@ void LTOCodeGenerator::applyScopeRestric<br>
                      NULL);<br>
   Mangler Mangler(MContext, TargetMach);<br>
   std::vector<const char*> MustPreserveList;<br>
+  std::vector<const char*> DSOList;<br>
   SmallPtrSet<GlobalValue*, 8> AsmUsed;<br>
<br>
   for (Module::iterator f = mergedModule->begin(),<br>
          e = mergedModule->end(); f != e; ++f)<br>
-    applyRestriction(*f, MustPreserveList, AsmUsed, Mangler);<br>
+    applyRestriction(*f, MustPreserveList, DSOList, AsmUsed, Mangler);<br>
   for (Module::global_iterator v = mergedModule->global_begin(),<br>
          e = mergedModule->global_end(); v !=  e; ++v)<br>
-    applyRestriction(*v, MustPreserveList, AsmUsed, Mangler);<br>
+    applyRestriction(*v, MustPreserveList, DSOList, AsmUsed, Mangler);<br>
   for (Module::alias_iterator a = mergedModule->alias_begin(),<br>
          e = mergedModule->alias_end(); a != e; ++a)<br>
-    applyRestriction(*a, MustPreserveList, AsmUsed, Mangler);<br>
+    applyRestriction(*a, MustPreserveList, DSOList, AsmUsed, Mangler);<br>
<br>
   GlobalVariable *LLVMCompilerUsed =<br>
     mergedModule->getGlobalVariable("llvm.compiler.used");<br>
@@ -386,7 +390,7 @@ void LTOCodeGenerator::applyScopeRestric<br>
     LLVMCompilerUsed->setSection("llvm.metadata");<br>
   }<br>
<br>
-  passes.add(createInternalizePass(MustPreserveList));<br>
+  passes.add(createInternalizePass(MustPreserveList, DSOList));<br>
<br>
   // apply scope restrictions<br>
   passes.run(*mergedModule);<br>
<br>
Modified: llvm/trunk/lib/Transforms/IPO/IPO.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/IPO.cpp?rev=191922&r1=191921&r2=191922&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/IPO.cpp?rev=191922&r1=191921&r2=191922&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/Transforms/IPO/IPO.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/IPO/IPO.cpp Thu Oct  3 13:29:09 2013<br>
@@ -98,7 +98,7 @@ void LLVMAddInternalizePass(LLVMPassMana<br>
   std::vector<const char *> Export;<br>
   if (AllButMain)<br>
     Export.push_back("main");<br>
-  unwrap(PM)->add(createInternalizePass(Export));<br>
+  unwrap(PM)->add(createInternalizePass(Export, None));<br>
 }<br>
<br>
 void LLVMAddStripDeadPrototypesPass(LLVMPassManagerRef PM) {<br>
<br>
Modified: llvm/trunk/lib/Transforms/IPO/Internalize.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/Internalize.cpp?rev=191922&r1=191921&r2=191922&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/Internalize.cpp?rev=191922&r1=191921&r2=191922&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/Transforms/IPO/Internalize.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/IPO/Internalize.cpp Thu Oct  3 13:29:09 2013<br>
@@ -44,13 +44,20 @@ APIList("internalize-public-api-list", c<br>
         cl::desc("A list of symbol names to preserve"),<br>
         cl::CommaSeparated);<br>
<br>
+static cl::list<std::string><br>
+DSOList("internalize-dso-list", cl::value_desc("list"),<br>
+        cl::desc("A list of symbol names need for a dso symbol table"),<br>
+        cl::CommaSeparated);<br>
+<br>
 namespace {<br>
   class InternalizePass : public ModulePass {<br>
     std::set<std::string> ExternalNames;<br>
+    std::set<std::string> DSONames;<br>
   public:<br>
     static char ID; // Pass identification, replacement for typeid<br>
     explicit InternalizePass();<br>
-    explicit InternalizePass(ArrayRef<const char *> ExportList);<br>
+    explicit InternalizePass(ArrayRef<const char *> ExportList,<br>
+                             ArrayRef<const char *> DSOList);<br>
     void LoadFile(const char *Filename);<br>
     virtual bool runOnModule(Module &M);<br>
<br>
@@ -71,15 +78,21 @@ InternalizePass::InternalizePass()<br>
   if (!APIFile.empty())           // If a filename is specified, use it.<br>
     LoadFile(APIFile.c_str());<br>
   ExternalNames.insert(APIList.begin(), APIList.end());<br>
+  DSONames.insert(DSOList.begin(), DSOList.end());<br>
 }<br>
<br>
-InternalizePass::InternalizePass(ArrayRef<const char *> ExportList)<br>
+InternalizePass::InternalizePass(ArrayRef<const char *> ExportList,<br>
+                                 ArrayRef<const char *> DSOList)<br>
   : ModulePass(ID){<br>
   initializeInternalizePassPass(*PassRegistry::getPassRegistry());<br>
   for(ArrayRef<const char *>::const_iterator itr = ExportList.begin();<br>
         itr != ExportList.end(); itr++) {<br>
     ExternalNames.insert(*itr);<br>
   }<br>
+  for(ArrayRef<const char *>::const_iterator itr = DSOList.begin();<br>
+        itr != DSOList.end(); itr++) {<br>
+    DSONames.insert(*itr);<br>
+  }<br>
 }<br>
<br>
 void InternalizePass::LoadFile(const char *Filename) {<br>
@@ -99,7 +112,8 @@ void InternalizePass::LoadFile(const cha<br>
 }<br>
<br>
 static bool shouldInternalize(const GlobalValue &GV,<br>
-                              const std::set<std::string> &ExternalNames) {<br>
+                              const std::set<std::string> &ExternalNames,<br>
+                              const std::set<std::string> &DSONames) {<br>
   // Function must be defined here<br>
   if (GV.isDeclaration())<br>
     return false;<br>
@@ -116,7 +130,20 @@ static bool shouldInternalize(const Glob<br>
   if (ExternalNames.count(GV.getName()))<br>
     return false;<br>
<br>
-  return true;<br>
+  // Not needed for the symbol table?<br>
+  if (!DSONames.count(GV.getName()))<br>
+    return true;<br>
+<br>
+  // Not a linkonce. Someone can depend on it being on the symbol table.<br>
+  if (!GV.hasLinkOnceLinkage())<br>
+    return false;<br>
+<br>
+  // The address is not important, we can hide it.<br>
+  if (GV.hasUnnamedAddr())<br>
+    return true;<br>
+<br>
+  // FIXME: Check if the address is used.<br>
+  return false;<br>
 }<br>
<br>
 bool InternalizePass::runOnModule(Module &M) {<br>
@@ -145,7 +172,7 @@ bool InternalizePass::runOnModule(Module<br>
   // Mark all functions not in the api as internal.<br>
   // FIXME: maybe use private linkage?<br>
   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {<br>
-    if (!shouldInternalize(*I, ExternalNames))<br>
+    if (!shouldInternalize(*I, ExternalNames, DSONames))<br>
       continue;<br>
<br>
     I->setLinkage(GlobalValue::InternalLinkage);<br>
@@ -182,7 +209,7 @@ bool InternalizePass::runOnModule(Module<br>
   // FIXME: maybe use private linkage?<br>
   for (Module::global_iterator I = M.global_begin(), E = M.global_end();<br>
        I != E; ++I) {<br>
-    if (!shouldInternalize(*I, ExternalNames))<br>
+    if (!shouldInternalize(*I, ExternalNames, DSONames))<br>
       continue;<br>
<br>
     I->setLinkage(GlobalValue::InternalLinkage);<br>
@@ -194,7 +221,7 @@ bool InternalizePass::runOnModule(Module<br>
   // Mark all aliases that are not in the api as internal as well.<br>
   for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();<br>
        I != E; ++I) {<br>
-    if (!shouldInternalize(*I, ExternalNames))<br>
+    if (!shouldInternalize(*I, ExternalNames, DSONames))<br>
       continue;<br>
<br>
     I->setLinkage(GlobalValue::InternalLinkage);<br>
@@ -210,6 +237,7 @@ ModulePass *llvm::createInternalizePass(<br>
   return new InternalizePass();<br>
 }<br>
<br>
-ModulePass *llvm::createInternalizePass(ArrayRef<const char *> ExportList) {<br>
-  return new InternalizePass(ExportList);<br>
+ModulePass *llvm::createInternalizePass(ArrayRef<const char *> ExportList,<br>
+                                        ArrayRef<const char *> DSOList) {<br>
+  return new InternalizePass(ExportList, DSOList);<br>
 }<br>
<br>
Modified: llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp?rev=191922&r1=191921&r2=191922&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp?rev=191922&r1=191921&r2=191922&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp Thu Oct  3 13:29:09 2013<br>
@@ -277,7 +277,7 @@ void PassManagerBuilder::populateLTOPass<br>
   // for a main function.  If main is defined, mark all other functions<br>
   // internal.<br>
   if (Internalize)<br>
-    PM.add(createInternalizePass("main"));<br>
+    PM.add(createInternalizePass("main", None));<br>
<br>
   // Propagate constants at call sites into the functions they call.  This<br>
   // opens opportunities for globalopt (and inlining) by substituting function<br>
<br>
Modified: llvm/trunk/test/LTO/cfi_endproc.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LTO/cfi_endproc.ll?rev=191922&r1=191921&r2=191922&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LTO/cfi_endproc.ll?rev=191922&r1=191921&r2=191922&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/test/LTO/cfi_endproc.ll (original)<br>
+++ llvm/trunk/test/LTO/cfi_endproc.ll Thu Oct  3 13:29:09 2013<br>
@@ -27,3 +27,11 @@ define i32 @main(i32 %argc, i8** %argv)<br>
   call void @PR14512()<br>
   ret i32 0<br>
 }<br>
+<br>
+; RUN: llvm-lto -o %t -dso-symbol=zed1 -dso-symbol=zed2 %t1 -disable-opt<br>
+; RUN: llvm-nm %t | FileCheck %s -check-prefix=ZED1_AND_ZED2<br>
+; ZED1_AND_ZED2: V zed1<br>
+@zed1 = linkonce_odr global i32 42<br>
+<br>
+; ZED1_AND_ZED2: d zed2<br>
+@zed2 = linkonce_odr unnamed_addr global i32 42<br>
<br>
Modified: llvm/trunk/test/Transforms/Internalize/lists.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Internalize/lists.ll?rev=191922&r1=191921&r2=191922&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Internalize/lists.ll?rev=191922&r1=191921&r2=191922&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/test/Transforms/Internalize/lists.ll (original)<br>
+++ llvm/trunk/test/Transforms/Internalize/lists.ll Thu Oct  3 13:29:09 2013<br>
@@ -13,6 +13,10 @@<br>
 ; -file and -list options should be merged, the apifile contains foo and j<br>
 ; RUN: opt < %s -internalize -internalize-public-api-list bar -internalize-public-api-file %S/apifile -S | FileCheck --check-prefix=FOO_J_AND_BAR %s<br>
<br>
+; Put zed1 and zed2 in the symbol table. If the address is not relevant, we<br>
+; internalize them.<br>
+; RUN: opt < %s -internalize -internalize-dso-list zed1,zed2 -S | FileCheck --check-prefix=ZED1_AND_ZED2 %s<br>
+<br>
 ; ALL: @i = internal global<br>
 ; FOO_AND_J: @i = internal global<br>
 ; FOO_AND_BAR: @i = internal global<br>
@@ -25,6 +29,12 @@<br>
 ; FOO_J_AND_BAR: @j = global<br>
 @j = global i32 0<br>
<br>
+; ZED1_AND_ZED2: @zed1 = linkonce_odr global i32 42<br>
+@zed1 = linkonce_odr global i32 42<br>
+<br>
+; ZED1_AND_ZED2: @zed2 = internal unnamed_addr global i32 42<br>
+@zed2 = linkonce_odr unnamed_addr global i32 42<br>
+<br>
 ; ALL: define internal void @main() {<br>
 ; FOO_AND_J: define internal void @main() {<br>
 ; FOO_AND_BAR: define internal void @main() {<br>
<br>
Modified: llvm/trunk/tools/gold/gold-plugin.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/gold/gold-plugin.cpp?rev=191922&r1=191921&r2=191922&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/gold/gold-plugin.cpp?rev=191922&r1=191921&r2=191922&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/tools/gold/gold-plugin.cpp (original)<br>
+++ llvm/trunk/tools/gold/gold-plugin.cpp Thu Oct  3 13:29:09 2013<br>
@@ -197,7 +197,7 @@ ld_plugin_status onload(ld_plugin_tv *tv<br>
       case LDPT_ADD_SYMBOLS:<br>
         add_symbols = tv->tv_u.tv_add_symbols;<br>
         break;<br>
-      case LDPT_GET_SYMBOLS:<br>
+      case LDPT_GET_SYMBOLS_V2:<br>
         get_symbols = tv->tv_u.tv_get_symbols;<br>
         break;<br>
       case LDPT_ADD_INPUT_FILE:<br>
@@ -386,6 +386,11 @@ static ld_plugin_status all_symbols_read<br>
<br>
         if (options::generate_api_file)<br>
           api_file << I->syms[i].name << "\n";<br>
+      } else if (I->syms[i].resolution == LDPR_PREVAILING_DEF_IRONLY_EXP) {<br></blockquote><div><br></div><div><div>third_party/llvm/llvm/tools/gold/gold-plugin.cpp:200:12: error: use of undeclared identifier 'LDPT_GET_SYMBOLS_V2'; did you mean 'LDPT_GET_SYMBOLS'?</div>
<div>third_party/llvm/llvm/tools/gold/gold-plugin.cpp:389:43: error: use of undeclared identifier 'LDPR_PREVAILING_DEF_IRONLY_EXP'; did you mean 'LDPR_PREVAILING_DEF_IRONLY'?</div></div><div><br></div><div>
I think you've increased the minimum required version of something. Can you make this change conditional on these names existing?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

+        lto_codegen_add_dso_symbol(code_gen, I->syms[i].name);<br>
+<br>
+        if (options::generate_api_file)<br>
+          api_file << I->syms[i].name << " dso only\n";<br>
       }<br>
     }<br>
   }<br>
<br>
Modified: llvm/trunk/tools/llvm-lto/llvm-lto.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-lto/llvm-lto.cpp?rev=191922&r1=191921&r2=191922&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-lto/llvm-lto.cpp?rev=191922&r1=191921&r2=191922&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/tools/llvm-lto/llvm-lto.cpp (original)<br>
+++ llvm/trunk/tools/llvm-lto/llvm-lto.cpp Thu Oct  3 13:29:09 2013<br>
@@ -50,6 +50,10 @@ ExportedSymbols("exported-symbol",<br>
   cl::desc("Symbol to export from the resulting object file"),<br>
   cl::ZeroOrMore);<br>
<br>
+static cl::list<std::string><br>
+DSOSymbols("dso-symbol",<br>
+  cl::desc("Symbol to put in the symtab in the resulting dso"),<br>
+  cl::ZeroOrMore);<br>
<br>
 int main(int argc, char **argv) {<br>
   // Print a stack trace if we signal out.<br>
@@ -117,6 +121,10 @@ int main(int argc, char **argv) {<br>
   for (unsigned i = 0; i < ExportedSymbols.size(); ++i)<br>
     CodeGen.addMustPreserveSymbol(ExportedSymbols[i].c_str());<br>
<br>
+  // Add all the dso symbols to the table of symbols to expose.<br>
+  for (unsigned i = 0; i < DSOSymbols.size(); ++i)<br>
+    CodeGen.addDSOSymbol(DSOSymbols[i].c_str());<br>
+<br>
   if (!OutputFilename.empty()) {<br>
     size_t len = 0;<br>
     std::string ErrorInfo;<br>
<br>
Modified: llvm/trunk/tools/lto/lto.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/lto.cpp?rev=191922&r1=191921&r2=191922&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/lto.cpp?rev=191922&r1=191921&r2=191922&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/tools/lto/lto.cpp (original)<br>
+++ llvm/trunk/tools/lto/lto.cpp Thu Oct  3 13:29:09 2013<br>
@@ -260,6 +260,10 @@ void lto_codegen_add_must_preserve_symbo<br>
   cg->addMustPreserveSymbol(symbol);<br>
 }<br>
<br>
+void lto_codegen_add_dso_symbol(lto_code_gen_t cg, const char *symbol) {<br>
+  cg->addDSOSymbol(symbol);<br>
+}<br>
+<br>
 /// lto_codegen_write_merged_modules - Writes a new file at the specified path<br>
 /// that contains the merged contents of all modules added so far. Returns true<br>
 /// on error (check lto_get_error_message() for details).<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>