
2009/3/9 Claus Reinke
let f = ..f.. in f{n,m} -PEEL-> let f = ..f.. in ..f{n-1,m}..
Probably what you intend here is that you create one copy of the definition every round rather than one per call site, is that right?
I don't think so - ultimately, the point of both peeling and unrolling is to unfold a definition into a use site, to enable further optimizations, not just to move from a recursive to a non-recursive definition. We could try to do it in two steps, as you suggest, but that would expose us to the heuristics of GHC inlining again (will or won't it inline the new shared definition?), in the middle of a user-annotation-based unfolding.
Ah - I was thinking of something a bit different, where: * PEEL / UNROLL pragmas duplicate the method body once per level of peeling / unrolling and fix up the recursive calls as appropriate * The user optionally adds an INLINE pragma to the function if he additionally wants to be SURE that those duplicates get inlined at the use sites This means that PEEL / UNROLL represent nice logically-orthogonal bits of functionality to INLINE-ing. Furthermore, I'm not too keen on duplicating method bodies at call sites willy-nilly because it may lead to increased allocations (of the function closures) in inner loops. At least if you bind the duplicated methods at the same level as the thing you are duplicating you only increase the dynamic number of closures created by a constant factor! I've actually been thinking about using a different strategy for case liberation (which duplicates method bodies at call sites) to make it more constructor-specialisation like (which duplicates method bodies at the definition site) partly for this reason. Cheers, Max