Skip to content

Multivalue type creation and inspection - #2459

Merged
tlively merged 5 commits into
WebAssembly:masterfrom
tlively:multivalue-types
Nov 22, 2019
Merged

tlively merged 5 commits into
WebAssembly:masterfrom
tlively:multivalue-types

Conversation

@tlively

@tlively tlively commented Nov 21, 2019

Copy link
Copy Markdown
Member

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.

@tlively
tlively requested a review from kripken November 21, 2019 00:07

@aheejin aheejin left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Mostly LGTM, some minor comments

Comment thread src/wasm/wasm-type.cpp Outdated
size_t operator()(const std::vector<wasm::Type::ValueType>& types) const {
size_t res = 0;
for (auto vt : types) {
res ^= hash<int>{}(vt);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

unsigned int?

Comment thread src/wasm-type.h Outdated
size_t getNumValueTypes() const;
const std::vector<ValueType> getValueTypes() const;

bool isValueType() { return id >= i32 && id < _last_value_type; }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

So multivalue types return false for this? Multivalues are also values. Maybe isSimpleValueType..? (Not sure about the name)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I mean "value type" in the sense used by the spec, which is always a single type.

Comment thread src/wasm/wasm-type.cpp Outdated
return typeLists[id].size();
}

const std::vector<Type::ValueType> Type::getValueTypes() const {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is there a missing & in the return type?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

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.

@aheejin aheejin Nov 21, 2019 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I see. But then does this have to be const?

Comment thread src/wasm/wasm-type.cpp Outdated
std::vector<Type::ValueType> vts = type.getValueTypes();
std::string res("(");
for (size_t i = 0; i < vts.size() - 1; ++i) {
res += ", ";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Doesn't this print something like (, type1, type2, ...)?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, oops.

Comment thread src/binaryen-c.cpp Outdated
std::cout << " {\n";
std::cout << " BinaryenType " << array << "[] = {";
for (size_t i = 0; i < numTypes; ++i) {
std::cout << int(valueTypes[i]);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

unsigned?

Comment thread src/binaryen-c.cpp Outdated
}
std::cout << "};\n";
std::cout << " BinaryenTypeCreate(" << array << ", " << numTypes
<< "); // " << int(result) << "\n";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

unsigned?

Comment thread src/binaryen-c.cpp Outdated
std::cout << " }\n";
}

return uint32_t(int(result));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why double cast? Isn't Types cast operand to uint32_t in the first place?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Thanks for catching these. I originally had the implicit conversion go to int and didn't update these when I changed it.

Comment thread src/wasm-type.h Outdated
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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this comment can be removed completely

Comment thread src/wasm-type.h Outdated
size_t getNumValueTypes() const;
const std::vector<ValueType> getValueTypes() const;

bool isValueType() { return id >= i32 && id < _last_value_type; }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Isn't this check the same as isConcreteType?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

No, isConcreteType includes multivalue types as well.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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?)

Comment thread src/wasm-type.h Outdated
constexpr Type unreachable = Type::unreachable;

const char* printType(Type type);
const std::string printType(Type type);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

does this change have an impact on performance? we may call this many many times in a huge wast.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

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.

Comment thread src/wasm-type.h Outdated

explicit Type(const std::vector<ValueType>& types);

size_t getNumValueTypes() const;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

How about getNumValues or getArity which are shorter?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Nice, I like getArity.

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
@tlively

tlively commented Nov 22, 2019

Copy link
Copy Markdown
Member Author

I have no idea why the behavior of wasm-reduce changed :/

@kripken

kripken commented Nov 22, 2019

Copy link
Copy Markdown
Member

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 kripken left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Basically lgtm aside from those questions. Nice work!

Comment thread src/wasm-type.h
};

bool operator!=(const ValueType& other) { return id != other; }
struct ParamType {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Are ParamType and ResultType just for printing purposes? If so maybe add a comment. Or is there another use?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, I'll add comments.

Comment thread src/wasm/wasm-type.cpp Outdated
size_t operator()(const std::vector<wasm::Type>& types) const {
size_t res = 0;
for (auto vt : types) {
res ^= hash<uint32_t>{}(vt);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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?)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is std::hash. I will add the namespace to disambiguate for the reader.

@tlively
tlively merged commit e2587f3 into WebAssembly:master Nov 22, 2019
@tlively
tlively deleted the multivalue-types branch April 24, 2020 23:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants