Repository navigation
Multivalue type creation and inspection - #2459
Conversation
aheejin
left a comment
There was a problem hiding this comment.
Mostly LGTM, some minor comments
| size_t operator()(const std::vector<wasm::Type::ValueType>& types) const { | ||
| size_t res = 0; | ||
| for (auto vt : types) { | ||
| res ^= hash<int>{}(vt); |
| size_t getNumValueTypes() const; | ||
| const std::vector<ValueType> getValueTypes() const; | ||
|
|
||
| bool isValueType() { return id >= i32 && id < _last_value_type; } |
There was a problem hiding this comment.
So multivalue types return false for this? Multivalues are also values. Maybe isSimpleValueType..? (Not sure about the name)
There was a problem hiding this comment.
I mean "value type" in the sense used by the spec, which is always a single type.
| return typeLists[id].size(); | ||
| } | ||
|
|
||
| const std::vector<Type::ValueType> Type::getValueTypes() const { |
There was a problem hiding this comment.
Is there a missing & in the return type?
There was a problem hiding this comment.
No, returning a reference to the vector would not be thread-safe because it could be moved by a different thread allocating a new type. I suppose it's worth storing pointers to vectors instead of directly storing vectors to avoid this problem.
There was a problem hiding this comment.
I see. But then does this have to be const?
| std::vector<Type::ValueType> vts = type.getValueTypes(); | ||
| std::string res("("); | ||
| for (size_t i = 0; i < vts.size() - 1; ++i) { | ||
| res += ", "; |
There was a problem hiding this comment.
Doesn't this print something like (, type1, type2, ...)?
| std::cout << " {\n"; | ||
| std::cout << " BinaryenType " << array << "[] = {"; | ||
| for (size_t i = 0; i < numTypes; ++i) { | ||
| std::cout << int(valueTypes[i]); |
| } | ||
| std::cout << "};\n"; | ||
| std::cout << " BinaryenTypeCreate(" << array << ", " << numTypes | ||
| << "); // " << int(result) << "\n"; |
| std::cout << " }\n"; | ||
| } | ||
|
|
||
| return uint32_t(int(result)); |
There was a problem hiding this comment.
Why double cast? Isn't Types cast operand to uint32_t in the first place?
There was a problem hiding this comment.
Thanks for catching these. I originally had the implicit conversion go to int and didn't update these when I changed it.
| exnref, | ||
| _last_value_type, | ||
| // none means no type, e.g. a block can have no return type. but unreachable | ||
| // is different, as it can be "ignored" when doing type checking across |
There was a problem hiding this comment.
this comment can be removed completely
| size_t getNumValueTypes() const; | ||
| const std::vector<ValueType> getValueTypes() const; | ||
|
|
||
| bool isValueType() { return id >= i32 && id < _last_value_type; } |
There was a problem hiding this comment.
Isn't this check the same as isConcreteType?
There was a problem hiding this comment.
No, isConcreteType includes multivalue types as well.
There was a problem hiding this comment.
I see, thanks.
How about isSingleType? "value" doesn't seem clear enough to me.
(Also, may as well be isSingle, as the whole thing is a type?)
| constexpr Type unreachable = Type::unreachable; | ||
|
|
||
| const char* printType(Type type); | ||
| const std::string printType(Type type); |
There was a problem hiding this comment.
does this change have an impact on performance? we may call this many many times in a huge wast.
There was a problem hiding this comment.
I believe that in the common case performance should still be good, but I'm not entirely sure. I expect to clean up this printing to use ostreams in a follow up PR, so I don't think it's worth blocking on here.
|
|
||
| explicit Type(const std::vector<ValueType>& types); | ||
|
|
||
| size_t getNumValueTypes() const; |
There was a problem hiding this comment.
How about getNumValues or getArity which are shorter?
Adds the ability to create multivalue types from vectors of Type::ValueType. Only concrete value types are allowed in multivalue type tuples. All types are transparently interned, so their representation is still a single uint32_t. Types can be extracted into vectors of ValueTypes, and all the value types expand into vectors containing themselves. Multivalue types are not yet used in the IR, but the creation and inspection functionality is exposed in the C and JS APIs and used in tests.
- Make Type method names more succinct - Use Type instead of ValueType in creation and inspection APIs - Make Type printing much more ergonomic - Use unique_ptr to safely return const references to type vectors - Make common Type predicates methods - Address miscellaneous comments
715b302 to
f40092e
Compare
|
I have no idea why the behavior of wasm-reduce changed :/ |
|
Running that test locally to see how the output of wasm-reduce changes with this PR might help. I can help do that if you want. |
kripken
left a comment
There was a problem hiding this comment.
Basically lgtm aside from those questions. Nice work!
| }; | ||
|
|
||
| bool operator!=(const ValueType& other) { return id != other; } | ||
| struct ParamType { |
There was a problem hiding this comment.
Are ParamType and ResultType just for printing purposes? If so maybe add a comment. Or is there another use?
| size_t operator()(const std::vector<wasm::Type>& types) const { | ||
| size_t res = 0; | ||
| for (auto vt : types) { | ||
| res ^= hash<uint32_t>{}(vt); |
There was a problem hiding this comment.
where is this hash from? (we have src/support/hash.h which ensures the same hash values across libcs, but this doesn't look like it?)
There was a problem hiding this comment.
This is std::hash. I will add the namespace to disambiguate for the reader.
Adds the ability to create multivalue types from vectors of Type::ValueType.
Only concrete value types are allowed in multivalue type tuples. All types are
transparently interned, so their representation is still a single
uint32_t. Types can be extracted into vectors of ValueTypes, and all the value
types expand into vectors containing themselves.
Multivalue types are not yet used in the IR, but the creation and inspection
functionality is exposed in the C and JS APIs and used in tests.