Repository navigation
Conversation
tlively
left a comment
There was a problem hiding this comment.
Some initial comments before I get into the meat of the new implementation.
Test coverage doesn't look great, especially for the new changes in type-generalizing.
Metric Covered / Total Details
------------ ---------------------- ----------------------------------
Lines 243 / 326 (74.5%) Executable lines in diff
Regions 195 / 232 (84.1%) Sub-line / block AST regions in diff
Branches 131 / 170 (77.1%) True/False branch outcomes in diff
MC/DC 6 / 21 (28.6%) Condition independence pairs in diff
Functions 28 / 103 (27.2%) Modified functions called >= 1x
| void visitRethrow(Rethrow* curr) {} | ||
| void visitThrowRef(ThrowRef* curr) {} | ||
| void visitThrowRef(ThrowRef* curr) { | ||
| self()->noteNonFlowSubtype(curr->exnref, Type(HeapType::exn, Nullable)); |
There was a problem hiding this comment.
Why "non-flow" here? The ref does flow into the throw and out of a later catch.
There was a problem hiding this comment.
Yes, but it doesn't flow out of this expression. Reading the docs on top, I guess this can be ambiguous. I can reword that?
| if (curr->ref->type.isRef() && curr->ref->type.getHeapType().isShared()) { | ||
| share = Shared; | ||
| } | ||
| self()->noteNonFlowSubtype( |
There was a problem hiding this comment.
Again, why non-flow? Previously the only use of noteNonFlowSubtype was for ref.eq. If all these new uses of noteNonFlowSubtype are correct, then I suspect there are many more places that should be using it.
There was a problem hiding this comment.
I think this is correct (for the reasons I mentioned above) but yes, there might be more places it makes sense to use. I didn't try to find them all in this PR - would make more sense in a place where we can cover them more easily with tests, though I don't know that we have a better pass, actually...
There was a problem hiding this comment.
I can remove the ones not directly needed for tests in this PR if you prefer, though e.g. the String ones seem obvious?
There was a problem hiding this comment.
(Aside from them, the ThrowRef one can also be removed from this PR, it looks like.)
| if (curr->desc) { | ||
| auto descType = curr->type.getHeapType().getDescriptorType(); | ||
| assert(descType); | ||
| self()->noteSubtype(curr->desc, Type(*descType, Nullable, Exact)); | ||
| } |
There was a problem hiding this comment.
If visitation order matters, this should come after visiting the fields. (And even if visitation order doesn't matter now, it would probably be better to be consistent about it.)
There was a problem hiding this comment.
BrOn and RefCast are also missing descriptor handling.
There was a problem hiding this comment.
The order doesn't matter, but I agree it is nice to follow. Fixed.
There was a problem hiding this comment.
BrOn and RefCast are also missing descriptor handling.
How about leaving those for later + tests? This PR is mainly focused on the reboot, but not adding new functionality.
There was a problem hiding this comment.
Yes. The fuzzer uses SubtypingDiscoverer internally (to find mutations, of the proper types). So improvements here lead to fuzzer improvements.
There was a problem hiding this comment.
It's probably worth a TODO about additional things that are not handled optimally by SubtypeDiscoverer because it assumes the result types cannot be generalized: specifically ref.as_non_null, br_on_null, publish, br_if, and maybe a couple others.
|
(In fact, |
|
Actually, |
Co-authored-by: Thomas Lively <tlively123@gmail.com>
|
Commit pushed with comprehensive tests for new functionality in this PR. The one thing I did not do here is verify they are new and not previously covered (as I didn't write the old ones originally, so I'd need to do a lot of work to match things up). But I had Gemini check that. In the worst case, if it got it wrong, we might be adding some small amount of overlap. |
|
Thanks, that sounds like the right trade off to me. |
Now that we have a "late opts" stage, we can do things like generalize
types. This initial PR rewrites the pass to use the SubtypingDiscoverer
logic that was added since, and which makes the pass a lot
simpler (about half the length).
More work is needed to get this fuzzed etc., but just this rewrite
already removes some TODOs and asserts that are no longer relevant.
The pass can now run on a large Kotlin testcase without erroring, and
it shrinks the size there by 0.25% (not much yet, but after adding cast
generalization, perhaps more..?)
All old tests pass like before. (One new test is added, to handle a
crash that happened during this porting process.)
This is basically NFC, except that removing the old asserts mean
that more things can run.