Skip to content

Commit da00140

Browse files
committed
Fix optimized grouping of locals
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 cfa8abd commit da00140

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

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

32513249
// Map the IR index pairs to indices.
@@ -3263,40 +3261,26 @@ void BinaryInstWriter::mapLocalsAndEmitHeader() {
32633261

32643262
o << U32LEB(localTypes.size());
32653263
for (auto& localType : localTypes) {
3266-
o << U32LEB(getNumLocalsForType(localType));
3264+
o << U32LEB(numLocalsByType[localType]);
32673265
parent.writeType(localType);
32683266
}
32693267
}
32703268

32713269
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);
32783270
auto& num = numLocalsByType[type];
32793271
if (num == 0) {
32803272
localTypes.push_back(type);
32813273
}
32823274
num += count;
32833275
}
32843276

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-
3294-
InsertOrderedMap<Type, Index> BinaryInstWriter::countScratchLocals() {
3277+
BinaryInstWriter::TypeIndexMap BinaryInstWriter::countScratchLocals() {
32953278
struct ScratchLocalFinder : PostWalker<ScratchLocalFinder> {
32963279
BinaryInstWriter& parent;
3297-
InsertOrderedMap<Type, Index> scratches;
3280+
TypeIndexMap scratches;
32983281

3299-
ScratchLocalFinder(BinaryInstWriter& parent) : parent(parent) {}
3282+
ScratchLocalFinder(BinaryInstWriter& parent)
3283+
: parent(parent), scratches(parent.parent.getModule()->features) {}
33003284

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

0 commit comments

Comments
 (0)