]> granicus.if.org Git - llvm/commitdiff
IR: Introduce local_unnamed_addr attribute.
authorPeter Collingbourne <peter@pcc.me.uk>
Tue, 14 Jun 2016 21:01:22 +0000 (21:01 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Tue, 14 Jun 2016 21:01:22 +0000 (21:01 +0000)
If a local_unnamed_addr attribute is attached to a global, the address
is known to be insignificant within the module. It is distinct from the
existing unnamed_addr attribute in that it only describes a local property
of the module rather than a global property of the symbol.

This attribute is intended to be used by the code generator and LTO to allow
the linker to decide whether the global needs to be in the symbol table. It is
possible to exclude a global from the symbol table if three things are true:
- This attribute is present on every instance of the global (which means that
  the normal rule that the global must have a unique address can be broken without
  being observable by the program by performing comparisons against the global's
  address)
- The global has linkonce_odr linkage (which means that each linkage unit must have
  its own copy of the global if it requires one, and the copy in each linkage unit
  must be the same)
- It is a constant or a function (which means that the program cannot observe that
  the unique-address rule has been broken by writing to the global)

Although this attribute could in principle be computed from the module
contents, LTO clients (i.e. linkers) will normally need to be able to compute
this property as part of symbol resolution, and it would be inefficient to
materialize every module just to compute it.

See:
http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20160509/356401.html
http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20160516/356738.html
for earlier discussion.

Part of the fix for PR27553.

Differential Revision: http://reviews.llvm.org/D20348

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@272709 91177308-0d34-0410-b5e6-96231b3b80d8

55 files changed:
docs/BitCodeFormat.rst
docs/LangRef.rst
include/llvm/IR/GlobalValue.h
lib/Analysis/InstructionSimplify.cpp
lib/AsmParser/LLLexer.cpp
lib/AsmParser/LLParser.cpp
lib/AsmParser/LLParser.h
lib/AsmParser/LLToken.h
lib/Bitcode/Reader/BitcodeReader.cpp
lib/Bitcode/Writer/BitcodeWriter.cpp
lib/CodeGen/Analysis.cpp
lib/CodeGen/AsmPrinter/AsmPrinter.cpp
lib/CodeGen/TargetLoweringObjectFileImpl.cpp
lib/ExecutionEngine/Orc/IndirectionUtils.cpp
lib/IR/AsmWriter.cpp
lib/IR/Core.cpp
lib/IR/Globals.cpp
lib/IR/IRBuilder.cpp
lib/IR/Verifier.cpp
lib/Linker/IRMover.cpp
lib/Linker/LinkModules.cpp
lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp
lib/Target/TargetLoweringObjectFile.cpp
lib/Transforms/IPO/ConstantMerge.cpp
lib/Transforms/IPO/GlobalOpt.cpp
lib/Transforms/IPO/MergeFunctions.cpp
lib/Transforms/Instrumentation/AddressSanitizer.cpp
lib/Transforms/Instrumentation/EfficiencySanitizer.cpp
lib/Transforms/Instrumentation/GCOVProfiling.cpp
lib/Transforms/Instrumentation/InstrProfiling.cpp
lib/Transforms/Scalar/LoopIdiomRecognize.cpp
lib/Transforms/Utils/FunctionImportUtils.cpp
lib/Transforms/Utils/GlobalStatus.cpp
lib/Transforms/Utils/SimplifyCFG.cpp
test/Assembler/local-unnamed-addr.ll [new file with mode: 0644]
test/Bitcode/compatibility.ll
test/CodeGen/PowerPC/weak_def_can_be_hidden.ll
test/CodeGen/X86/weak_def_can_be_hidden.ll
test/Feature/OperandBundles/pr26510.ll
test/LTO/X86/cfi_endproc.ll
test/LTO/X86/linkonce_odr_func.ll
test/Other/constant-fold-gep.ll
test/Transforms/GlobalOpt/2010-10-19-WeakOdr.ll
test/Transforms/GlobalOpt/alias-used-address-space.ll
test/Transforms/GlobalOpt/alias-used.ll
test/Transforms/GlobalOpt/assume.ll
test/Transforms/GlobalOpt/constantfold-initializers.ll
test/Transforms/GlobalOpt/ctor-list-opt-inbounds.ll
test/Transforms/GlobalOpt/invariant.group.barrier.ll
test/Transforms/GlobalOpt/invoke.ll
test/Transforms/GlobalOpt/pr21191.ll
test/Transforms/GlobalOpt/unnamed-addr.ll
test/tools/gold/X86/coff.ll
test/tools/gold/X86/emit-llvm.ll
tools/gold/gold-plugin.cpp

index ac051c49bc8ec2212d32b72d96fd156e06d9fac0..f9989936a1fc644b57ffe1e48b082851f34c9ef4 100644 (file)
@@ -731,8 +731,14 @@ global variable. The operand fields are:
   * ``initialexec``: code 3
   * ``localexec``: code 4
 
-* *unnamed_addr*: If present and non-zero, indicates that the variable has
-  ``unnamed_addr``
+.. _bcunnamedaddr:
+
+* *unnamed_addr*: If present, an encoding of the ``unnamed_addr`` attribute of this
+  variable:
+
+  * not ``unnamed_addr``: code 0
+  * ``unnamed_addr``: code 1
+  * ``local_unnamed_addr``: code 2
 
 .. _bcdllstorageclass:
 
@@ -791,8 +797,8 @@ function. The operand fields are:
 * *gc*: If present and nonzero, the 1-based garbage collector index in the table
   of `MODULE_CODE_GCNAME`_ entries.
 
-* *unnamed_addr*: If present and non-zero, indicates that the function has
-  ``unnamed_addr``
+* *unnamed_addr*: If present, an encoding of the
+  :ref:`unnamed_addr<bcunnamedaddr>` attribute of this function
 
 * *prologuedata*: If non-zero, the value index of the prologue data for this function,
   plus 1.
@@ -830,8 +836,8 @@ fields are
 * *threadlocal*: If present, an encoding of the
   :ref:`thread local property<bcthreadlocal>` of the alias
 
-* *unnamed_addr*: If present and non-zero, indicates that the alias has
-  ``unnamed_addr``
+* *unnamed_addr*: If present, an encoding of the
+  :ref:`unnamed_addr<bcunnamedaddr>` attribute of this alias
 
 MODULE_CODE_PURGEVALS Record
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
index 1645371787e4d14cbbf5f6fd9d868fe9d35a768f..086df648da47f05212deaf7e7b77de51b74a9f42 100644 (file)
@@ -589,6 +589,9 @@ initializer. Note that a constant with significant address *can* be
 merged with a ``unnamed_addr`` constant, the result being a constant
 whose address is significant.
 
+If the ``local_unnamed_addr`` attribute is given, the address is known to
+not be significant within the module.
+
 A global variable may be declared to reside in a target-specific
 numbered address space. For targets that support them, address spaces
 may affect how optimizations are performed and/or what target
@@ -628,7 +631,8 @@ Variables and aliases can have a
 Syntax::
 
       @<GlobalVarName> = [Linkage] [Visibility] [DLLStorageClass] [ThreadLocal]
-                         [unnamed_addr] [AddrSpace] [ExternallyInitialized]
+                         [(unnamed_addr|local_unnamed_addr)] [AddrSpace]
+                         [ExternallyInitialized]
                          <global | constant> <Type> [<InitializerConstant>]
                          [, section "name"] [, comdat [($name)]]
                          [, align <Alignment>] (, !name !N)*
@@ -675,14 +679,14 @@ an optional list of attached :ref:`metadata <metadata>`,
 an opening curly brace, a list of basic blocks, and a closing curly brace.
 
 LLVM function declarations consist of the "``declare``" keyword, an
-optional :ref:`linkage type <linkage>`, an optional :ref:`visibility
-style <visibility>`, an optional :ref:`DLL storage class <dllstorageclass>`,
-an optional :ref:`calling convention <callingconv>`,
-an optional ``unnamed_addr`` attribute, a return type, an optional
-:ref:`parameter attribute <paramattrs>` for the return type, a function
-name, a possibly empty list of arguments, an optional alignment, an optional
-:ref:`garbage collector name <gc>`, an optional :ref:`prefix <prefixdata>`,
-and an optional :ref:`prologue <prologuedata>`.
+optional :ref:`linkage type <linkage>`, an optional :ref:`visibility style
+<visibility>`, an optional :ref:`DLL storage class <dllstorageclass>`, an
+optional :ref:`calling convention <callingconv>`, an optional ``unnamed_addr``
+or ``local_unnamed_addr`` attribute, a return type, an optional :ref:`parameter
+attribute <paramattrs>` for the return type, a function name, a possibly
+empty list of arguments, an optional alignment, an optional :ref:`garbage
+collector name <gc>`, an optional :ref:`prefix <prefixdata>`, and an optional
+:ref:`prologue <prologuedata>`.
 
 A function definition contains a list of basic blocks, forming the CFG (Control
 Flow Graph) for the function. Each basic block may optionally start with a label
@@ -713,14 +717,17 @@ alignment. All alignments must be a power of 2.
 If the ``unnamed_addr`` attribute is given, the address is known to not
 be significant and two identical functions can be merged.
 
+If the ``local_unnamed_addr`` attribute is given, the address is known to
+not be significant within the module.
+
 Syntax::
 
     define [linkage] [visibility] [DLLStorageClass]
            [cconv] [ret attrs]
            <ResultType> @<FunctionName> ([argument list])
-           [unnamed_addr] [fn Attrs] [section "name"] [comdat [($name)]]
-           [align N] [gc] [prefix Constant] [prologue Constant]
-           [personality Constant] (!name !N)* { ... }
+           [(unnamed_addr|local_unnamed_addr)] [fn Attrs] [section "name"]
+           [comdat [($name)]] [align N] [gc] [prefix Constant]
+           [prologue Constant] [personality Constant] (!name !N)* { ... }
 
 The argument list is a comma separated sequence of arguments where each
 argument is of the following form:
@@ -747,7 +754,7 @@ Aliases may have an optional :ref:`linkage type <linkage>`, an optional
 
 Syntax::
 
-    @<Name> = [Linkage] [Visibility] [DLLStorageClass] [ThreadLocal] [unnamed_addr] alias <AliaseeTy>, <AliaseeTy>* @<Aliasee>
+    @<Name> = [Linkage] [Visibility] [DLLStorageClass] [ThreadLocal] [(unnamed_addr|local_unnamed_addr)] alias <AliaseeTy>, <AliaseeTy>* @<Aliasee>
 
 The linkage must be one of ``private``, ``internal``, ``linkonce``, ``weak``,
 ``linkonce_odr``, ``weak_odr``, ``external``. Note that some system linkers
@@ -757,6 +764,9 @@ Aliases that are not ``unnamed_addr`` are guaranteed to have the same address as
 the aliasee expression. ``unnamed_addr`` ones are only guaranteed to point
 to the same content.
 
+If the ``local_unnamed_addr`` attribute is given, the address is known to
+not be significant within the module.
+
 Since aliases are only a second name, some restrictions apply, of which
 some can only be checked when producing an object file:
 
index c6a4b3fdb91cb27071bab1f6fac4679c6ef7b07f..09682f7aa349abf2330235581d4eef4344b027d3 100644 (file)
@@ -70,8 +70,9 @@ protected:
               LinkageTypes Linkage, const Twine &Name, unsigned AddressSpace)
       : Constant(PointerType::get(Ty, AddressSpace), VTy, Ops, NumOps),
         ValueType(Ty), Linkage(Linkage), Visibility(DefaultVisibility),
-        UnnamedAddr(0), DllStorageClass(DefaultStorageClass),
-        ThreadLocal(NotThreadLocal), IntID((Intrinsic::ID)0U), Parent(nullptr) {
+        UnnamedAddrVal(unsigned(UnnamedAddr::None)),
+        DllStorageClass(DefaultStorageClass), ThreadLocal(NotThreadLocal),
+        IntID((Intrinsic::ID)0U), Parent(nullptr) {
     setName(Name);
   }
 
@@ -80,7 +81,7 @@ protected:
   // them.
   unsigned Linkage : 4;       // The linkage of this global
   unsigned Visibility : 2;    // The visibility style of this global
-  unsigned UnnamedAddr : 1;   // This value's address is not significant
+  unsigned UnnamedAddrVal : 2; // This value's address is not significant
   unsigned DllStorageClass : 2; // DLL storage class
 
   unsigned ThreadLocal : 3; // Is this symbol "Thread Local", if so, what is
@@ -89,7 +90,7 @@ protected:
 
 private:
   // Give subclasses access to what otherwise would be wasted padding.
-  // (19 + 3 + 2 + 1 + 2 + 5) == 32.
+  // (19 + 4 + 2 + 2 + 2 + 3) == 32.
   unsigned SubClassData : GlobalValueSubClassDataBits;
 
   friend class Constant;
@@ -153,8 +154,37 @@ public:
 
   unsigned getAlignment() const;
 
-  bool hasUnnamedAddr() const { return UnnamedAddr; }
-  void setUnnamedAddr(bool Val) { UnnamedAddr = Val; }
+  enum class UnnamedAddr {
+    None,
+    Local,
+    Global,
+  };
+
+  bool hasGlobalUnnamedAddr() const {
+    return getUnnamedAddr() == UnnamedAddr::Global;
+  }
+
+  /// Returns true if this value's address is not significant in this module.
+  /// This attribute is intended to be used only by the code generator and LTO
+  /// to allow the linker to decide whether the global needs to be in the symbol
+  /// table. It should probably not be used in optimizations, as the value may
+  /// have uses outside the module; use hasGlobalUnnamedAddr() instead.
+  bool hasAtLeastLocalUnnamedAddr() const {
+    return getUnnamedAddr() != UnnamedAddr::None;
+  }
+
+  UnnamedAddr getUnnamedAddr() const {
+    return UnnamedAddr(UnnamedAddrVal);
+  }
+  void setUnnamedAddr(UnnamedAddr Val) { UnnamedAddrVal = unsigned(Val); }
+
+  static UnnamedAddr getMinUnnamedAddr(UnnamedAddr A, UnnamedAddr B) {
+    if (A == UnnamedAddr::None || B == UnnamedAddr::None)
+      return UnnamedAddr::None;
+    if (A == UnnamedAddr::Local || B == UnnamedAddr::Local)
+      return UnnamedAddr::Local;
+    return UnnamedAddr::Global;
+  }
 
   bool hasComdat() const { return getComdat() != nullptr; }
   Comdat *getComdat();
index 43dcaec1373e489cba3faca6f337419f391b8d15..a9fed16f8aa8d1690c6cfb4025e4c32316882e84 100644 (file)
@@ -2086,7 +2086,7 @@ computePointerICmp(const DataLayout &DL, const TargetLibraryInfo *TLI,
           return AI->getParent() && AI->getFunction() && AI->isStaticAlloca();
         if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
           return (GV->hasLocalLinkage() || GV->hasHiddenVisibility() ||
-                  GV->hasProtectedVisibility() || GV->hasUnnamedAddr()) &&
+                  GV->hasProtectedVisibility() || GV->hasGlobalUnnamedAddr()) &&
                  !GV->isThreadLocal();
         if (const Argument *A = dyn_cast<Argument>(V))
           return A->hasByValAttr();
index 1ba698ebd6110ab38cde3606a099e2e5baeef9bb..a3d1346e7d26a5d2b36a9d315df81642e4bd3fc8 100644 (file)
@@ -513,6 +513,7 @@ lltok::Kind LLLexer::LexIdentifier() {
   KEYWORD(hidden);
   KEYWORD(protected);
   KEYWORD(unnamed_addr);
+  KEYWORD(local_unnamed_addr);
   KEYWORD(externally_initialized);
   KEYWORD(extern_weak);
   KEYWORD(external);
index cc7b98fa56dea68f2d24316fd05282c0158ecf38..2725386f8da575f7a07da9f8fee662eb328b0cc4 100644 (file)
@@ -429,6 +429,17 @@ bool LLParser::ParseGlobalType(bool &IsConstant) {
   return false;
 }
 
+bool LLParser::ParseOptionalUnnamedAddr(
+    GlobalVariable::UnnamedAddr &UnnamedAddr) {
+  if (EatIfPresent(lltok::kw_unnamed_addr))
+    UnnamedAddr = GlobalValue::UnnamedAddr::Global;
+  else if (EatIfPresent(lltok::kw_local_unnamed_addr))
+    UnnamedAddr = GlobalValue::UnnamedAddr::Local;
+  else
+    UnnamedAddr = GlobalValue::UnnamedAddr::None;
+  return false;
+}
+
 /// ParseUnnamedGlobal:
 ///   OptionalVisibility (ALIAS | IFUNC) ...
 ///   OptionalLinkage OptionalVisibility OptionalDLLStorageClass
@@ -455,9 +466,9 @@ bool LLParser::ParseUnnamedGlobal() {
   bool HasLinkage;
   unsigned Linkage, Visibility, DLLStorageClass;
   GlobalVariable::ThreadLocalMode TLM;
-  bool UnnamedAddr;
+  GlobalVariable::UnnamedAddr UnnamedAddr;
   if (ParseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass) ||
-      ParseOptionalThreadLocal(TLM) || parseOptionalUnnamedAddr(UnnamedAddr))
+      ParseOptionalThreadLocal(TLM) || ParseOptionalUnnamedAddr(UnnamedAddr))
     return true;
 
   if (Lex.getKind() != lltok::kw_alias && Lex.getKind() != lltok::kw_ifunc)
@@ -481,10 +492,10 @@ bool LLParser::ParseNamedGlobal() {
   bool HasLinkage;
   unsigned Linkage, Visibility, DLLStorageClass;
   GlobalVariable::ThreadLocalMode TLM;
-  bool UnnamedAddr;
+  GlobalVariable::UnnamedAddr UnnamedAddr;
   if (ParseToken(lltok::equal, "expected '=' in global variable") ||
       ParseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass) ||
-      ParseOptionalThreadLocal(TLM) || parseOptionalUnnamedAddr(UnnamedAddr))
+      ParseOptionalThreadLocal(TLM) || ParseOptionalUnnamedAddr(UnnamedAddr))
     return true;
 
   if (Lex.getKind() != lltok::kw_alias && Lex.getKind() != lltok::kw_ifunc)
@@ -659,11 +670,10 @@ static bool isValidVisibilityForLinkage(unsigned V, unsigned L) {
 ///
 /// Everything through OptionalUnnamedAddr has already been parsed.
 ///
-bool LLParser::parseIndirectSymbol(const std::string &Name, LocTy NameLoc,
-                                   unsigned L, unsigned Visibility,
-                                   unsigned DLLStorageClass,
-                                   GlobalVariable::ThreadLocalMode TLM,
-                                   bool UnnamedAddr) {
+bool LLParser::parseIndirectSymbol(
+    const std::string &Name, LocTy NameLoc, unsigned L, unsigned Visibility,
+    unsigned DLLStorageClass, GlobalVariable::ThreadLocalMode TLM,
+    GlobalVariable::UnnamedAddr UnnamedAddr) {
   bool IsAlias;
   if (Lex.getKind() == lltok::kw_alias)
     IsAlias = true;
@@ -799,7 +809,7 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc,
                            unsigned Linkage, bool HasLinkage,
                            unsigned Visibility, unsigned DLLStorageClass,
                            GlobalVariable::ThreadLocalMode TLM,
-                           bool UnnamedAddr) {
+                           GlobalVariable::UnnamedAddr UnnamedAddr) {
   if (!isValidVisibilityForLinkage(Visibility, Linkage))
     return Error(NameLoc,
                  "symbol with local linkage must have default visibility");
@@ -4580,7 +4590,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
   std::string Section;
   unsigned Alignment;
   std::string GC;
-  bool UnnamedAddr;
+  GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::UnnamedAddr::None;
   LocTy UnnamedAddrLoc;
   Constant *Prefix = nullptr;
   Constant *Prologue = nullptr;
@@ -4588,8 +4598,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
   Comdat *C;
 
   if (ParseArgumentList(ArgList, isVarArg) ||
-      ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr,
-                         &UnnamedAddrLoc) ||
+      ParseOptionalUnnamedAddr(UnnamedAddr) ||
       ParseFnAttributeValuePairs(FuncAttrs, FwdRefAttrGrps, false,
                                  BuiltinLoc) ||
       (EatIfPresent(lltok::kw_section) &&
index 7c32f2c7facaaac0731303a0a5aaac3fffb7fc03..479ff96bc8a352afeb1ab01aca2cedf358d5ac4e 100644 (file)
@@ -226,9 +226,7 @@ namespace llvm {
 
     bool ParseTLSModel(GlobalVariable::ThreadLocalMode &TLM);
     bool ParseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM);
-    bool parseOptionalUnnamedAddr(bool &UnnamedAddr) {
-      return ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr);
-    }
+    bool ParseOptionalUnnamedAddr(GlobalVariable::UnnamedAddr &UnnamedAddr);
     bool ParseOptionalAddrSpace(unsigned &AddrSpace);
     bool ParseOptionalParamAttrs(AttrBuilder &B);
     bool ParseOptionalReturnAttrs(AttrBuilder &B);
@@ -275,12 +273,13 @@ namespace llvm {
     bool ParseGlobal(const std::string &Name, LocTy Loc, unsigned Linkage,
                      bool HasLinkage, unsigned Visibility,
                      unsigned DLLStorageClass,
-                     GlobalVariable::ThreadLocalMode TLM, bool UnnamedAddr);
+                     GlobalVariable::ThreadLocalMode TLM,
+                     GlobalVariable::UnnamedAddr UnnamedAddr);
     bool parseIndirectSymbol(const std::string &Name, LocTy Loc,
                              unsigned Linkage, unsigned Visibility,
                              unsigned DLLStorageClass,
                              GlobalVariable::ThreadLocalMode TLM,
-                             bool UnnamedAddr);
+                             GlobalVariable::UnnamedAddr UnnamedAddr);
     bool parseComdat();
     bool ParseStandaloneMetadata();
     bool ParseNamedMetadata();
index 85881d6f11b14069221d9fd4d1d530287244007d..be3697aefddbaf104f8e87beab55665962b0c2d9 100644 (file)
@@ -60,6 +60,7 @@ enum Kind {
   kw_hidden,
   kw_protected,
   kw_unnamed_addr,
+  kw_local_unnamed_addr,
   kw_externally_initialized,
   kw_extern_weak,
   kw_external,
index 3bba0250af56e41d406f07d3c2982f631dcd02e3..ac72f69c76ee6e0cd8522a1ecd4ad9dbc31e01bd 100644 (file)
@@ -773,6 +773,15 @@ static GlobalVariable::ThreadLocalMode getDecodedThreadLocalMode(unsigned Val) {
   }
 }
 
+static GlobalVariable::UnnamedAddr getDecodedUnnamedAddrType(unsigned Val) {
+  switch (Val) {
+    default: // Map unknown to UnnamedAddr::None.
+    case 0: return GlobalVariable::UnnamedAddr::None;
+    case 1: return GlobalVariable::UnnamedAddr::Global;
+    case 2: return GlobalVariable::UnnamedAddr::Local;
+  }
+}
+
 static int getDecodedCastOpcode(unsigned Val) {
   switch (Val) {
   default: return -1;
@@ -3791,9 +3800,9 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit,
       if (Record.size() > 7)
         TLM = getDecodedThreadLocalMode(Record[7]);
 
-      bool UnnamedAddr = false;
+      GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::UnnamedAddr::None;
       if (Record.size() > 8)
-        UnnamedAddr = Record[8];
+        UnnamedAddr = getDecodedUnnamedAddrType(Record[8]);
 
       bool ExternallyInitialized = false;
       if (Record.size() > 9)
@@ -3828,6 +3837,7 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit,
       } else if (hasImplicitComdat(RawLinkage)) {
         NewGV->setComdat(reinterpret_cast<Comdat *>(1));
       }
+
       break;
     }
     case bitc::MODULE_CODE_GLOBALVAR_ATTACHMENT: {
@@ -3885,9 +3895,9 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit,
           return error("Invalid ID");
         Func->setGC(GCTable[Record[8] - 1]);
       }
-      bool UnnamedAddr = false;
+      GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::UnnamedAddr::None;
       if (Record.size() > 9)
-        UnnamedAddr = Record[9];
+        UnnamedAddr = getDecodedUnnamedAddrType(Record[9]);
       Func->setUnnamedAddr(UnnamedAddr);
       if (Record.size() > 10 && Record[10] != 0)
         FunctionPrologues.push_back(std::make_pair(Func, Record[10]-1));
@@ -3974,7 +3984,7 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit,
       if (OpNum != Record.size())
         NewGA->setThreadLocalMode(getDecodedThreadLocalMode(Record[OpNum++]));
       if (OpNum != Record.size())
-        NewGA->setUnnamedAddr(Record[OpNum++]);
+        NewGA->setUnnamedAddr(getDecodedUnnamedAddrType(Record[OpNum++]));
       ValueList.push_back(NewGA);
       IndirectSymbolInits.push_back(std::make_pair(NewGA, Val));
       break;
index 06a4ef1892de349e8a72a0fcd8ed2e9a393f37d8..4699e7dac77a44c8f122190dc54ead56db6ccebf 100644 (file)
@@ -996,6 +996,15 @@ static unsigned getEncodedComdatSelectionKind(const Comdat &C) {
   llvm_unreachable("Invalid selection kind");
 }
 
+static unsigned getEncodedUnnamedAddr(const GlobalValue &GV) {
+  switch (GV.getUnnamedAddr()) {
+  case GlobalValue::UnnamedAddr::None:   return 0;
+  case GlobalValue::UnnamedAddr::Local:  return 2;
+  case GlobalValue::UnnamedAddr::Global: return 1;
+  }
+  llvm_unreachable("Invalid unnamed_addr");
+}
+
 void ModuleBitcodeWriter::writeComdats() {
   SmallVector<unsigned, 64> Vals;
   for (const Comdat *C : VE.getComdats()) {
@@ -1157,12 +1166,13 @@ void ModuleBitcodeWriter::writeModuleInfo() {
     Vals.push_back(GV.hasSection() ? SectionMap[GV.getSection()] : 0);
     if (GV.isThreadLocal() ||
         GV.getVisibility() != GlobalValue::DefaultVisibility ||
-        GV.hasUnnamedAddr() || GV.isExternallyInitialized() ||
+        GV.getUnnamedAddr() != GlobalValue::UnnamedAddr::None ||
+        GV.isExternallyInitialized() ||
         GV.getDLLStorageClass() != GlobalValue::DefaultStorageClass ||
         GV.hasComdat()) {
       Vals.push_back(getEncodedVisibility(GV));
       Vals.push_back(getEncodedThreadLocalMode(GV));
-      Vals.push_back(GV.hasUnnamedAddr());
+      Vals.push_back(getEncodedUnnamedAddr(GV));
       Vals.push_back(GV.isExternallyInitialized());
       Vals.push_back(getEncodedDLLStorageClass(GV));
       Vals.push_back(GV.hasComdat() ? VE.getComdatID(GV.getComdat()) : 0);
@@ -1188,7 +1198,7 @@ void ModuleBitcodeWriter::writeModuleInfo() {
     Vals.push_back(F.hasSection() ? SectionMap[F.getSection()] : 0);
     Vals.push_back(getEncodedVisibility(F));
     Vals.push_back(F.hasGC() ? GCMap[F.getGC()] : 0);
-    Vals.push_back(F.hasUnnamedAddr());
+    Vals.push_back(getEncodedUnnamedAddr(F));
     Vals.push_back(F.hasPrologueData() ? (VE.getValueID(F.getPrologueData()) + 1)
                                        : 0);
     Vals.push_back(getEncodedDLLStorageClass(F));
@@ -1205,7 +1215,8 @@ void ModuleBitcodeWriter::writeModuleInfo() {
 
   // Emit the alias information.
   for (const GlobalAlias &A : M.aliases()) {
-    // ALIAS: [alias type, aliasee val#, linkage, visibility]
+    // ALIAS: [alias type, aliasee val#, linkage, visibility, dllstorageclass,
+    //         threadlocal, unnamed_addr]
     Vals.push_back(VE.getTypeID(A.getValueType()));
     Vals.push_back(A.getType()->getAddressSpace());
     Vals.push_back(VE.getValueID(A.getAliasee()));
@@ -1213,7 +1224,7 @@ void ModuleBitcodeWriter::writeModuleInfo() {
     Vals.push_back(getEncodedVisibility(A));
     Vals.push_back(getEncodedDLLStorageClass(A));
     Vals.push_back(getEncodedThreadLocalMode(A));
-    Vals.push_back(A.hasUnnamedAddr());
+    Vals.push_back(getEncodedUnnamedAddr(A));
     unsigned AbbrevToUse = 0;
     Stream.EmitRecord(bitc::MODULE_CODE_ALIAS, Vals, AbbrevToUse);
     Vals.clear();
index ef405484e84c30264945096689bdecbb570c61c3..73bd3d29eae59a97fd8d839ede3725b01fe971f7 100644 (file)
@@ -623,7 +623,9 @@ bool llvm::canBeOmittedFromSymbolTable(const GlobalValue *GV) {
   if (!GV->hasLinkOnceODRLinkage())
     return false;
 
-  if (GV->hasUnnamedAddr())
+  // We assume that anyone who sets global unnamed_addr on a non-constant knows
+  // what they're doing.
+  if (GV->hasGlobalUnnamedAddr())
     return true;
 
   // If it is a non constant variable, it needs to be uniqued across shared
@@ -633,21 +635,7 @@ bool llvm::canBeOmittedFromSymbolTable(const GlobalValue *GV) {
       return false;
   }
 
-  // An alias can point to a variable. We could try to resolve the alias to
-  // decide, but for now just don't hide them.
-  if (isa<GlobalAlias>(GV))
-    return false;
-
-  // If we don't see every use, we have to be conservative and assume the value
-  // address is significant.
-  if (GV->getParent()->getMaterializer())
-    return false;
-
-  GlobalStatus GS;
-  if (GlobalStatus::analyzeGlobal(GV, GS))
-    return false;
-
-  return !GS.IsCompared;
+  return GV->hasAtLeastLocalUnnamedAddr();
 }
 
 // FIXME: make this a proper option
index d39881d9ce3e299032459f99e508cb428144d132..02640f55fa2340515e28f125efab18670f93f00a 100644 (file)
@@ -1001,7 +1001,7 @@ static bool isGOTEquivalentCandidate(const GlobalVariable *GV,
   // Global GOT equivalents are unnamed private globals with a constant
   // pointer initializer to another global symbol. They must point to a
   // GlobalVariable or Function, i.e., as GlobalValue.
-  if (!GV->hasUnnamedAddr() || !GV->hasInitializer() || !GV->isConstant() ||
+  if (!GV->hasGlobalUnnamedAddr() || !GV->hasInitializer() || !GV->isConstant() ||
       !GV->isDiscardableIfUnused() || !dyn_cast<GlobalValue>(GV->getOperand(0)))
     return false;
 
index f7ba62ff2315a6e0f8883cc9a673449af7e8b9e6..6d5dd5fa4d5a98cc21de7b698888547c7458514f 100644 (file)
@@ -429,7 +429,7 @@ const MCExpr *TargetLoweringObjectFileELF::lowerRelativeReference(
     const TargetMachine &TM) const {
   // We may only use a PLT-relative relocation to refer to unnamed_addr
   // functions.
-  if (!LHS->hasUnnamedAddr() || !LHS->getValueType()->isFunctionTy())
+  if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy())
     return nullptr;
 
   // Basic sanity checks.
index c7b97865ab7e597803f59c9c0a95494ff5c0f0c1..6f7c29feef0dfa0b5c840924acd39ee842cf3880 100644 (file)
@@ -144,7 +144,7 @@ static void raiseVisibilityOnValue(GlobalValue &V, GlobalRenamer &R) {
     V.setLinkage(GlobalValue::ExternalLinkage);
     V.setVisibility(GlobalValue::HiddenVisibility);
   }
-  V.setUnnamedAddr(false);
+  V.setUnnamedAddr(GlobalValue::UnnamedAddr::None);
   assert(!R.needsRenaming(V) && "Invalid global name.");
 }
 
index 24b92b8eb3c1b596588dab95d1bc34486804aa9f..0d488c27aa8a7acc61091a7c2ac093a720e2e076 100644 (file)
@@ -2426,6 +2426,17 @@ static void PrintThreadLocalModel(GlobalVariable::ThreadLocalMode TLM,
   }
 }
 
+static StringRef getUnnamedAddrEncoding(GlobalVariable::UnnamedAddr UA) {
+  switch (UA) {
+  case GlobalVariable::UnnamedAddr::None:
+    return "";
+  case GlobalVariable::UnnamedAddr::Local:
+    return "local_unnamed_addr";
+  case GlobalVariable::UnnamedAddr::Global:
+    return "unnamed_addr";
+  }
+}
+
 static void maybePrintComdat(formatted_raw_ostream &Out,
                              const GlobalObject &GO) {
   const Comdat *C = GO.getComdat();
@@ -2458,8 +2469,9 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
   PrintVisibility(GV->getVisibility(), Out);
   PrintDLLStorageClass(GV->getDLLStorageClass(), Out);
   PrintThreadLocalModel(GV->getThreadLocalMode(), Out);
-  if (GV->hasUnnamedAddr())
-    Out << "unnamed_addr ";
+  StringRef UA = getUnnamedAddrEncoding(GV->getUnnamedAddr());
+  if (!UA.empty())
+      Out << UA << ' ';
 
   if (unsigned AddressSpace = GV->getType()->getAddressSpace())
     Out << "addrspace(" << AddressSpace << ") ";
@@ -2499,8 +2511,9 @@ void AssemblyWriter::printIndirectSymbol(const GlobalIndirectSymbol *GIS) {
   PrintVisibility(GIS->getVisibility(), Out);
   PrintDLLStorageClass(GIS->getDLLStorageClass(), Out);
   PrintThreadLocalModel(GIS->getThreadLocalMode(), Out);
-  if (GIS->hasUnnamedAddr())
-    Out << "unnamed_addr ";
+  StringRef UA = getUnnamedAddrEncoding(GIS->getUnnamedAddr());
+  if (!UA.empty())
+      Out << UA << ' ';
 
   if (isa<GlobalAlias>(GIS))
     Out << "alias ";
@@ -2656,8 +2669,9 @@ void AssemblyWriter::printFunction(const Function *F) {
     Out << "...";  // Output varargs portion of signature!
   }
   Out << ')';
-  if (F->hasUnnamedAddr())
-    Out << " unnamed_addr";
+  StringRef UA = getUnnamedAddrEncoding(F->getUnnamedAddr());
+  if (!UA.empty())
+    Out << ' ' << UA;
   if (Attrs.hasAttributes(AttributeSet::FunctionIndex))
     Out << " #" << Machine.getAttributeGroupSlot(Attrs.getFnAttributes());
   if (F->hasSection()) {
index 380fca8c10f7c27068b57af29b3ecd39fd5041de..b044781302c25570a60cb87544786eb39f1f8aee 100644 (file)
@@ -1560,11 +1560,13 @@ void LLVMSetDLLStorageClass(LLVMValueRef Global, LLVMDLLStorageClass Class) {
 }
 
 LLVMBool LLVMHasUnnamedAddr(LLVMValueRef Global) {
-  return unwrap<GlobalValue>(Global)->hasUnnamedAddr();
+  return unwrap<GlobalValue>(Global)->hasGlobalUnnamedAddr();
 }
 
 void LLVMSetUnnamedAddr(LLVMValueRef Global, LLVMBool HasUnnamedAddr) {
-  unwrap<GlobalValue>(Global)->setUnnamedAddr(HasUnnamedAddr);
+  unwrap<GlobalValue>(Global)->setUnnamedAddr(
+      HasUnnamedAddr ? GlobalValue::UnnamedAddr::Global
+                     : GlobalValue::UnnamedAddr::None);
 }
 
 /*--.. Operations on global variables, load and store instructions .........--*/
index d151b9c5dc2485ed524672ae2de5bf4082597415..c5e1b9b9fa033463f1ccb73732dd8187f9d9d2e6 100644 (file)
@@ -51,7 +51,7 @@ Value *GlobalValue::handleOperandChangeImpl(Value *From, Value *To) {
 /// create a GlobalValue) from the GlobalValue Src to this one.
 void GlobalValue::copyAttributesFrom(const GlobalValue *Src) {
   setVisibility(Src->getVisibility());
-  setUnnamedAddr(Src->hasUnnamedAddr());
+  setUnnamedAddr(Src->getUnnamedAddr());
   setDLLStorageClass(Src->getDLLStorageClass());
 }
 
index bc75de2693bc7a7c15818b46a8753e08ef252d38..480e5e5d426326cf33cbeeaf9ff2bf5a1c758213 100644 (file)
@@ -34,7 +34,7 @@ GlobalVariable *IRBuilderBase::CreateGlobalString(StringRef Str,
                                           StrConstant, Name, nullptr,
                                           GlobalVariable::NotThreadLocal,
                                           AddressSpace);
-  GV->setUnnamedAddr(true);
+  GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
   return GV;
 }
 
index 79c9f4d3a1357344c31f6183bc8a7ac6e31b1438..0395f5b36fef76162c25c6abb15299e3ffef7a0a 100644 (file)
@@ -1535,7 +1535,7 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs,
   if (Attrs.hasAttribute(AttributeSet::FunctionIndex,
                          Attribute::JumpTable)) {
     const GlobalValue *GV = cast<GlobalValue>(V);
-    Assert(GV->hasUnnamedAddr(),
+    Assert(GV->hasGlobalUnnamedAddr(),
            "Attribute 'jumptable' requires 'unnamed_addr'", V);
   }
 
index d2c6d78abe22f6432803327a6162978feed408a1..14b0a43030dab4655524f932c0c8c3b466dd5d71 100644 (file)
@@ -791,7 +791,7 @@ IRLinker::linkAppendingVarProto(GlobalVariable *DstGV,
       return stringErr(
           "Appending variables with different visibility need to be linked!");
 
-    if (DstGV->hasUnnamedAddr() != SrcGV->hasUnnamedAddr())
+    if (DstGV->hasGlobalUnnamedAddr() != SrcGV->hasGlobalUnnamedAddr())
       return stringErr(
           "Appending variables with different unnamed_addr need to be linked!");
 
index ff36f90b53f438a8e4208aeae4bf80eaa813f1c8..fae9c95ebe8fb0ec8f806fbfffa7023fab0a3c9e 100644 (file)
@@ -377,9 +377,10 @@ bool ModuleLinker::linkIfNeeded(GlobalValue &GV) {
     DGV->setVisibility(Visibility);
     GV.setVisibility(Visibility);
 
-    bool HasUnnamedAddr = GV.hasUnnamedAddr() && DGV->hasUnnamedAddr();
-    DGV->setUnnamedAddr(HasUnnamedAddr);
-    GV.setUnnamedAddr(HasUnnamedAddr);
+    GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::getMinUnnamedAddr(
+        DGV->getUnnamedAddr(), GV.getUnnamedAddr());
+    DGV->setUnnamedAddr(UnnamedAddr);
+    GV.setUnnamedAddr(UnnamedAddr);
   }
 
   // Don't want to append to global_ctors list, for example, when we
index 5222bed0d25acf95750b502524cf62ed52ccfab0..17b45fa65f14124684d6c43f0c6675a6b1c9dce0 100644 (file)
@@ -694,7 +694,7 @@ void AMDGPUPromoteAlloca::handleAlloca(AllocaInst &I) {
       nullptr,
       GlobalVariable::NotThreadLocal,
       AMDGPUAS::LOCAL_ADDRESS);
-  GV->setUnnamedAddr(true);
+  GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
   GV->setAlignment(I.getAlignment());
 
   Value *TCntY, *TCntZ;
index b2b69025851e13e3a567a241ddb239335e550c3a..fd4936e1904bd4e4eb36aa684201e378c4c372c4 100644 (file)
@@ -174,7 +174,7 @@ SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalValue *GV,
       // If the global is required to have a unique address, it can't be put
       // into a mergable section: just drop it into the general read-only
       // section instead.
-      if (!GVar->hasUnnamedAddr())
+      if (!GVar->hasGlobalUnnamedAddr())
         return SectionKind::getReadOnly();
 
       // If initializer is a null-terminated string, put it in a "cstring"
index 11f40e864601f1dcd868c27c3b5137cd590bd3a0..65b042534f39a91849dd62a999242cfcfb7e2c3f 100644 (file)
@@ -57,7 +57,7 @@ static bool IsBetterCanonical(const GlobalVariable &A,
   if (A.hasLocalLinkage() && !B.hasLocalLinkage())
     return false;
 
-  return A.hasUnnamedAddr();
+  return A.hasGlobalUnnamedAddr();
 }
 
 static unsigned getAlignment(GlobalVariable *GV) {
@@ -152,11 +152,11 @@ static bool mergeConstants(Module &M) {
       if (!Slot || Slot == GV)
         continue;
 
-      if (!Slot->hasUnnamedAddr() && !GV->hasUnnamedAddr())
+      if (!Slot->hasGlobalUnnamedAddr() && !GV->hasGlobalUnnamedAddr())
         continue;
 
-      if (!GV->hasUnnamedAddr())
-        Slot->setUnnamedAddr(false);
+      if (!GV->hasGlobalUnnamedAddr())
+        Slot->setUnnamedAddr(GlobalValue::UnnamedAddr::None);
 
       // Make all uses of the duplicate constant use the canonical version.
       Replacements.push_back(std::make_pair(GV, Slot));
index e66ed8359ffd1e0f7598bc4117f6fd071b012a18..ded55dbb4439303d12837d6eb60d45f132c5b909 100644 (file)
@@ -1942,8 +1942,7 @@ static bool processInternalGlobal(
 static bool
 processGlobal(GlobalValue &GV, TargetLibraryInfo *TLI,
               function_ref<DominatorTree &(Function &)> LookupDomTree) {
-  // Do more involved optimizations if the global is internal.
-  if (!GV.hasLocalLinkage())
+  if (GV.getName().startswith("llvm."))
     return false;
 
   GlobalStatus GS;
@@ -1952,12 +1951,20 @@ processGlobal(GlobalValue &GV, TargetLibraryInfo *TLI,
     return false;
 
   bool Changed = false;
-  if (!GS.IsCompared && !GV.hasUnnamedAddr()) {
-    GV.setUnnamedAddr(true);
-    NumUnnamed++;
-    Changed = true;
+  if (!GS.IsCompared && !GV.hasGlobalUnnamedAddr()) {
+    auto NewUnnamedAddr = GV.hasLocalLinkage() ? GlobalValue::UnnamedAddr::Global
+                                               : GlobalValue::UnnamedAddr::Local;
+    if (NewUnnamedAddr != GV.getUnnamedAddr()) {
+      GV.setUnnamedAddr(NewUnnamedAddr);
+      NumUnnamed++;
+      Changed = true;
+    }
   }
 
+  // Do more involved optimizations if the global is internal.
+  if (!GV.hasLocalLinkage())
+    return Changed;
+
   auto *GVar = dyn_cast<GlobalVariable>(&GV);
   if (!GVar)
     return Changed;
index 27caa07c165ac54df535b06ce9030bc0d28125ad..adf0d3f680bc129600d1728409bc5538e5693fbd 100644 (file)
@@ -1637,7 +1637,7 @@ void MergeFunctions::replaceDirectCallers(Function *Old, Function *New) {
 
 // Replace G with an alias to F if possible, or else a thunk to F. Deletes G.
 void MergeFunctions::writeThunkOrAlias(Function *F, Function *G) {
-  if (HasGlobalAliases && G->hasUnnamedAddr()) {
+  if (HasGlobalAliases && G->hasGlobalUnnamedAddr()) {
     if (G->hasExternalLinkage() || G->hasLocalLinkage() ||
         G->hasWeakLinkage()) {
       writeAlias(F, G);
index 08f148139a237351b7119a25334ef2433f3b0dc3..16a55527c20639eebcdcbad7e40b58eb78b4c2dd 100644 (file)
@@ -832,7 +832,7 @@ static GlobalVariable *createPrivateGlobalForString(Module &M, StringRef Str,
   GlobalVariable *GV =
       new GlobalVariable(M, StrConst->getType(), true,
                          GlobalValue::PrivateLinkage, StrConst, kAsanGenPrefix);
-  if (AllowMerging) GV->setUnnamedAddr(true);
+  if (AllowMerging) GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
   GV->setAlignment(1);  // Strings may not be merged w/o setting align 1.
   return GV;
 }
@@ -849,7 +849,7 @@ static GlobalVariable *createPrivateGlobalForSourceLoc(Module &M,
   auto GV = new GlobalVariable(M, LocStruct->getType(), true,
                                GlobalValue::PrivateLinkage, LocStruct,
                                kAsanGenPrefix);
-  GV->setUnnamedAddr(true);
+  GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
   return GV;
 }
 
index 40a9fce7b0b3f0d36f4043ef145792f3974fb5d3..eafab784e57881fb5363c7dba774c9b81fc2b826 100644 (file)
@@ -137,7 +137,7 @@ static GlobalVariable *createPrivateGlobalForString(Module &M, StringRef Str,
     new GlobalVariable(M, StrConst->getType(), true,
                        GlobalValue::PrivateLinkage, StrConst, "");
   if (AllowMerging)
-    GV->setUnnamedAddr(true);
+    GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
   GV->setAlignment(1);  // Strings may not be merged w/o setting align 1.
   return GV;
 }
index 9b19833cb75b3016f1cef35dda114aa93aab72b0..6b2df2a1d9d9212a7a2215f36afefd6cb83bad64 100644 (file)
@@ -691,7 +691,7 @@ bool GCOVProfiler::emitProfileArcs() {
     FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
     Function *F = Function::Create(FTy, GlobalValue::InternalLinkage,
                                    "__llvm_gcov_init", M);
-    F->setUnnamedAddr(true);
+    F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
     F->setLinkage(GlobalValue::InternalLinkage);
     F->addFnAttr(Attribute::NoInline);
     if (Options.NoRedZone)
@@ -766,7 +766,7 @@ GlobalVariable *GCOVProfiler::buildEdgeLookupTable(
           ConstantArray::get(EdgeTableTy,
                              makeArrayRef(&EdgeTable[0],TableSize)),
           "__llvm_gcda_edge_table");
-  EdgeTableGV->setUnnamedAddr(true);
+  EdgeTableGV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
   return EdgeTableGV;
 }
 
@@ -840,7 +840,7 @@ GlobalVariable *GCOVProfiler::getEdgeStateValue() {
                             ConstantInt::get(Type::getInt32Ty(*Ctx),
                                              0xffffffff),
                             "__llvm_gcov_global_state_pred");
-    GV->setUnnamedAddr(true);
+    GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
   }
   return GV;
 }
@@ -852,7 +852,7 @@ Function *GCOVProfiler::insertCounterWriteout(
   if (!WriteoutF)
     WriteoutF = Function::Create(WriteoutFTy, GlobalValue::InternalLinkage,
                                  "__llvm_gcov_writeout", M);
-  WriteoutF->setUnnamedAddr(true);
+  WriteoutF->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
   WriteoutF->addFnAttr(Attribute::NoInline);
   if (Options.NoRedZone)
     WriteoutF->addFnAttr(Attribute::NoRedZone);
@@ -912,7 +912,7 @@ Function *GCOVProfiler::insertCounterWriteout(
 void GCOVProfiler::insertIndirectCounterIncrement() {
   Function *Fn =
     cast<Function>(GCOVProfiler::getIncrementIndirectCounterFunc());
-  Fn->setUnnamedAddr(true);
+  Fn->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
   Fn->setLinkage(GlobalValue::InternalLinkage);
   Fn->addFnAttr(Attribute::NoInline);
   if (Options.NoRedZone)
@@ -969,7 +969,7 @@ insertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> > CountersBySP) {
                               "__llvm_gcov_flush", M);
   else
     FlushF->setLinkage(GlobalValue::InternalLinkage);
-  FlushF->setUnnamedAddr(true);
+  FlushF->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
   FlushF->addFnAttr(Attribute::NoInline);
   if (Options.NoRedZone)
     FlushF->addFnAttr(Attribute::NoRedZone);
index 7bb3bdc11375f595aa9ba8fd8cb388cd6bd88b54..a3fc16c9a9f73310f3fbe06b8e5950cca94036ac 100644 (file)
@@ -506,7 +506,7 @@ void InstrProfiling::emitRegistration() {
   auto *RegisterFTy = FunctionType::get(VoidTy, false);
   auto *RegisterF = Function::Create(RegisterFTy, GlobalValue::InternalLinkage,
                                      getInstrProfRegFuncsName(), M);
-  RegisterF->setUnnamedAddr(true);
+  RegisterF->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
   if (Options.NoRedZone) RegisterF->addFnAttr(Attribute::NoRedZone);
 
   auto *RuntimeRegisterTy = FunctionType::get(VoidTy, VoidPtrTy, false);
@@ -606,7 +606,7 @@ void InstrProfiling::emitInitialization() {
   auto *F = Function::Create(FunctionType::get(VoidTy, false),
                              GlobalValue::InternalLinkage,
                              getInstrProfInitFuncName(), M);
-  F->setUnnamedAddr(true);
+  F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
   F->addFnAttr(Attribute::NoInline);
   if (Options.NoRedZone) F->addFnAttr(Attribute::NoRedZone);
 
index d99d4b6e596686d0256ec97937448a6961b27bf7..f923673484f17aff8accc65c696b48514963d1c8 100644 (file)
@@ -777,7 +777,7 @@ bool LoopIdiomRecognize::processLoopStridedStore(
     GlobalVariable *GV = new GlobalVariable(*M, PatternValue->getType(), true,
                                             GlobalValue::PrivateLinkage,
                                             PatternValue, ".memset_pattern");
-    GV->setUnnamedAddr(true); // Ok to merge these.
+    GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); // Ok to merge these.
     GV->setAlignment(16);
     Value *PatternPtr = ConstantExpr::getBitCast(GV, Int8PtrTy);
     NewCall = Builder.CreateCall(MSP, {BasePtr, PatternPtr, NumBytes});
index 92e7fbc7e6905846469dd71278dcb0b81a60c949..fcb25baf32167a57431074968d3822c8491d220f 100644 (file)
@@ -64,7 +64,7 @@ bool FunctionImportGlobalProcessing::doPromoteLocalToGlobal(
   // of the module and recorded in the summary index for use when importing
   // from that module.
   auto *GVar = dyn_cast<GlobalVariable>(SGV);
-  if (GVar && GVar->isConstant() && GVar->hasUnnamedAddr())
+  if (GVar && GVar->isConstant() && GVar->hasGlobalUnnamedAddr())
     return false;
 
   if (GVar && GVar->hasSection())
index 8be42aed9724f734a589b440c333fd2aa3df08d6..266be41fbeadd3a1c515872fd14c3a90782299a1 100644 (file)
@@ -105,7 +105,7 @@ static bool analyzeGlobalAux(const Value *V, GlobalStatus &GS,
               }
             }
 
-            if (StoredVal == GV->getInitializer()) {
+            if (GV->hasInitializer() && StoredVal == GV->getInitializer()) {
               if (GS.StoredType < GlobalStatus::InitializerStored)
                 GS.StoredType = GlobalStatus::InitializerStored;
             } else if (isa<LoadInst>(StoredVal) &&
index ec2c1af97ea1f1007e06b461a3137076f0a06c4e..8f35f887c0b79b5f773a21af1fb714659729fb0b 100644 (file)
@@ -4540,7 +4540,7 @@ SwitchLookupTable::SwitchLookupTable(
   Array = new GlobalVariable(M, ArrayTy, /*constant=*/true,
                              GlobalVariable::PrivateLinkage, Initializer,
                              "switch.table");
-  Array->setUnnamedAddr(true);
+  Array->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
   Kind = ArrayKind;
 }
 
diff --git a/test/Assembler/local-unnamed-addr.ll b/test/Assembler/local-unnamed-addr.ll
new file mode 100644 (file)
index 0000000..ba27840
--- /dev/null
@@ -0,0 +1,13 @@
+; RUN: llvm-as < %s | llvm-dis | FileCheck %s
+; RUN: verify-uselistorder %s
+
+; CHECK: @c = local_unnamed_addr constant i32 0
+@c = local_unnamed_addr constant i32 0
+
+; CHECK: @a = local_unnamed_addr alias i32, i32* @c
+@a = local_unnamed_addr alias i32, i32* @c
+
+; CHECK: define void @f() local_unnamed_addr {
+define void @f() local_unnamed_addr {
+  ret void
+}
index 4f0f29cfc8731d8b414441ee08783d6267794329..827bc6a56caa53963420dc96062f07db9686d998 100644 (file)
@@ -80,7 +80,7 @@ $comdat.samesize = comdat samesize
 
 ;; Global Variables
 ; Format: [@<GlobalVarName> =] [Linkage] [Visibility] [DLLStorageClass]
-;         [ThreadLocal] [unnamed_addr] [AddrSpace] [ExternallyInitialized]
+;         [ThreadLocal] [(unnamed_addr|local_unnamed_addr)] [AddrSpace] [ExternallyInitialized]
 ;         <global | constant> <Type> [<InitializerConstant>]
 ;         [, section "name"] [, comdat [($name)]] [, align <Alignment>]
 
@@ -142,9 +142,11 @@ $comdat.samesize = comdat samesize
 @g.localexec = thread_local(localexec) global i32 0
 ; CHECK: @g.localexec = thread_local(localexec) global i32 0
 
-; Global Variables -- unnamed_addr
+; Global Variables -- unnamed_addr and local_unnamed_addr
 @g.unnamed_addr = unnamed_addr global i32 0
 ; CHECK: @g.unnamed_addr = unnamed_addr global i32 0
+@g.local_unnamed_addr = local_unnamed_addr global i32 0
+; CHECK: @g.local_unnamed_addr = local_unnamed_addr global i32 0
 
 ; Global Variables -- AddrSpace
 @g.addrspace = addrspace(1) global i32 0
@@ -245,9 +247,11 @@ declare void @g.f1()
 @a.localexec = thread_local(localexec) alias i32, i32* @g.localexec
 ; CHECK: @a.localexec = thread_local(localexec) alias i32, i32* @g.localexec
 
-; Aliases -- unnamed_addr
+; Aliases -- unnamed_addr and local_unnamed_addr
 @a.unnamed_addr = unnamed_addr alias i32, i32* @g.unnamed_addr
 ; CHECK: @a.unnamed_addr = unnamed_addr alias i32, i32* @g.unnamed_addr
+@a.local_unnamed_addr = local_unnamed_addr alias i32, i32* @g.local_unnamed_addr
+; CHECK: @a.local_unnamed_addr = local_unnamed_addr alias i32, i32* @g.local_unnamed_addr
 
 ;; IFunc
 ; Format @<Name> = [Linkage] [Visibility] ifunc <IFuncTy>,
@@ -278,7 +282,7 @@ entry:
 ; Format: define [linkage] [visibility] [DLLStorageClass]
 ;         [cconv] [ret attrs]
 ;         <ResultType> @<FunctionName> ([argument list])
-;         [unnamed_addr] [fn Attrs] [section "name"] [comdat [($name)]]
+;         [(unnamed_addr|local_unnamed_addr)] [fn Attrs] [section "name"] [comdat [($name)]]
 ;         [align N] [gc] [prefix Constant] [prologue Constant]
 ;         [personality Constant] { ... }
 
@@ -523,9 +527,11 @@ declare void @f.param.dereferenceable(i8* dereferenceable(4))
 declare void @f.param.dereferenceable_or_null(i8* dereferenceable_or_null(4))
 ; CHECK: declare void @f.param.dereferenceable_or_null(i8* dereferenceable_or_null(4))
 
-; Functions -- unnamed_addr
+; Functions -- unnamed_addr and local_unnamed_addr
 declare void @f.unnamed_addr() unnamed_addr
 ; CHECK: declare void @f.unnamed_addr() unnamed_addr
+declare void @f.local_unnamed_addr() local_unnamed_addr
+; CHECK: declare void @f.local_unnamed_addr() local_unnamed_addr
 
 ; Functions -- fn Attrs (Function attributes)
 declare void @f.alignstack4() alignstack(4)
index 0b87613bb4d8c6e7a774899969aee81a47280aa7..3760f1bb165766173d0cbb1e924030ae00df60e0 100644 (file)
@@ -3,7 +3,7 @@
 ; RUN: llc -mtriple=powerpc-apple-darwin9 -O0 < %s | FileCheck --check-prefix=CHECK-D89 %s
 ; RUN: llc -mtriple=powerpc-apple-darwin8 -O0 < %s | FileCheck --check-prefix=CHECK-D89 %s
 
-@v1 = linkonce_odr constant i32 32
+@v1 = linkonce_odr local_unnamed_addr constant i32 32
 ; CHECK: .globl  _v1
 ; CHECK: .weak_def_can_be_hidden _v1
 
@@ -26,7 +26,7 @@ define i32* @f2() {
   ret i32* @v2
 }
 
-@v3 = linkonce_odr unnamed_addr global i32 32
+@v3 = linkonce_odr unnamed_addr constant i32 32
 ; CHECK: .globl  _v3
 ; CHECK: .weak_def_can_be_hidden _v3
 
@@ -37,9 +37,9 @@ define i32* @f3() {
   ret i32* @v3
 }
 
-@v4 = linkonce_odr global i32 32
+@v4 = linkonce_odr unnamed_addr global i32 32
 ; CHECK: .globl  _v4
-; CHECK: .weak_definition _v4
+; CHECK: .weak_def_can_be_hidden _v4
 
 ; CHECK-D89: .globl  _v4
 ; CHECK-D89: .weak_definition _v4
index 8e6d34c89d88afda247b97c4bd7045c92b246311..516bc02cc2f83bac303e6637bdbdfa4117c905d6 100644 (file)
@@ -4,7 +4,7 @@
 ; RUN: llc -mtriple=i686-apple-darwin9 -O0 < %s | FileCheck --check-prefix=CHECK-D89 %s
 ; RUN: llc -mtriple=i686-apple-darwin8 -O0 < %s | FileCheck --check-prefix=CHECK-D89 %s
 
-@v1 = linkonce_odr constant i32 32
+@v1 = linkonce_odr local_unnamed_addr constant i32 32
 ; CHECK: .globl  _v1
 ; CHECK: .weak_def_can_be_hidden _v1
 
@@ -27,7 +27,7 @@ define i32* @f2() {
   ret i32* @v2
 }
 
-@v3 = linkonce_odr unnamed_addr global i32 32
+@v3 = linkonce_odr unnamed_addr constant i32 32
 ; CHECK: .globl  _v3
 ; CHECK: .weak_def_can_be_hidden _v3
 
@@ -38,9 +38,9 @@ define i32* @f3() {
   ret i32* @v3
 }
 
-@v4 = linkonce_odr global i32 32
+@v4 = linkonce_odr unnamed_addr global i32 32
 ; CHECK: .globl  _v4
-; CHECK: .weak_definition _v4
+; CHECK: .weak_def_can_be_hidden _v4
 
 ; CHECK-D89: .globl  _v4
 ; CHECK-D89: .weak_definition _v4
index d1d60b473136118112112eb08f9e6cf04d08b0ec..08bd92aa6fa306b42ba9f66979867c426c0f68e5 100644 (file)
@@ -10,7 +10,7 @@
 
 declare void @foo() readnone
 
-; CHECK-LABEL: define i8* @test(i8* %p) {
+; CHECK-LABEL: define i8* @test(i8* %p)
 ; CHECK:   %a = alloca i8*, align 8
 ; CHECK:   store i8* %p, i8** %a, align 8
 ; CHECK:   call void @foo() [ "abc"(i8** %a) ]
index 57d822b047e33ee024845eac2700088a545a9a7c..7a9ab2b23b50462e25ac4a46520364569f9f7f34 100644 (file)
@@ -33,8 +33,8 @@ define i32* @get_zed1() {
   ret i32* @zed1
 }
 
-; ZED1_AND_ZED2: d zed2
-@zed2 = linkonce_odr unnamed_addr global i32 42
+; ZED1_AND_ZED2: r zed2
+@zed2 = linkonce_odr unnamed_addr constant i32 42
 
 define i32 @useZed2() {
   %x = load i32, i32* @zed2
index 671b30a460ce4cd4ae55c22ed83fb3c385b07171..df81e06e935f38968cdd4727fcf0a12eeaa7bc6e 100644 (file)
@@ -1,61 +1,54 @@
 ; RUN: llvm-as < %s >%t1
 ; RUN: llvm-lto -o %t2 -dso-symbol=foo1 -dso-symbol=foo2 -dso-symbol=foo3 \
-; RUN:     -dso-symbol=foo4 -dso-symbol=v1 -dso-symbol=v2 %t1 -O0
+; RUN:     -dso-symbol=v1 -dso-symbol=v2 -dso-symbol=v3 \
+; RUN:     -dso-symbol=v4 -dso-symbol=v5 -dso-symbol=v6 %t1 -O0
 ; RUN: llvm-nm %t2 | FileCheck %s
 
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
 
-; CHECK: t foo1
+; CHECK: W foo1
 define linkonce_odr void @foo1() noinline {
   ret void
 }
 
-; CHECK: W foo2
-define linkonce_odr void @foo2() noinline {
+; CHECK: t foo2
+define linkonce_odr void @foo2() local_unnamed_addr noinline {
   ret void
 }
 
 ; CHECK: t foo3
-define linkonce_odr void @foo3() noinline {
+define linkonce_odr void @foo3() unnamed_addr noinline {
   ret void
 }
 
-; CHECK: W foo4
-define linkonce_odr void @foo4() noinline {
-  ret void
-}
-
-; CHECK: r v1
+; CHECK: V v1
 @v1 = linkonce_odr constant i32 32
 
-define i32 @useV1() {
-  %x = load i32, i32* @v1
-  ret i32 %x
-}
+; CHECK: r v2
+@v2 = linkonce_odr local_unnamed_addr constant i32 32
 
-; CHECK: V v2
-@v2 = linkonce_odr global i32 32
+; CHECK: r v3
+@v3 = linkonce_odr unnamed_addr constant i32 32
 
-define i32 @useV2() {
-  %x = load i32, i32* @v2
-  ret i32 %x
-}
+; CHECK: V v4
+@v4 = linkonce_odr global i32 32
 
-declare void @f(void()*)
+; CHECK: V v5
+@v5 = linkonce_odr local_unnamed_addr global i32 32
 
-declare void @p()
+; CHECK: d v6
+@v6 = linkonce_odr unnamed_addr global i32 32
 
-define void @bar() personality void()* @p {
-bb0:
+define void @use() {
   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, i32} cleanup
+  call void @foo2()
+  call void @foo3()
+  %x1 = load i32, i32* @v1
+  %x2 = load i32, i32* @v2
+  %x3 = load i32, i32* @v3
+  %x4 = load i32, i32* @v4
+  %x5 = load i32, i32* @v5
+  %x6 = load i32, i32* @v6
   ret void
 }
index 6923aadeb44a4ede11c02b1f45a5b3923cc73e27..9d52f800bc2926599b2e6f5ccb471bb3bddc0109 100644 (file)
 ; PLAIN: @F1 = global i1* getelementptr (i1, i1* inttoptr (i32 1 to i1*), i32 -2)
 ; PLAIN: @H8 = global i8* getelementptr (i8, i8* null, i32 -1)
 ; PLAIN: @H1 = global i1* getelementptr (i1, i1* null, i32 -1)
-; OPT: @G8 = global i8* null
-; OPT: @G1 = global i1* null
-; OPT: @F8 = global i8* inttoptr (i64 -1 to i8*)
-; OPT: @F1 = global i1* inttoptr (i64 -1 to i1*)
-; OPT: @H8 = global i8* inttoptr (i64 -1 to i8*)
-; OPT: @H1 = global i1* inttoptr (i64 -1 to i1*)
-; TO: @G8 = global i8* null
-; TO: @G1 = global i1* null
-; TO: @F8 = global i8* inttoptr (i64 -1 to i8*)
-; TO: @F1 = global i1* inttoptr (i64 -1 to i1*)
-; TO: @H8 = global i8* inttoptr (i64 -1 to i8*)
-; TO: @H1 = global i1* inttoptr (i64 -1 to i1*)
+; OPT: @G8 = local_unnamed_addr global i8* null
+; OPT: @G1 = local_unnamed_addr global i1* null
+; OPT: @F8 = local_unnamed_addr global i8* inttoptr (i64 -1 to i8*)
+; OPT: @F1 = local_unnamed_addr global i1* inttoptr (i64 -1 to i1*)
+; OPT: @H8 = local_unnamed_addr global i8* inttoptr (i64 -1 to i8*)
+; OPT: @H1 = local_unnamed_addr global i1* inttoptr (i64 -1 to i1*)
+; TO: @G8 = local_unnamed_addr global i8* null
+; TO: @G1 = local_unnamed_addr global i1* null
+; TO: @F8 = local_unnamed_addr global i8* inttoptr (i64 -1 to i8*)
+; TO: @F1 = local_unnamed_addr global i1* inttoptr (i64 -1 to i1*)
+; TO: @H8 = local_unnamed_addr global i8* inttoptr (i64 -1 to i8*)
+; TO: @H1 = local_unnamed_addr global i1* inttoptr (i64 -1 to i1*)
 
 @G8 = global i8* getelementptr (i8, i8* inttoptr (i32 1 to i8*), i32 -1)
 @G1 = global i1* getelementptr (i1, i1* inttoptr (i32 1 to i1*), i32 -1)
 ; PLAIN: @g = constant i64 ptrtoint (double* getelementptr ({ i1, double }, { i1, double }* null, i64 0, i32 1) to i64)
 ; PLAIN: @h = constant i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64)
 ; PLAIN: @i = constant i64 ptrtoint (i1** getelementptr ({ i1, i1* }, { i1, i1* }* null, i64 0, i32 1) to i64)
-; OPT: @a = constant i64 18480
-; OPT: @b = constant i64 8
-; OPT: @c = constant i64 16
-; OPT: @d = constant i64 88
-; OPT: @e = constant i64 16
-; OPT: @f = constant i64 1
-; OPT: @g = constant i64 8
-; OPT: @h = constant i64 8
-; OPT: @i = constant i64 8
-; TO: @a = constant i64 18480
-; TO: @b = constant i64 8
-; TO: @c = constant i64 16
-; TO: @d = constant i64 88
-; TO: @e = constant i64 16
-; TO: @f = constant i64 1
-; TO: @g = constant i64 8
-; TO: @h = constant i64 8
-; TO: @i = constant i64 8
+; OPT: @a = local_unnamed_addr constant i64 18480
+; OPT: @b = local_unnamed_addr constant i64 8
+; OPT: @c = local_unnamed_addr constant i64 16
+; OPT: @d = local_unnamed_addr constant i64 88
+; OPT: @e = local_unnamed_addr constant i64 16
+; OPT: @f = local_unnamed_addr constant i64 1
+; OPT: @g = local_unnamed_addr constant i64 8
+; OPT: @h = local_unnamed_addr constant i64 8
+; OPT: @i = local_unnamed_addr constant i64 8
+; TO: @a = local_unnamed_addr constant i64 18480
+; TO: @b = local_unnamed_addr constant i64 8
+; TO: @c = local_unnamed_addr constant i64 16
+; TO: @d = local_unnamed_addr constant i64 88
+; TO: @e = local_unnamed_addr constant i64 16
+; TO: @f = local_unnamed_addr constant i64 1
+; TO: @g = local_unnamed_addr constant i64 8
+; TO: @h = local_unnamed_addr constant i64 8
+; TO: @i = local_unnamed_addr constant i64 8
 
 @a = constant i64 mul (i64 3, i64 mul (i64 ptrtoint ({[7 x double], [7 x double]}* getelementptr ({[7 x double], [7 x double]}, {[7 x double], [7 x double]}* null, i64 11) to i64), i64 5))
 @b = constant i64 ptrtoint ([13 x double]* getelementptr ({i1, [13 x double]}, {i1, [13 x double]}* null, i64 0, i32 1) to i64)
 ; PLAIN: @M = constant i64* getelementptr (i64, i64* null, i32 1)
 ; PLAIN: @N = constant i64* getelementptr ({ i64, i64 }, { i64, i64 }* null, i32 0, i32 1)
 ; PLAIN: @O = constant i64* getelementptr ([2 x i64], [2 x i64]* null, i32 0, i32 1)
-; OPT: @M = constant i64* inttoptr (i64 8 to i64*)
-; OPT: @N = constant i64* inttoptr (i64 8 to i64*)
-; OPT: @O = constant i64* inttoptr (i64 8 to i64*)
-; TO: @M = constant i64* inttoptr (i64 8 to i64*)
-; TO: @N = constant i64* inttoptr (i64 8 to i64*)
-; TO: @O = constant i64* inttoptr (i64 8 to i64*)
+; OPT: @M = local_unnamed_addr constant i64* inttoptr (i64 8 to i64*)
+; OPT: @N = local_unnamed_addr constant i64* inttoptr (i64 8 to i64*)
+; OPT: @O = local_unnamed_addr constant i64* inttoptr (i64 8 to i64*)
+; TO: @M = local_unnamed_addr constant i64* inttoptr (i64 8 to i64*)
+; TO: @N = local_unnamed_addr constant i64* inttoptr (i64 8 to i64*)
+; TO: @O = local_unnamed_addr constant i64* inttoptr (i64 8 to i64*)
 
 @M = constant i64* getelementptr (i64, i64* null, i32 1)
 @N = constant i64* getelementptr ({ i64, i64 }, { i64, i64 }* null, i32 0, i32 1)
 
 ; PLAIN: @Y = global [3 x { i32, i32 }]* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 2)
 ; PLAIN: @Z = global i32* getelementptr inbounds (i32, i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 0), i64 1)
-; OPT: @Y = global [3 x { i32, i32 }]* getelementptr ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 2)
-; OPT: @Z = global i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 1)
-; TO: @Y = global [3 x { i32, i32 }]* getelementptr ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 2)
-; TO: @Z = global i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 1)
+; OPT: @Y = local_unnamed_addr global [3 x { i32, i32 }]* getelementptr ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 2)
+; OPT: @Z = local_unnamed_addr global i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 1)
+; TO: @Y = local_unnamed_addr global [3 x { i32, i32 }]* getelementptr ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 2)
+; TO: @Z = local_unnamed_addr global i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 1)
 
 @ext = external global [3 x { i32, i32 }]
 @Y = global [3 x { i32, i32 }]* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 1), i64 1)
 ; PLAIN:   %t = bitcast i1* getelementptr (i1, i1* null, i32 -1) to i1*
 ; PLAIN:   ret i1* %t
 ; PLAIN: }
-; OPT: define i8* @goo8() #0 {
+; OPT: define i8* @goo8() local_unnamed_addr #0 {
 ; OPT:   ret i8* null
 ; OPT: }
-; OPT: define i1* @goo1() #0 {
+; OPT: define i1* @goo1() local_unnamed_addr #0 {
 ; OPT:   ret i1* null
 ; OPT: }
-; OPT: define i8* @foo8() #0 {
+; OPT: define i8* @foo8() local_unnamed_addr #0 {
 ; OPT:   ret i8* inttoptr (i64 -1 to i8*)
 ; OPT: }
-; OPT: define i1* @foo1() #0 {
+; OPT: define i1* @foo1() local_unnamed_addr #0 {
 ; OPT:   ret i1* inttoptr (i64 -1 to i1*)
 ; OPT: }
-; OPT: define i8* @hoo8() #0 {
+; OPT: define i8* @hoo8() local_unnamed_addr #0 {
 ; OPT:   ret i8* inttoptr (i64 -1 to i8*)
 ; OPT: }
-; OPT: define i1* @hoo1() #0 {
+; OPT: define i1* @hoo1() local_unnamed_addr #0 {
 ; OPT:   ret i1* inttoptr (i64 -1 to i1*)
 ; OPT: }
-; TO: define i8* @goo8() #0 {
+; TO: define i8* @goo8() local_unnamed_addr #0 {
 ; TO:   ret i8* null
 ; TO: }
-; TO: define i1* @goo1() #0 {
+; TO: define i1* @goo1() local_unnamed_addr #0 {
 ; TO:   ret i1* null
 ; TO: }
-; TO: define i8* @foo8() #0 {
+; TO: define i8* @foo8() local_unnamed_addr #0 {
 ; TO:   ret i8* inttoptr (i64 -1 to i8*)
 ; TO: }
-; TO: define i1* @foo1() #0 {
+; TO: define i1* @foo1() local_unnamed_addr #0 {
 ; TO:   ret i1* inttoptr (i64 -1 to i1*)
 ; TO: }
-; TO: define i8* @hoo8() #0 {
+; TO: define i8* @hoo8() local_unnamed_addr #0 {
 ; TO:   ret i8* inttoptr (i64 -1 to i8*)
 ; TO: }
-; TO: define i1* @hoo1() #0 {
+; TO: define i1* @hoo1() local_unnamed_addr #0 {
 ; TO:   ret i1* inttoptr (i64 -1 to i1*)
 ; TO: }
 ; SCEV: Classifying expressions for: @goo8
@@ -256,58 +256,58 @@ define i1* @hoo1() nounwind {
 ; PLAIN:   %t = bitcast i64 ptrtoint (i1** getelementptr ({ i1, i1* }, { i1, i1* }* null, i64 0, i32 1) to i64) to i64
 ; PLAIN:   ret i64 %t
 ; PLAIN: }
-; OPT: define i64 @fa() #0 {
+; OPT: define i64 @fa() local_unnamed_addr #0 {
 ; OPT:   ret i64 18480
 ; OPT: }
-; OPT: define i64 @fb() #0 {
+; OPT: define i64 @fb() local_unnamed_addr #0 {
 ; OPT:   ret i64 8
 ; OPT: }
-; OPT: define i64 @fc() #0 {
+; OPT: define i64 @fc() local_unnamed_addr #0 {
 ; OPT:   ret i64 16
 ; OPT: }
-; OPT: define i64 @fd() #0 {
+; OPT: define i64 @fd() local_unnamed_addr #0 {
 ; OPT:   ret i64 88
 ; OPT: }
-; OPT: define i64 @fe() #0 {
+; OPT: define i64 @fe() local_unnamed_addr #0 {
 ; OPT:   ret i64 16
 ; OPT: }
-; OPT: define i64 @ff() #0 {
+; OPT: define i64 @ff() local_unnamed_addr #0 {
 ; OPT:   ret i64 1
 ; OPT: }
-; OPT: define i64 @fg() #0 {
+; OPT: define i64 @fg() local_unnamed_addr #0 {
 ; OPT:   ret i64 8
 ; OPT: }
-; OPT: define i64 @fh() #0 {
+; OPT: define i64 @fh() local_unnamed_addr #0 {
 ; OPT:   ret i64 8
 ; OPT: }
-; OPT: define i64 @fi() #0 {
+; OPT: define i64 @fi() local_unnamed_addr #0 {
 ; OPT:   ret i64 8
 ; OPT: }
-; TO: define i64 @fa() #0 {
+; TO: define i64 @fa() local_unnamed_addr #0 {
 ; TO:   ret i64 18480
 ; TO: }
-; TO: define i64 @fb() #0 {
+; TO: define i64 @fb() local_unnamed_addr #0 {
 ; TO:   ret i64 8
 ; TO: }
-; TO: define i64 @fc() #0 {
+; TO: define i64 @fc() local_unnamed_addr #0 {
 ; TO:   ret i64 16
 ; TO: }
-; TO: define i64 @fd() #0 {
+; TO: define i64 @fd() local_unnamed_addr #0 {
 ; TO:   ret i64 88
 ; TO: }
-; TO: define i64 @fe() #0 {
+; TO: define i64 @fe() local_unnamed_addr #0 {
 ; TO:   ret i64 16
 ; TO: }
-; TO: define i64 @ff() #0 {
+; TO: define i64 @ff() local_unnamed_addr #0 {
 ; TO:   ret i64 1
 ; TO: }
-; TO: define i64 @fg() #0 {
+; TO: define i64 @fg() local_unnamed_addr #0 {
 ; TO:   ret i64 8
 ; TO: }
-; TO: define i64 @fh() #0 {
+; TO: define i64 @fh() local_unnamed_addr #0 {
 ; TO:   ret i64 8
 ; TO: }
-; TO: define i64 @fi() #0 {
+; TO: define i64 @fi() local_unnamed_addr #0 {
 ; TO:   ret i64 8
 ; TO: }
 ; SCEV: Classifying expressions for: @fa
@@ -387,22 +387,22 @@ define i64 @fi() nounwind {
 ; PLAIN:   %t = bitcast i64* getelementptr ([2 x i64], [2 x i64]* null, i32 0, i32 1) to i64*
 ; PLAIN:   ret i64* %t
 ; PLAIN: }
-; OPT: define i64* @fM() #0 {
+; OPT: define i64* @fM() local_unnamed_addr #0 {
 ; OPT:   ret i64* inttoptr (i64 8 to i64*)
 ; OPT: }
-; OPT: define i64* @fN() #0 {
+; OPT: define i64* @fN() local_unnamed_addr #0 {
 ; OPT:   ret i64* inttoptr (i64 8 to i64*)
 ; OPT: }
-; OPT: define i64* @fO() #0 {
+; OPT: define i64* @fO() local_unnamed_addr #0 {
 ; OPT:   ret i64* inttoptr (i64 8 to i64*)
 ; OPT: }
-; TO: define i64* @fM() #0 {
+; TO: define i64* @fM() local_unnamed_addr #0 {
 ; TO:   ret i64* inttoptr (i64 8 to i64*)
 ; TO: }
-; TO: define i64* @fN() #0 {
+; TO: define i64* @fN() local_unnamed_addr #0 {
 ; TO:   ret i64* inttoptr (i64 8 to i64*)
 ; TO: }
-; TO: define i64* @fO() #0 {
+; TO: define i64* @fO() local_unnamed_addr #0 {
 ; TO:   ret i64* inttoptr (i64 8 to i64*)
 ; TO: }
 ; SCEV: Classifying expressions for: @fM
@@ -432,10 +432,10 @@ define i64* @fO() nounwind {
 ; PLAIN:   %t = bitcast i32* getelementptr inbounds (i32, i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 0), i64 1) to i32*
 ; PLAIN:   ret i32* %t
 ; PLAIN: }
-; OPT: define i32* @fZ() #0 {
+; OPT: define i32* @fZ() local_unnamed_addr #0 {
 ; OPT:   ret i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 1)
 ; OPT: }
-; TO: define i32* @fZ() #0 {
+; TO: define i32* @fZ() local_unnamed_addr #0 {
 ; TO:   ret i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 1)
 ; TO: }
 ; SCEV: Classifying expressions for: @fZ
index ad5b440a5abe886828132239243d5df1fe5663e7..c88dc1c2d12496eaca125354e9a9cc59eb8e1543 100644 (file)
@@ -2,7 +2,7 @@
 
 ; PR8389: Globals with weak_odr linkage type must not be modified
 
-; CHECK: weak_odr global i32 0
+; CHECK: weak_odr local_unnamed_addr global i32 0
 
 @SomeVar = weak_odr global i32 0
 
index 367f375ec900f7beb298f1ca6fb79770b7e0140d..08081b89ac685ef8e118f067bdb289333f1ca47a 100644 (file)
@@ -16,7 +16,7 @@ target datalayout = "p:32:32:32-p1:16:16:16"
 ; CHECK-DAG: @llvm.compiler.used = appending global [1 x i8*] [i8* addrspacecast (i8 addrspace(1)* @ia to i8*)], section "llvm.metadata"
 
 @sameAsUsed = global [1 x i8*] [i8* addrspacecast(i8 addrspace(1)* @ca to i8*)]
-; CHECK-DAG: @sameAsUsed = global [1 x i8*] [i8* addrspacecast (i8 addrspace(1)* @c to i8*)]
+; CHECK-DAG: @sameAsUsed = local_unnamed_addr global [1 x i8*] [i8* addrspacecast (i8 addrspace(1)* @c to i8*)]
 
 @ca = internal alias i8, i8 addrspace(1)* @c
 ; CHECK: @ca = internal alias i8, i8 addrspace(1)* @c
index bb905871764fa559bd97e0dec5fb83cec01ca527..91601fb992709eda4525669972c62bd4ccf9a394 100644 (file)
 ; CHECK-DAG: @llvm.compiler.used = appending global [2 x i8*] [i8* bitcast (void ()* @fa3 to i8*), i8* @ia], section "llvm.metadata"
 
 @sameAsUsed = global [3 x i8*] [i8* bitcast (void ()* @fa to i8*), i8* bitcast (void ()* @f to i8*), i8* @ca]
-; CHECK-DAG: @sameAsUsed = global [3 x i8*] [i8* bitcast (void ()* @f to i8*), i8* bitcast (void ()* @f to i8*), i8* @c]
+; CHECK-DAG: @sameAsUsed = local_unnamed_addr global [3 x i8*] [i8* bitcast (void ()* @f to i8*), i8* bitcast (void ()* @f to i8*), i8* @c]
 
 @other = global i32* bitcast (void ()* @fa to i32*)
-; CHECK-DAG: @other = global i32* bitcast (void ()* @f to i32*)
+; CHECK-DAG: @other = local_unnamed_addr global i32* bitcast (void ()* @f to i32*)
 
 @fa = internal alias void (), void ()* @f
 ; CHECK: @fa = internal alias void (), void ()* @f
index 3f3157a38fbb8565732039c85493306189ea5bf9..b15106bc83ac0f5b323568acc788a45dfb77ef0b 100644 (file)
@@ -1,6 +1,6 @@
 ; RUN: opt -S -globalopt < %s | FileCheck %s
 
-; CHECK: @tmp = global i32 42
+; CHECK: @tmp = local_unnamed_addr global i32 42
 
 @llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }]
 @tmp = global i32 0
index d0c18812cd94e002e2b9f3cb7ef347ca0b889bfb..3c20353d157bf7e22437203838e61d88b3d39f78 100644 (file)
@@ -4,13 +4,13 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
 
 @.str91250 = global [3 x i8] zeroinitializer
 
-; CHECK: @A = global i1 false
+; CHECK: @A = local_unnamed_addr global i1 false
 @A = global i1 icmp ne (i64 sub nsw (i64 ptrtoint (i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str91250, i64 0, i64 1) to i64), i64 ptrtoint ([3 x i8]* @.str91250 to i64)), i64 1)
 
 ; PR11352
 
 @xs = global [2 x i32] zeroinitializer, align 4
-; CHECK: @xs = global [2 x i32] [i32 1, i32 1]
+; CHECK: @xs = local_unnamed_addr global [2 x i32] [i32 1, i32 1]
 
 ; PR12642
 %PR12642.struct = type { i8 }
@@ -32,7 +32,7 @@ entry:
 @f = internal global %closure zeroinitializer, align 4
 @m = global i32 0, align 4
 ; CHECK-NOT: @f
-; CHECK: @m = global i32 13
+; CHECK: @m = local_unnamed_addr global i32 13
 
 define internal i32 @test2_helper(%closure* %this, i32 %b) {
 entry:
@@ -53,7 +53,7 @@ entry:
 ; PR19955
 
 @dllimportptr = global i32* null, align 4
-; CHECK: @dllimportptr = global i32* null, align 4
+; CHECK: @dllimportptr = local_unnamed_addr global i32* null, align 4
 @dllimportvar = external dllimport global i32
 define internal void @test3() {
 entry:
@@ -62,7 +62,7 @@ entry:
 }
 
 @dllexportptr = global i32* null, align 4
-; CHECK: @dllexportptr = global i32* @dllexportvar, align 4
+; CHECK: @dllexportptr = local_unnamed_addr global i32* @dllexportvar, align 4
 @dllexportvar = dllexport global i32 0, align 4
 ; CHECK: @dllexportvar = dllexport global i32 20, align 4
 define internal void @test4() {
@@ -83,7 +83,7 @@ entry:
 
 @test6_v1 = internal global { i32, i32 } { i32 42, i32 0 }, align 8
 @test6_v2 = global i32 0, align 4
-; CHECK: @test6_v2 = global i32 42, align 4
+; CHECK: @test6_v2 = local_unnamed_addr global i32 42, align 4
 define internal void @test6() {
   %load = load { i32, i32 }, { i32, i32 }* @test6_v1, align 8
   %xv0 = extractvalue { i32, i32 } %load, 0
index 63dc783ae196f9f771d9692f9285ee8607889041..b969345710d5b1d31616ac0f45719d0c5c51b8ba 100644 (file)
@@ -3,8 +3,8 @@
 ; Don't get fooled by the inbounds keyword; it doesn't change
 ; the computed address.
 
-; CHECK: @H = global i32 2
-; CHECK: @I = global i32 2
+; CHECK: @H = local_unnamed_addr global i32 2
+; CHECK: @I = local_unnamed_addr global i32 2
 
 @llvm.global_ctors = appending global [1 x { i32, void ()* }] [ { i32, void ()* } { i32 65535, void ()* @CTOR } ]
 @addr = external global i32
index 54d91d408019c9a1892b8cf318732c870a5e8ecd..80cd411afdc788c71df15efdb86c5de1097b9872 100644 (file)
@@ -2,8 +2,8 @@
 
 ; This test is hint, what could globalOpt optimize and what it can't
 ; FIXME: @tmp and @tmp2 can be safely set to 42
-; CHECK: @tmp = global i32 0
-; CHECK: @tmp2 = global i32 0
+; CHECK: @tmp = local_unnamed_addr global i32 0
+; CHECK: @tmp2 = local_unnamed_addr global i32 0
 ; CHECK: @tmp3 = global i32 0
 
 @tmp = global i32 0
index a0f7890a985bbfcbc4e08d64ab3e3bbc6d456822..a301993973511ce08e6cefdf761875bcb49ee005 100644 (file)
@@ -2,7 +2,7 @@
 ; rdar://11022897
 
 ; Globalopt should be able to evaluate an invoke.
-; CHECK: @tmp = global i32 1
+; CHECK: @tmp = local_unnamed_addr global i32 1
 
 @llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }]
 @tmp = global i32 0
index 34e15cb3404a7f26ef18fdcc03adf99081811785..9e201b888be3594b160f227eeb2c889da57cf2cc 100644 (file)
@@ -6,12 +6,12 @@ $c = comdat any
 define linkonce_odr void @foo() comdat($c) {
   ret void
 }
-; CHECK: define linkonce_odr void @foo() comdat($c)
+; CHECK: define linkonce_odr void @foo() local_unnamed_addr comdat($c)
 
 define linkonce_odr void @bar() comdat($c) {
   ret void
 }
-; CHECK: define linkonce_odr void @bar() comdat($c)
+; CHECK: define linkonce_odr void @bar() local_unnamed_addr comdat($c)
 
 define void @zed()  {
   call void @foo()
index de436c62a3474a75a2ed2da0fbf0d06764a3e88f..9f11f1bd92c228e23678fb96e6bc7f52780efd2d 100644 (file)
@@ -10,7 +10,7 @@
 ; CHECK: @b = internal global i32 0, align 4
 ; CHECK: @c = internal unnamed_addr global i32 0, align 4
 ; CHECK: @d = internal unnamed_addr constant [4 x i8] c"foo\00", align 1
-; CHECK: @e = linkonce_odr global i32 0
+; CHECK: @e = linkonce_odr local_unnamed_addr global i32 0
 
 ; CHECK: define internal fastcc void @used_internal() unnamed_addr {
 define internal void @used_internal() {
index 5d8a1c9da5fca79403479c18518670adf6d3aeb1..7ab80707ba1bff7b9f9a4dad1615ab316dc19f10 100644 (file)
@@ -16,7 +16,7 @@ define hidden void @g() {
   ret void
 }
 
-; CHECK: define internal void @h() {
-define linkonce_odr void @h() {
+; CHECK: define internal void @h() local_unnamed_addr {
+define linkonce_odr void @h() local_unnamed_addr {
   ret void
 }
index 4a6d5963cff066de0e4c5540b0c5ecac479fd437..0a955088c4047190f968103688e533a0c7ba1c54 100644 (file)
 
 target triple = "x86_64-unknown-linux-gnu"
 
+; CHECK-DAG: @g1 = linkonce_odr constant i32 32
+@g1 = linkonce_odr constant i32 32
+
+; CHECK-DAG: @g2 = internal local_unnamed_addr constant i32 32
+@g2 = linkonce_odr local_unnamed_addr constant i32 32
+
+; CHECK-DAG: @g3 = internal unnamed_addr constant i32 32
+@g3 = linkonce_odr unnamed_addr constant i32 32
+
+; CHECK-DAG: @g4 = linkonce_odr global i32 32
+@g4 = linkonce_odr global i32 32
+
+; CHECK-DAG: @g5 = linkonce_odr local_unnamed_addr global i32 32
+@g5 = linkonce_odr local_unnamed_addr global i32 32
+
+; CHECK-DAG: @g6 = internal unnamed_addr global i32 32
+@g6 = linkonce_odr unnamed_addr global i32 32
+
 @g7 = extern_weak global i32
 ; CHECK-DAG: @g7 = extern_weak global i32
 
@@ -53,7 +71,7 @@ define void @f3() {
 
 ; CHECK-DAG: define internal void @f4()
 ; OPT2-NOT: @f4
-define linkonce_odr void @f4() {
+define linkonce_odr void @f4() local_unnamed_addr {
   ret void
 }
 
@@ -62,14 +80,14 @@ define linkonce_odr void @f4() {
 define linkonce_odr void @f5() {
   ret void
 }
-@g5 = global void()* @f5
+@g9 = global void()* @f5
 
 ; CHECK-DAG: define internal void @f6() unnamed_addr
 ; OPT-DAG: define internal void @f6() unnamed_addr
 define linkonce_odr void @f6() unnamed_addr {
   ret void
 }
-@g6 = global void()* @f6
+@g10 = global void()* @f6
 
 define i32* @f7() {
   ret i32* @g7
@@ -89,5 +107,5 @@ define i32* @f8() {
 ; API: f8 PREVAILING_DEF_IRONLY_EXP
 ; API: g7 UNDEF
 ; API: g8 UNDEF
-; API: g5 PREVAILING_DEF_IRONLY_EXP
-; API: g6 PREVAILING_DEF_IRONLY_EXP
+; API: g9 PREVAILING_DEF_IRONLY_EXP
+; API: g10 PREVAILING_DEF_IRONLY_EXP
index 595e0695b08b621ae3e77b7b6370176b5c24c487..105fef9a2d745ce25f0b2555a1a386e1b886d839 100644 (file)
@@ -109,7 +109,7 @@ struct ResolutionInfo {
   uint64_t CommonSize = 0;
   unsigned CommonAlign = 0;
   bool IsLinkonceOdr = true;
-  bool UnnamedAddr = true;
+  GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::UnnamedAddr::Global;
   GlobalValue::VisibilityTypes Visibility = GlobalValue::DefaultVisibility;
   bool CommonInternal = false;
   bool UseCommon = false;
@@ -551,7 +551,8 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
 
     sym.visibility = LDPV_DEFAULT;
     if (GV) {
-      Res.UnnamedAddr &= GV->hasUnnamedAddr();
+      Res.UnnamedAddr =
+          GlobalValue::getMinUnnamedAddr(Res.UnnamedAddr, GV->getUnnamedAddr());
       Res.IsLinkonceOdr &= GV->hasLinkOnceLinkage();
       Res.Visibility = getMinVisibility(Res.Visibility, GV->getVisibility());
       switch (GV->getVisibility()) {
@@ -690,10 +691,11 @@ getModuleSummaryIndexForFile(claimed_file &F) {
   return Obj.takeIndex();
 }
 
-static std::unique_ptr<Module> getModuleForFile(
-    LLVMContext &Context, claimed_file &F, const void *View, StringRef Name,
-    raw_fd_ostream *ApiFile, StringSet<> &Internalize, StringSet<> &Maybe,
-    std::vector<GlobalValue *> &Keep, StringMap<unsigned> &Realign) {
+static std::unique_ptr<Module>
+getModuleForFile(LLVMContext &Context, claimed_file &F, const void *View,
+                 StringRef Name, raw_fd_ostream *ApiFile,
+                 StringSet<> &Internalize, std::vector<GlobalValue *> &Keep,
+                 StringMap<unsigned> &Realign) {
   MemoryBufferRef BufferRef(StringRef((const char *)View, F.filesize), Name);
   ErrorOr<std::unique_ptr<object::IRObjectFile>> ObjOrErr =
       object::IRObjectFile::create(BufferRef, Context);
@@ -827,12 +829,9 @@ static std::unique_ptr<Module> getModuleForFile(
       break;
 
     case LDPR_PREVAILING_DEF_IRONLY_EXP: {
-      // We can only check for address uses after we merge the modules. The
-      // reason is that this GV might have a copy in another module
-      // and in that module the address might be significant, but that
-      // copy will be LDPR_PREEMPTED_IR.
-      Maybe.insert(GV->getName());
       Keep.push_back(GV);
+      if (canBeOmittedFromSymbolTable(GV))
+        Internalize.insert(GV->getName());
       break;
     }
     }
@@ -1149,11 +1148,11 @@ void CodeGen::runAll() {
 static void linkInModule(LLVMContext &Context, IRMover &L, claimed_file &F,
                          const void *View, StringRef Name,
                          raw_fd_ostream *ApiFile, StringSet<> &Internalize,
-                         StringSet<> &Maybe, bool SetName = false) {
+                         bool SetName = false) {
   std::vector<GlobalValue *> Keep;
   StringMap<unsigned> Realign;
-  std::unique_ptr<Module> M = getModuleForFile(
-      Context, F, View, Name, ApiFile, Internalize, Maybe, Keep, Realign);
+  std::unique_ptr<Module> M = getModuleForFile(Context, F, View, Name, ApiFile,
+                                               Internalize, Keep, Realign);
   if (!M.get())
     return;
   if (!options::triple.empty())
@@ -1204,7 +1203,7 @@ static void thinLTOBackendTask(claimed_file &F, const void *View,
   IRMover L(*NewModule.get());
 
   StringSet<> Dummy;
-  linkInModule(Context, L, F, View, Name, ApiFile, Dummy, Dummy, true);
+  linkInModule(Context, L, F, View, Name, ApiFile, Dummy, true);
   if (renameModuleForThinLTO(*NewModule, CombinedIndex))
     message(LDPL_FATAL, "Failed to rename module for ThinLTO");
 
@@ -1474,7 +1473,6 @@ static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) {
   IRMover L(*Combined);
 
   StringSet<> Internalize;
-  StringSet<> Maybe;
   for (claimed_file &F : Modules) {
     // RAII object to manage the file opening and releasing interfaces with
     // gold.
@@ -1482,7 +1480,7 @@ static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) {
     const void *View = getSymbolsAndView(F);
     if (!View)
       continue;
-    linkInModule(Context, L, F, View, F.name, ApiFile, Internalize, Maybe);
+    linkInModule(Context, L, F, View, F.name, ApiFile, Internalize);
   }
 
   for (const auto &Name : Internalize) {
@@ -1491,15 +1489,6 @@ static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) {
       internalize(*GV);
   }
 
-  for (const auto &Name : Maybe) {
-    GlobalValue *GV = Combined->getNamedValue(Name.first());
-    if (!GV)
-      continue;
-    GV->setLinkage(GlobalValue::LinkOnceODRLinkage);
-    if (canBeOmittedFromSymbolTable(GV))
-      internalize(*GV);
-  }
-
   if (options::TheOutputType == options::OT_DISABLE)
     return LDPS_OK;