[llvm] r347033 - [ThinLTO] Internalize readonly globals

David Blaikie via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 4 18:49:52 PST 2018


Sent https://reviews.llvm.org/D55309 to fix forward.

On Tue, Dec 4, 2018 at 5:52 PM David Blaikie <dblaikie at gmail.com> wrote:

> Oh, right, this was committed and reverted, so yeah - I've demonstrated to
> myself that r346584 did cause the regression I'm looking into - going one
> before that revision does fix/remove the bug. I'll keep looking to see if I
> can figure out a forward-fix for this while waiting to discuss a temporary
> revert.
>
> On Tue, Dec 4, 2018 at 5:43 PM David Blaikie <dblaikie at gmail.com> wrote:
>
>> Hmm, nope - managed to reproduce this as far back as r346600 - continuing
>> to bisect...
>>
>> On Tue, Dec 4, 2018 at 3:41 PM David Blaikie <dblaikie at gmail.com> wrote:
>>
>>> Hi Eugene,
>>>
>>> Looks like this change may have significantly (50% increase in
>>> debug_line size, 23x growth in cu_index (when using Split DWARF), and a few
>>> other related increases/issues) regressed debug info size (at least, I'm
>>> pretty sure this patch is the culprit - I haven't quite been able to manage
>>> a clean local revert to verify entirely) under ThinLTO.
>>>
>>> To demonstrate the kind of problem, try compiling this with ThinLTO:
>>>
>>> a.cpp:
>>>   extern int glbl;
>>>   int glbl;
>>>   __attribute__((always_inline)) void f() {}
>>> b.cpp:
>>>   int main() { f(); }
>>>
>>> Previously, when compiling b.cpp, only one DWARF Compile Unit would be
>>> produced, because nothing imported from a.cpp into b.cpp was emitted into
>>> the code. But it seems after your change, the global 'glbl' is emitted into
>>> the DWARF (though it has no location/storage) & thus the (somewhat
>>> minimized - it doesn't describe 'f') CU for a.cpp is emitted as well.
>>>
>>> At scale, this means where previously each ThinLTO compile would produce
>>> one CU, they now produce potentially hundreds - any imported module with
>>> globals. This produced a growth of 22x in the number of CUs emitted in a
>>> large/practical binary at Google, which is how I came across it.
>>>
>>> If possible, could you roll this back for now, while I help/work with
>>> you to address this regression? I worked on the DWARF support in the
>>> original ThinLTO work a couple of years ago, so I'm familiar with some of
>>> the ins/outs & quirks of supporting this & happy to help out here.
>>>
>>> - Dave
>>>
>>>
>>> On Thu, Nov 15, 2018 at 11:10 PM Eugene Leviant via llvm-commits <
>>> llvm-commits at lists.llvm.org> wrote:
>>>
>>>> Author: evgeny777
>>>> Date: Thu Nov 15 23:08:00 2018
>>>> New Revision: 347033
>>>>
>>>> URL: http://llvm.org/viewvc/llvm-project?rev=347033&view=rev
>>>> Log:
>>>> [ThinLTO] Internalize readonly globals
>>>>
>>>> An attempt to recommit r346584 after failure on OSX build bot.
>>>> Fixed cache key computation in ThinLTOCodeGenerator and added
>>>> test case
>>>>
>>>> Added:
>>>>     llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-alias.ll
>>>>     llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-cache-foo.ll
>>>>     llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-cache-test1.ll
>>>>     llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-cache-test2.ll
>>>>     llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-comdat.ll
>>>>     llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-define-g.ll
>>>>     llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-full-lto.ll
>>>>     llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-gvref.ll
>>>>     llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-linkage.ll
>>>>     llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop.ll
>>>>     llvm/trunk/test/ThinLTO/X86/index-const-prop-O0.ll
>>>>     llvm/trunk/test/ThinLTO/X86/index-const-prop-alias.ll
>>>>     llvm/trunk/test/ThinLTO/X86/index-const-prop-cache.ll
>>>>     llvm/trunk/test/ThinLTO/X86/index-const-prop-comdat.ll
>>>>     llvm/trunk/test/ThinLTO/X86/index-const-prop-dead.ll
>>>>     llvm/trunk/test/ThinLTO/X86/index-const-prop-full-lto.ll
>>>>     llvm/trunk/test/ThinLTO/X86/index-const-prop-gvref.ll
>>>>     llvm/trunk/test/ThinLTO/X86/index-const-prop-ldst.ll
>>>>     llvm/trunk/test/ThinLTO/X86/index-const-prop-linkage.ll
>>>>     llvm/trunk/test/ThinLTO/X86/index-const-prop.ll
>>>>     llvm/trunk/test/ThinLTO/X86/index-const-prop2.ll
>>>> Modified:
>>>>     llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h
>>>>     llvm/trunk/include/llvm/Transforms/IPO/FunctionImport.h
>>>>     llvm/trunk/include/llvm/Transforms/Utils/FunctionImportUtils.h
>>>>     llvm/trunk/lib/Analysis/ModuleSummaryAnalysis.cpp
>>>>     llvm/trunk/lib/AsmParser/LLParser.cpp
>>>>     llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
>>>>     llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
>>>>     llvm/trunk/lib/IR/ModuleSummaryIndex.cpp
>>>>     llvm/trunk/lib/LTO/LTO.cpp
>>>>     llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp
>>>>     llvm/trunk/lib/Linker/IRMover.cpp
>>>>     llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp
>>>>     llvm/trunk/lib/Transforms/Utils/FunctionImportUtils.cpp
>>>>     llvm/trunk/test/Bitcode/summary_version.ll
>>>>     llvm/trunk/test/Bitcode/thinlto-alias.ll
>>>>     llvm/trunk/test/Bitcode/thinlto-alias2.ll
>>>>     llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph-cast.ll
>>>>     llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph-pgo.ll
>>>>
>>>> llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph-profile-summary.ll
>>>>     llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph-relbf.ll
>>>>
>>>> llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph-sample-profile-summary.ll
>>>>     llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph.ll
>>>>     llvm/trunk/test/Bitcode/thinlto-function-summary-refgraph.ll
>>>>     llvm/trunk/test/ThinLTO/X86/dot-dumper.ll
>>>>     llvm/trunk/test/ThinLTO/X86/globals-import-const-fold.ll
>>>>
>>>> Modified: llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h?rev=347033&r1=347032&r2=347033&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h (original)
>>>> +++ llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h Thu Nov 15 23:08:00
>>>> 2018
>>>> @@ -163,13 +163,13 @@ using GlobalValueSummaryMapTy =
>>>>  /// Struct that holds a reference to a particular GUID in a global
>>>> value
>>>>  /// summary.
>>>>  struct ValueInfo {
>>>> -  PointerIntPair<const GlobalValueSummaryMapTy::value_type *, 1, bool>
>>>> -      RefAndFlag;
>>>> +  PointerIntPair<const GlobalValueSummaryMapTy::value_type *, 2, int>
>>>> +      RefAndFlags;
>>>>
>>>>    ValueInfo() = default;
>>>>    ValueInfo(bool HaveGVs, const GlobalValueSummaryMapTy::value_type
>>>> *R) {
>>>> -    RefAndFlag.setPointer(R);
>>>> -    RefAndFlag.setInt(HaveGVs);
>>>> +    RefAndFlags.setPointer(R);
>>>> +    RefAndFlags.setInt(HaveGVs);
>>>>    }
>>>>
>>>>    operator bool() const { return getRef(); }
>>>> @@ -189,10 +189,12 @@ struct ValueInfo {
>>>>                       : getRef()->second.U.Name;
>>>>    }
>>>>
>>>> -  bool haveGVs() const { return RefAndFlag.getInt(); }
>>>> +  bool haveGVs() const { return RefAndFlags.getInt() & 0x1; }
>>>> +  bool isReadOnly() const { return RefAndFlags.getInt() & 0x2; }
>>>> +  void setReadOnly() { RefAndFlags.setInt(RefAndFlags.getInt() | 0x2);
>>>> }
>>>>
>>>>    const GlobalValueSummaryMapTy::value_type *getRef() const {
>>>> -    return RefAndFlag.getPointer();
>>>> +    return RefAndFlags.getPointer();
>>>>    }
>>>>
>>>>    bool isDSOLocal() const;
>>>> @@ -543,6 +545,8 @@ public:
>>>>            std::move(TypeTestAssumeConstVCalls),
>>>>            std::move(TypeCheckedLoadConstVCalls)});
>>>>    }
>>>> +  // Gets the number of immutable refs in RefEdgeList
>>>> +  unsigned immutableRefCount() const;
>>>>
>>>>    /// Check if this is a function summary.
>>>>    static bool classof(const GlobalValueSummary *GVS) {
>>>> @@ -652,19 +656,30 @@ template <> struct DenseMapInfo<Function
>>>>  /// Global variable summary information to aid decisions and
>>>>  /// implementation of importing.
>>>>  ///
>>>> -/// Currently this doesn't add anything to the base \p
>>>> GlobalValueSummary,
>>>> -/// but is a placeholder as additional info may be added to the summary
>>>> -/// for variables.
>>>> +/// Global variable summary has extra flag, telling if it is
>>>> +/// modified during the program run or not. This affects ThinLTO
>>>> +/// internalization
>>>>  class GlobalVarSummary : public GlobalValueSummary {
>>>> -
>>>>  public:
>>>> -  GlobalVarSummary(GVFlags Flags, std::vector<ValueInfo> Refs)
>>>> -      : GlobalValueSummary(GlobalVarKind, Flags, std::move(Refs)) {}
>>>> +  struct GVarFlags {
>>>> +    GVarFlags(bool ReadOnly = false) : ReadOnly(ReadOnly) {}
>>>> +
>>>> +    unsigned ReadOnly : 1;
>>>> +  } VarFlags;
>>>> +
>>>> +  GlobalVarSummary(GVFlags Flags, GVarFlags VarFlags,
>>>> +                   std::vector<ValueInfo> Refs)
>>>> +      : GlobalValueSummary(GlobalVarKind, Flags, std::move(Refs)),
>>>> +        VarFlags(VarFlags) {}
>>>>
>>>>    /// Check if this is a global variable summary.
>>>>    static bool classof(const GlobalValueSummary *GVS) {
>>>>      return GVS->getSummaryKind() == GlobalVarKind;
>>>>    }
>>>> +
>>>> +  GVarFlags varflags() const { return VarFlags; }
>>>> +  void setReadOnly(bool RO) { VarFlags.ReadOnly = RO; }
>>>> +  bool isReadOnly() const { return VarFlags.ReadOnly; }
>>>>  };
>>>>
>>>>  struct TypeTestResolution {
>>>> @@ -1135,6 +1150,9 @@ public:
>>>>
>>>>    /// Print out strongly connected components for debugging.
>>>>    void dumpSCCs(raw_ostream &OS);
>>>> +
>>>> +  /// Analyze index and detect unmodified globals
>>>> +  void propagateConstants(const DenseSet<GlobalValue::GUID>
>>>> &PreservedSymbols);
>>>>  };
>>>>
>>>>  /// GraphTraits definition to build SCC for the index
>>>> @@ -1184,6 +1202,14 @@ struct GraphTraits<ModuleSummaryIndex *>
>>>>    }
>>>>  };
>>>>
>>>> +static inline bool canImportGlobalVar(GlobalValueSummary *S) {
>>>> +  assert(isa<GlobalVarSummary>(S->getBaseObject()));
>>>> +
>>>> +  // We don't import GV with references, because it can result
>>>> +  // in promotion of local variables in the source module.
>>>> +  return !GlobalValue::isInterposableLinkage(S->linkage()) &&
>>>> +         !S->notEligibleToImport() && S->refs().empty();
>>>> +}
>>>>  } // end namespace llvm
>>>>
>>>>  #endif // LLVM_IR_MODULESUMMARYINDEX_H
>>>>
>>>> Modified: llvm/trunk/include/llvm/Transforms/IPO/FunctionImport.h
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/IPO/FunctionImport.h?rev=347033&r1=347032&r2=347033&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/include/llvm/Transforms/IPO/FunctionImport.h (original)
>>>> +++ llvm/trunk/include/llvm/Transforms/IPO/FunctionImport.h Thu Nov 15
>>>> 23:08:00 2018
>>>> @@ -176,6 +176,14 @@ void computeDeadSymbols(
>>>>      const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols,
>>>>      function_ref<PrevailingType(GlobalValue::GUID)> isPrevailing);
>>>>
>>>> +/// Compute dead symbols and run constant propagation in combined index
>>>> +/// after that.
>>>> +void computeDeadSymbolsWithConstProp(
>>>> +    ModuleSummaryIndex &Index,
>>>> +    const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols,
>>>> +    function_ref<PrevailingType(GlobalValue::GUID)> isPrevailing,
>>>> +    bool ImportEnabled);
>>>> +
>>>>  /// Converts value \p GV to declaration, or replaces with a
>>>> declaration if
>>>>  /// it is an alias. Returns true if converted, false if replaced.
>>>>  bool convertToDeclaration(GlobalValue &GV);
>>>>
>>>> Modified: llvm/trunk/include/llvm/Transforms/Utils/FunctionImportUtils.h
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/FunctionImportUtils.h?rev=347033&r1=347032&r2=347033&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/include/llvm/Transforms/Utils/FunctionImportUtils.h
>>>> (original)
>>>> +++ llvm/trunk/include/llvm/Transforms/Utils/FunctionImportUtils.h Thu
>>>> Nov 15 23:08:00 2018
>>>> @@ -113,7 +113,6 @@ public:
>>>>  bool renameModuleForThinLTO(
>>>>      Module &M, const ModuleSummaryIndex &Index,
>>>>      SetVector<GlobalValue *> *GlobalsToImport = nullptr);
>>>> -
>>>>  } // End llvm namespace
>>>>
>>>>  #endif
>>>>
>>>> Modified: llvm/trunk/lib/Analysis/ModuleSummaryAnalysis.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ModuleSummaryAnalysis.cpp?rev=347033&r1=347032&r2=347033&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/lib/Analysis/ModuleSummaryAnalysis.cpp (original)
>>>> +++ llvm/trunk/lib/Analysis/ModuleSummaryAnalysis.cpp Thu Nov 15
>>>> 23:08:00 2018
>>>> @@ -220,10 +220,19 @@ static void addIntrinsicToSummary(
>>>>    }
>>>>  }
>>>>
>>>> -static void computeFunctionSummary(
>>>> -    ModuleSummaryIndex &Index, const Module &M, const Function &F,
>>>> -    BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI, DominatorTree
>>>> &DT,
>>>> -    bool HasLocalsInUsedOrAsm, DenseSet<GlobalValue::GUID>
>>>> &CantBePromoted) {
>>>> +static bool isNonVolatileLoad(const Instruction *I) {
>>>> +  if (const auto *LI = dyn_cast<LoadInst>(I))
>>>> +    return !LI->isVolatile();
>>>> +
>>>> +  return false;
>>>> +}
>>>> +
>>>> +static void computeFunctionSummary(ModuleSummaryIndex &Index, const
>>>> Module &M,
>>>> +                                   const Function &F,
>>>> BlockFrequencyInfo *BFI,
>>>> +                                   ProfileSummaryInfo *PSI,
>>>> DominatorTree &DT,
>>>> +                                   bool HasLocalsInUsedOrAsm,
>>>> +                                   DenseSet<GlobalValue::GUID>
>>>> &CantBePromoted,
>>>> +                                   bool IsThinLTO) {
>>>>    // Summary not currently supported for anonymous functions, they
>>>> should
>>>>    // have been named.
>>>>    assert(F.hasName());
>>>> @@ -244,6 +253,7 @@ static void computeFunctionSummary(
>>>>    // Add personality function, prefix data and prologue data to
>>>> function's ref
>>>>    // list.
>>>>    findRefEdges(Index, &F, RefEdges, Visited);
>>>> +  std::vector<const Instruction *> NonVolatileLoads;
>>>>
>>>>    bool HasInlineAsmMaybeReferencingInternal = false;
>>>>    bool InitsVarArgs = false;
>>>> @@ -256,6 +266,13 @@ static void computeFunctionSummary(
>>>>            InitsVarArgs = true;
>>>>        }
>>>>        ++NumInsts;
>>>> +      if (isNonVolatileLoad(&I)) {
>>>> +        // Postpone processing of non-volatile load instructions
>>>> +        // See comments below
>>>> +        Visited.insert(&I);
>>>> +        NonVolatileLoads.push_back(&I);
>>>> +        continue;
>>>> +      }
>>>>        findRefEdges(Index, &I, RefEdges, Visited);
>>>>        auto CS = ImmutableCallSite(&I);
>>>>        if (!CS)
>>>> @@ -345,6 +362,24 @@ static void computeFunctionSummary(
>>>>        }
>>>>      }
>>>>
>>>> +  // By now we processed all instructions in a function, except
>>>> +  // non-volatile loads. All new refs we add in a loop below
>>>> +  // are obviously constant. All constant refs are grouped in the
>>>> +  // end of RefEdges vector, so we can use a single integer value
>>>> +  // to identify them.
>>>> +  unsigned RefCnt = RefEdges.size();
>>>> +  for (const Instruction *I : NonVolatileLoads) {
>>>> +    Visited.erase(I);
>>>> +    findRefEdges(Index, I, RefEdges, Visited);
>>>> +  }
>>>> +  std::vector<ValueInfo> Refs = RefEdges.takeVector();
>>>> +  // Regular LTO module doesn't participate in ThinLTO import,
>>>> +  // so no reference from it can be readonly, since this would
>>>> +  // require importing variable as local copy
>>>> +  if (IsThinLTO)
>>>> +    for (; RefCnt < Refs.size(); ++RefCnt)
>>>> +      Refs[RefCnt].setReadOnly();
>>>> +
>>>>    // Explicit add hot edges to enforce importing for designated GUIDs
>>>> for
>>>>    // sample PGO, to enable the same inlines as the profiled optimized
>>>> binary.
>>>>    for (auto &I : F.getImportGUIDs())
>>>> @@ -368,9 +403,9 @@ static void computeFunctionSummary(
>>>>            // Don't try to import functions with noinline attribute.
>>>>            F.getAttributes().hasFnAttribute(Attribute::NoInline)};
>>>>    auto FuncSummary = llvm::make_unique<FunctionSummary>(
>>>> -      Flags, NumInsts, FunFlags, RefEdges.takeVector(),
>>>> -      CallGraphEdges.takeVector(), TypeTests.takeVector(),
>>>> -      TypeTestAssumeVCalls.takeVector(),
>>>> TypeCheckedLoadVCalls.takeVector(),
>>>> +      Flags, NumInsts, FunFlags, std::move(Refs),
>>>> CallGraphEdges.takeVector(),
>>>> +      TypeTests.takeVector(), TypeTestAssumeVCalls.takeVector(),
>>>> +      TypeCheckedLoadVCalls.takeVector(),
>>>>        TypeTestAssumeConstVCalls.takeVector(),
>>>>        TypeCheckedLoadConstVCalls.takeVector());
>>>>    if (NonRenamableLocal)
>>>> @@ -387,8 +422,13 @@ computeVariableSummary(ModuleSummaryInde
>>>>    bool NonRenamableLocal = isNonRenamableLocal(V);
>>>>    GlobalValueSummary::GVFlags Flags(V.getLinkage(), NonRenamableLocal,
>>>>                                      /* Live = */ false,
>>>> V.isDSOLocal());
>>>> -  auto GVarSummary =
>>>> -      llvm::make_unique<GlobalVarSummary>(Flags,
>>>> RefEdges.takeVector());
>>>> +
>>>> +  // Don't mark variables we won't be able to internalize as read-only.
>>>> +  GlobalVarSummary::GVarFlags VarFlags(
>>>> +      !V.hasComdat() && !V.hasAppendingLinkage() &&
>>>> !V.isInterposable() &&
>>>> +      !V.hasAvailableExternallyLinkage() &&
>>>> !V.hasDLLExportStorageClass());
>>>> +  auto GVarSummary = llvm::make_unique<GlobalVarSummary>(Flags,
>>>> VarFlags,
>>>> +
>>>>  RefEdges.takeVector());
>>>>    if (NonRenamableLocal)
>>>>      CantBePromoted.insert(V.getGUID());
>>>>    if (HasBlockAddress)
>>>> @@ -492,13 +532,19 @@ ModuleSummaryIndex llvm::buildModuleSumm
>>>>              Index.addGlobalValueSummary(*GV, std::move(Summary));
>>>>            } else {
>>>>              std::unique_ptr<GlobalVarSummary> Summary =
>>>> -                llvm::make_unique<GlobalVarSummary>(GVFlags,
>>>> -
>>>> ArrayRef<ValueInfo>{});
>>>> +                llvm::make_unique<GlobalVarSummary>(
>>>> +                    GVFlags, GlobalVarSummary::GVarFlags(),
>>>> +                    ArrayRef<ValueInfo>{});
>>>>              Index.addGlobalValueSummary(*GV, std::move(Summary));
>>>>            }
>>>>          });
>>>>    }
>>>>
>>>> +  bool IsThinLTO = true;
>>>> +  if (auto *MD =
>>>> +
>>>> mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("ThinLTO")))
>>>> +    IsThinLTO = MD->getZExtValue();
>>>> +
>>>>    // Compute summaries for all functions defined in module, and save
>>>> in the
>>>>    // index.
>>>>    for (auto &F : M) {
>>>> @@ -519,7 +565,7 @@ ModuleSummaryIndex llvm::buildModuleSumm
>>>>
>>>>      computeFunctionSummary(Index, M, F, BFI, PSI, DT,
>>>>                             !LocalsUsed.empty() ||
>>>> HasLocalInlineAsmSymbol,
>>>> -                           CantBePromoted);
>>>> +                           CantBePromoted, IsThinLTO);
>>>>    }
>>>>
>>>>    // Compute summaries for all variables defined in module, and save
>>>> in the
>>>> @@ -550,11 +596,6 @@ ModuleSummaryIndex llvm::buildModuleSumm
>>>>    setLiveRoot(Index, "llvm.global_dtors");
>>>>    setLiveRoot(Index, "llvm.global.annotations");
>>>>
>>>> -  bool IsThinLTO = true;
>>>> -  if (auto *MD =
>>>> -
>>>> mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("ThinLTO")))
>>>> -    IsThinLTO = MD->getZExtValue();
>>>> -
>>>>    for (auto &GlobalList : Index) {
>>>>      // Ignore entries for references that are undefined in the current
>>>> module.
>>>>      if (GlobalList.second.SummaryList.empty())
>>>>
>>>> Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=347033&r1=347032&r2=347033&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
>>>> +++ llvm/trunk/lib/AsmParser/LLParser.cpp Thu Nov 15 23:08:00 2018
>>>> @@ -7715,7 +7715,8 @@ bool LLParser::ParseVariableSummary(std:
>>>>    if (ParseToken(lltok::rparen, "expected ')' here"))
>>>>      return true;
>>>>
>>>> -  auto GS = llvm::make_unique<GlobalVarSummary>(GVFlags,
>>>> std::move(Refs));
>>>> +  auto GS = llvm::make_unique<GlobalVarSummary>(
>>>> +      GVFlags, GlobalVarSummary::GVarFlags(), std::move(Refs));
>>>>
>>>>    GS->setModulePath(ModulePath);
>>>>
>>>>
>>>> Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=347033&r1=347032&r2=347033&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
>>>> +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Thu Nov 15 23:08:00
>>>> 2018
>>>> @@ -898,6 +898,11 @@ static GlobalValueSummary::GVFlags getDe
>>>>    return GlobalValueSummary::GVFlags(Linkage, NotEligibleToImport,
>>>> Live, Local);
>>>>  }
>>>>
>>>> +// Decode the flags for GlobalVariable in the summary
>>>> +static GlobalVarSummary::GVarFlags getDecodedGVarFlags(uint64_t
>>>> RawFlags) {
>>>> +  return GlobalVarSummary::GVarFlags((RawFlags & 0x1) ? true : false);
>>>> +}
>>>> +
>>>>  static GlobalValue::VisibilityTypes getDecodedVisibility(unsigned Val)
>>>> {
>>>>    switch (Val) {
>>>>    default: // Map unknown visibilities to default.
>>>> @@ -5219,6 +5224,12 @@ static void parseTypeIdSummaryRecord(Arr
>>>>      parseWholeProgramDevirtResolution(Record, Strtab, Slot, TypeId);
>>>>  }
>>>>
>>>> +static void setImmutableRefs(std::vector<ValueInfo> &Refs, unsigned
>>>> Count) {
>>>> +  // Read-only refs are in the end of the refs list.
>>>> +  for (unsigned RefNo = Refs.size() - Count; RefNo < Refs.size();
>>>> ++RefNo)
>>>> +    Refs[RefNo].setReadOnly();
>>>> +}
>>>> +
>>>>  // Eagerly parse the entire summary block. This populates the
>>>> GlobalValueSummary
>>>>  // objects in the index.
>>>>  Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID)
>>>> {
>>>> @@ -5236,9 +5247,9 @@ Error ModuleSummaryIndexBitcodeReader::p
>>>>    }
>>>>    const uint64_t Version = Record[0];
>>>>    const bool IsOldProfileFormat = Version == 1;
>>>> -  if (Version < 1 || Version > 4)
>>>> +  if (Version < 1 || Version > 5)
>>>>      return error("Invalid summary version " + Twine(Version) +
>>>> -                 ", 1, 2, 3 or 4 expected");
>>>> +                 ", 1, 2, 3, 4 or 5 expected");
>>>>    Record.clear();
>>>>
>>>>    // Keep around the last seen summary to be used when we see an
>>>> optional
>>>> @@ -5317,11 +5328,16 @@ Error ModuleSummaryIndexBitcodeReader::p
>>>>        unsigned InstCount = Record[2];
>>>>        uint64_t RawFunFlags = 0;
>>>>        unsigned NumRefs = Record[3];
>>>> +      unsigned NumImmutableRefs = 0;
>>>>        int RefListStartIndex = 4;
>>>>        if (Version >= 4) {
>>>>          RawFunFlags = Record[3];
>>>>          NumRefs = Record[4];
>>>>          RefListStartIndex = 5;
>>>> +        if (Version >= 5) {
>>>> +          NumImmutableRefs = Record[5];
>>>> +          RefListStartIndex = 6;
>>>> +        }
>>>>        }
>>>>
>>>>        auto Flags = getDecodedGVSummaryFlags(RawFlags, Version);
>>>> @@ -5340,6 +5356,7 @@ Error ModuleSummaryIndexBitcodeReader::p
>>>>        std::vector<FunctionSummary::EdgeTy> Calls = makeCallList(
>>>>            ArrayRef<uint64_t>(Record).slice(CallGraphEdgeStartIndex),
>>>>            IsOldProfileFormat, HasProfile, HasRelBF);
>>>> +      setImmutableRefs(Refs, NumImmutableRefs);
>>>>        auto FS = llvm::make_unique<FunctionSummary>(
>>>>            Flags, InstCount, getDecodedFFlags(RawFunFlags),
>>>> std::move(Refs),
>>>>            std::move(Calls), std::move(PendingTypeTests),
>>>> @@ -5388,14 +5405,21 @@ Error ModuleSummaryIndexBitcodeReader::p
>>>>        TheIndex.addGlobalValueSummary(GUID.first, std::move(AS));
>>>>        break;
>>>>      }
>>>> -    // FS_PERMODULE_GLOBALVAR_INIT_REFS: [valueid, flags, n x valueid]
>>>> +    // FS_PERMODULE_GLOBALVAR_INIT_REFS: [valueid, flags, varflags, n
>>>> x valueid]
>>>>      case bitc::FS_PERMODULE_GLOBALVAR_INIT_REFS: {
>>>>        unsigned ValueID = Record[0];
>>>>        uint64_t RawFlags = Record[1];
>>>> +      unsigned RefArrayStart = 2;
>>>> +      GlobalVarSummary::GVarFlags GVF;
>>>>        auto Flags = getDecodedGVSummaryFlags(RawFlags, Version);
>>>> +      if (Version >= 5) {
>>>> +        GVF = getDecodedGVarFlags(Record[2]);
>>>> +        RefArrayStart = 3;
>>>> +      }
>>>>        std::vector<ValueInfo> Refs =
>>>> -          makeRefList(ArrayRef<uint64_t>(Record).slice(2));
>>>> -      auto FS = llvm::make_unique<GlobalVarSummary>(Flags,
>>>> std::move(Refs));
>>>> +          makeRefList(ArrayRef<uint64_t>(Record).slice(RefArrayStart));
>>>> +      auto FS =
>>>> +          llvm::make_unique<GlobalVarSummary>(Flags, GVF,
>>>> std::move(Refs));
>>>>        FS->setModulePath(getThisModule()->first());
>>>>        auto GUID = getValueInfoFromValueId(ValueID);
>>>>        FS->setOriginalName(GUID.second);
>>>> @@ -5414,12 +5438,17 @@ Error ModuleSummaryIndexBitcodeReader::p
>>>>        unsigned InstCount = Record[3];
>>>>        uint64_t RawFunFlags = 0;
>>>>        unsigned NumRefs = Record[4];
>>>> +      unsigned NumImmutableRefs = 0;
>>>>        int RefListStartIndex = 5;
>>>>
>>>>        if (Version >= 4) {
>>>>          RawFunFlags = Record[4];
>>>>          NumRefs = Record[5];
>>>>          RefListStartIndex = 6;
>>>> +        if (Version >= 5) {
>>>> +          NumImmutableRefs = Record[6];
>>>> +          RefListStartIndex = 7;
>>>> +        }
>>>>        }
>>>>
>>>>        auto Flags = getDecodedGVSummaryFlags(RawFlags, Version);
>>>> @@ -5433,6 +5462,7 @@ Error ModuleSummaryIndexBitcodeReader::p
>>>>            ArrayRef<uint64_t>(Record).slice(CallGraphEdgeStartIndex),
>>>>            IsOldProfileFormat, HasProfile, false);
>>>>        ValueInfo VI = getValueInfoFromValueId(ValueID).first;
>>>> +      setImmutableRefs(Refs, NumImmutableRefs);
>>>>        auto FS = llvm::make_unique<FunctionSummary>(
>>>>            Flags, InstCount, getDecodedFFlags(RawFunFlags),
>>>> std::move(Refs),
>>>>            std::move(Edges), std::move(PendingTypeTests),
>>>> @@ -5481,10 +5511,17 @@ Error ModuleSummaryIndexBitcodeReader::p
>>>>        unsigned ValueID = Record[0];
>>>>        uint64_t ModuleId = Record[1];
>>>>        uint64_t RawFlags = Record[2];
>>>> +      unsigned RefArrayStart = 3;
>>>> +      GlobalVarSummary::GVarFlags GVF;
>>>>        auto Flags = getDecodedGVSummaryFlags(RawFlags, Version);
>>>> +      if (Version >= 5) {
>>>> +        GVF = getDecodedGVarFlags(Record[3]);
>>>> +        RefArrayStart = 4;
>>>> +      }
>>>>        std::vector<ValueInfo> Refs =
>>>> -          makeRefList(ArrayRef<uint64_t>(Record).slice(3));
>>>> -      auto FS = llvm::make_unique<GlobalVarSummary>(Flags,
>>>> std::move(Refs));
>>>> +          makeRefList(ArrayRef<uint64_t>(Record).slice(RefArrayStart));
>>>> +      auto FS =
>>>> +          llvm::make_unique<GlobalVarSummary>(Flags, GVF,
>>>> std::move(Refs));
>>>>        LastSeenSummary = FS.get();
>>>>        FS->setModulePath(ModuleIdMap[ModuleId]);
>>>>        ValueInfo VI = getValueInfoFromValueId(ValueID).first;
>>>>
>>>> Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=347033&r1=347032&r2=347033&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
>>>> +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Thu Nov 15 23:08:00
>>>> 2018
>>>> @@ -1000,6 +1000,11 @@ static uint64_t getEncodedGVSummaryFlags
>>>>    return RawFlags;
>>>>  }
>>>>
>>>> +static uint64_t getEncodedGVarFlags(GlobalVarSummary::GVarFlags Flags)
>>>> {
>>>> +  uint64_t RawFlags = Flags.ReadOnly;
>>>> +  return RawFlags;
>>>> +}
>>>> +
>>>>  static unsigned getEncodedVisibility(const GlobalValue &GV) {
>>>>    switch (GV.getVisibility()) {
>>>>    case GlobalValue::DefaultVisibility:   return 0;
>>>> @@ -3539,6 +3544,7 @@ void ModuleBitcodeWriterBase::writePerMo
>>>>    NameVals.push_back(FS->instCount());
>>>>    NameVals.push_back(getEncodedFFlags(FS->fflags()));
>>>>    NameVals.push_back(FS->refs().size());
>>>> +  NameVals.push_back(FS->immutableRefCount());
>>>>
>>>>    for (auto &RI : FS->refs())
>>>>      NameVals.push_back(VE.getValueID(RI.getValue()));
>>>> @@ -3580,6 +3586,7 @@ void ModuleBitcodeWriterBase::writeModul
>>>>    NameVals.push_back(VE.getValueID(&V));
>>>>    GlobalVarSummary *VS = cast<GlobalVarSummary>(Summary);
>>>>    NameVals.push_back(getEncodedGVSummaryFlags(VS->flags()));
>>>> +  NameVals.push_back(getEncodedGVarFlags(VS->varflags()));
>>>>
>>>>    unsigned SizeBeforeRefs = NameVals.size();
>>>>    for (auto &RI : VS->refs())
>>>> @@ -3596,7 +3603,7 @@ void ModuleBitcodeWriterBase::writeModul
>>>>  // Current version for the summary.
>>>>  // This is bumped whenever we introduce changes in the way some record
>>>> are
>>>>  // interpreted, like flags for instance.
>>>> -static const uint64_t INDEX_VERSION = 4;
>>>> +static const uint64_t INDEX_VERSION = 5;
>>>>
>>>>  /// Emit the per-module summary section alongside the rest of
>>>>  /// the module's bitcode.
>>>> @@ -3631,6 +3638,7 @@ void ModuleBitcodeWriterBase::writePerMo
>>>>    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));   // instcount
>>>>    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4));   // fflags
>>>>    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4));   // numrefs
>>>> +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4));   //
>>>> immutablerefcnt
>>>>    // numrefs x valueid, n x (valueid, hotness)
>>>>    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
>>>>    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
>>>> @@ -3647,6 +3655,7 @@ void ModuleBitcodeWriterBase::writePerMo
>>>>    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));   // instcount
>>>>    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4));   // fflags
>>>>    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4));   // numrefs
>>>> +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4));   //
>>>> immutablerefcnt
>>>>    // numrefs x valueid, n x (valueid [, rel_block_freq])
>>>>    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
>>>>    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
>>>> @@ -3741,6 +3750,7 @@ void IndexBitcodeWriter::writeCombinedGl
>>>>    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));   // instcount
>>>>    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4));   // fflags
>>>>    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4));   // numrefs
>>>> +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4));   //
>>>> immutablerefcnt
>>>>    // numrefs x valueid, n x (valueid)
>>>>    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
>>>>    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
>>>> @@ -3755,6 +3765,7 @@ void IndexBitcodeWriter::writeCombinedGl
>>>>    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));   // instcount
>>>>    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4));   // fflags
>>>>    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4));   // numrefs
>>>> +  Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4));   //
>>>> immutablerefcnt
>>>>    // numrefs x valueid, n x (valueid, hotness)
>>>>    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
>>>>    Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
>>>> @@ -3827,6 +3838,7 @@ void IndexBitcodeWriter::writeCombinedGl
>>>>        NameVals.push_back(*ValueId);
>>>>        NameVals.push_back(Index.getModuleId(VS->modulePath()));
>>>>        NameVals.push_back(getEncodedGVSummaryFlags(VS->flags()));
>>>> +      NameVals.push_back(getEncodedGVarFlags(VS->varflags()));
>>>>        for (auto &RI : VS->refs()) {
>>>>          auto RefValueId = getValueId(RI.getGUID());
>>>>          if (!RefValueId)
>>>> @@ -3852,17 +3864,21 @@ void IndexBitcodeWriter::writeCombinedGl
>>>>      NameVals.push_back(FS->instCount());
>>>>      NameVals.push_back(getEncodedFFlags(FS->fflags()));
>>>>      // Fill in below
>>>> -    NameVals.push_back(0);
>>>> +    NameVals.push_back(0); // numrefs
>>>> +    NameVals.push_back(0); // immutablerefcnt
>>>>
>>>> -    unsigned Count = 0;
>>>> +    unsigned Count = 0, ImmutableRefCnt = 0;
>>>>      for (auto &RI : FS->refs()) {
>>>>        auto RefValueId = getValueId(RI.getGUID());
>>>>        if (!RefValueId)
>>>>          continue;
>>>>        NameVals.push_back(*RefValueId);
>>>> +      if (RI.isReadOnly())
>>>> +        ImmutableRefCnt++;
>>>>        Count++;
>>>>      }
>>>>      NameVals[5] = Count;
>>>> +    NameVals[6] = ImmutableRefCnt;
>>>>
>>>>      bool HasProfileData = false;
>>>>      for (auto &EI : FS->calls()) {
>>>>
>>>> Modified: llvm/trunk/lib/IR/ModuleSummaryIndex.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/ModuleSummaryIndex.cpp?rev=347033&r1=347032&r2=347033&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/lib/IR/ModuleSummaryIndex.cpp (original)
>>>> +++ llvm/trunk/lib/IR/ModuleSummaryIndex.cpp Thu Nov 15 23:08:00 2018
>>>> @@ -30,6 +30,17 @@ bool ValueInfo::isDSOLocal() const {
>>>>                        });
>>>>  }
>>>>
>>>> +// Gets the number of immutable refs in RefEdgeList
>>>> +unsigned FunctionSummary::immutableRefCount() const {
>>>> +  // Here we take advantage of having all readonly references
>>>> +  // located in the end of the RefEdgeList.
>>>> +  auto Refs = refs();
>>>> +  unsigned ImmutableRefCnt = 0;
>>>> +  for (int I = Refs.size() - 1; I >= 0 && Refs[I].isReadOnly(); --I)
>>>> +    ImmutableRefCnt++;
>>>> +  return ImmutableRefCnt;
>>>> +}
>>>> +
>>>>  // Collect for the given module the list of function it defines
>>>>  // (GUID -> Summary).
>>>>  void ModuleSummaryIndex::collectDefinedFunctionsForModule(
>>>> @@ -84,6 +95,73 @@ bool ModuleSummaryIndex::isGUIDLive(Glob
>>>>    return false;
>>>>  }
>>>>
>>>> +static void propagateConstantsToRefs(GlobalValueSummary *S) {
>>>> +  // If reference is not readonly then referenced summary is not
>>>> +  // readonly either. Note that:
>>>> +  // - All references from GlobalVarSummary are conservatively
>>>> considered as
>>>> +  //   not readonly. Tracking them properly requires more complex
>>>> analysis
>>>> +  //   then we have now.
>>>> +  //
>>>> +  // - AliasSummary objects have no refs at all so this function is a
>>>> no-op
>>>> +  //   for them.
>>>> +  for (auto &VI : S->refs()) {
>>>> +    if (VI.isReadOnly()) {
>>>> +      // We only mark refs as readonly when computing function
>>>> summaries on
>>>> +      // analysis phase.
>>>> +      assert(isa<FunctionSummary>(S));
>>>> +      continue;
>>>> +    }
>>>> +    for (auto &Ref : VI.getSummaryList())
>>>> +      // If references to alias is not readonly then aliasee is not
>>>> readonly
>>>> +      if (auto *GVS = dyn_cast<GlobalVarSummary>(Ref->getBaseObject()))
>>>> +        GVS->setReadOnly(false);
>>>> +  }
>>>> +}
>>>> +
>>>> +// Do the constant propagation in combined index.
>>>> +// The goal of constant propagation is internalization of readonly
>>>> +// variables. To determine which variables are readonly and which
>>>> +// are not we take following steps:
>>>> +// - During analysis we speculatively assign readonly attribute to
>>>> +//   all variables which can be internalized. When computing function
>>>> +//   summary we also assign readonly attribute to a reference if
>>>> +//   function doesn't modify referenced variable.
>>>> +//
>>>> +// - After computing dead symbols in combined index we do the constant
>>>> +//   propagation. During this step we clear readonly attribute from
>>>> +//   all variables which:
>>>> +//   a. are dead, preserved or can't be imported
>>>> +//   b. referenced by any global variable initializer
>>>> +//   c. referenced by a function and reference is not readonly
>>>> +//
>>>> +// Internalization itself happens in the backend after import is
>>>> finished
>>>> +// See internalizeImmutableGVs.
>>>> +void ModuleSummaryIndex::propagateConstants(
>>>> +    const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols) {
>>>> +  for (auto &P : *this)
>>>> +    for (auto &S : P.second.SummaryList) {
>>>> +      if (!isGlobalValueLive(S.get()))
>>>> +        // We don't examine references from dead objects
>>>> +        continue;
>>>> +
>>>> +      // Global variable can't be marked read only if it is not
>>>> eligible
>>>> +      // to import since we need to ensure that all external references
>>>> +      // get a local (imported) copy. It also can't be marked read only
>>>> +      // if it or any alias (since alias points to the same memory) are
>>>> +      // preserved or notEligibleToImport, since either of those means
>>>> +      // there could be writes that are not visible (because preserved
>>>> +      // means it could have external to DSO writes, and
>>>> notEligibleToImport
>>>> +      // means it could have writes via inline assembly leading it to
>>>> be
>>>> +      // in the @llvm.*used).
>>>> +      if (auto *GVS = dyn_cast<GlobalVarSummary>(S->getBaseObject()))
>>>> +        // Here we intentionally pass S.get() not GVS, because S could
>>>> be
>>>> +        // an alias.
>>>> +        if (!canImportGlobalVar(S.get()) ||
>>>> GUIDPreservedSymbols.count(P.first))
>>>> +          GVS->setReadOnly(false);
>>>> +      propagateConstantsToRefs(S.get());
>>>> +    }
>>>> +}
>>>> +
>>>>  // TODO: write a graphviz dumper for SCCs (see
>>>> ModuleSummaryIndex::exportToDot)
>>>>  // then delete this function and update its tests
>>>>  LLVM_DUMP_METHOD
>>>> @@ -108,6 +186,7 @@ namespace {
>>>>  struct Attributes {
>>>>    void add(const Twine &Name, const Twine &Value,
>>>>             const Twine &Comment = Twine());
>>>> +  void addComment(const Twine &Comment);
>>>>    std::string getAsString() const;
>>>>
>>>>    std::vector<std::string> Attrs;
>>>> @@ -129,6 +208,10 @@ void Attributes::add(const Twine &Name,
>>>>    A += Value.str();
>>>>    A += "\"";
>>>>    Attrs.push_back(A);
>>>> +  addComment(Comment);
>>>> +}
>>>> +
>>>> +void Attributes::addComment(const Twine &Comment) {
>>>>    if (!Comment.isTriviallyEmpty()) {
>>>>      if (Comments.empty())
>>>>        Comments = " // ";
>>>> @@ -237,6 +320,12 @@ static void defineExternalNode(raw_ostre
>>>>    OS << "\"]; // defined externally\n";
>>>>  }
>>>>
>>>> +static bool hasReadOnlyFlag(const GlobalValueSummary *S) {
>>>> +  if (auto *GVS = dyn_cast<GlobalVarSummary>(S))
>>>> +    return GVS->isReadOnly();
>>>> +  return false;
>>>> +}
>>>> +
>>>>  void ModuleSummaryIndex::exportToDot(raw_ostream &OS) const {
>>>>    std::vector<Edge> CrossModuleEdges;
>>>>    DenseMap<GlobalValue::GUID, std::vector<uint64_t>> NodeMap;
>>>> @@ -252,13 +341,17 @@ void ModuleSummaryIndex::exportToDot(raw
>>>>    };
>>>>
>>>>    auto DrawEdge = [&](const char *Pfx, uint64_t SrcMod,
>>>> GlobalValue::GUID SrcId,
>>>> -                      uint64_t DstMod, GlobalValue::GUID DstId, int
>>>> TypeOrHotness) {
>>>> -    // 0 corresponds to alias edge, 1 to ref edge, 2 to call with
>>>> unknown
>>>> -    // hotness, ...
>>>> -    TypeOrHotness += 2;
>>>> +                      uint64_t DstMod, GlobalValue::GUID DstId,
>>>> +                      int TypeOrHotness) {
>>>> +    // 0 - alias
>>>> +    // 1 - reference
>>>> +    // 2 - constant reference
>>>> +    // Other value: (hotness - 3).
>>>> +    TypeOrHotness += 3;
>>>>      static const char *EdgeAttrs[] = {
>>>>          " [style=dotted]; // alias",
>>>>          " [style=dashed]; // ref",
>>>> +        " [style=dashed,color=forestgreen]; // const-ref",
>>>>          " // call (hotness : Unknown)",
>>>>          " [color=blue]; // call (hotness : Cold)",
>>>>          " // call (hotness : None)",
>>>> @@ -301,6 +394,8 @@ void ModuleSummaryIndex::exportToDot(raw
>>>>          A.add("shape", "box");
>>>>        } else {
>>>>          A.add("shape", "Mrecord", "variable");
>>>> +        if (Flags.Live && hasReadOnlyFlag(SummaryIt.second))
>>>> +          A.addComment("immutable");
>>>>        }
>>>>
>>>>        auto VI = getValueInfo(SummaryIt.first);
>>>> @@ -318,7 +413,7 @@ void ModuleSummaryIndex::exportToDot(raw
>>>>      for (auto &SummaryIt : GVSMap) {
>>>>        auto *GVS = SummaryIt.second;
>>>>        for (auto &R : GVS->refs())
>>>> -        Draw(SummaryIt.first, R.getGUID(), -1);
>>>> +        Draw(SummaryIt.first, R.getGUID(), R.isReadOnly() ? -1 : -2);
>>>>
>>>>        if (auto *AS = dyn_cast_or_null<AliasSummary>(SummaryIt.second))
>>>> {
>>>>          GlobalValue::GUID AliaseeId;
>>>> @@ -331,7 +426,7 @@ void ModuleSummaryIndex::exportToDot(raw
>>>>              AliaseeId = AliaseeOrigId;
>>>>          }
>>>>
>>>> -        Draw(SummaryIt.first, AliaseeId, -2);
>>>> +        Draw(SummaryIt.first, AliaseeId, -3);
>>>>          continue;
>>>>        }
>>>>
>>>>
>>>> Modified: llvm/trunk/lib/LTO/LTO.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTO.cpp?rev=347033&r1=347032&r2=347033&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/lib/LTO/LTO.cpp (original)
>>>> +++ llvm/trunk/lib/LTO/LTO.cpp Thu Nov 15 23:08:00 2018
>>>> @@ -187,6 +187,8 @@ static void computeCacheKey(
>>>>        AddUnsigned(VI.isDSOLocal());
>>>>        AddUsedCfiGlobal(VI.getGUID());
>>>>      }
>>>> +    if (auto *GVS = dyn_cast<GlobalVarSummary>(GS))
>>>> +      AddUnsigned(GVS->isReadOnly());
>>>>      if (auto *FS = dyn_cast<FunctionSummary>(GS)) {
>>>>        for (auto &TT : FS->type_tests())
>>>>          UsedTypeIds.insert(TT);
>>>> @@ -809,7 +811,8 @@ Error LTO::run(AddStreamFn AddStream, Na
>>>>        return PrevailingType::Unknown;
>>>>      return It->second;
>>>>    };
>>>> -  computeDeadSymbols(ThinLTO.CombinedIndex, GUIDPreservedSymbols,
>>>> isPrevailing);
>>>> +  computeDeadSymbolsWithConstProp(ThinLTO.CombinedIndex,
>>>> GUIDPreservedSymbols,
>>>> +                                  isPrevailing, Conf.OptLevel > 0);
>>>>
>>>>    // Setup output file to emit statistics.
>>>>    std::unique_ptr<ToolOutputFile> StatsFile = nullptr;
>>>>
>>>> Modified: llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp?rev=347033&r1=347032&r2=347033&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp (original)
>>>> +++ llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp Thu Nov 15 23:08:00 2018
>>>> @@ -298,7 +298,7 @@ public:
>>>>        const FunctionImporter::ImportMapTy &ImportList,
>>>>        const FunctionImporter::ExportSetTy &ExportList,
>>>>        const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
>>>> &ResolvedODR,
>>>> -      const GVSummaryMapTy &DefinedFunctions,
>>>> +      const GVSummaryMapTy &DefinedGVSummaries,
>>>>        const DenseSet<GlobalValue::GUID> &PreservedSymbols, unsigned
>>>> OptLevel,
>>>>        bool Freestanding, const TargetMachineBuilder &TMBuilder) {
>>>>      if (CachePath.empty())
>>>> @@ -368,6 +368,10 @@ public:
>>>>      for (auto &Entry : ImportList) {
>>>>        auto ModHash = Index.getModuleHash(Entry.first());
>>>>        Hasher.update(ArrayRef<uint8_t>((uint8_t *)&ModHash[0],
>>>> sizeof(ModHash)));
>>>> +      for (auto Guid : Entry.second)
>>>> +        if (auto *GVS = dyn_cast<GlobalVarSummary>(
>>>> +                Index.getGlobalValueSummary(Guid, false)))
>>>> +          AddUnsigned(GVS->isReadOnly());
>>>>      }
>>>>
>>>>      // Include the hash for the resolved ODR.
>>>> @@ -380,11 +384,15 @@ public:
>>>>
>>>>      // Include the hash for the preserved symbols.
>>>>      for (auto &Entry : PreservedSymbols) {
>>>> -      if (DefinedFunctions.count(Entry))
>>>> +      if (DefinedGVSummaries.count(Entry))
>>>>          Hasher.update(
>>>>              ArrayRef<uint8_t>((const uint8_t *)&Entry,
>>>> sizeof(GlobalValue::GUID)));
>>>>      }
>>>>
>>>> +    for (auto &Entry : DefinedGVSummaries)
>>>> +      if (auto *GVS = dyn_cast<GlobalVarSummary>(Entry.second))
>>>> +        AddUnsigned(GVS->isReadOnly());
>>>> +
>>>>      // This choice of file name allows the cache to be pruned (see
>>>> pruneCache()
>>>>      // in include/llvm/Support/CachePruning.h).
>>>>      sys::path::append(EntryPath, CachePath,
>>>> @@ -646,7 +654,8 @@ static void computeDeadSymbolsInIndex(
>>>>    auto isPrevailing = [&](GlobalValue::GUID G) {
>>>>      return PrevailingType::Unknown;
>>>>    };
>>>> -  computeDeadSymbols(Index, GUIDPreservedSymbols, isPrevailing);
>>>> +  computeDeadSymbolsWithConstProp(Index, GUIDPreservedSymbols,
>>>> isPrevailing,
>>>> +                                  /* ImportEnabled = */ true);
>>>>  }
>>>>
>>>>  /**
>>>> @@ -983,13 +992,13 @@ void ThinLTOCodeGenerator::run() {
>>>>          auto ModuleIdentifier = ModuleBuffer.getBufferIdentifier();
>>>>          auto &ExportList = ExportLists[ModuleIdentifier];
>>>>
>>>> -        auto &DefinedFunctions =
>>>> ModuleToDefinedGVSummaries[ModuleIdentifier];
>>>> +        auto &DefinedGVSummaries =
>>>> ModuleToDefinedGVSummaries[ModuleIdentifier];
>>>>
>>>>          // The module may be cached, this helps handling it.
>>>>          ModuleCacheEntry CacheEntry(CacheOptions.Path, *Index,
>>>> ModuleIdentifier,
>>>>                                      ImportLists[ModuleIdentifier],
>>>> ExportList,
>>>>                                      ResolvedODR[ModuleIdentifier],
>>>> -                                    DefinedFunctions,
>>>> GUIDPreservedSymbols,
>>>> +                                    DefinedGVSummaries,
>>>> GUIDPreservedSymbols,
>>>>                                      OptLevel, Freestanding, TMBuilder);
>>>>          auto CacheEntryPath = CacheEntry.getEntryPath();
>>>>
>>>>
>>>> Modified: llvm/trunk/lib/Linker/IRMover.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/IRMover.cpp?rev=347033&r1=347032&r2=347033&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/lib/Linker/IRMover.cpp (original)
>>>> +++ llvm/trunk/lib/Linker/IRMover.cpp Thu Nov 15 23:08:00 2018
>>>> @@ -1062,11 +1062,6 @@ void IRLinker::prepareCompileUnitsForImp
>>>>      ValueMap.MD()[CU->getRawEnumTypes()].reset(nullptr);
>>>>      ValueMap.MD()[CU->getRawMacros()].reset(nullptr);
>>>>      ValueMap.MD()[CU->getRawRetainedTypes()].reset(nullptr);
>>>> -    // We import global variables only temporarily in order for
>>>> instcombine
>>>> -    // and globalopt to perform constant folding and static constructor
>>>> -    // evaluation. After that elim-avail-extern will covert imported
>>>> globals
>>>> -    // back to declarations, so we don't need debug info for them.
>>>> -    ValueMap.MD()[CU->getRawGlobalVariables()].reset(nullptr);
>>>>
>>>>      // Imported entities only need to be mapped in if they have local
>>>>      // scope, as those might correspond to an imported entity inside a
>>>>
>>>> Modified: llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp?rev=347033&r1=347032&r2=347033&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp (original)
>>>> +++ llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp Thu Nov 15
>>>> 23:08:00 2018
>>>> @@ -294,10 +294,8 @@ static void computeImportForReferencedGl
>>>>      LLVM_DEBUG(dbgs() << " ref -> " << VI << "\n");
>>>>
>>>>      for (auto &RefSummary : VI.getSummaryList())
>>>> -      if (RefSummary->getSummaryKind() ==
>>>> GlobalValueSummary::GlobalVarKind &&
>>>> -          !RefSummary->notEligibleToImport() &&
>>>> -          !GlobalValue::isInterposableLinkage(RefSummary->linkage()) &&
>>>> -          RefSummary->refs().empty()) {
>>>> +      if (isa<GlobalVarSummary>(RefSummary.get()) &&
>>>> +          canImportGlobalVar(RefSummary.get())) {
>>>>          auto ILI =
>>>> ImportList[RefSummary->modulePath()].insert(VI.getGUID());
>>>>          // Only update stat if we haven't already imported this
>>>> variable.
>>>>          if (ILI.second)
>>>> @@ -824,6 +822,25 @@ void llvm::computeDeadSymbols(
>>>>    NumLiveSymbols += LiveSymbols;
>>>>  }
>>>>
>>>> +// Compute dead symbols and propagate constants in combined index.
>>>> +void llvm::computeDeadSymbolsWithConstProp(
>>>> +    ModuleSummaryIndex &Index,
>>>> +    const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols,
>>>> +    function_ref<PrevailingType(GlobalValue::GUID)> isPrevailing,
>>>> +    bool ImportEnabled) {
>>>> +  computeDeadSymbols(Index, GUIDPreservedSymbols, isPrevailing);
>>>> +  if (ImportEnabled) {
>>>> +    Index.propagateConstants(GUIDPreservedSymbols);
>>>> +  } else {
>>>> +    // If import is disabled we should drop read-only attribute
>>>> +    // from all summaries to prevent internalization.
>>>> +    for (auto &P : Index)
>>>> +      for (auto &S : P.second.SummaryList)
>>>> +        if (auto *GVS = dyn_cast<GlobalVarSummary>(S.get()))
>>>> +          GVS->setReadOnly(false);
>>>> +  }
>>>> +}
>>>> +
>>>>  /// Compute the set of summaries needed for a ThinLTO backend
>>>> compilation of
>>>>  /// \p ModulePath.
>>>>  void llvm::gatherImportedSummariesForModule(
>>>> @@ -1020,6 +1037,18 @@ static Function *replaceAliasWithAliasee
>>>>    return NewFn;
>>>>  }
>>>>
>>>> +// Internalize values that we marked with specific attribute
>>>> +// in processGlobalForThinLTO.
>>>> +static void internalizeImmutableGVs(Module &M) {
>>>> +  for (auto &GV : M.globals())
>>>> +    // Skip GVs which have been converted to declarations
>>>> +    // by dropDeadSymbols.
>>>> +    if (!GV.isDeclaration() && GV.hasAttribute("thinlto-internalize"))
>>>> {
>>>> +      GV.setLinkage(GlobalValue::InternalLinkage);
>>>> +      GV.setVisibility(GlobalValue::DefaultVisibility);
>>>> +    }
>>>> +}
>>>> +
>>>>  // Automatically import functions in Module \p DestModule based on the
>>>> summaries
>>>>  // index.
>>>>  Expected<bool> FunctionImporter::importFunctions(
>>>> @@ -1143,6 +1172,8 @@ Expected<bool> FunctionImporter::importF
>>>>      NumImportedModules++;
>>>>    }
>>>>
>>>> +  internalizeImmutableGVs(DestModule);
>>>> +
>>>>    NumImportedFunctions += (ImportedCount - ImportedGVCount);
>>>>    NumImportedGlobalVars += ImportedGVCount;
>>>>
>>>>
>>>> Modified: llvm/trunk/lib/Transforms/Utils/FunctionImportUtils.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/FunctionImportUtils.cpp?rev=347033&r1=347032&r2=347033&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/lib/Transforms/Utils/FunctionImportUtils.cpp (original)
>>>> +++ llvm/trunk/lib/Transforms/Utils/FunctionImportUtils.cpp Thu Nov 15
>>>> 23:08:00 2018
>>>> @@ -204,8 +204,9 @@ void FunctionImportGlobalProcessing::pro
>>>>
>>>>    // Check the summaries to see if the symbol gets resolved to a known
>>>> local
>>>>    // definition.
>>>> +  ValueInfo VI;
>>>>    if (GV.hasName()) {
>>>> -    ValueInfo VI = ImportIndex.getValueInfo(GV.getGUID());
>>>> +    VI = ImportIndex.getValueInfo(GV.getGUID());
>>>>      if (VI && VI.isDSOLocal()) {
>>>>        GV.setDSOLocal(true);
>>>>        if (GV.hasDLLImportStorageClass())
>>>> @@ -213,6 +214,22 @@ void FunctionImportGlobalProcessing::pro
>>>>      }
>>>>    }
>>>>
>>>> +  // Mark read-only variables which can be imported with specific
>>>> attribute.
>>>> +  // We can't internalize them now because IRMover will fail to link
>>>> variable
>>>> +  // definitions to their external declarations during ThinLTO import.
>>>> We'll
>>>> +  // internalize read-only variables later, after import is finished.
>>>> +  // See internalizeImmutableGVs.
>>>> +  //
>>>> +  // If global value dead stripping is not enabled in summary then
>>>> +  // propagateConstants hasn't been run. We can't internalize GV
>>>> +  // in such case.
>>>> +  if (!GV.isDeclaration() && VI &&
>>>> ImportIndex.withGlobalValueDeadStripping()) {
>>>> +    const auto &SL = VI.getSummaryList();
>>>> +    auto *GVS = SL.empty() ? nullptr :
>>>> dyn_cast<GlobalVarSummary>(SL[0].get());
>>>> +    if (GVS && GVS->isReadOnly())
>>>> +      cast<GlobalVariable>(&GV)->addAttribute("thinlto-internalize");
>>>> +  }
>>>> +
>>>>    bool DoPromote = false;
>>>>    if (GV.hasLocalLinkage() &&
>>>>        ((DoPromote = shouldPromoteLocalToGlobal(&GV)) ||
>>>> isPerformingImport())) {
>>>> @@ -230,7 +247,7 @@ void FunctionImportGlobalProcessing::pro
>>>>    // Remove functions imported as available externally defs from
>>>> comdats,
>>>>    // as this is a declaration for the linker, and will be dropped
>>>> eventually.
>>>>    // It is illegal for comdats to contain declarations.
>>>> -  auto *GO = dyn_cast_or_null<GlobalObject>(&GV);
>>>> +  auto *GO = dyn_cast<GlobalObject>(&GV);
>>>>    if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) {
>>>>      // The IRMover should not have placed any imported declarations in
>>>>      // a comdat, so the only declaration that should be in a comdat
>>>>
>>>> Modified: llvm/trunk/test/Bitcode/summary_version.ll
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/summary_version.ll?rev=347033&r1=347032&r2=347033&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/test/Bitcode/summary_version.ll (original)
>>>> +++ llvm/trunk/test/Bitcode/summary_version.ll Thu Nov 15 23:08:00 2018
>>>> @@ -2,7 +2,7 @@
>>>>  ; RUN: opt  -module-summary  %s -o - | llvm-bcanalyzer -dump |
>>>> FileCheck %s
>>>>
>>>>  ; CHECK: <GLOBALVAL_SUMMARY_BLOCK
>>>> -; CHECK: <VERSION op0=4/>
>>>> +; CHECK: <VERSION op0=5/>
>>>>
>>>>
>>>>
>>>>
>>>> Modified: llvm/trunk/test/Bitcode/thinlto-alias.ll
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/thinlto-alias.ll?rev=347033&r1=347032&r2=347033&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/test/Bitcode/thinlto-alias.ll (original)
>>>> +++ llvm/trunk/test/Bitcode/thinlto-alias.ll Thu Nov 15 23:08:00 2018
>>>> @@ -20,7 +20,7 @@
>>>>  ; CHECK-NEXT:    <VERSION
>>>>  ; See if the call to func is registered.
>>>>  ; The value id 1 matches the second FUNCTION record above.
>>>> -; CHECK-NEXT:    <PERMODULE {{.*}} op5=1/>
>>>> +; CHECK-NEXT:    <PERMODULE {{.*}} op6=1/>
>>>>  ; CHECK-NEXT:  </GLOBALVAL_SUMMARY_BLOCK>
>>>>
>>>>  ; CHECK: <STRTAB_BLOCK
>>>> @@ -33,7 +33,7 @@
>>>>  ; COMBINED-NEXT:    <VALUE_GUID op0=[[ALIASID:[0-9]+]]
>>>> op1=-5751648690987223394/>
>>>>  ; COMBINED-NEXT:    <VALUE_GUID
>>>>  ; COMBINED-NEXT:    <VALUE_GUID op0=[[ALIASEEID:[0-9]+]]
>>>> op1=-1039159065113703048/>
>>>> -; COMBINED-NEXT:    <COMBINED {{.*}} op6=[[ALIASID]]/>
>>>> +; COMBINED-NEXT:    <COMBINED {{.*}} op7=[[ALIASID]]/>
>>>>  ; COMBINED-NEXT:    <COMBINED {{.*}}
>>>>  ; COMBINED-NEXT:    <COMBINED_ALIAS  {{.*}} op3=[[ALIASEEID]]
>>>>  ; COMBINED-NEXT:  </GLOBALVAL_SUMMARY_BLOCK
>>>>
>>>> Modified: llvm/trunk/test/Bitcode/thinlto-alias2.ll
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/thinlto-alias2.ll?rev=347033&r1=347032&r2=347033&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/test/Bitcode/thinlto-alias2.ll (original)
>>>> +++ llvm/trunk/test/Bitcode/thinlto-alias2.ll Thu Nov 15 23:08:00 2018
>>>> @@ -4,7 +4,7 @@
>>>>
>>>>  ; CHECK:       <GLOBALVAL_SUMMARY_BLOCK
>>>>  ; CHECK-NEXT:    <VERSION
>>>> -; CHECK-NEXT:    <PERMODULE {{.*}} op4=0 op5=[[ALIASID:[0-9]+]]/>
>>>> +; CHECK-NEXT:    <PERMODULE {{.*}} op4=0 op5=0 op6=[[ALIASID:[0-9]+]]/>
>>>>  ; CHECK-NEXT:    <PERMODULE {{.*}} op0=[[ALIASEEID:[0-9]+]]
>>>>  ; CHECK-NEXT:    <ALIAS {{.*}} op0=[[ALIASID]] {{.*}}
>>>> op2=[[ALIASEEID]]/>
>>>>  ; CHECK-NEXT:  </GLOBALVAL_SUMMARY_BLOCK>
>>>>
>>>> Modified:
>>>> llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph-cast.ll
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph-cast.ll?rev=347033&r1=347032&r2=347033&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph-cast.ll
>>>> (original)
>>>> +++ llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph-cast.ll
>>>> Thu Nov 15 23:08:00 2018
>>>> @@ -6,9 +6,9 @@
>>>>  ; CHECK:       <GLOBALVAL_SUMMARY_BLOCK
>>>>  ; CHECK-NEXT:    <VERSION
>>>>  ; "op7" is a call to "callee" function.
>>>> -; CHECK-NEXT:    <PERMODULE {{.*}} op7=3 op8=[[ALIASID:[0-9]+]]/>
>>>> +; CHECK-NEXT:    <PERMODULE {{.*}} op8=3 op9=[[ALIASID:[0-9]+]]/>
>>>>  ; "another_caller" has only references but no calls.
>>>> -; CHECK-NEXT:    <PERMODULE {{.*}} op4=3 {{.*}} op7={{[0-9]+}}/>
>>>> +; CHECK-NEXT:    <PERMODULE {{.*}} op4=3 {{.*}} op8={{[0-9]+}}/>
>>>>  ; CHECK-NEXT:    <PERMODULE {{.*}} op0=[[ALIASEEID:[0-9]+]]
>>>>  ; CHECK-NEXT:    <ALIAS {{.*}} op0=[[ALIASID]] {{.*}}
>>>> op2=[[ALIASEEID]]/>
>>>>  ; CHECK-NEXT:  </GLOBALVAL_SUMMARY_BLOCK>
>>>>
>>>> Modified:
>>>> llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph-pgo.ll
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph-pgo.ll?rev=347033&r1=347032&r2=347033&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph-pgo.ll
>>>> (original)
>>>> +++ llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph-pgo.ll
>>>> Thu Nov 15 23:08:00 2018
>>>> @@ -17,7 +17,7 @@
>>>>  ; CHECK:       <GLOBALVAL_SUMMARY_BLOCK
>>>>  ; CHECK-NEXT:    <VERSION
>>>>  ; See if the call to func is registered, using the expected hotness
>>>> type.
>>>> -; CHECK-NEXT:    <PERMODULE_PROFILE {{.*}} op5=1 op6=2/>
>>>> +; CHECK-NEXT:    <PERMODULE_PROFILE {{.*}} op6=1 op7=2/>
>>>>  ; CHECK-NEXT:  </GLOBALVAL_SUMMARY_BLOCK>
>>>>  ; CHECK: <STRTAB_BLOCK
>>>>  ; CHECK-NEXT: blob data = 'mainfunc{{.*}}'
>>>> @@ -30,7 +30,7 @@
>>>>  ; COMBINED-NEXT:    <COMBINED
>>>>  ; See if the call to func is registered, using the expected hotness
>>>> type.
>>>>  ; op6=2 which is hotnessType::None.
>>>> -; COMBINED-NEXT:    <COMBINED_PROFILE {{.*}} op6=[[FUNCID]] op7=2/>
>>>> +; COMBINED-NEXT:    <COMBINED_PROFILE {{.*}} op7=[[FUNCID]] op8=2/>
>>>>  ; COMBINED-NEXT:  </GLOBALVAL_SUMMARY_BLOCK>
>>>>
>>>>  ; ModuleID = 'thinlto-function-summary-callgraph.ll'
>>>>
>>>> Modified:
>>>> llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph-profile-summary.ll
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph-profile-summary.ll?rev=347033&r1=347032&r2=347033&view=diff
>>>>
>>>> ==============================================================================
>>>> ---
>>>> llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph-profile-summary.ll
>>>> (original)
>>>> +++
>>>> llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph-profile-summary.ll
>>>> Thu Nov 15 23:08:00 2018
>>>> @@ -48,7 +48,7 @@
>>>>  ; CHECK-NEXT:    <VERSION
>>>>  ; CHECK-NEXT:    <VALUE_GUID op0=25 op1=123/>
>>>>  ; op4=hot1 op6=cold op8=hot2 op10=hot4 op12=none1 op14=hot3 op16=none2
>>>> op18=none3 op20=123
>>>> -; CHECK-NEXT:    <PERMODULE_PROFILE {{.*}} op5=1 op6=3 op7=5 op8=1
>>>> op9=2 op10=3 op11=4 op12=1 op13=6 op14=2 op15=3 op16=3 op17=7 op18=2 op19=8
>>>> op20=2 op21=25 op22=4/>
>>>> +; CHECK-NEXT:    <PERMODULE_PROFILE {{.*}} op6=1 op7=3 op8=5 op9=1
>>>> op10=2 op11=3 op12=4 op13=1 op14=6 op15=2 op16=3 op17=3 op18=7 op19=2
>>>> op20=8 op21=2 op22=25 op23=4/>
>>>>  ; CHECK-NEXT:  </GLOBALVAL_SUMMARY_BLOCK>
>>>>
>>>>  ; CHECK: <STRTAB_BLOCK
>>>> @@ -71,7 +71,7 @@
>>>>  ; COMBINED-NEXT:    <COMBINED abbrevid=
>>>>  ; COMBINED-NEXT:    <COMBINED abbrevid=
>>>>  ; COMBINED-NEXT:    <COMBINED abbrevid=
>>>> -; COMBINED-NEXT:    <COMBINED_PROFILE {{.*}} op6=[[HOT1:.*]] op7=3
>>>> op8=[[COLD:.*]] op9=1 op10=[[HOT2:.*]] op11=3 op12=[[NONE1:.*]] op13=2
>>>> op14=[[HOT3:.*]] op15=3 op16=[[NONE2:.*]] op17=2 op18=[[NONE3:.*]] op19=2/>
>>>> +; COMBINED-NEXT:    <COMBINED_PROFILE {{.*}} op7=[[HOT1:.*]] op8=3
>>>> op9=[[COLD:.*]] op10=1 op11=[[HOT2:.*]] op12=3 op13=[[NONE1:.*]] op14=2
>>>> op15=[[HOT3:.*]] op16=3 op17=[[NONE2:.*]] op18=2 op19=[[NONE3:.*]] op20=2/>
>>>>  ; COMBINED_NEXT:    <COMBINED abbrevid=
>>>>  ; COMBINED_NEXT:  </GLOBALVAL_SUMMARY_BLOCK>
>>>>
>>>>
>>>> Modified:
>>>> llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph-relbf.ll
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph-relbf.ll?rev=347033&r1=347032&r2=347033&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph-relbf.ll
>>>> (original)
>>>> +++ llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph-relbf.ll
>>>> Thu Nov 15 23:08:00 2018
>>>> @@ -13,7 +13,7 @@
>>>>  ; CHECK:       <GLOBALVAL_SUMMARY_BLOCK
>>>>  ; CHECK-NEXT:    <VERSION
>>>>  ; See if the call to func is registered.
>>>> -; CHECK-NEXT:    <PERMODULE_RELBF {{.*}} op4=1 {{.*}} op7=256
>>>> +; CHECK-NEXT:    <PERMODULE_RELBF {{.*}} op4=1 {{.*}} op8=256
>>>>  ; CHECK-NEXT:  </GLOBALVAL_SUMMARY_BLOCK>
>>>>  ; CHECK: <STRTAB_BLOCK
>>>>  ; CHECK-NEXT: blob data = 'undefinedglobmainfunc{{.*}}'
>>>>
>>>> Modified:
>>>> llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph-sample-profile-summary.ll
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph-sample-profile-summary.ll?rev=347033&r1=347032&r2=347033&view=diff
>>>>
>>>> ==============================================================================
>>>> ---
>>>> llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph-sample-profile-summary.ll
>>>> (original)
>>>> +++
>>>> llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph-sample-profile-summary.ll
>>>> Thu Nov 15 23:08:00 2018
>>>> @@ -31,7 +31,7 @@
>>>>  ; CHECK-NEXT:    <VERSION
>>>>  ; CHECK-NEXT:    <VALUE_GUID op0=26 op1=123/>
>>>>  ; op4=none1 op6=hot1 op8=cold1 op10=none2 op12=hot2 op14=cold2
>>>> op16=none3 op18=hot3 op20=cold3 op22=123
>>>> -; CHECK-NEXT:    <PERMODULE_PROFILE {{.*}} op5=7 op6=0 op7=1 op8=3
>>>> op9=4 op10=1 op11=8 op12=0 op13=2 op14=3 op15=5 op16=1 op17=9 op18=0 op19=3
>>>> op20=3 op21=6 op22=1 op23=26 op24=4/>
>>>> +; CHECK-NEXT:    <PERMODULE_PROFILE {{.*}} op6=7 op7=0 op8=1 op9=3
>>>> op10=4 op11=1 op12=8 op13=0 op14=2 op15=3 op16=5 op17=1 op18=9 op19=0
>>>> op20=3 op21=3 op22=6 op23=1 op24=26 op25=4/>
>>>>  ; CHECK-NEXT:  </GLOBALVAL_SUMMARY_BLOCK>
>>>>
>>>>  ; CHECK: <STRTAB_BLOCK
>>>> @@ -58,7 +58,7 @@
>>>>  ; COMBINED-NEXT:    <COMBINED abbrevid=
>>>>  ; COMBINED-NEXT:    <COMBINED abbrevid=
>>>>  ; COMBINED-NEXT:    <COMBINED abbrevid=
>>>> -; COMBINED-NEXT:    <COMBINED_PROFILE {{.*}} op6=[[NONE1:.*]] op7=0
>>>> op8=[[HOT1:.*]] op9=3 op10=[[COLD1:.*]] op11=1 op12=[[NONE2:.*]] op13=0
>>>> op14=[[HOT2:.*]] op15=3 op16=[[COLD2:.*]] op17=1 op18=[[NONE3:.*]] op19=0
>>>> op20=[[HOT3:.*]] op21=3 op22=[[COLD3:.*]] op23=1/>
>>>> +; COMBINED-NEXT:    <COMBINED_PROFILE {{.*}} op7=[[NONE1:.*]] op8=0
>>>> op9=[[HOT1:.*]] op10=3 op11=[[COLD1:.*]] op12=1 op13=[[NONE2:.*]] op14=0
>>>> op15=[[HOT2:.*]] op16=3 op17=[[COLD2:.*]] op18=1 op19=[[NONE3:.*]] op20=0
>>>> op21=[[HOT3:.*]] op22=3 op23=[[COLD3:.*]] op24=1/>
>>>>  ; COMBINED_NEXT:    <COMBINED abbrevid=
>>>>  ; COMBINED_NEXT:  </GLOBALVAL_SUMMARY_BLOCK>
>>>>
>>>>
>>>> Modified: llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph.ll
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph.ll?rev=347033&r1=347032&r2=347033&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph.ll
>>>> (original)
>>>> +++ llvm/trunk/test/Bitcode/thinlto-function-summary-callgraph.ll Thu
>>>> Nov 15 23:08:00 2018
>>>> @@ -17,7 +17,7 @@
>>>>  ; CHECK-NEXT: <FUNCTION op0=17 op1=4
>>>>  ; CHECK:       <GLOBALVAL_SUMMARY_BLOCK
>>>>  ; CHECK-NEXT:    <VERSION
>>>> -; See if the call to func is registered.
>>>> +; See if the call to func is registered
>>>>  ; CHECK-NEXT:    <PERMODULE {{.*}} op4=1
>>>>  ; CHECK-NEXT:  </GLOBALVAL_SUMMARY_BLOCK>
>>>>  ; CHECK: <STRTAB_BLOCK
>>>> @@ -33,7 +33,7 @@
>>>>  ; COMBINED-NEXT:    <VALUE_GUID
>>>>  ; COMBINED-NEXT:    <COMBINED
>>>>  ; See if the call to func is registered.
>>>> -; COMBINED-NEXT:    <COMBINED {{.*}} op6=[[FUNCID]]/>
>>>> +; COMBINED-NEXT:    <COMBINED {{.*}} op7=[[FUNCID]]/>
>>>>  ; COMBINED-NEXT:  </GLOBALVAL_SUMMARY_BLOCK>
>>>>
>>>>  ; ModuleID = 'thinlto-function-summary-callgraph.ll'
>>>>
>>>> Modified: llvm/trunk/test/Bitcode/thinlto-function-summary-refgraph.ll
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/thinlto-function-summary-refgraph.ll?rev=347033&r1=347032&r2=347033&view=diff
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/test/Bitcode/thinlto-function-summary-refgraph.ll
>>>> (original)
>>>> +++ llvm/trunk/test/Bitcode/thinlto-function-summary-refgraph.ll Thu
>>>> Nov 15 23:08:00 2018
>>>> @@ -41,27 +41,27 @@
>>>>  ; CHECK:       <GLOBALVAL_SUMMARY_BLOCK
>>>>  ; Function main contains call to func, as well as address reference to
>>>> func:
>>>>  ; op0=main op4=func op5=func
>>>> -; CHECK-DAG:    <PERMODULE {{.*}} op0=11 op1=0 {{.*}} op4=1 op5=2
>>>> op6=2/>
>>>> +; CHECK-DAG:    <PERMODULE {{.*}} op0=11 op1=0 {{.*}} op4=1 op5=0
>>>> op6=2 op7=2/>
>>>>  ; Function W contains a call to func3 as well as a reference to
>>>> globalvar:
>>>>  ; op0=W op4=globalvar op5=func3
>>>> -; CHECK-DAG:    <PERMODULE {{.*}} op0=6 op1=5 {{.*}} op4=1 op5=1
>>>> op6=5/>
>>>> +; CHECK-DAG:    <PERMODULE {{.*}} op0=6 op1=5 {{.*}} op4=1 op5=0 op6=1
>>>> op7=5/>
>>>>  ; Function X contains call to foo, as well as address reference to foo
>>>>  ; which is in the same instruction as the call:
>>>>  ; op0=X op4=foo op5=foo
>>>> -; CHECK-DAG:    <PERMODULE {{.*}} op0=7 op1=1 {{.*}} op4=1 op5=4
>>>> op6=4/>
>>>> +; CHECK-DAG:    <PERMODULE {{.*}} op0=7 op1=1 {{.*}} op4=1 op5=0 op6=4
>>>> op7=4/>
>>>>  ; Function Y contains call to func2, and ensures we don't incorrectly
>>>> add
>>>>  ; a reference to it when reached while earlier analyzing the phi using
>>>> its
>>>>  ; return value:
>>>>  ; op0=Y op4=func2
>>>> -; CHECK-DAG:    <PERMODULE {{.*}} op0=8 op1=72 {{.*}} op4=0 op5=3/>
>>>> +; CHECK-DAG:    <PERMODULE {{.*}} op0=8 op1=72 {{.*}} op4=0 op5=0
>>>> op6=3/>
>>>>  ; Function Z contains call to func2, and ensures we don't incorrectly
>>>> add
>>>>  ; a reference to it when reached while analyzing subsequent use of its
>>>> return
>>>>  ; value:
>>>>  ; op0=Z op4=func2
>>>> -; CHECK-DAG:    <PERMODULE {{.*}} op0=9 op1=3 {{.*}} op4=0 op5=3/>
>>>> +; CHECK-DAG:    <PERMODULE {{.*}} op0=9 op1=3 {{.*}} op4=0 op5=0
>>>> op6=3/>
>>>>  ; Variable bar initialization contains address reference to func:
>>>>  ; op0=bar op2=func
>>>> -; CHECK-DAG:    <PERMODULE_GLOBALVAR_INIT_REFS {{.*}} op0=0 op1=0
>>>> op2=2/>
>>>> +; CHECK-DAG:    <PERMODULE_GLOBALVAR_INIT_REFS {{.*}} op0=0 op1=0
>>>> op2=1 op3=2/>
>>>>  ; CHECK:  </GLOBALVAL_SUMMARY_BLOCK>
>>>>
>>>>  ; CHECK: <STRTAB_BLOCK
>>>>
>>>> Added: llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-alias.ll
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-alias.ll?rev=347033&view=auto
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-alias.ll (added)
>>>> +++ llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-alias.ll Thu
>>>> Nov 15 23:08:00 2018
>>>> @@ -0,0 +1,5 @@
>>>> +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
>>>> +target triple = "x86_64-unknown-linux-gnu"
>>>> +
>>>> + at g = global i32 42, align 4
>>>> + at g.alias = weak alias i32, i32* @g
>>>>
>>>> Added: llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-cache-foo.ll
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-cache-foo.ll?rev=347033&view=auto
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-cache-foo.ll
>>>> (added)
>>>> +++ llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-cache-foo.ll
>>>> Thu Nov 15 23:08:00 2018
>>>> @@ -0,0 +1,19 @@
>>>> +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
>>>> +target triple = "x86_64-unknown-linux-gnu"
>>>> +
>>>> + at gFoo = internal unnamed_addr global i32 1, align 4
>>>> +
>>>> +; Function Attrs: norecurse nounwind readonly ssp uwtable
>>>> +define i32 @foo() local_unnamed_addr {
>>>> +  %1 = load i32, i32* @gFoo, align 4
>>>> +  ret i32 %1
>>>> +}
>>>> +
>>>> +; Function Attrs: nounwind ssp uwtable
>>>> +define void @bar() local_unnamed_addr {
>>>> +  %1 = tail call i32 @rand()
>>>> +  store i32 %1, i32* @gFoo, align 4
>>>> +  ret void
>>>> +}
>>>> +
>>>> +declare i32 @rand() local_unnamed_addr
>>>>
>>>> Added:
>>>> llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-cache-test1.ll
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-cache-test1.ll?rev=347033&view=auto
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-cache-test1.ll
>>>> (added)
>>>> +++ llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-cache-test1.ll
>>>> Thu Nov 15 23:08:00 2018
>>>> @@ -0,0 +1,10 @@
>>>> +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
>>>> +target triple = "x86_64-unknown-linux-gnu"
>>>> +
>>>> +; Function Attrs: nounwind ssp uwtable
>>>> +define i32 @test() local_unnamed_addr {
>>>> +  %1 = tail call i32 (...) @foo()
>>>> +  ret i32 %1
>>>> +}
>>>> +
>>>> +declare i32 @foo(...) local_unnamed_addr
>>>>
>>>> Added:
>>>> llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-cache-test2.ll
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-cache-test2.ll?rev=347033&view=auto
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-cache-test2.ll
>>>> (added)
>>>> +++ llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-cache-test2.ll
>>>> Thu Nov 15 23:08:00 2018
>>>> @@ -0,0 +1,14 @@
>>>> +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
>>>> +target triple = "x86_64-unknown-linux-gnu"
>>>> +
>>>> +; Function Attrs: nounwind ssp uwtable
>>>> +define i32 @test() local_unnamed_addr {
>>>> +  %1 = tail call i32 (...) @foo()
>>>> +  %2 = tail call i32 (...) @bar()
>>>> +  %3 = add nsw i32 %2, %1
>>>> +  ret i32 %3
>>>> +}
>>>> +
>>>> +declare i32 @foo(...) local_unnamed_addr
>>>> +
>>>> +declare i32 @bar(...) local_unnamed_addr
>>>>
>>>> Added: llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-comdat.ll
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-comdat.ll?rev=347033&view=auto
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-comdat.ll
>>>> (added)
>>>> +++ llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-comdat.ll Thu
>>>> Nov 15 23:08:00 2018
>>>> @@ -0,0 +1,5 @@
>>>> +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
>>>> +target triple = "x86_64-unknown-linux-gnu"
>>>> +
>>>> +$comdat.any = comdat any
>>>> + at g = global i32 42, comdat($comdat.any)
>>>>
>>>> Added: llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-define-g.ll
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-define-g.ll?rev=347033&view=auto
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-define-g.ll
>>>> (added)
>>>> +++ llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-define-g.ll Thu
>>>> Nov 15 23:08:00 2018
>>>> @@ -0,0 +1,4 @@
>>>> +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
>>>> +target triple = "x86_64-unknown-linux-gnu"
>>>> +
>>>> + at g = global i32 42, align 4
>>>>
>>>> Added: llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-full-lto.ll
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-full-lto.ll?rev=347033&view=auto
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-full-lto.ll
>>>> (added)
>>>> +++ llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-full-lto.ll Thu
>>>> Nov 15 23:08:00 2018
>>>> @@ -0,0 +1,12 @@
>>>> +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
>>>> +target triple = "x86_64-unknown-linux-gnu"
>>>> +
>>>> + at g = external global i32
>>>> +
>>>> +define i32 @foo() {
>>>> +  %v = load i32, i32* @g
>>>> +  ret i32 %v
>>>> +}
>>>> +
>>>> +!0 = !{i32 1, !"ThinLTO", i32 0}
>>>> +!llvm.module.flags = !{ !0 }
>>>>
>>>> Added: llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-gvref.ll
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-gvref.ll?rev=347033&view=auto
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-gvref.ll (added)
>>>> +++ llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-gvref.ll Thu
>>>> Nov 15 23:08:00 2018
>>>> @@ -0,0 +1,5 @@
>>>> +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
>>>> +target triple = "x86_64-unknown-linux-gnu"
>>>> +
>>>> + at b = global i32* @a, align 8
>>>> + at a = global i32 42, align 4
>>>>
>>>> Added: llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-linkage.ll
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-linkage.ll?rev=347033&view=auto
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-linkage.ll
>>>> (added)
>>>> +++ llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop-linkage.ll Thu
>>>> Nov 15 23:08:00 2018
>>>> @@ -0,0 +1,15 @@
>>>> +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
>>>> +target triple = "x86_64-unknown-linux-gnu"
>>>> +
>>>> + at g1 = common global i32 0, align 4
>>>> + at g2 = global i32 42, align 4
>>>> + at g3 = available_externally global i32 42, align 4
>>>> +
>>>> +define i32 @foo() {
>>>> +  %v1 = load i32, i32* @g1
>>>> +  %v2 = load i32, i32* @g2
>>>> +  %v3 = load i32, i32* @g3
>>>> +  %s1 = add i32 %v1, %v2
>>>> +  %s2 = add i32 %s1, %v3
>>>> +  ret i32 %s2
>>>> +}
>>>>
>>>> Added: llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop.ll
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop.ll?rev=347033&view=auto
>>>>
>>>> ==============================================================================
>>>> --- llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop.ll (added)
>>>> +++ llvm/trunk/test/ThinLTO/X86/Inputs/index-const-prop.ll Thu Nov 15
>>>> 23:08:00 2018
>>>> @@ -0,0 +1,64 @@
>>>> +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
>>>> +target triple = "x86_64-pc-linux-gnu"
>>>> +
>>>> + at gBar = local_unnamed_addr global i32 2, align 4, !dbg !0
>>>> + at gFoo = internal unnamed_addr global i32 1, align 4, !dbg !6
>>>> +
>>>> +; Function Attrs: norecurse nounwind readonly
>>>> +define i32 @foo() local_unnamed_addr #0 !dbg !14 {
>>>> +  %1 = load i32, i32* @gFoo, align 4, !dbg !17
>>>> +  ret i32 %1, !dbg !18
>>>> +}
>>>> +
>>>> +; Function Attrs: norecurse nounwind readonly
>>>> +define i32 @bar() local_unnamed_addr #0 !dbg !19 {
>>>> +  %1 = load i32, i32* @gBar, align 4, !dbg !20
>>>> +  ret i32 %1, !dbg !21
>>>> +}
>>>> +
>>>> +define void @baz() local_unnamed_addr !dbg !22 {
>>>> +  %1 = tail call i32 @rand(), !dbg !25
>>>> +  store i32 %1, i32* @gFoo, align 4, !dbg !26
>>>> +  %2 = tail call i32 @rand(), !dbg !27
>>>> +  store i32 %2, i32* @gBar, align 4, !dbg !28
>>>> +  ret void, !dbg !29
>>>> +}
>>>> +
>>>> +declare i32 @rand() local_unnamed_addr
>>>> +
>>>> +attributes #0 = { norecurse nounwind readonly }
>>>> +
>>>> +!llvm.dbg.cu = !{!2}
>>>> +!llvm.module.flags = !{!9, !10, !11, !12}
>>>> +!llvm.ident = !{!13}
>>>> +
>>>> +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
>>>> +!1 = distinct !DIGlobalVariable(name: "gBar", scope: !2, file: !3,
>>>> line: 4, type: !8, isLocal: false, isDefinition: true
>>>
>>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181204/12065a79/attachment-0001.html>


More information about the llvm-commits mailing list