[llvm] r193800 - Use LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN instead of the "dso list".

Rafael Espindola rafael.espindola at gmail.com
Thu Oct 31 13:51:59 PDT 2013


Author: rafael
Date: Thu Oct 31 15:51:58 2013
New Revision: 193800

URL: http://llvm.org/viewvc/llvm-project?rev=193800&view=rev
Log:
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.

Added:
    llvm/trunk/test/LTO/linkonce_odr_func.ll
      - copied, changed from r193798, llvm/trunk/test/Transforms/Internalize/linkonce_odr_func.ll
Removed:
    llvm/trunk/test/Transforms/Internalize/linkonce_odr_func.ll
Modified:
    llvm/trunk/include/llvm-c/lto.h
    llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h
    llvm/trunk/include/llvm/Transforms/IPO.h
    llvm/trunk/lib/LTO/LTOCodeGenerator.cpp
    llvm/trunk/lib/LTO/LTOModule.cpp
    llvm/trunk/lib/Transforms/IPO/IPO.cpp
    llvm/trunk/lib/Transforms/IPO/Internalize.cpp
    llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp
    llvm/trunk/test/Transforms/Internalize/lists.ll
    llvm/trunk/tools/gold/gold-plugin.cpp
    llvm/trunk/tools/llvm-lto/llvm-lto.cpp
    llvm/trunk/tools/lto/lto.cpp
    llvm/trunk/tools/lto/lto.exports

Modified: llvm/trunk/include/llvm-c/lto.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/lto.h?rev=193800&r1=193799&r2=193800&view=diff
==============================================================================
--- llvm/trunk/include/llvm-c/lto.h (original)
+++ llvm/trunk/include/llvm-c/lto.h Thu Oct 31 15:51:58 2013
@@ -270,15 +270,6 @@ lto_codegen_set_assembler_args(lto_code_
 extern void
 lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg, const char* symbol);
 
-
-/**
- * Tells LTO optimization passes that a dynamic shared library is being
- * built and this symbol may be exported. Unless IR semantics allow the symbol
- * to be made local to the library, it should remain so it can be exported by
- * the shared library.
- */
-extern void lto_codegen_add_dso_symbol(lto_code_gen_t cg, const char *symbol);
-
 /**
  * Writes a new object file at the specified path that contains the
  * merged contents of all modules added so far.

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

Modified: llvm/trunk/include/llvm/Transforms/IPO.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/IPO.h?rev=193800&r1=193799&r2=193800&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/IPO.h (original)
+++ llvm/trunk/include/llvm/Transforms/IPO.h Thu Oct 31 15:51:58 2013
@@ -111,25 +111,9 @@ Pass *createPruneEHPass();
 /// The symbol in DSOList are internalized if it is safe to drop them from
 /// the symbol table.
 ///
-/// For example of the difference, consider a dynamic library being built from
-/// two translation units. The first one compiled to a native object
-/// (ELF/MachO/COFF) and second one compiled to IL. Translation unit A has a
-/// copy of linkonce_odr unnamed_addr function F. The translation unit B has a
-/// copy of the linkonce_odr unnamed_addr functions F and G.
-///
-/// Assume the linker decides to keep the copy of F in B. This means that LLVM
-/// must produce F in the object file it passes to the linker, otherwise we
-/// will have an undefined reference. For G the situation is different. The
-/// linker puts the function in the DSOList, since it is only wanted for the
-/// symbol table. With this information internalize can now reason that since
-/// the function is a linkonce_odr and its address is not important, it can be
-/// omitted. Any other shared library needing this function will have a copy of
-/// it.
-///
 /// Note that commandline options that are used with the above function are not
 /// used now!
-ModulePass *createInternalizePass(ArrayRef<const char *> ExportList,
-                                  ArrayRef<const char *> DSOList);
+ModulePass *createInternalizePass(ArrayRef<const char *> ExportList);
 /// createInternalizePass - Same as above, but with an empty exportList.
 ModulePass *createInternalizePass();
 

Modified: llvm/trunk/lib/LTO/LTOCodeGenerator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTOCodeGenerator.cpp?rev=193800&r1=193799&r2=193800&view=diff
==============================================================================
--- llvm/trunk/lib/LTO/LTOCodeGenerator.cpp (original)
+++ llvm/trunk/lib/LTO/LTOCodeGenerator.cpp Thu Oct 31 15:51:58 2013
@@ -313,7 +313,6 @@ bool LTOCodeGenerator::determineTarget(s
 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::applyScopeRestric
   // 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::applyScopeRestric
     LLVMCompilerUsed->setSection("llvm.metadata");
   }
 
-  passes.add(createInternalizePass(MustPreserveList, DSOList));
+  passes.add(createInternalizePass(MustPreserveList));
 
   // apply scope restrictions
   passes.run(*mergedModule);

Modified: llvm/trunk/lib/LTO/LTOModule.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTOModule.cpp?rev=193800&r1=193799&r2=193800&view=diff
==============================================================================
--- llvm/trunk/lib/LTO/LTOModule.cpp (original)
+++ llvm/trunk/lib/LTO/LTOModule.cpp Thu Oct 31 15:51:58 2013
@@ -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(Memo
 
   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
   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 G
     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;
 

Modified: llvm/trunk/lib/Transforms/IPO/IPO.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/IPO.cpp?rev=193800&r1=193799&r2=193800&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/IPO.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/IPO.cpp Thu Oct 31 15:51:58 2013
@@ -98,7 +98,7 @@ void LLVMAddInternalizePass(LLVMPassMana
   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) {

Modified: llvm/trunk/lib/Transforms/IPO/Internalize.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/Internalize.cpp?rev=193800&r1=193799&r2=193800&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/Internalize.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/Internalize.cpp Thu Oct 31 15:51:58 2013
@@ -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", c
         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 cha
 }
 
 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 Glob
   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
   // 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
   // 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
   // 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);
 }

Modified: llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp?rev=193800&r1=193799&r2=193800&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp Thu Oct 31 15:51:58 2013
@@ -277,7 +277,7 @@ void PassManagerBuilder::populateLTOPass
   // 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

Copied: llvm/trunk/test/LTO/linkonce_odr_func.ll (from r193798, llvm/trunk/test/Transforms/Internalize/linkonce_odr_func.ll)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LTO/linkonce_odr_func.ll?p2=llvm/trunk/test/LTO/linkonce_odr_func.ll&p1=llvm/trunk/test/Transforms/Internalize/linkonce_odr_func.ll&r1=193798&r2=193800&rev=193800&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/Internalize/linkonce_odr_func.ll (original)
+++ llvm/trunk/test/LTO/linkonce_odr_func.ll Thu Oct 31 15:51:58 2013
@@ -1,27 +1,32 @@
-; RUN: opt < %s -internalize -internalize-dso-list foo1,foo2,foo3,foo4 -S | FileCheck %s
+; RUN: llvm-as < %s >%t1
+; RUN: llvm-lto -o %t2 -dso-symbol=foo1 -dso-symbol=foo2 -dso-symbol=foo3 \
+; RUN:     -dso-symbol=foo4  %t1 -disable-opt
+; RUN: llvm-nm %t2 | FileCheck %s
 
-; CHECK: define internal void @foo1(
+; CHECK: t foo1
 define linkonce_odr void @foo1() noinline {
   ret void
 }
 
-; CHECK: define linkonce_odr void @foo2(
+; CHECK: W foo2
 define linkonce_odr void @foo2() noinline {
   ret void
 }
 
-; CHECK: define internal void @foo3(
+; CHECK: t foo3
 define linkonce_odr void @foo3() noinline {
   ret void
 }
 
-; CHECK: define linkonce_odr void @foo4(
+; CHECK: W foo4
 define linkonce_odr void @foo4() noinline {
   ret void
 }
 
 declare void @f(void()*)
 
+declare void @p()
+
 define void @bar() {
 bb0:
   call void @foo1()
@@ -32,6 +37,6 @@ bb1:
 bb2:
   ret void
 clean:
-  landingpad i32 personality i8* null cleanup
+  landingpad {i32, i32} personality void()* @p cleanup
   ret void
 }

Removed: llvm/trunk/test/Transforms/Internalize/linkonce_odr_func.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Internalize/linkonce_odr_func.ll?rev=193799&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/Internalize/linkonce_odr_func.ll (original)
+++ llvm/trunk/test/Transforms/Internalize/linkonce_odr_func.ll (removed)
@@ -1,37 +0,0 @@
-; RUN: opt < %s -internalize -internalize-dso-list foo1,foo2,foo3,foo4 -S | FileCheck %s
-
-; CHECK: define internal void @foo1(
-define linkonce_odr void @foo1() noinline {
-  ret void
-}
-
-; CHECK: define linkonce_odr void @foo2(
-define linkonce_odr void @foo2() noinline {
-  ret void
-}
-
-; CHECK: define internal void @foo3(
-define linkonce_odr void @foo3() noinline {
-  ret void
-}
-
-; CHECK: define linkonce_odr void @foo4(
-define linkonce_odr void @foo4() noinline {
-  ret void
-}
-
-declare void @f(void()*)
-
-define void @bar() {
-bb0:
-  call void @foo1()
-  call void @f(void()* @foo2)
-  invoke void @foo3() to label %bb1 unwind label %clean
-bb1:
-  invoke void @f(void()* @foo4) to label %bb2 unwind label %clean
-bb2:
-  ret void
-clean:
-  landingpad i32 personality i8* null cleanup
-  ret void
-}

Modified: llvm/trunk/test/Transforms/Internalize/lists.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Internalize/lists.ll?rev=193800&r1=193799&r2=193800&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/Internalize/lists.ll (original)
+++ llvm/trunk/test/Transforms/Internalize/lists.ll Thu Oct 31 15:51:58 2013
@@ -13,10 +13,6 @@
 ; -file and -list options should be merged, the apifile contains foo and j
 ; RUN: opt < %s -internalize -internalize-public-api-list bar -internalize-public-api-file %S/apifile -S | FileCheck --check-prefix=FOO_J_AND_BAR %s
 
-; Put zed1 and zed2 in the symbol table. If the address is not relevant, we
-; internalize them.
-; RUN: opt < %s -internalize -internalize-dso-list zed1,zed2,zed3 -S | FileCheck --check-prefix=ZEDS %s
-
 ; ALL: @i = internal global
 ; FOO_AND_J: @i = internal global
 ; FOO_AND_BAR: @i = internal global
@@ -29,18 +25,6 @@
 ; FOO_J_AND_BAR: @j = global
 @j = global i32 0
 
-; ZEDS: @zed1 = internal global i32 42
- at zed1 = linkonce_odr global i32 42
-
-; ZEDS: @zed2 = internal unnamed_addr global i32 42
- at zed2 = linkonce_odr unnamed_addr global i32 42
-
-; ZEDS: @zed3 = linkonce_odr global i32 42
- at zed3 = linkonce_odr global i32 42
-define i32* @get_zed3() {
-       ret i32* @zed3
-}
-
 ; ALL: define internal void @main() {
 ; FOO_AND_J: define internal void @main() {
 ; FOO_AND_BAR: define internal void @main() {

Modified: llvm/trunk/tools/gold/gold-plugin.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/gold/gold-plugin.cpp?rev=193800&r1=193799&r2=193800&view=diff
==============================================================================
--- llvm/trunk/tools/gold/gold-plugin.cpp (original)
+++ llvm/trunk/tools/gold/gold-plugin.cpp Thu Oct 31 15:51:58 2013
@@ -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(
     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(
         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(
   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
       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";
       }
     }
   }

Modified: llvm/trunk/tools/llvm-lto/llvm-lto.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-lto/llvm-lto.cpp?rev=193800&r1=193799&r2=193800&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-lto/llvm-lto.cpp (original)
+++ llvm/trunk/tools/llvm-lto/llvm-lto.cpp Thu Oct 31 15:51:58 2013
@@ -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;

Modified: llvm/trunk/tools/lto/lto.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/lto.cpp?rev=193800&r1=193799&r2=193800&view=diff
==============================================================================
--- llvm/trunk/tools/lto/lto.cpp (original)
+++ llvm/trunk/tools/lto/lto.cpp Thu Oct 31 15:51:58 2013
@@ -260,10 +260,6 @@ void lto_codegen_add_must_preserve_symbo
   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).

Modified: llvm/trunk/tools/lto/lto.exports
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/lto.exports?rev=193800&r1=193799&r2=193800&view=diff
==============================================================================
--- llvm/trunk/tools/lto/lto.exports (original)
+++ llvm/trunk/tools/lto/lto.exports Thu Oct 31 15:51:58 2013
@@ -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





More information about the llvm-commits mailing list