- Notifications
You must be signed in to change notification settings - Fork 817
Avoid duplicate type names #6633
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can just skip adding new names entirely, including the deduping logic, when old == new
.
Thanks! Makes sense, I guess it is simple to just check if the types changed or not. I added that now. This almost removes the entire diff, but (aside from a correct diff to a signature-pruning test) there is still a diff on an unsubtyping test. The test is this: (module (type $super (sub (struct))) (type $sub (sub $super (struct))) (tag $t (param (ref $super))) (func $throw (throw $t (struct.new $sub) ) ) ) Roundtripping that text leads to (module (type $super (sub (struct ))) (type $1 (func (param (ref $super)))) (type $2 (func)) (type $sub (sub $super (struct ))) (tag $t (param (ref $super))) (func $throw (type $2) (throw $t (struct.new_default $sub) ) ) ) and that seemingly-unused (no references in the text format) type (module (rec (type $super (sub (struct ))) (type $sub (sub $super (struct ))) (type $2 (func)) (type $3 (func (param (ref $super)))) ) (type $4 (func (param (ref $super)))) (tag $t (param (ref $super))) (func $throw (type $2) (throw $t (struct.new_default $sub) ) ) ) and after (module (rec (type $super_1 (sub (struct ))) (type $sub_1 (sub $super_1 (struct ))) (type $2 (func)) (type $3 (func (param (ref $super_1)))) ) (type $4 (func (param (ref $super_1)))) (tag $t (param (ref $super_1))) (func $throw (type $2) (throw $t (struct.new_default $sub_1) ) ) ) Note @tlively is there a reason we don't have a HeapType in Tags and just a Signature? I am guessing that we create the type implicitly and that is related here. |
To be clear, the issue is that the final comparison ends up comparing the type from outside the rec group to one inside it, so they are unequal, and since types changed it updates the names which end up uglier. I didn't dig into why it sees the old type as the one from outside the rec group but I'm guessing it's due to not having a HeapType on Tags - if that doesn't sound right though I can investigate more. |
Yeah, the binary writer will implicitly create a function heap type for the signature on the tag if there is not already a type with a matching signature. This implicitly created type will not be in a rec group with any other type. We should update tags to use heap types internally. |
src/ir/type-updating.cpp Outdated
auto newType = newTypes[index]; | ||
oldToNewTypes[type] = newType; | ||
if (newType != type) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want to be fancy about this ;)
auto newType = newTypes[index]; | |
oldToNewTypes[type] = newType; | |
if (newType != type) { | |
if (type != (oldToNewTypes[type] = newTypes[index])) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moot after the last commit, but that would definitely have been more concise.
Got it, thanks. Yeah, that seems important to do, as right now we are actually shipping an unneeded type in these cases (we add tag types to the singleton rec group). But I realized we can work around it here in a reasonable way but just comparing on a type by type basis rather than the entire rec group, that seems to work, PTAL. |
The patch is simple but the large diff in tests is quite annoying. I think I figured out at least part of the problem but I don't have a good idea how to fix it:
IIANM what happens is this:
--print
shows the original module. Note each type is in its own rec group.--unsubtyping --print
creates a new singleton rec group for them. Note how they still have the proper names, because the patch makes the new types have the old names, and modifies the old names, but luckily the old names are no longer used.--remove-unused-types --print
looks identical except that now the names are have ugly_1
suffixes. That pass refreshes the private types by rebuilding them. It turns out that the new rec group we create is identical to the old, so they get folded together. In particular it seems that the new rec group, with the good names, is folded into the old rec group, with the ugly names.