Inlining is the most important compiler optimisation pass as it enables most other optimisation opportunities. The pass is simple, saturated names are replaced with their definitions, the details are complicated. The compiler must make judgements as to whether inlining a function will lead to further optimisations, if not then it is easy to increase the code size needlessly.
- Secrets of the GHC inliner -- quite an old paper but a great description of the main ideas
- GHC User Guide -- Provides a description of
Generics and Inlining
Inlining is essential to remove intermediate representations from generic programs. There are a number of papers about the topic.
Debugging the inliner
Firstly, remember that the inliner only fires with optimisations turns on (at least
-O1). This will save you a lot of time wondering why nothing is happening!
There are several flags which are useful when working with the inliner.
|`--show-iface`||Shows the contents of an interface file. Can be useful to check which unfoldings are being included.|
|`-dshow-passes`||Shows the size of the program after each optimisation pass.|
|`-ddump-inlinings`||Shows inlinings which take place|
|`-ddump-simpl`||Dump the (core) output of the simplifer|
There are lots of old relevant tickets related to inlining. Perfect for a keen newcomer!
- Avoid reconstructing dictionaries in recursive instance methods
- Improve join point inlining
- Improve inlining for local functions
- Better inlining test in CoreUnfold
- Allow both INLINE and INLINABLE for the same function
- INLINABLE fails to specialize in presence of simple wrapper
- Inlining depends on datatype size, even with INLINE pragmas
- Cannot recover (good) inlining behaviour from 7.0.2 in 7.4.1
- Specialise INLINE functions
- Room for GHC runtime improvement >~5%, inlining related
- Superclass methods are left unspecialized
- make better/more robust loopbreaker choices
- Alternate syntax for indicating when a function is "fully applied" for purposes of inlining
- Bad choice of loop breaker with INLINABLE/INLINE
- GHC does not inline cheap inner loop when used in two places
- SPECIALIZE silently fails to apply
- Transitivity of Auto-Specialization
- 7.8 optimizes attoparsec improperly
- Massive blowup of code size on trivial program
- Inlining regression/strangeness in 7.8
- unfolding info as seen when building a module depends on flags in a previously-compiled module
- Warnings about "INLINE binder is (non-rule) loop breaker"
- GADTs not specialized properly
- Frustrating behaviour of the INLINE pragma
- GHC fails to inline and specialize a function
- exponential blowup in inlining (without INLINE pragmas)
- More self-explanatory pragmas for inlining phase control
- user manual: INLINE's interaction with optimization levels is not clear
- Make Generic/Generic1 methods inlinable
- "Simplifier ticks exhausted" that resolves with fsimpl-tick-factor=200
- Remove the `isInlinePragma prag` test
- GHC panic: simplifier ticks exhausted
- Cross-module specialisation of recursive functions
- SPECIALIZABLE pragma?
- Compilation time/space regression in GHC 8.0/8.1 (search in type-level lists and -O)
- No automatic SCC annotations for functions marked INLINABLE
Relevant Wiki Pages
unroll0.hs (1.6 KB) - added by 8 years ago.
trivial loop, INLINE loop PEEL 1 UNROLL 4, plus reassociation RULES
unroll1.hs (1.6 KB) - added by 8 years ago.
loop over bulk-array op, INLINE loop PEEL 1 UNROLL 4 activates array fusion RULES
unroll2.hs (729 bytes) - added by 8 years ago.
non-strict foldl, INLINE foldl PEEL 1 (+SAT) prevents stackoverflow
Download all attachments as: .zip