Fix duplication of code in Cmmgen#1370
Conversation
|
After looking at the code I have two questions:
|
|
The problem is triggered when switches generated during translation to lambda code contain a limited number of cases, and no fail action. Since the switch structure also contains information about the number of constructors in the type, the following passes tend to generate actions for those missing cases, and those additional actions are not shared properly. About the t_store type change, I first tried using a |
asmcomp/cmmgen.ml
Outdated
| | Cexit (i,[]) -> Some i | ||
| | _ -> None | ||
| in | ||
| match index, cont with |
There was a problem hiding this comment.
I apologize for the extreme nitpicking but would you mind matching on cont, index? That's the order they are always in.
|
Following suggestions from @chambart I've duplicated the StoreExp module to reflect that the context is different between the standard switches and string switches. |
|
(cc @maranget : do you have an opinion on this proposed change? ) |
|
Hi, The change fixes a real problem. It uses the existing Store component appropriatly and should be scheduled for integration. Well done. May I ask for the pull request authors to comment on the following suggestion: Impact on file others than switch.ml and cmmgen.ml can be significantly reduced by renaming your Store module into, say, CtxStore and then adding a new Store module that would be the application of CtxStore with type context being unit. Then, there would be no need to change matching.ml, lambda.ml etc. |
|
I've pushed a commit that splits the t_store type and Store functor into context-aware and context-unaware versions, which indeed allows to revert the changes to unrelated files. It is a bit disappointing that the Anyway, I'm not attached to any particular solution, so I can revert back or go for a middle ground solution if you think it's better. |
|
(Personally I find the two |
|
Im an not sure at all that the store_t type have to be duplicated. My idea was rather In switch.mli
(2) Define Stored with context as a signature "extension" (3) then define the two functors for building sharing stores with and without context, ... In switch.ml, Store will basically be: .... Ok, that way we still have some strange |
|
It works, and removes part of the patches in lambda.ml, bytegen.ml and so on, but the parts that call But as @gasche pointed out, this is not a goal that we absolutely need to reach. I'll update the pull request to revert the t_store duplication (but keep Store and CtxStore distinct), so it should get more or less to what you had in mind. |
* Fix duplicates in Cmmgen when handling switches with no default and not all cases * Improve handling of incomplete Lambda switches in Flambda * Add test (for reference) and changes * Fix nitpick * Cleanup: split the switch stores to reflect usage * Improve compilation of incomplete switches with flambda * Split switch stores into context-aware and -unaware versions * Credit reviewers * Go back to a single Switch.t_store type
In some very specific cases, translation of switch expressions from clambda to cmm can duplicate the code contained in a branch of the original match.
I saw this happen while compiling middle_end/lift_let_to_initialize_symbol.ml, and from there built a smaller example for reproduction purposes :
Compiling this example with
ocamlopt -dclambda -dcmmwill show theset 2instruction getting duplicated in cmm, even though it only occurs once in clambda.Only one of the duplicated copies is actually reachable, so there is no soundness issue that I'm aware of, but the duplication stays there through all the remaining passes, so at least for code size it makes sense to remove it.