Skip to content

Commit 527140a

Browse files
authored
[NFC] Use a SmallVector for HeapType children (#7565)
This was one of danleh's top findings in the mimalloc investigation, where this method accounted for 25% (!) of all allocations. I measured various sizes of SmallVectors and indeed it is possible to get noticeably faster here: this PR is a 5% speedup for -O3 as a whole, tested on a large Java testcase and a large Kotlin testcase. The change to MinimizeRecGroups is NFC (the order is reversed, but it doesn't matters). This is needed to compile, as our current SmallVector doesn't have reverse iteration support (I looked into that for a few minutes but it was not trivial to add; anyhow, the new code is idiomatic in the codebase, I think).
1 parent 45f3c26 commit 527140a

File tree

3 files changed

+18
-10
lines changed

3 files changed

+18
-10
lines changed

src/passes/MinimizeRecGroups.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,9 @@ struct MinimizeRecGroups : Pass {
748748
if (seen.insert(curr).second) {
749749
dfsOrders[i].push_back(curr);
750750
auto children = curr.getReferencedHeapTypes();
751-
workList.insert(workList.end(), children.rbegin(), children.rend());
751+
for (auto child : children) {
752+
workList.push_back(child);
753+
}
752754
}
753755
}
754756
assert(dfsOrders[i].size() == types.size());

src/wasm-type.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "support/index.h"
2929
#include "support/name.h"
3030
#include "support/parent_index_iterator.h"
31+
#include "support/small_vector.h"
3132
#include "wasm-features.h"
3233

3334
// TODO: At various code locations we were assuming that single types are basic
@@ -79,6 +80,10 @@ using HeapTypeNameGenerator = std::function<TypeNames(HeapType)>;
7980
// HeapType.
8081
using TypeID = uint64_t;
8182

83+
// The number of HeapType children is typically small (1 for an array, and for
84+
// a struct, in practice <=4 is common).
85+
using HeapTypeChildren = SmallVector<HeapType, 4>;
86+
8287
enum Shareability { Shared, Unshared };
8388

8489
enum class HeapTypeKind {
@@ -242,11 +247,12 @@ class HeapType {
242247
std::vector<Type> getTypeChildren() const;
243248

244249
// Return the ordered HeapType children, looking through child Types.
245-
std::vector<HeapType> getHeapTypeChildren() const;
250+
HeapTypeChildren getHeapTypeChildren() const;
246251

247-
// Similar to `getHeapTypeChildren`, but also includes the supertype if it
248-
// exists.
249-
std::vector<HeapType> getReferencedHeapTypes() const;
252+
// Similar to `getHeapTypeChildren`, but also includes references types that
253+
// are not children (i.e. that are not in fields of a struct, etc.; such
254+
// referenced types include the super, and descriptor/described types).
255+
HeapTypeChildren getReferencedHeapTypes() const;
250256

251257
// Return the LUB of two HeapTypes, which may or may not exist.
252258
static std::optional<HeapType> getLeastUpperBound(HeapType a, HeapType b);
@@ -489,7 +495,7 @@ class Type {
489495
static bool isSubType(Type left, Type right);
490496

491497
// Return the ordered HeapType children, looking through child Types.
492-
std::vector<HeapType> getHeapTypeChildren();
498+
HeapTypeChildren getHeapTypeChildren();
493499

494500
// Computes the least upper bound from the type lattice.
495501
// If one of the type is unreachable, the other type becomes the result. If

src/wasm/wasm-type.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ template<typename Self> struct HeapTypeChildWalker : TypeGraphWalkerBase<Self> {
361361
};
362362

363363
struct HeapTypeChildCollector : HeapTypeChildWalker<HeapTypeChildCollector> {
364-
std::vector<HeapType> children;
364+
HeapTypeChildren children;
365365
void noteChild(HeapType type) { children.push_back(type); }
366366
};
367367

@@ -753,7 +753,7 @@ bool Type::isSubType(Type left, Type right) {
753753
return SubTyper().isSubType(left, right);
754754
}
755755

756-
std::vector<HeapType> Type::getHeapTypeChildren() {
756+
HeapTypeChildren Type::getHeapTypeChildren() {
757757
HeapTypeChildCollector collector;
758758
collector.walkRoot(this);
759759
return collector.children;
@@ -1175,13 +1175,13 @@ std::vector<Type> HeapType::getTypeChildren() const {
11751175
WASM_UNREACHABLE("unexpected kind");
11761176
}
11771177

1178-
std::vector<HeapType> HeapType::getHeapTypeChildren() const {
1178+
HeapTypeChildren HeapType::getHeapTypeChildren() const {
11791179
HeapTypeChildCollector collector;
11801180
collector.walkRoot(const_cast<HeapType*>(this));
11811181
return collector.children;
11821182
}
11831183

1184-
std::vector<HeapType> HeapType::getReferencedHeapTypes() const {
1184+
HeapTypeChildren HeapType::getReferencedHeapTypes() const {
11851185
auto types = getHeapTypeChildren();
11861186
if (auto super = getDeclaredSuperType()) {
11871187
types.push_back(*super);

0 commit comments

Comments
 (0)