Skip to content

Commit a6f85e5

Browse files
authored
Fix optimized grouping of locals (#8577)
In #8568 we optimized the grouping of locals in the binary writer to account for how types will be written given the enabled features. However, that change did not properly update the handling of scratch locals accordingly, leading to inconsistencies in the indices assigned to local types in different locations. Fix the problem by reverting the changes from #8568 and handling the mapping from IR types to written types at a lower level; specifically, create a new `TypeIndexMap` type that extends `InsertOrderedMap` but always applies `asWrittenGivenFeatures` to its keys. Use this new map type both for the `numLocalsByType` map and the `scratchLocals` map.
1 parent 27dbce1 commit a6f85e5

File tree

2 files changed

+39
-28
lines changed

2 files changed

+39
-28
lines changed

src/wasm-stack.h

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,9 @@ class BinaryInstWriter : public OverriddenVisitor<BinaryInstWriter> {
9494
BufferWithRandomAccess& o,
9595
Function* func,
9696
bool DWARF)
97-
: parent(parent), o(o), func(func), DWARF(DWARF) {}
97+
: parent(parent), o(o), func(func), DWARF(DWARF),
98+
numLocalsByType(parent.getModule()->features),
99+
scratchLocals(parent.getModule()->features) {}
98100

99101
void visit(Expression* curr) {
100102
if (func) {
@@ -144,20 +146,45 @@ class BinaryInstWriter : public OverriddenVisitor<BinaryInstWriter> {
144146

145147
std::vector<Name> breakStack;
146148

149+
// Map types to indices or counts, but transparently convert the key types to
150+
// their written versions given the enabled features.
151+
struct TypeIndexMap : private InsertOrderedMap<Type, Index> {
152+
FeatureSet feats;
153+
154+
public:
155+
using InsertOrderedMap<Type, Index>::iterator;
156+
using InsertOrderedMap<Type, Index>::const_iterator;
157+
using InsertOrderedMap<Type, Index>::begin;
158+
using InsertOrderedMap<Type, Index>::end;
159+
using InsertOrderedMap<Type, Index>::size;
160+
161+
TypeIndexMap(FeatureSet feats)
162+
: InsertOrderedMap<Type, Index>(), feats(feats) {}
163+
164+
Index& operator[](Type type) {
165+
return InsertOrderedMap::operator[](type.asWrittenGivenFeatures(feats));
166+
}
167+
iterator find(Type type) {
168+
return InsertOrderedMap::find(type.asWrittenGivenFeatures(feats));
169+
}
170+
const_iterator find(Type type) const {
171+
return InsertOrderedMap::find(type.asWrittenGivenFeatures(feats));
172+
}
173+
};
174+
147175
// The types of locals in the compact form, in order.
148176
std::vector<Type> localTypes;
149177
// type => number of locals of that type in the compact form
150-
std::unordered_map<Type, size_t> numLocalsByType;
178+
TypeIndexMap numLocalsByType;
151179

152180
void noteLocalType(Type type, Index count = 1);
153-
Index getNumLocalsForType(Type type);
154181

155182
// Keeps track of the binary index of the scratch locals used to lower
156183
// tuple.extract. If there are multiple scratch locals of the same type, they
157184
// are contiguous and this map holds the index of the first.
158-
InsertOrderedMap<Type, Index> scratchLocals;
185+
TypeIndexMap scratchLocals;
159186
// Return the type and number of required scratch locals.
160-
InsertOrderedMap<Type, Index> countScratchLocals();
187+
TypeIndexMap countScratchLocals();
161188

162189
// local.get, local.tee, and global.get expressions that will be followed by
163190
// tuple.extracts. We can optimize these by getting only the local for the

src/wasm/wasm-stack.cpp

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,8 @@
1515
*/
1616

1717
#include "wasm-stack.h"
18-
#include "ir/find_all.h"
1918
#include "ir/properties.h"
2019
#include "wasm-binary.h"
21-
#include "wasm-debug.h"
2220

2321
namespace wasm {
2422

@@ -3245,11 +3243,11 @@ void BinaryInstWriter::mapLocalsAndEmitHeader() {
32453243
// Map IR (local index, tuple index) pairs to binary local indices. Since
32463244
// locals are grouped by type, start by calculating the base indices for each
32473245
// type.
3248-
std::unordered_map<Type, Index> nextFreeIndex;
3246+
TypeIndexMap nextFreeIndex(parent.getModule()->features);
32493247
Index baseIndex = func->getVarIndexBase();
32503248
for (auto& type : localTypes) {
32513249
nextFreeIndex[type] = baseIndex;
3252-
baseIndex += getNumLocalsForType(type);
3250+
baseIndex += numLocalsByType[type];
32533251
}
32543252

32553253
// Map the IR index pairs to indices.
@@ -3267,40 +3265,26 @@ void BinaryInstWriter::mapLocalsAndEmitHeader() {
32673265

32683266
o << U32LEB(localTypes.size());
32693267
for (auto& localType : localTypes) {
3270-
o << U32LEB(getNumLocalsForType(localType));
3268+
o << U32LEB(numLocalsByType[localType]);
32713269
parent.writeType(localType);
32723270
}
32733271
}
32743272

32753273
void BinaryInstWriter::noteLocalType(Type type, Index count) {
3276-
// Group locals by the type they will eventually be written out as. For
3277-
// example, we do not need to differentiate exact and inexact versions of the
3278-
// same reference type if custom descriptors is not enabled and the type will
3279-
// be written as inexact either way.
3280-
auto feats = parent.getModule()->features;
3281-
type = type.asWrittenGivenFeatures(feats);
32823274
auto& num = numLocalsByType[type];
32833275
if (num == 0) {
32843276
localTypes.push_back(type);
32853277
}
32863278
num += count;
32873279
}
32883280

3289-
Index BinaryInstWriter::getNumLocalsForType(Type type) {
3290-
auto feats = parent.getModule()->features;
3291-
type = type.asWrittenGivenFeatures(feats);
3292-
if (auto it = numLocalsByType.find(type); it != numLocalsByType.end()) {
3293-
return it->second;
3294-
}
3295-
return 0;
3296-
}
3297-
3298-
InsertOrderedMap<Type, Index> BinaryInstWriter::countScratchLocals() {
3281+
BinaryInstWriter::TypeIndexMap BinaryInstWriter::countScratchLocals() {
32993282
struct ScratchLocalFinder : PostWalker<ScratchLocalFinder> {
33003283
BinaryInstWriter& parent;
3301-
InsertOrderedMap<Type, Index> scratches;
3284+
TypeIndexMap scratches;
33023285

3303-
ScratchLocalFinder(BinaryInstWriter& parent) : parent(parent) {}
3286+
ScratchLocalFinder(BinaryInstWriter& parent)
3287+
: parent(parent), scratches(parent.parent.getModule()->features) {}
33043288

33053289
void visitTupleExtract(TupleExtract* curr) {
33063290
if (curr->type == Type::unreachable) {

0 commit comments

Comments
 (0)