Skip to content

Commit 13cb918

Browse files
authored
Group locals by written type in binary writer (#8568)
We have logic to group locals by type in the binary writer to take advantage of the run-length encoding of locals. But that logic previously grouped locals by their IR types, rather than the types that would actually be written to the binary. These can differ in when the IR uses more precise types than are allowed to be written given the enabled feature set. For example, the IR might use exact types but have to write inexact types because custom descriptors are not enabled. In such cases, it is possible that different groups of locals would be written with the same type, which is suboptimal. Fix the problem by grouping locals by their written types given the enabled features. Fixes #7934.
1 parent c64410a commit 13cb918

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

src/wasm-stack.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ class BinaryInstWriter : public OverriddenVisitor<BinaryInstWriter> {
150150
std::unordered_map<Type, size_t> numLocalsByType;
151151

152152
void noteLocalType(Type type, Index count = 1);
153+
Index getNumLocalsForType(Type type);
153154

154155
// Keeps track of the binary index of the scratch locals used to lower
155156
// tuple.extract. If there are multiple scratch locals of the same type, they

src/wasm/wasm-stack.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3245,7 +3245,7 @@ void BinaryInstWriter::mapLocalsAndEmitHeader() {
32453245
Index baseIndex = func->getVarIndexBase();
32463246
for (auto& type : localTypes) {
32473247
nextFreeIndex[type] = baseIndex;
3248-
baseIndex += numLocalsByType[type];
3248+
baseIndex += getNumLocalsForType(type);
32493249
}
32503250

32513251
// Map the IR index pairs to indices.
@@ -3261,21 +3261,36 @@ void BinaryInstWriter::mapLocalsAndEmitHeader() {
32613261
scratchLocals[type] = nextFreeIndex[type];
32623262
}
32633263

3264-
o << U32LEB(numLocalsByType.size());
3264+
o << U32LEB(localTypes.size());
32653265
for (auto& localType : localTypes) {
3266-
o << U32LEB(numLocalsByType.at(localType));
3266+
o << U32LEB(getNumLocalsForType(localType));
32673267
parent.writeType(localType);
32683268
}
32693269
}
32703270

32713271
void BinaryInstWriter::noteLocalType(Type type, Index count) {
3272+
// Group locals by the type they will eventually be written out as. For
3273+
// example, we do not need to differentiate exact and inexact versions of the
3274+
// same reference type if custom descriptors is not enabled and the type will
3275+
// be written as inexact either way.
3276+
auto feats = parent.getModule()->features;
3277+
type = type.asWrittenGivenFeatures(feats);
32723278
auto& num = numLocalsByType[type];
32733279
if (num == 0) {
32743280
localTypes.push_back(type);
32753281
}
32763282
num += count;
32773283
}
32783284

3285+
Index BinaryInstWriter::getNumLocalsForType(Type type) {
3286+
auto feats = parent.getModule()->features;
3287+
type = type.asWrittenGivenFeatures(feats);
3288+
if (auto it = numLocalsByType.find(type); it != numLocalsByType.end()) {
3289+
return it->second;
3290+
}
3291+
return 0;
3292+
}
3293+
32793294
InsertOrderedMap<Type, Index> BinaryInstWriter::countScratchLocals() {
32803295
struct ScratchLocalFinder : PostWalker<ScratchLocalFinder> {
32813296
BinaryInstWriter& parent;

0 commit comments

Comments
 (0)