Skip to content

Commit 3180c6f

Browse files
authored
[NFC] Inline more core HeapType methods (#8681)
This makes Unsubtyping over 2x faster on a large Dart testcase. This was the slowest pass there by far. On -Os this saves 5.5% of total time. The key slowdowns this fixes are HeapType::getShared() took 33% (!) of total runtime in Unsubtyping and HeapType::getKind() took 6%, all due to the call overhead that inlining can fix.
1 parent dc67627 commit 3180c6f

2 files changed

Lines changed: 105 additions & 85 deletions

File tree

src/wasm-type.h

Lines changed: 105 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -151,23 +151,17 @@ class HeapType {
151151
HeapTypeKind getKind() const;
152152

153153
constexpr bool isBasic() const { return id <= _last_basic_type; }
154-
bool isFunction() const {
155-
return isMaybeShared(func) || getKind() == HeapTypeKind::Func;
156-
}
157-
bool isData() const {
158-
auto kind = getKind();
159-
return isMaybeShared(string) || kind == HeapTypeKind::Struct ||
160-
kind == HeapTypeKind::Array;
161-
}
162-
bool isSignature() const { return getKind() == HeapTypeKind::Func; }
163-
bool isContinuation() const { return getKind() == HeapTypeKind::Cont; }
164-
bool isStruct() const { return getKind() == HeapTypeKind::Struct; }
165-
bool isArray() const { return getKind() == HeapTypeKind::Array; }
154+
bool isFunction() const;
155+
bool isData() const;
156+
bool isSignature() const;
157+
bool isContinuation() const;
158+
bool isStruct() const;
159+
bool isArray() const;
166160
bool isExn() const { return isMaybeShared(HeapType::exn); }
167161
bool isString() const { return isMaybeShared(HeapType::string); }
168162
bool isBottom() const;
169163
bool isOpen() const;
170-
bool isShared() const { return getShared() == Shared; }
164+
bool isShared() const;
171165

172166
Shareability getShared() const;
173167

@@ -1117,6 +1111,104 @@ std::ostream& operator<<(std::ostream&, const TypeBuilder::ErrorReason&);
11171111

11181112
// Inline some nontrivial methods here for performance reasons.
11191113

1114+
using RecGroupInfo = std::vector<HeapType>;
1115+
1116+
struct HeapTypeInfo {
1117+
using type_t = HeapType;
1118+
// Used in assertions to ensure that temporary types don't leak into the
1119+
// global store.
1120+
bool isTemp = false;
1121+
bool isOpen = false;
1122+
Shareability share = Unshared;
1123+
// The supertype of this HeapType, if it exists.
1124+
HeapTypeInfo* supertype = nullptr;
1125+
// The descriptor of this HeapType, if it exists.
1126+
HeapTypeInfo* descriptor = nullptr;
1127+
// The HeapType described by this one, if it exists.
1128+
HeapTypeInfo* described = nullptr;
1129+
// The recursion group of this type or null if the recursion group is trivial
1130+
// (i.e. contains only this type).
1131+
RecGroupInfo* recGroup = nullptr;
1132+
size_t recGroupIndex = 0;
1133+
HeapTypeKind kind;
1134+
union {
1135+
Signature signature;
1136+
Continuation continuation;
1137+
Struct struct_;
1138+
Array array;
1139+
};
1140+
1141+
HeapTypeInfo(Signature sig) : kind(HeapTypeKind::Func), signature(sig) {}
1142+
HeapTypeInfo(Continuation continuation)
1143+
: kind(HeapTypeKind::Cont), continuation(continuation) {}
1144+
HeapTypeInfo(const Struct& struct_)
1145+
: kind(HeapTypeKind::Struct), struct_(struct_) {}
1146+
HeapTypeInfo(Struct&& struct_)
1147+
: kind(HeapTypeKind::Struct), struct_(std::move(struct_)) {}
1148+
HeapTypeInfo(Array array) : kind(HeapTypeKind::Array), array(array) {}
1149+
~HeapTypeInfo();
1150+
1151+
constexpr bool isSignature() const { return kind == HeapTypeKind::Func; }
1152+
constexpr bool isContinuation() const { return kind == HeapTypeKind::Cont; }
1153+
constexpr bool isStruct() const { return kind == HeapTypeKind::Struct; }
1154+
constexpr bool isArray() const { return kind == HeapTypeKind::Array; }
1155+
constexpr bool isData() const { return isStruct() || isArray(); }
1156+
};
1157+
1158+
inline HeapTypeInfo* getHeapTypeInfo(HeapType ht) {
1159+
assert(!ht.isBasic());
1160+
return (HeapTypeInfo*)ht.getID();
1161+
}
1162+
1163+
inline HeapTypeKind HeapType::getKind() const {
1164+
if (isBasic()) {
1165+
return HeapTypeKind::Basic;
1166+
}
1167+
return getHeapTypeInfo(*this)->kind;
1168+
}
1169+
1170+
inline bool HeapType::isFunction() const {
1171+
return isMaybeShared(func) || getKind() == HeapTypeKind::Func;
1172+
}
1173+
1174+
inline bool HeapType::isData() const {
1175+
auto kind = getKind();
1176+
return isMaybeShared(string) || kind == HeapTypeKind::Struct ||
1177+
kind == HeapTypeKind::Array;
1178+
}
1179+
1180+
inline bool HeapType::isSignature() const {
1181+
return getKind() == HeapTypeKind::Func;
1182+
}
1183+
1184+
inline bool HeapType::isContinuation() const {
1185+
return getKind() == HeapTypeKind::Cont;
1186+
}
1187+
1188+
inline bool HeapType::isStruct() const {
1189+
return getKind() == HeapTypeKind::Struct;
1190+
}
1191+
1192+
inline bool HeapType::isArray() const {
1193+
return getKind() == HeapTypeKind::Array;
1194+
}
1195+
1196+
inline bool HeapType::isOpen() const {
1197+
if (isBasic()) {
1198+
return false;
1199+
}
1200+
return getHeapTypeInfo(*this)->isOpen;
1201+
}
1202+
1203+
inline bool HeapType::isShared() const { return getShared() == Shared; }
1204+
1205+
inline Shareability HeapType::getShared() const {
1206+
if (isBasic()) {
1207+
return (getID() & SharedMask) != 0 ? Shared : Unshared;
1208+
}
1209+
return getHeapTypeInfo(*this)->share;
1210+
}
1211+
11201212
inline bool HeapType::isBottom() const {
11211213
if (isBasic()) {
11221214
switch (getBasic(Unshared)) {

src/wasm/wasm-type.cpp

Lines changed: 0 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -38,50 +38,6 @@ namespace wasm {
3838

3939
namespace {
4040

41-
using RecGroupInfo = std::vector<HeapType>;
42-
43-
struct HeapTypeInfo {
44-
using type_t = HeapType;
45-
// Used in assertions to ensure that temporary types don't leak into the
46-
// global store.
47-
bool isTemp = false;
48-
bool isOpen = false;
49-
Shareability share = Unshared;
50-
// The supertype of this HeapType, if it exists.
51-
HeapTypeInfo* supertype = nullptr;
52-
// The descriptor of this HeapType, if it exists.
53-
HeapTypeInfo* descriptor = nullptr;
54-
// The HeapType described by this one, if it exists.
55-
HeapTypeInfo* described = nullptr;
56-
// The recursion group of this type or null if the recursion group is trivial
57-
// (i.e. contains only this type).
58-
RecGroupInfo* recGroup = nullptr;
59-
size_t recGroupIndex = 0;
60-
HeapTypeKind kind;
61-
union {
62-
Signature signature;
63-
Continuation continuation;
64-
Struct struct_;
65-
Array array;
66-
};
67-
68-
HeapTypeInfo(Signature sig) : kind(HeapTypeKind::Func), signature(sig) {}
69-
HeapTypeInfo(Continuation continuation)
70-
: kind(HeapTypeKind::Cont), continuation(continuation) {}
71-
HeapTypeInfo(const Struct& struct_)
72-
: kind(HeapTypeKind::Struct), struct_(struct_) {}
73-
HeapTypeInfo(Struct&& struct_)
74-
: kind(HeapTypeKind::Struct), struct_(std::move(struct_)) {}
75-
HeapTypeInfo(Array array) : kind(HeapTypeKind::Array), array(array) {}
76-
~HeapTypeInfo();
77-
78-
constexpr bool isSignature() const { return kind == HeapTypeKind::Func; }
79-
constexpr bool isContinuation() const { return kind == HeapTypeKind::Cont; }
80-
constexpr bool isStruct() const { return kind == HeapTypeKind::Struct; }
81-
constexpr bool isArray() const { return kind == HeapTypeKind::Array; }
82-
constexpr bool isData() const { return isStruct() || isArray(); }
83-
};
84-
8541
// Helper for finding the equirecursive least upper bound of two types.
8642
// Helper for printing types.
8743
struct TypePrinter {
@@ -210,11 +166,6 @@ template<typename T> class equal_to<reference_wrapper<const T>> {
210166
namespace wasm {
211167
namespace {
212168

213-
HeapTypeInfo* getHeapTypeInfo(HeapType ht) {
214-
assert(!ht.isBasic());
215-
return (HeapTypeInfo*)ht.getID();
216-
}
217-
218169
HeapType asHeapType(std::unique_ptr<HeapTypeInfo>& info) {
219170
return HeapType(uintptr_t(info.get()));
220171
}
@@ -881,29 +832,6 @@ HeapType::HeapType(Array array) {
881832
HeapType(globalRecGroupStore.insert(std::make_unique<HeapTypeInfo>(array)));
882833
}
883834

884-
HeapTypeKind HeapType::getKind() const {
885-
if (isBasic()) {
886-
return HeapTypeKind::Basic;
887-
}
888-
return getHeapTypeInfo(*this)->kind;
889-
}
890-
891-
bool HeapType::isOpen() const {
892-
if (isBasic()) {
893-
return false;
894-
} else {
895-
return getHeapTypeInfo(*this)->isOpen;
896-
}
897-
}
898-
899-
Shareability HeapType::getShared() const {
900-
if (isBasic()) {
901-
return (id & SharedMask) != 0 ? Shared : Unshared;
902-
} else {
903-
return getHeapTypeInfo(*this)->share;
904-
}
905-
}
906-
907835
bool HeapType::isCastable() {
908836
return !isContinuation() && !isMaybeShared(HeapType::cont) &&
909837
!isMaybeShared(HeapType::nocont);

0 commit comments

Comments
 (0)