17static std::pair<StringRef, uint64_t>
20 auto [Iter, Inserted] = Map.try_emplace(Saver.
save(Str), Map.size());
27 return make_error<StringError>(
"Empty symbol name",
32std::optional<DataAccessProfRecord>
35 if (std::holds_alternative<StringRef>(SymbolID)) {
40 std::get<StringRef>(SymbolID).
empty() &&
41 "Name canonicalization only fails when stringified string is empty.");
47 auto It = Records.find(Key);
48 if (It != Records.end()) {
50 It->second.Locations);
57 if (std::holds_alternative<uint64_t>(SymID))
58 return KnownColdHashes.
contains(std::get<uint64_t>(SymID));
59 return KnownColdSymbols.contains(std::get<StringRef>(SymID));
65 const bool IsStringLiteral = std::holds_alternative<uint64_t>(Symbol);
67 if (IsStringLiteral) {
68 RecordID = std::get<uint64_t>(Symbol);
73 return CanonicalName.takeError();
74 std::tie(Key, RecordID) =
78 auto [Iter, Inserted] =
79 Records.try_emplace(Key, RecordID, AccessCount, IsStringLiteral);
81 return make_error<StringError>(
"Duplicate symbol or string literal added. "
82 "User of DataAccessProfData should "
83 "aggregate count for the same symbol. ",
95 auto &
Record = Records.back().second;
96 for (
const auto &Location : Locations)
97 Record.Locations.push_back(
106 if (std::holds_alternative<uint64_t>(SymbolID)) {
107 KnownColdHashes.
insert(std::get<uint64_t>(SymbolID));
112 return CanonicalName.takeError();
113 KnownColdSymbols.insert(
120 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
122 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
123 if (
Error E = deserializeSymbolsAndFilenames(
Ptr, NumSampledSymbols,
124 NumColdKnownSymbols))
128 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
131 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr));
133 return deserializeRecords(
Ptr);
137 OS.write(StrToIndexMap.
size());
138 OS.write(KnownColdSymbols.size());
140 std::vector<std::string> Strs;
141 Strs.reserve(StrToIndexMap.
size() + KnownColdSymbols.size());
142 for (
const auto &Str : StrToIndexMap)
143 Strs.push_back(Str.first.str());
144 for (
const auto &Str : KnownColdSymbols)
145 Strs.push_back(Str.str());
147 std::string CompressedStrings;
152 const uint64_t CompressedStringLen = CompressedStrings.length();
154 OS.write(CompressedStringLen);
156 for (
char C : CompressedStrings)
161 for (
uint64_t K = CompressedStringLen; K < PaddedLength; K++)
167DataAccessProfData::getEncodedIndex(
const SymbolHandleRef SymbolID)
const {
168 if (std::holds_alternative<uint64_t>(SymbolID))
169 return std::get<uint64_t>(SymbolID);
171 auto Iter = StrToIndexMap.find(std::get<StringRef>(SymbolID));
172 assert(Iter != StrToIndexMap.end() &&
173 "String literals not found in StrToIndexMap");
178 if (
Error E = serializeSymbolsAndFilenames(
OS))
180 OS.write(KnownColdHashes.
size());
181 for (
const auto &Hash : KnownColdHashes)
184 for (
const auto &[Key, Rec] : Records) {
185 OS.write(getEncodedIndex(Rec.SymbolID));
186 OS.writeByte(Rec.IsStringLiteral);
187 OS.write(Rec.AccessCount);
188 OS.write(Rec.Locations.size());
189 for (
const auto &Loc : Rec.Locations) {
190 OS.write(getEncodedIndex(Loc.FileName));
191 OS.write32(Loc.Line);
197Error DataAccessProfData::deserializeSymbolsAndFilenames(
198 const unsigned char *&
Ptr,
const uint64_t NumSampledSymbols,
199 const uint64_t NumColdKnownSymbols) {
201 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
207 if (StringCnt < NumSampledSymbols)
210 KnownColdSymbols.insert(Saver.
save(
Name));
222Error DataAccessProfData::deserializeRecords(
const unsigned char *&
Ptr) {
223 SmallVector<StringRef> Strings =
227 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
231 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
233 bool IsStringLiteral =
234 support::endian::readNext<uint8_t, llvm::endianness::little>(
Ptr);
237 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
243 SymbolID = Strings[
ID];
247 auto &Record = Records.back().second;
250 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
252 Record.Locations.reserve(NumLocations);
253 for (
uint64_t J = 0; J < NumLocations; ++J) {
255 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
257 support::endian::readNext<uint32_t, llvm::endianness::little>(
Ptr);
258 Record.Locations.push_back({Strings[FileNameIndex], Line});
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
static LLVM_ABI StringRef getCanonicalName(StringRef PGOName)
size_type size() const
Determine the number of elements in the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
bool contains(const key_type &key) const
Check if the SetVector contains the given key.
StringRef - Represent a constant reference to a string, i.e.
Saves strings in the provided stable storage and returns a StringRef with a stable character pointer.
StringRef save(const char *S)
LLVM_ABI Error addKnownSymbolWithoutSamples(SymbolHandleRef SymbolID)
Add a symbol that's seen in the profiled binary without samples.
ArrayRef< StringToIndexMap::value_type > getStrToIndexMapRef() const
The following methods return array reference for various internal data structures.
LLVM_ABI Error serialize(ProfOStream &OS) const
Serialize profile data to the output stream.
LLVM_ABI std::optional< DataAccessProfRecord > getProfileRecord(const SymbolHandleRef SymID) const
Returns a profile record for SymbolID, or std::nullopt if there isn't a record.
LLVM_ABI Error deserialize(const unsigned char *&Ptr)
Deserialize this class from the given buffer.
LLVM_ABI bool isKnownColdSymbol(const SymbolHandleRef SymID) const
Returns true if SymID is seen in profiled binaries and cold.
LLVM_ABI Error setDataAccessProfile(SymbolHandleRef SymbolID, uint64_t AccessCount)
Methods to set symbolized data access profile.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
LLVM_ABI bool isAvailable()
static Expected< StringRef > getCanonicalName(StringRef Name)
static std::pair< StringRef, uint64_t > saveStringToMap(DataAccessProfData::StringToIndexMap &Map, llvm::UniqueStringSaver &Saver, StringRef Str)
std::variant< StringRef, uint64_t > SymbolHandleRef
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI Error readAndDecodeStrings(StringRef NameStrings, std::function< Error(StringRef)> NameCallback)
NameStrings is a string composed of one or more possibly encoded sub-strings.
auto make_first_range(ContainerTy &&c)
Given a container of pairs, return a range over the first elements.
SmallVector< ValueTypeFromRangeType< R >, Size > to_vector(R &&Range)
Given a range of type R, iterate the entire range and return a SmallVector with elements of the vecto...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
LLVM_ABI Error collectGlobalObjectNameStrings(ArrayRef< std::string > NameStrs, bool doCompression, std::string &Result)
Given a vector of strings (names of global objects like functions or, virtual tables) NameStrs,...
The data access profiles for a symbol.