Please use GitHub pull requests for new patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
llvm/include/llvm/IR/ModuleSummaryIndex.h
Show All 36 Lines | |||||
#include <cstdint> | #include <cstdint> | ||||
#include <map> | #include <map> | ||||
#include <memory> | #include <memory> | ||||
#include <set> | #include <set> | ||||
#include <string> | #include <string> | ||||
#include <utility> | #include <utility> | ||||
#include <vector> | #include <vector> | ||||
namespace Opt { | |||||
enum MergeLevelEnum { none, size, all }; | |||||
} | |||||
namespace llvm { | namespace llvm { | ||||
// This is for now until I figure out a better place to put this declaration in. | |||||
// Compute a similarity metric for function F. Useful for merging functions. | |||||
unsigned profileFunction(const Function *F); | |||||
bool isComparisonCandidate(const Function *F); | |||||
bool isAliasCapable(const Function* G); | |||||
Lint: Pre-merge checks: clang-format: please reformat the code
```
-bool isAliasCapable(const Function* G);
+bool… | |||||
namespace yaml { | namespace yaml { | ||||
template <typename T> struct MappingTraits; | template <typename T> struct MappingTraits; | ||||
} // end namespace yaml | } // end namespace yaml | ||||
/// Class to accumulate and hold information about a callee. | /// Class to accumulate and hold information about a callee. | ||||
struct CalleeInfo { | struct CalleeInfo { | ||||
▲ Show 20 Lines • Show All 507 Lines • ▼ Show 20 Lines | return FunctionSummary( | ||||
/*NotEligibleToImport=*/true, /*Live=*/true, /*IsLocal=*/false, | /*NotEligibleToImport=*/true, /*Live=*/true, /*IsLocal=*/false, | ||||
/*CanAutoHide=*/false), | /*CanAutoHide=*/false), | ||||
/*InsCount=*/0, FunctionSummary::FFlags{}, /*EntryCount=*/0, | /*InsCount=*/0, FunctionSummary::FFlags{}, /*EntryCount=*/0, | ||||
std::vector<ValueInfo>(), std::move(Edges), | std::vector<ValueInfo>(), std::move(Edges), | ||||
std::vector<GlobalValue::GUID>(), | std::vector<GlobalValue::GUID>(), | ||||
std::vector<FunctionSummary::VFuncId>(), | std::vector<FunctionSummary::VFuncId>(), | ||||
std::vector<FunctionSummary::VFuncId>(), | std::vector<FunctionSummary::VFuncId>(), | ||||
std::vector<FunctionSummary::ConstVCall>(), | std::vector<FunctionSummary::ConstVCall>(), | ||||
std::vector<FunctionSummary::ConstVCall>()); | std::vector<FunctionSummary::ConstVCall>(), 0); | ||||
} | } | ||||
/// A dummy node to reference external functions that aren't in the index | /// A dummy node to reference external functions that aren't in the index | ||||
static FunctionSummary ExternalNode; | static FunctionSummary ExternalNode; | ||||
private: | private: | ||||
/// Number of instructions (ignoring debug instructions, e.g.) computed | /// Number of instructions (ignoring debug instructions, e.g.) computed | ||||
/// during the initial compile step when the summary index is first built. | /// during the initial compile step when the summary index is first built. | ||||
unsigned InstCount; | unsigned InstCount; | ||||
/// Function summary specific flags. | /// Function summary specific flags. | ||||
FFlags FunFlags; | FFlags FunFlags; | ||||
/// The synthesized entry count of the function. | /// The synthesized entry count of the function. | ||||
/// This is only populated during ThinLink phase and remains unused while | /// This is only populated during ThinLink phase and remains unused while | ||||
/// generating per-module summaries. | /// generating per-module summaries. | ||||
uint64_t EntryCount = 0; | uint64_t EntryCount = 0; | ||||
/// List of <CalleeValueInfo, CalleeInfo> call edge pairs from this function. | /// List of <CalleeValueInfo, CalleeInfo> call edge pairs from this function. | ||||
std::vector<EdgeTy> CallGraphEdgeList; | std::vector<EdgeTy> CallGraphEdgeList; | ||||
std::unique_ptr<TypeIdInfo> TIdInfo; | std::unique_ptr<TypeIdInfo> TIdInfo; | ||||
unsigned SimilarityHash; | |||||
public: | public: | ||||
FunctionSummary(GVFlags Flags, unsigned NumInsts, FFlags FunFlags, | FunctionSummary(GVFlags Flags, unsigned NumInsts, FFlags FunFlags, | ||||
uint64_t EntryCount, std::vector<ValueInfo> Refs, | uint64_t EntryCount, std::vector<ValueInfo> Refs, | ||||
std::vector<EdgeTy> CGEdges, | std::vector<EdgeTy> CGEdges, | ||||
std::vector<GlobalValue::GUID> TypeTests, | std::vector<GlobalValue::GUID> TypeTests, | ||||
std::vector<VFuncId> TypeTestAssumeVCalls, | std::vector<VFuncId> TypeTestAssumeVCalls, | ||||
std::vector<VFuncId> TypeCheckedLoadVCalls, | std::vector<VFuncId> TypeCheckedLoadVCalls, | ||||
std::vector<ConstVCall> TypeTestAssumeConstVCalls, | std::vector<ConstVCall> TypeTestAssumeConstVCalls, | ||||
std::vector<ConstVCall> TypeCheckedLoadConstVCalls) | std::vector<ConstVCall> TypeCheckedLoadConstVCalls, | ||||
unsigned SimHash) | |||||
: GlobalValueSummary(FunctionKind, Flags, std::move(Refs)), | : GlobalValueSummary(FunctionKind, Flags, std::move(Refs)), | ||||
InstCount(NumInsts), FunFlags(FunFlags), EntryCount(EntryCount), | InstCount(NumInsts), FunFlags(FunFlags), EntryCount(EntryCount), | ||||
CallGraphEdgeList(std::move(CGEdges)) { | CallGraphEdgeList(std::move(CGEdges)), | ||||
Lint: Pre-merge checks clang-format: please reformat the code - CallGraphEdgeList(std::move(CGEdges)), - SimilarityHash(SimHash) { + CallGraphEdgeList(std::move(CGEdges)), SimilarityHash(SimHash) { Lint: Pre-merge checks: clang-format: please reformat the code
```
- CallGraphEdgeList(std::move(CGEdges))… | |||||
SimilarityHash(SimHash) { | |||||
if (!TypeTests.empty() || !TypeTestAssumeVCalls.empty() || | if (!TypeTests.empty() || !TypeTestAssumeVCalls.empty() || | ||||
!TypeCheckedLoadVCalls.empty() || !TypeTestAssumeConstVCalls.empty() || | !TypeCheckedLoadVCalls.empty() || !TypeTestAssumeConstVCalls.empty() || | ||||
!TypeCheckedLoadConstVCalls.empty()) | !TypeCheckedLoadConstVCalls.empty()) | ||||
TIdInfo = std::make_unique<TypeIdInfo>(TypeIdInfo{ | TIdInfo = std::make_unique<TypeIdInfo>(TypeIdInfo{ | ||||
std::move(TypeTests), std::move(TypeTestAssumeVCalls), | std::move(TypeTests), std::move(TypeTestAssumeVCalls), | ||||
std::move(TypeCheckedLoadVCalls), | std::move(TypeCheckedLoadVCalls), | ||||
std::move(TypeTestAssumeConstVCalls), | std::move(TypeTestAssumeConstVCalls), | ||||
std::move(TypeCheckedLoadConstVCalls)}); | std::move(TypeCheckedLoadConstVCalls)}); | ||||
} | } | ||||
// Gets the number of readonly and writeonly refs in RefEdgeList | // Gets the number of readonly and writeonly refs in RefEdgeList | ||||
std::pair<unsigned, unsigned> specialRefCounts() const; | std::pair<unsigned, unsigned> specialRefCounts() const; | ||||
/// Check if this is a function summary. | /// Check if this is a function summary. | ||||
static bool classof(const GlobalValueSummary *GVS) { | static bool classof(const GlobalValueSummary *GVS) { | ||||
return GVS->getSummaryKind() == FunctionKind; | return GVS->getSummaryKind() == FunctionKind; | ||||
} | } | ||||
/// Get the SimilarityHash of this function. | |||||
unsigned similarityHash() const { return SimilarityHash; } | |||||
/// Get function summary flags. | /// Get function summary flags. | ||||
FFlags fflags() const { return FunFlags; } | FFlags fflags() const { return FunFlags; } | ||||
/// Get the instruction count recorded for this function. | /// Get the instruction count recorded for this function. | ||||
unsigned instCount() const { return InstCount; } | unsigned instCount() const { return InstCount; } | ||||
/// Get the synthetic entry count for this function. | /// Get the synthetic entry count for this function. | ||||
uint64_t entryCount() const { return EntryCount; } | uint64_t entryCount() const { return EntryCount; } | ||||
▲ Show 20 Lines • Show All 371 Lines • ▼ Show 20 Lines | private: | ||||
std::set<std::string> CfiFunctionDefs; | std::set<std::string> CfiFunctionDefs; | ||||
std::set<std::string> CfiFunctionDecls; | std::set<std::string> CfiFunctionDecls; | ||||
// Used in cases where we want to record the name of a global, but | // Used in cases where we want to record the name of a global, but | ||||
// don't have the string owned elsewhere (e.g. the Strtab on a module). | // don't have the string owned elsewhere (e.g. the Strtab on a module). | ||||
StringSaver Saver; | StringSaver Saver; | ||||
BumpPtrAllocator Alloc; | BumpPtrAllocator Alloc; | ||||
/// Functions with hash code as a measure of structural similarity. | |||||
/// Used by MergeSimilarFunctions. The value_type is the hash code | |||||
/// computed by profileFunction. | |||||
std::map<GlobalValue::GUID, unsigned> FunctionSimilarityHashes; | |||||
/// Reverse map of @var SimilarFunctionsHash to be used during thin-lto. | |||||
/// Each GUID in the vector corresponds to functions with same hash (id). | |||||
std::map<unsigned, std::vector<GlobalValue::GUID>> SimilarFunctions; | |||||
/// Functions having multiple entries in ModuleSummaryIndex. | |||||
std::set<GlobalValue::GUID> DuplicateFunctions; | |||||
/// All similar functions w.r.t the one in this set will be imported into | |||||
/// the module of these functions during thin-lto stage. | |||||
/// FIXME: Maybe use a vector? | |||||
std::set<GlobalValue::GUID> HostSimilarFunction; | |||||
// YAML I/O support. | // YAML I/O support. | ||||
friend yaml::MappingTraits<ModuleSummaryIndex>; | friend yaml::MappingTraits<ModuleSummaryIndex>; | ||||
GlobalValueSummaryMapTy::value_type * | GlobalValueSummaryMapTy::value_type * | ||||
getOrInsertValuePtr(GlobalValue::GUID GUID) { | getOrInsertValuePtr(GlobalValue::GUID GUID) { | ||||
return &*GlobalValueMap.emplace(GUID, GlobalValueSummaryInfo(HaveGVs)) | return &*GlobalValueMap.emplace(GUID, GlobalValueSummaryInfo(HaveGVs)) | ||||
.first; | .first; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | FunctionSummary calculateCallGraphRoot() { | ||||
if (Edges.empty()) { | if (Edges.empty()) { | ||||
// Failed to find root - return an empty node | // Failed to find root - return an empty node | ||||
return FunctionSummary::makeDummyFunctionSummary({}); | return FunctionSummary::makeDummyFunctionSummary({}); | ||||
} | } | ||||
auto CallGraphRoot = FunctionSummary::makeDummyFunctionSummary(Edges); | auto CallGraphRoot = FunctionSummary::makeDummyFunctionSummary(Edges); | ||||
return CallGraphRoot; | return CallGraphRoot; | ||||
} | } | ||||
bool hasSimilarFunction(unsigned id) { return SimilarFunctions.count(id); } | |||||
void addToSimilarFunctions(unsigned id, GlobalValue::GUID GUID) { | |||||
if (id == 0) | |||||
return; // invalid id. | |||||
if (DuplicateFunctions.count(GUID)) | |||||
return; | |||||
ValueInfo VI = getValueInfo(GUID); | |||||
if (!VI) | |||||
return; | |||||
// assert(VI.getSummaryList().size() == 1); | |||||
if (VI.getSummaryList().size() != 1) | |||||
return; | |||||
GlobalValueSummary *S = VI.getSummaryList()[0].get(); | |||||
if (!isa<FunctionSummary>(S)) | |||||
return; | |||||
assert(isa<FunctionSummary>(S) && "Not a function summary!"); | |||||
if (FunctionSimilarityHashes.count(GUID)) { | |||||
// Erase the GUID having multiple visits in the ModuleSummaryIndex. | |||||
FunctionSimilarityHashes.erase(GUID); | |||||
DuplicateFunctions.insert(GUID); | |||||
return; | |||||
} | |||||
FunctionSimilarityHashes[GUID] = id; | |||||
} | |||||
void populateReverseSimilarityHashMap() { | |||||
for (auto &p : FunctionSimilarityHashes) | |||||
SimilarFunctions[p.second].push_back(p.first); | |||||
} | |||||
void removeSingleEntriesFromSimHashMaps() { | |||||
// Iterate over the hash to remove entries with no duplicates. | |||||
for (auto I = SimilarFunctions.begin(), E = SimilarFunctions.end(); | |||||
I != E;) { | |||||
auto Next = std::next(I); | |||||
assert(I->second.size() && "Empty Entry!"); | |||||
if (I->second.size() == 1) { | |||||
FunctionSimilarityHashes.erase(I->second[0]); | |||||
SimilarFunctions.erase(I); | |||||
} | |||||
I = Next; | |||||
} | |||||
} | |||||
std::map<unsigned, std::vector<GlobalValue::GUID>> &getSimilarFunctions() { | |||||
return SimilarFunctions; | |||||
} | |||||
const std::map<unsigned, std::vector<GlobalValue::GUID>> & | |||||
getSimilarFunctions() const { | |||||
return SimilarFunctions; | |||||
} | |||||
unsigned getSimilarityHash(GlobalValue::GUID ID) const { | |||||
return FunctionSimilarityHashes.find(ID)->second; | |||||
} | |||||
std::map<GlobalValue::GUID, unsigned> &getSimilarFunctionsHash() { | |||||
return FunctionSimilarityHashes; | |||||
} | |||||
const std::map<GlobalValue::GUID, unsigned> &getSimilarFunctionsHash() const { | |||||
return FunctionSimilarityHashes; | |||||
} | |||||
void addToHostSimilarFunction(GlobalValue::GUID ID) { | |||||
HostSimilarFunction.insert(ID); | |||||
} | |||||
std::set<GlobalValue::GUID> &getHostSimilarFunction() { | |||||
return HostSimilarFunction; | |||||
} | |||||
const std::set<GlobalValue::GUID> &getHostSimilarFunction() const { | |||||
return HostSimilarFunction; | |||||
} | |||||
bool withGlobalValueDeadStripping() const { | bool withGlobalValueDeadStripping() const { | ||||
return WithGlobalValueDeadStripping; | return WithGlobalValueDeadStripping; | ||||
} | } | ||||
void setWithGlobalValueDeadStripping() { | void setWithGlobalValueDeadStripping() { | ||||
WithGlobalValueDeadStripping = true; | WithGlobalValueDeadStripping = true; | ||||
} | } | ||||
bool withAttributePropagation() const { return WithAttributePropagation; } | bool withAttributePropagation() const { return WithAttributePropagation; } | ||||
▲ Show 20 Lines • Show All 382 Lines • Show Last 20 Lines |
clang-format: please reformat the code