-
Simon Peyton Jones authored
--------------------------- Add a new case optimisation --------------------------- I found that lib/std/PrelCError had a case-expression that was generating terrible code. Something like this x | p `is` 1 -> e1 | p `is` 2 -> e2 ...etc... where @is@ was something like p `is` n = p /= (-1) && p == n This gave rise to a horrible sequence of cases case p of (-1) -> $j p 1 -> e1 DEFAULT -> $j p and similarly in cascade for all the join points! Solution: add the following transformation: case e of =====> case e of C _ -> <expr> D v -> ....v.... D v -> ....v.... DEFAULT -> <expr> DEFAULT -> <expr> The point is that we merge common RHSs, at least for the DEFAULT case. [One could do something more elaborate but I've never seen it needed.] This transformation is implemented in SimplUtils.mkCase *** WARNING *** To make this transformation easy, I have switched the convention for DEFAULT clauses. They must now occur FIRST in the list of alternatives for a Core case expression. (The semantics is unchanged: they still are a catch-all case.) The reason is that DEFAULT clauses sometimes need special treatment, and it's a lot easier to find them at the front. The easiest way to be insensitive to this change is to use CoreUtils.findDefault to pull the default clause out. I've made the (surprisingly few) changes consequent on this changed of convention, but they aren't in this commit. Instead they are part of the big commit on newtypes I'm doing at the same time.
3622a7de