19#define DEBUG_TYPE "stable-function-map-record"
44 IO.
mapRequired(
"IndexOperandHashes", Func.IndexOperandHashes);
56 for (
auto &Func :
P.second.Entries)
60 FuncEntries, [&](
auto &
A,
auto &
B) {
77 return IndexOperandHashes;
81 raw_ostream &OS, std::vector<CGDataPatchItem> &PatchItems)
const {
87 std::vector<CGDataPatchItem> &PatchItems) {
97 for (
auto &Name : Names)
98 Writer.
OS << Name <<
'\0';
103 const auto NamesByteSize =
104 Writer.
OS.
tell() - NamesByteSizeOffset -
sizeof(NamesByteSizeOffset);
105 PatchItems.emplace_back(NamesByteSizeOffset, &NamesByteSize, 1);
110 for (
const auto *FuncRef : FuncEntries)
112 std::vector<uint64_t> IndexOperandHashesOffsets;
113 IndexOperandHashesOffsets.reserve(FuncEntries.size());
114 for (
const auto *FuncRef : FuncEntries) {
119 IndexOperandHashesOffsets.push_back(
Offset);
122 const uint64_t IndexOperandHashesByteSizeOffset = Writer.
OS.
tell();
124 for (
size_t I = 0;
I < FuncEntries.size(); ++
I) {
126 PatchItems.emplace_back(IndexOperandHashesOffsets[
I], &
Offset, 1);
128 const auto *FuncRef = FuncEntries[
I];
132 for (
auto &IndexOperandHash : IndexOperandHashes) {
139 const uint64_t IndexOperandHashesByteSize =
140 Writer.
OS.
tell() - IndexOperandHashesByteSizeOffset -
sizeof(
uint64_t);
141 PatchItems.emplace_back(IndexOperandHashesByteSizeOffset,
142 &IndexOperandHashesByteSize, 1);
148 auto FunctionNameId =
152 "FunctionNameId out of range");
157 "ModuleNameId out of range");
162 auto CurrentPosition =
reinterpret_cast<uintptr_t
>(
Ptr);
163 auto IndexOperandHashesOffset =
165 auto *IndexOperandHashesPtr =
reinterpret_cast<const unsigned char *
>(
166 CurrentPosition + IndexOperandHashesOffset);
167 auto NumIndexOperandHashes =
169 IndexOperandHashesPtr);
170 auto IndexOperandHashMap = std::make_unique<IndexOperandHashMapType>();
171 for (
unsigned J = 0; J < NumIndexOperandHashes; ++J) {
173 IndexOperandHashesPtr);
175 IndexOperandHashesPtr);
178 IndexOperandHashesPtr);
179 assert(InstIndex < InstCount &&
"InstIndex out of range");
181 IndexOperandHashMap->try_emplace({InstIndex, OpndIndex}, OpndHash);
185 auto FuncEntry = std::make_unique<StableFunctionMap::StableFunctionEntry>(
186 Hash, FunctionNameId, ModuleNameId, InstCount,
187 std::move(IndexOperandHashMap));
202 const auto NamesByteSize =
204 const auto NamesOffset =
reinterpret_cast<uintptr_t
>(
Ptr);
206 for (
unsigned I = 0;
I < NumNames; ++
I) {
208 Ptr += Name.size() + 1;
213 assert(
reinterpret_cast<uintptr_t
>(
Ptr) - NamesOffset == NamesByteSize &&
214 "NamesByteSize does not match the actual size of names");
217 Ptr =
reinterpret_cast<const uint8_t *
>(NamesOffset + NamesByteSize);
223 auto FixedSizeFieldsOffset =
224 reinterpret_cast<uintptr_t
>(
Ptr) + NumFuncs *
sizeof(
stable_hash);
225 constexpr uint32_t FixedSizeFieldsSizePerEntry =
234 for (
unsigned I = 0;
I < NumFuncs; ++
I) {
238 auto It =
FunctionMap->HashToFuncs.try_emplace(Hash).first;
239 StableFunctionMap::EntryStorage &Storage = It->second;
240 Storage.Offsets.
push_back(FixedSizeFieldsOffset);
243 reinterpret_cast<const unsigned char *
>(FixedSizeFieldsOffset), Hash,
246 FixedSizeFieldsOffset += FixedSizeFieldsSizePerEntry;
251 Ptr =
reinterpret_cast<const unsigned char *
>(FixedSizeFieldsOffset);
252 auto IndexOperandHashesByteSize =
254 Ptr =
reinterpret_cast<const unsigned char *
>(
255 reinterpret_cast<uintptr_t
>(
Ptr) + IndexOperandHashesByteSize);
264 const auto *
Ptr =
reinterpret_cast<const unsigned char *
>(
265 reinterpret_cast<uintptr_t
>(Buffer->getBufferStart()) +
Offset);
273 for (
const auto *FuncEntry : FuncEntries) {
275 Functions.emplace_back(
276 FuncEntry->Hash, *
FunctionMap->getNameForId(FuncEntry->FunctionNameId),
277 *
FunctionMap->getNameForId(FuncEntry->ModuleNameId),
278 FuncEntry->InstCount, std::move(IndexOperandHashes));
285 std::vector<StableFunction> Funcs;
287 for (
auto &Func : Funcs)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static IndexOperandHashVecType getStableIndexOperandHashes(const StableFunctionMap::StableFunctionEntry *FuncEntry)
static SmallVector< const StableFunctionMap::StableFunctionEntry * > getStableFunctionEntries(const StableFunctionMap &SFM)
#define LLVM_YAML_IS_SEQUENCE_VECTOR(type)
Utility for declaring that a std::vector of a particular type should be considered a YAML sequence.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
This class implements an extremely fast bulk output stream that can only output to a stream.
uint64_t tell() const
tell - Return the current offset with the file.
void mapRequired(const char *Key, T &Val)
The Output class is used to generate a yaml document from in-memory structs and vectors.
value_type readNext(const CharT *&memory, endianness endian)
Read a value of a particular endianness from a buffer, and increment the buffer past that value.
This is an optimization pass for GlobalISel generic memory operations.
void stable_sort(R &&Range)
uint64_t stable_hash
An opaque object representing a stable hash code.
SmallVector< IndexPairHash > IndexOperandHashVecType
void sort(IteratorTy Start, IteratorTy End)
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
std::pair< IndexPair, stable_hash > IndexPairHash
uintptr_t alignAddr(const void *Addr, Align Alignment)
Aligns Addr to Alignment bytes, rounding up.
This struct is a compact representation of a valid (non-zero power of two) alignment.
static LLVM_ABI void deserializeEntry(const unsigned char *Ptr, stable_hash Hash, StableFunctionMap *FunctionMap)
A static helper function to deserialize the stable function map entry.
LLVM_ABI void deserialize(const unsigned char *&Ptr)
Deserialize the stable function map from a raw_ostream.
std::unique_ptr< StableFunctionMap > FunctionMap
static LLVM_ABI void serialize(raw_ostream &OS, const StableFunctionMap *FunctionMap, std::vector< CGDataPatchItem > &PatchItems)
A static helper function to serialize the stable function map without owning the stable function map.
LLVM_ABI void deserializeYAML(yaml::Input &YIS)
Deserialize the stable function map from a YAML stream.
LLVM_ABI void lazyDeserialize(std::shared_ptr< MemoryBuffer > Buffer, uint64_t Offset)
Lazily deserialize the stable function map from Buffer starting at Offset.
LLVM_ABI void serializeYAML(yaml::Output &YOS) const
Serialize the stable function map to a YAML stream.
An efficient form of StableFunction for fast look-up.
std::unique_ptr< IndexOperandHashMapType > IndexOperandHashMap
A map from an IndexPair to a stable_hash which was skipped.
LLVM_ABI std::optional< std::string > getNameForId(unsigned Id) const
Get the name associated with a given ID.
const HashFuncsMapType & getFunctionMap() const
Get the HashToFuncs map for serialization.
A stable function is a function with a stable hash while tracking the locations of ignored operands a...
Adapter to write values to a stream in a particular byte order.
void write(ArrayRef< value_type > Val)
static void mapping(IO &IO, IndexPairHash &Key)
static void mapping(IO &IO, StableFunction &Func)
This class should be specialized by any type that needs to be converted to/from a YAML mapping.