Inlining module.
This module will let you perform some inlining on Yhc.Core code. The InlineMode
argument
lets you select what algorithm is used. All should be terminating, and none should
increase the number of function calls in a program.
For comparison, GHC's inlining mode is more powerful than InlineForward
, but less
powerful than InlineFull
. (And just so people understand, powerful does not mean more
performance, it means more inlining - the two are not always the same!)
No inlining. Equivalent to id
:)
A function is inlined if it is aliased to another function.
A function is aliased if all it does is call another function with the same arguments in the same order. i.e.
f x y z = g x y z
Note that a function is not aliased if any argument is duplicated, the RHS is a primitive or a constructor, or the arguments are reordered.
This restriction means that inlining can even occur when f is used higher order, g can be replaced.
This mode will never increase the code size.
A function is inlined if it is a forwarder.
A function is a forwarder if all it does is call another function, using only the given arguments, possibly reordered but not duplicated. A forwarder can also be a single constant value, or a simple argument value (a projection), or a constructor with no arguments. i.e.
f x y z = 12 f x y z = g z y f x y z = x
The function is only inlined if it is called saturated.
This mode will never increase the code size.
A function is inlined if it is a forwarder, or if there is only one caller. Only inlined if called saturated. Will never increase the code size.
This does the most inlining it can, but never inlines the same function more than once in a given expression - to ensure termination. Also doesn't inline CAF's, since that would go wrong. Large functions, recursive functions, duplicated arguments etc - all are inlined without question.
Duplicated arguments are moved into a let, to ensure they are not computed additional times.
This mode is more than likely to increase the code size in most programs.
- coreInline :: InlineMode -> Core -> Core
- data InlineMode
- coreInlineFunc :: CoreFunc -> [CoreExpr] -> Maybe CoreExpr
- coreInlineFuncLambda :: CoreFunc -> [CoreExpr] -> ([String], CoreExpr)
Documentation
coreInline :: InlineMode -> Core -> CoreSource
data InlineMode Source
InlineNone | no inlining at all |
InlineAlias | f a b c = g a b c, calls to g become calls to f |
InlineForward | f a b c = g a b, g b a, a (g may be a constructor) |
InlineCallOnce | f is called only once |
InlineFull | If you can inline it, do so! Breaks on first recursive call |
coreInlineFunc :: CoreFunc -> [CoreExpr] -> Maybe CoreExprSource
Inline a function, fails if it would produce a lambda
See coreInlineFuncLambda
for a version without this property