Skip to content

Commit 07d3a73

Browse files
committed
Revert "[CGData] Lazy loading support for stable function map (#151660)"
This reverts commit 76dd742.
1 parent 3bc4d66 commit 07d3a73

20 files changed

+86
-327
lines changed

llvm/include/llvm/CGData/CodeGenData.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -285,9 +285,6 @@ enum CGDataVersion {
285285
// Version 3 adds the total size of the Names in the stable function map so
286286
// we can skip reading them into the memory for non-assertion builds.
287287
Version3 = 3,
288-
// Version 4 adjusts the structure of stable function merging map for
289-
// efficient lazy loading support.
290-
Version4 = 4,
291288
CurrentVersion = CG_DATA_INDEX_VERSION
292289
};
293290
const uint64_t Version = CGDataVersion::CurrentVersion;

llvm/include/llvm/CGData/CodeGenData.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,4 @@ CG_DATA_SECT_ENTRY(CG_merge, CG_DATA_QUOTE(CG_DATA_MERGE_COMMON),
4949
#endif
5050

5151
/* Indexed codegen data format version (start from 1). */
52-
#define CG_DATA_INDEX_VERSION 4
52+
#define CG_DATA_INDEX_VERSION 3

llvm/include/llvm/CGData/StableFunctionMap.h

Lines changed: 5 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020
#include "llvm/ADT/StringMap.h"
2121
#include "llvm/IR/StructuralHash.h"
2222
#include "llvm/Support/Compiler.h"
23-
#include "llvm/Support/MemoryBuffer.h"
24-
#include <mutex>
2523

2624
namespace llvm {
2725

@@ -74,37 +72,11 @@ struct StableFunctionMap {
7472
IndexOperandHashMap(std::move(IndexOperandHashMap)) {}
7573
};
7674

77-
using StableFunctionEntries =
78-
SmallVector<std::unique_ptr<StableFunctionEntry>>;
79-
80-
/// In addition to the deserialized StableFunctionEntry, the struct stores
81-
/// the offsets of corresponding serialized stable function entries, and a
82-
/// once flag for safe lazy loading in a multithreaded environment.
83-
struct EntryStorage {
84-
/// The actual storage of deserialized stable function entries. If the map
85-
/// is lazily loaded, this will be empty until the first access by the
86-
/// corresponding function hash.
87-
StableFunctionEntries Entries;
88-
89-
private:
90-
/// This is used to deserialize the entry lazily. Each element is the
91-
/// corresponding serialized stable function entry's offset in the memory
92-
/// buffer (StableFunctionMap::Buffer).
93-
/// The offsets are only populated when loading the map lazily, otherwise
94-
/// it is empty.
95-
SmallVector<uint64_t> Offsets;
96-
std::once_flag LazyLoadFlag;
97-
friend struct StableFunctionMap;
98-
friend struct StableFunctionMapRecord;
99-
};
100-
101-
// Note: DenseMap requires value type to be copyable even if only using
102-
// in-place insertion. Use STL instead. This also affects the
103-
// deletion-while-iteration in finalize().
104-
using HashFuncsMapType = std::unordered_map<stable_hash, EntryStorage>;
75+
using HashFuncsMapType =
76+
DenseMap<stable_hash, SmallVector<std::unique_ptr<StableFunctionEntry>>>;
10577

10678
/// Get the HashToFuncs map for serialization.
107-
const HashFuncsMapType &getFunctionMap() const;
79+
const HashFuncsMapType &getFunctionMap() const { return HashToFuncs; }
10880

10981
/// Get the NameToId vector for serialization.
11082
ArrayRef<std::string> getNames() const { return IdToName; }
@@ -127,19 +99,6 @@ struct StableFunctionMap {
12799
/// \returns true if there is no stable function entry.
128100
bool empty() const { return size() == 0; }
129101

130-
/// \returns true if there is an entry for the given function hash.
131-
/// This does not trigger lazy loading.
132-
bool contains(HashFuncsMapType::key_type FunctionHash) const {
133-
return HashToFuncs.count(FunctionHash) > 0;
134-
}
135-
136-
/// \returns the stable function entries for the given function hash. If the
137-
/// map is lazily loaded, it will deserialize the entries if it is not already
138-
/// done, other requests to the same hash at the same time will be blocked
139-
/// until the entries are deserialized.
140-
const StableFunctionEntries &
141-
at(HashFuncsMapType::key_type FunctionHash) const;
142-
143102
enum SizeType {
144103
UniqueHashCount, // The number of unique hashes in HashToFuncs.
145104
TotalFunctionCount, // The number of total functions in HashToFuncs.
@@ -160,31 +119,17 @@ struct StableFunctionMap {
160119
/// `StableFunctionEntry` is ready for insertion.
161120
void insert(std::unique_ptr<StableFunctionEntry> FuncEntry) {
162121
assert(!Finalized && "Cannot insert after finalization");
163-
HashToFuncs[FuncEntry->Hash].Entries.emplace_back(std::move(FuncEntry));
122+
HashToFuncs[FuncEntry->Hash].emplace_back(std::move(FuncEntry));
164123
}
165124

166-
void deserializeLazyLoadingEntry(HashFuncsMapType::iterator It) const;
167-
168-
/// Eagerly deserialize all the unloaded entries in the lazy loading map.
169-
void deserializeLazyLoadingEntries() const;
170-
171-
bool isLazilyLoaded() const { return (bool)Buffer; }
172-
173125
/// A map from a stable_hash to a vector of functions with that hash.
174-
mutable HashFuncsMapType HashToFuncs;
126+
HashFuncsMapType HashToFuncs;
175127
/// A vector of strings to hold names.
176128
SmallVector<std::string> IdToName;
177129
/// A map from StringRef (name) to an ID.
178130
StringMap<unsigned> NameToId;
179131
/// True if the function map is finalized with minimal content.
180132
bool Finalized = false;
181-
/// The memory buffer that contains the serialized stable function map for
182-
/// lazy loading.
183-
/// Non-empty only if this StableFunctionMap is created from a MemoryBuffer
184-
/// (i.e. by IndexedCodeGenDataReader::read()) and lazily deserialized.
185-
std::shared_ptr<MemoryBuffer> Buffer;
186-
/// Whether to read stable function names from the buffer.
187-
bool ReadStableFunctionMapNames = true;
188133

189134
friend struct StableFunctionMapRecord;
190135
};

llvm/include/llvm/CGData/StableFunctionMapRecord.h

Lines changed: 2 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -24,26 +24,6 @@
2424

2525
namespace llvm {
2626

27-
/// The structure of the serialized stable function map is as follows:
28-
/// - Number of unique function/module names
29-
/// - Total size of unique function/module names for opt-in skipping
30-
/// - Unique function/module names
31-
/// - Padding to align to 4 bytes
32-
/// - Number of StableFunctionEntries
33-
/// - Hashes of each StableFunctionEntry
34-
/// - Fixed-size fields for each StableFunctionEntry (the order is consistent
35-
/// with the hashes above):
36-
/// - FunctionNameId
37-
/// - ModuleNameId
38-
/// - InstCount
39-
/// - Relative offset to the beginning of IndexOperandHashes for this entry
40-
/// - Total size of variable-sized IndexOperandHashes for lazy-loading support
41-
/// - Variable-sized IndexOperandHashes for each StableFunctionEntry:
42-
/// - Number of IndexOperandHashes
43-
/// - Contents of each IndexOperandHashes
44-
/// - InstIndex
45-
/// - OpndIndex
46-
/// - OpndHash
4727
struct StableFunctionMapRecord {
4828
std::unique_ptr<StableFunctionMap> FunctionMap;
4929

@@ -60,25 +40,13 @@ struct StableFunctionMapRecord {
6040
const StableFunctionMap *FunctionMap,
6141
std::vector<CGDataPatchItem> &PatchItems);
6242

63-
/// A static helper function to deserialize the stable function map entry.
64-
/// Ptr should be pointing to the start of the fixed-sized fields of the
65-
/// entry when passed in.
66-
LLVM_ABI static void deserializeEntry(const unsigned char *Ptr,
67-
stable_hash Hash,
68-
StableFunctionMap *FunctionMap);
69-
7043
/// Serialize the stable function map to a raw_ostream.
7144
LLVM_ABI void serialize(raw_ostream &OS,
7245
std::vector<CGDataPatchItem> &PatchItems) const;
7346

7447
/// Deserialize the stable function map from a raw_ostream.
75-
LLVM_ABI void deserialize(const unsigned char *&Ptr);
76-
77-
/// Lazily deserialize the stable function map from `Buffer` starting at
78-
/// `Offset`. The individual stable function entry would be read lazily from
79-
/// `Buffer` when the function map is accessed.
80-
LLVM_ABI void lazyDeserialize(std::shared_ptr<MemoryBuffer> Buffer,
81-
uint64_t Offset);
48+
LLVM_ABI void deserialize(const unsigned char *&Ptr,
49+
bool ReadStableFunctionMapNames = true);
8250

8351
/// Serialize the stable function map to a YAML stream.
8452
LLVM_ABI void serializeYAML(yaml::Output &YOS) const;
@@ -102,18 +70,6 @@ struct StableFunctionMapRecord {
10270
yaml::Output YOS(OS);
10371
serializeYAML(YOS);
10472
}
105-
106-
/// Set whether to read stable function names from the buffer.
107-
/// Has no effect if the function map is read from a YAML stream.
108-
void setReadStableFunctionMapNames(bool Read) {
109-
assert(
110-
FunctionMap->empty() &&
111-
"Cannot change ReadStableFunctionMapNames after the map is populated");
112-
FunctionMap->ReadStableFunctionMapNames = Read;
113-
}
114-
115-
private:
116-
void deserialize(const unsigned char *&Ptr, bool Lazy);
11773
};
11874

11975
} // namespace llvm

llvm/lib/CGData/CodeGenData.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ Expected<Header> Header::readFromBuffer(const unsigned char *Curr) {
186186
return make_error<CGDataError>(cgdata_error::unsupported_version);
187187
H.DataKind = endian::readNext<uint32_t, endianness::little, unaligned>(Curr);
188188

189-
static_assert(IndexedCGData::CGDataVersion::CurrentVersion == Version4,
189+
static_assert(IndexedCGData::CGDataVersion::CurrentVersion == Version3,
190190
"Please update the offset computation below if a new field has "
191191
"been added to the header.");
192192
H.OutlinedHashTreeOffset =

llvm/lib/CGData/CodeGenDataReader.cpp

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,6 @@ static cl::opt<bool> IndexedCodeGenDataReadFunctionMapNames(
2626
"disabled to save memory and time for final consumption of the "
2727
"indexed CodeGenData in production."));
2828

29-
cl::opt<bool> IndexedCodeGenDataLazyLoading(
30-
"indexed-codegen-data-lazy-loading", cl::init(false), cl::Hidden,
31-
cl::desc(
32-
"Lazily load indexed CodeGenData. Enable to save memory and time "
33-
"for final consumption of the indexed CodeGenData in production."));
34-
3529
namespace llvm {
3630

3731
static Expected<std::unique_ptr<MemoryBuffer>>
@@ -115,20 +109,11 @@ Error IndexedCodeGenDataReader::read() {
115109
return error(cgdata_error::eof);
116110
HashTreeRecord.deserialize(Ptr);
117111
}
118-
119-
// TODO: lazy loading support for outlined hash tree.
120-
std::shared_ptr<MemoryBuffer> SharedDataBuffer = std::move(DataBuffer);
121112
if (hasStableFunctionMap()) {
122113
const unsigned char *Ptr = Start + Header.StableFunctionMapOffset;
123114
if (Ptr >= End)
124115
return error(cgdata_error::eof);
125-
FunctionMapRecord.setReadStableFunctionMapNames(
126-
IndexedCodeGenDataReadFunctionMapNames);
127-
if (IndexedCodeGenDataLazyLoading)
128-
FunctionMapRecord.lazyDeserialize(SharedDataBuffer,
129-
Header.StableFunctionMapOffset);
130-
else
131-
FunctionMapRecord.deserialize(Ptr);
116+
FunctionMapRecord.deserialize(Ptr, IndexedCodeGenDataReadFunctionMapNames);
132117
}
133118

134119
return success();

llvm/lib/CGData/StableFunctionMap.cpp

Lines changed: 13 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,8 @@
1515

1616
#include "llvm/CGData/StableFunctionMap.h"
1717
#include "llvm/ADT/SmallSet.h"
18-
#include "llvm/CGData/StableFunctionMapRecord.h"
1918
#include "llvm/Support/CommandLine.h"
2019
#include "llvm/Support/Debug.h"
21-
#include <mutex>
2220

2321
#define DEBUG_TYPE "stable-function-map"
2422

@@ -95,10 +93,9 @@ void StableFunctionMap::insert(const StableFunction &Func) {
9593

9694
void StableFunctionMap::merge(const StableFunctionMap &OtherMap) {
9795
assert(!Finalized && "Cannot merge after finalization");
98-
deserializeLazyLoadingEntries();
9996
for (auto &[Hash, Funcs] : OtherMap.HashToFuncs) {
100-
auto &ThisFuncs = HashToFuncs[Hash].Entries;
101-
for (auto &Func : Funcs.Entries) {
97+
auto &ThisFuncs = HashToFuncs[Hash];
98+
for (auto &Func : Funcs) {
10299
auto FuncNameId =
103100
getIdOrCreateForName(*OtherMap.getNameForId(Func->FunctionNameId));
104101
auto ModuleNameId =
@@ -117,63 +114,25 @@ size_t StableFunctionMap::size(SizeType Type) const {
117114
case UniqueHashCount:
118115
return HashToFuncs.size();
119116
case TotalFunctionCount: {
120-
deserializeLazyLoadingEntries();
121117
size_t Count = 0;
122118
for (auto &Funcs : HashToFuncs)
123-
Count += Funcs.second.Entries.size();
119+
Count += Funcs.second.size();
124120
return Count;
125121
}
126122
case MergeableFunctionCount: {
127-
deserializeLazyLoadingEntries();
128123
size_t Count = 0;
129124
for (auto &[Hash, Funcs] : HashToFuncs)
130-
if (Funcs.Entries.size() >= 2)
131-
Count += Funcs.Entries.size();
125+
if (Funcs.size() >= 2)
126+
Count += Funcs.size();
132127
return Count;
133128
}
134129
}
135130
llvm_unreachable("Unhandled size type");
136131
}
137132

138-
const StableFunctionMap::StableFunctionEntries &
139-
StableFunctionMap::at(HashFuncsMapType::key_type FunctionHash) const {
140-
auto It = HashToFuncs.find(FunctionHash);
141-
if (isLazilyLoaded())
142-
deserializeLazyLoadingEntry(It);
143-
return It->second.Entries;
144-
}
145-
146-
void StableFunctionMap::deserializeLazyLoadingEntry(
147-
HashFuncsMapType::iterator It) const {
148-
assert(isLazilyLoaded() && "Cannot deserialize non-lazily-loaded map");
149-
auto &[Hash, Storage] = *It;
150-
std::call_once(Storage.LazyLoadFlag,
151-
[this, HashArg = Hash, &StorageArg = Storage]() {
152-
for (auto Offset : StorageArg.Offsets)
153-
StableFunctionMapRecord::deserializeEntry(
154-
reinterpret_cast<const unsigned char *>(Offset),
155-
HashArg, const_cast<StableFunctionMap *>(this));
156-
});
157-
}
158-
159-
void StableFunctionMap::deserializeLazyLoadingEntries() const {
160-
if (!isLazilyLoaded())
161-
return;
162-
for (auto It = HashToFuncs.begin(); It != HashToFuncs.end(); ++It)
163-
deserializeLazyLoadingEntry(It);
164-
}
165-
166-
const StableFunctionMap::HashFuncsMapType &
167-
StableFunctionMap::getFunctionMap() const {
168-
// Ensure all entries are deserialized before returning the raw map.
169-
if (isLazilyLoaded())
170-
deserializeLazyLoadingEntries();
171-
return HashToFuncs;
172-
}
173-
174133
using ParamLocs = SmallVector<IndexPair>;
175-
static void
176-
removeIdenticalIndexPair(StableFunctionMap::StableFunctionEntries &SFS) {
134+
static void removeIdenticalIndexPair(
135+
SmallVector<std::unique_ptr<StableFunctionMap::StableFunctionEntry>> &SFS) {
177136
auto &RSF = SFS[0];
178137
unsigned StableFunctionCount = SFS.size();
179138

@@ -200,7 +159,9 @@ removeIdenticalIndexPair(StableFunctionMap::StableFunctionEntries &SFS) {
200159
SF->IndexOperandHashMap->erase(Pair);
201160
}
202161

203-
static bool isProfitable(const StableFunctionMap::StableFunctionEntries &SFS) {
162+
static bool isProfitable(
163+
const SmallVector<std::unique_ptr<StableFunctionMap::StableFunctionEntry>>
164+
&SFS) {
204165
unsigned StableFunctionCount = SFS.size();
205166
if (StableFunctionCount < GlobalMergingMinMerges)
206167
return false;
@@ -241,11 +202,8 @@ static bool isProfitable(const StableFunctionMap::StableFunctionEntries &SFS) {
241202
}
242203

243204
void StableFunctionMap::finalize(bool SkipTrim) {
244-
deserializeLazyLoadingEntries();
245-
SmallVector<HashFuncsMapType::iterator> ToDelete;
246205
for (auto It = HashToFuncs.begin(); It != HashToFuncs.end(); ++It) {
247-
auto &[StableHash, Storage] = *It;
248-
auto &SFS = Storage.Entries;
206+
auto &[StableHash, SFS] = *It;
249207

250208
// Group stable functions by ModuleIdentifier.
251209
llvm::stable_sort(SFS, [&](const std::unique_ptr<StableFunctionEntry> &L,
@@ -278,7 +236,7 @@ void StableFunctionMap::finalize(bool SkipTrim) {
278236
}
279237
}
280238
if (Invalid) {
281-
ToDelete.push_back(It);
239+
HashToFuncs.erase(It);
282240
continue;
283241
}
284242

@@ -290,10 +248,8 @@ void StableFunctionMap::finalize(bool SkipTrim) {
290248
removeIdenticalIndexPair(SFS);
291249

292250
if (!isProfitable(SFS))
293-
ToDelete.push_back(It);
251+
HashToFuncs.erase(It);
294252
}
295-
for (auto It : ToDelete)
296-
HashToFuncs.erase(It);
297253

298254
Finalized = true;
299255
}

0 commit comments

Comments
 (0)