Update prebuilt Clang to match Android kernel.
Bug: 132428451
Change-Id: I8f6e2cb23f381fc0c02ddea99b867e58e925e5be
diff --git a/linux-x64/clang/include/llvm/IR/ModuleSummaryIndex.h b/linux-x64/clang/include/llvm/IR/ModuleSummaryIndex.h
index 778907b..bcb3aa0 100644
--- a/linux-x64/clang/include/llvm/IR/ModuleSummaryIndex.h
+++ b/linux-x64/clang/include/llvm/IR/ModuleSummaryIndex.h
@@ -1,9 +1,8 @@
//===- llvm/ModuleSummaryIndex.h - Module Summary Index ---------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -163,13 +162,13 @@
/// 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 +188,12 @@
: 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;
@@ -408,6 +409,7 @@
return const_cast<GlobalValueSummary &>(
static_cast<const AliasSummary *>(this)->getAliasee());
}
+ bool hasAliaseeGUID() const { return AliaseeGUID != 0; }
const GlobalValue::GUID &getAliaseeGUID() const {
assert(AliaseeGUID && "Unexpected missing aliasee GUID");
return AliaseeGUID;
@@ -477,13 +479,17 @@
TypeCheckedLoadConstVCalls;
};
- /// Function attribute flags. Used to track if a function accesses memory,
- /// recurses or aliases.
+ /// Flags specific to function summaries.
struct FFlags {
+ // Function attribute flags. Used to track if a function accesses memory,
+ // recurses or aliases.
unsigned ReadNone : 1;
unsigned ReadOnly : 1;
unsigned NoRecurse : 1;
unsigned ReturnDoesNotAlias : 1;
+
+ // Indicate if the global value cannot be inlined.
+ unsigned NoInline : 1;
};
/// Create an empty FunctionSummary (with specified call edges).
@@ -494,8 +500,9 @@
FunctionSummary::GVFlags(
GlobalValue::LinkageTypes::AvailableExternallyLinkage,
/*NotEligibleToImport=*/true, /*Live=*/true, /*IsLocal=*/false),
- 0, FunctionSummary::FFlags{}, std::vector<ValueInfo>(),
- std::move(Edges), std::vector<GlobalValue::GUID>(),
+ /*InsCount=*/0, FunctionSummary::FFlags{}, /*EntryCount=*/0,
+ std::vector<ValueInfo>(), std::move(Edges),
+ std::vector<GlobalValue::GUID>(),
std::vector<FunctionSummary::VFuncId>(),
std::vector<FunctionSummary::VFuncId>(),
std::vector<FunctionSummary::ConstVCall>(),
@@ -510,10 +517,14 @@
/// during the initial compile step when the summary index is first built.
unsigned InstCount;
- /// Function attribute flags. Used to track if a function accesses memory,
- /// recurses or aliases.
+ /// Function summary specific flags.
FFlags FunFlags;
+ /// The synthesized entry count of the function.
+ /// This is only populated during ThinLink phase and remains unused while
+ /// generating per-module summaries.
+ uint64_t EntryCount = 0;
+
/// List of <CalleeValueInfo, CalleeInfo> call edge pairs from this function.
std::vector<EdgeTy> CallGraphEdgeList;
@@ -521,14 +532,15 @@
public:
FunctionSummary(GVFlags Flags, unsigned NumInsts, FFlags FunFlags,
- std::vector<ValueInfo> Refs, std::vector<EdgeTy> CGEdges,
+ uint64_t EntryCount, std::vector<ValueInfo> Refs,
+ std::vector<EdgeTy> CGEdges,
std::vector<GlobalValue::GUID> TypeTests,
std::vector<VFuncId> TypeTestAssumeVCalls,
std::vector<VFuncId> TypeCheckedLoadVCalls,
std::vector<ConstVCall> TypeTestAssumeConstVCalls,
std::vector<ConstVCall> TypeCheckedLoadConstVCalls)
: GlobalValueSummary(FunctionKind, Flags, std::move(Refs)),
- InstCount(NumInsts), FunFlags(FunFlags),
+ InstCount(NumInsts), FunFlags(FunFlags), EntryCount(EntryCount),
CallGraphEdgeList(std::move(CGEdges)) {
if (!TypeTests.empty() || !TypeTestAssumeVCalls.empty() ||
!TypeCheckedLoadVCalls.empty() || !TypeTestAssumeConstVCalls.empty() ||
@@ -539,18 +551,26 @@
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) {
return GVS->getSummaryKind() == FunctionKind;
}
- /// Get function attribute flags.
+ /// Get function summary flags.
FFlags fflags() const { return FunFlags; }
/// Get the instruction count recorded for this function.
unsigned instCount() const { return InstCount; }
+ /// Get the synthetic entry count for this function.
+ uint64_t entryCount() const { return EntryCount; }
+
+ /// Set the synthetic entry count for this function.
+ void setEntryCount(uint64_t EC) { EntryCount = EC; }
+
/// Return the list of <CalleeValueInfo, CalleeInfo> pairs.
ArrayRef<EdgeTy> calls() const { return CallGraphEdgeList; }
@@ -648,19 +668,30 @@
/// 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 {
@@ -783,6 +814,9 @@
/// considered live.
bool WithGlobalValueDeadStripping = false;
+ /// Indicates that summary-based synthetic entry count propagation has run
+ bool HasSyntheticEntryCounts = false;
+
/// Indicates that distributed backend should skip compilation of the
/// module. Flag is suppose to be set by distributed ThinLTO indexing
/// when it detected that the module is not needed during the final
@@ -796,6 +830,13 @@
/// union.
bool HaveGVs;
+ // True if the index was created for a module compiled with -fsplit-lto-unit.
+ bool EnableSplitLTOUnit;
+
+ // True if some of the modules were compiled with -fsplit-lto-unit and
+ // some were not. Set when the combined index is created during the thin link.
+ bool PartiallySplitLTOUnits = false;
+
std::set<std::string> CfiFunctionDefs;
std::set<std::string> CfiFunctionDecls;
@@ -815,7 +856,9 @@
public:
// See HaveGVs variable comment.
- ModuleSummaryIndex(bool HaveGVs) : HaveGVs(HaveGVs), Saver(Alloc) {}
+ ModuleSummaryIndex(bool HaveGVs, bool EnableSplitLTOUnit = false)
+ : HaveGVs(HaveGVs), EnableSplitLTOUnit(EnableSplitLTOUnit), Saver(Alloc) {
+ }
bool haveGVs() const { return HaveGVs; }
@@ -895,6 +938,9 @@
WithGlobalValueDeadStripping = true;
}
+ bool hasSyntheticEntryCounts() const { return HasSyntheticEntryCounts; }
+ void setHasSyntheticEntryCounts() { HasSyntheticEntryCounts = true; }
+
bool skipModuleByDistributedBackend() const {
return SkipModuleByDistributedBackend;
}
@@ -902,6 +948,12 @@
SkipModuleByDistributedBackend = true;
}
+ bool enableSplitLTOUnit() const { return EnableSplitLTOUnit; }
+ void setEnableSplitLTOUnit() { EnableSplitLTOUnit = true; }
+
+ bool partiallySplitLTOUnits() const { return PartiallySplitLTOUnits; }
+ void setPartiallySplitLTOUnits() { PartiallySplitLTOUnits = true; }
+
bool isGlobalValueLive(const GlobalValueSummary *GVS) const {
return !WithGlobalValueDeadStripping || GVS->isLive();
}
@@ -927,7 +979,7 @@
// Save a string in the Index. Use before passing Name to
// getOrInsertValueInfo when the string isn't owned elsewhere (e.g. on the
// module's Strtab).
- StringRef saveString(std::string String) { return Saver.save(String); }
+ StringRef saveString(StringRef String) { return Saver.save(String); }
/// Return a ValueInfo for \p GUID setting value \p Name.
ValueInfo getOrInsertValueInfo(GlobalValue::GUID GUID, StringRef Name) {
@@ -1131,11 +1183,15 @@
/// 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
template <> struct GraphTraits<ValueInfo> {
typedef ValueInfo NodeRef;
+ using EdgeRef = FunctionSummary::EdgeTy &;
static NodeRef valueInfoFromEdge(FunctionSummary::EdgeTy &P) {
return P.first;
@@ -1144,6 +1200,8 @@
mapped_iterator<std::vector<FunctionSummary::EdgeTy>::iterator,
decltype(&valueInfoFromEdge)>;
+ using ChildEdgeIteratorType = std::vector<FunctionSummary::EdgeTy>::iterator;
+
static NodeRef getEntryNode(ValueInfo V) { return V; }
static ChildIteratorType child_begin(NodeRef N) {
@@ -1165,6 +1223,26 @@
cast<FunctionSummary>(N.getSummaryList().front()->getBaseObject());
return ChildIteratorType(F->CallGraphEdgeList.end(), &valueInfoFromEdge);
}
+
+ static ChildEdgeIteratorType child_edge_begin(NodeRef N) {
+ if (!N.getSummaryList().size()) // handle external function
+ return FunctionSummary::ExternalNode.CallGraphEdgeList.begin();
+
+ FunctionSummary *F =
+ cast<FunctionSummary>(N.getSummaryList().front()->getBaseObject());
+ return F->CallGraphEdgeList.begin();
+ }
+
+ static ChildEdgeIteratorType child_edge_end(NodeRef N) {
+ if (!N.getSummaryList().size()) // handle external function
+ return FunctionSummary::ExternalNode.CallGraphEdgeList.end();
+
+ FunctionSummary *F =
+ cast<FunctionSummary>(N.getSummaryList().front()->getBaseObject());
+ return F->CallGraphEdgeList.end();
+ }
+
+ static NodeRef edge_dest(EdgeRef E) { return E.first; }
};
template <>
@@ -1180,6 +1258,14 @@
}
};
+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