[llvm] r347033 - [ThinLTO] Internalize readonly globals

David Blaikie via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 4 15:41:45 PST 2018


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/8df7d32a/attachment-0001.html>


More information about the llvm-commits mailing list