-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Convert the default-case optimisation to a MIR pass #33567
Comments
The question is whether to change the Also, it being non-exhaustive means we can build the initial MIR a bit smarter. There are often cases where we can narrow down the candidates based on the fact that previous arms weren't taken: enum Foo {
A,
B,
C
}
match (x, y) {
(_, A) => {},
(A, _) => {} // We know that the `_` can't be A here because otherwise the earlier case would have been taken
} I'm pretty sure the existing code tries to handle this already, I know old trans does. |
IMO we should remove switch altogether. A big part of MIR is getting rid of things tied to language (e.g. we have no for, while etc loops, only a goto), but we (due to historical accidents, already!) have both the What I think we ought to do, is:
The only downside I see – we would end up duplicating the values being |
Incidentally that should also decrease our reliance on trans::adt greatly. |
also cc @nikomatsakis, in case you want to discuss this. |
Unsurprisingly, I do have an opinion:
I'm not sure how much to weigh the first point. It seems like it's probably good to keep in mind, but bad to be overly constrained by this -- after all, if we want to change things later, we can do so, and it's clear that we don't know the full set of constraints right now. Another way to look at unifying Finally, I imagine we could bridge the gap just by making
In other words, we wouldn't generate code like:
but just
|
So @scottcarr is starting up an internship and I was thinking this would make a good starter problem for him (presuming nobody else is hacking on it just now?). I was thinking specifically not of modifying the MIR in any particular way, but just modifying the MIR generation to not build a basic block for every variant, but instead to be more selective. (In other words, it would directly generate the IR that we wind up optimizing to.) We could also change the IR, but the two things seem somewhat orthogonal to me. |
Here are some test cases (just for reference) that exhibit the N^2 blowup we observed (at least initially). Note that the one that uses integral constants does not: I think the simplest fix to the blowup is just to have the enum case use a similar pattern to what constants do, where it figures out which variants are "of interest" and creates an otherwise-like block to use as the target for the remainder (we might also change the IR; just seems orthogonal). https://gist.github.com/nikomatsakis/dc3641659919d11b01a6fc14051831bd |
generate fewer basic blocks for variant switches CC #33567 Adds a new field to TestKind::Switch that tracks the variants that are actually matched against. The other candidates target a common "otherwise" block.
generate fewer basic blocks for variant switches CC #33567 Adds a new field to TestKind::Switch that tracks the variants that are actually matched against. The other candidates target a common "otherwise" block.
I think this is done now after we switched to the SwitchInt everywhere. |
#33566 introduces an optimisation which speeds up LLVM greatly. My suspicion is that this optimisation is also very relevant to the MIR pipeline (i.e. MIR transformations ought to be slower to analyse and transform the switches with more branches). Thus we should port this optimisation over to a MIR pass down the line.
Moreover, the code in the PR relies on the assumption that the
otherwise
branch of the switches is always unreachable. This assumption has potential to become not true after we get more complex optimisations on the MIR going. Having such optimisation to be a plain MIR transformation would help with this too.cc @dotdash
The text was updated successfully, but these errors were encountered: