This email relates to the paper "Optimising generics is easy" www.cs.uu.nl/research/techreps/repo/CS-2009/2009-022.pdf. Copying cvs-ghc who will, I think, be interested. Maybe someone will have some good ideas.
Jose writes (about a case where inlining doesn't work well): | I put a minimal source code for this test and resulting Core | (with GHC 6.13.20091115) in https://subversion.cs.uu.nl/repos/staff.jpm.public/Inline/. | UpdateInt behaves great: in UpdateInt.core.O1.hs, there are no traces of | generic representations in testOne, testTwo, testThree and testFour. | UpdateString, however, does not behave so well. In UpdateString.core.O1.hs, | Test.testLogic_updateString still has loads of generic representations. OK, I've had a look. It's easy to see what is happening. Compile UpdateString with -ddump-simpl, and look at the core. You see stuff like Rec { $j1_rx32 = \x. <big nested case expression> ; f = \y. ....($j1_rx32 <big constructor expression>) ---($j1_rx32 <big constructor expression).... } So here the $j (which is a "join point") isn't inlined because it's big, although if it *were* inlined there would be much goodness because the case expressions would cancel with the explicit constructors. Why did this happen despite lots of INLINE pragmas? I have not followed all the details, but I'm guessing that if we have, say {-# INLINE from #-} from = \x. case x of from_alts {-# INLINE to #-} to = \x. case x of to_alts and we try to optimize this calle: from (to x) then after inlining from and to we'll get case (case x of to_alts) of from_alts And now the case-of-case transform happens, which creates the join points to avoid duplicating from_alts into every branch of to_alts. You may say that we've already said that it's ok to duplicate from (and hence from_alts) but we duplicated it once when we inlined it, and then we forget the origin of the code. And indeed, in the worse case you could get a quadratic blow up; and there are only two functions involved. So I'm not unhappy with that. However, it does make me wonder whether we could not do a better job on the above Rec {..}. Two thoughts occur. 1. We could beef up SpecConstr. It doesn't fire at the moment for some reason, even with -O2 2. If we have f = \x. case x of { C1 x11..x1n -> e1; ... Ck xk1 ... xkm -> ek } maybe we should worker-wrapper it to f1 x1 .. x1n = e1 ... fn xk1 .. xkm = en f = \x of pi -> fi xi and now inline f. (2) is very similar to the way join points work right now, but it would make it multi-level. Interesting Simon _______________________________________________ Cvs-ghc mailing list [email protected] http://www.haskell.org/mailman/listinfo/cvs-ghc
