Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 25 additions & 11 deletions src/ir/type-updating.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ GlobalTypeRewriter::rebuildTypes(std::vector<HeapType> types) {
for (Index i = 0; i < types.size(); ++i) {
typeIndices[types[i]] = i;
}
assert(typeIndices.size() == types.size());

if (typeIndices.size() == 0) {
return {};
Expand Down Expand Up @@ -326,34 +327,47 @@ void GlobalTypeRewriter::mapTypes(const TypeMap& oldToNewTypes) {
}

void GlobalTypeRewriter::mapTypeNamesAndIndices(const TypeMap& oldToNewTypes) {
// Update type names to avoid duplicates.
std::unordered_set<Name> typeNames;
// Track all the existing names to avoid creating duplicates.
std::unordered_set<Name> seenTypeNames;
for (auto& [type, info] : wasm.typeNames) {
typeNames.insert(info.name);
}
seenTypeNames.insert(info.name);
}
// Collect new and updated type names and indices. Do not mutate the module's
// names and indices until the end to avoid iteration order affecting the
// results in the case where oldToNewTypes maps old types to different old
// types.
std::unordered_map<HeapType, TypeNames> newTypeNames;
std::unordered_map<HeapType, Index> newTypeIndices;
for (auto& [old, new_] : oldToNewTypes) {
if (old == new_) {
// The type is being mapped to itself; no need to rename anything.
continue;
}

if (auto it = wasm.typeNames.find(old); it != wasm.typeNames.end()) {
auto& oldNames = it->second;
wasm.typeNames[new_] = oldNames;
auto& names = it->second;
newTypeNames[new_] = names;
// Use the existing name in the new type, as usually it completely
// replaces the old. Rename the old name in a unique way to avoid
// confusion in the case that it remains used.
auto deduped = Names::getValidName(
oldNames.name, [&](Name test) { return !typeNames.count(test); });
oldNames.name = deduped;
typeNames.insert(deduped);
names.name, [&](Name test) { return !seenTypeNames.count(test); });
names.name = deduped;
// Use `insert` to avoid overwriting the entry for the old type if it has
// already appeared as a new type.
if (newTypeNames.insert({old, names}).second) {
seenTypeNames.insert(names.name);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it ok to unconditionally do this insert? I'm not sure what the comment is saying is dangerous to overwrite, as this is just a set of names - we can't overwrite a value for a key, given there are only keys?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment is referring to the use of newTypeNames.insert({old, names}) rather than newTypeNames[old] = names.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, now i see, thanks...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although looking at this again, I'm not sure that's even necessary. We're iterating over the old types, so they can only ever appear once as keys. I think this insert probably always succeeds.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh no, nevermind, because we already do newTypeNames[new_] = ... above.

}
}
if (auto it = wasm.typeIndices.find(old); it != wasm.typeIndices.end()) {
// It's ok if we end up with duplicate indices. Ties will be resolved in
// some arbitrary manner.
wasm.typeIndices[new_] = it->second;
newTypeIndices[new_] = it->second;
}
}
newTypeNames.merge(wasm.typeNames);
wasm.typeNames = std::move(newTypeNames);
newTypeIndices.merge(wasm.typeIndices);
wasm.typeIndices = std::move(newTypeIndices);
}

Type GlobalTypeRewriter::getTempType(Type type) {
Expand Down
Loading