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.

Getting Started

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.

Flag Usage
`--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

Newcomer Tickets

Better inlining test in CoreUnfold
unfolding info as seen when building a module depends on flags in a previously-compiled module
Make Generic/Generic1 methods inlinable
Remove the `isInlinePragma prag` test

Relevant Tickets

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
With -O1 and above causes ghc to use all available memory before being killed by OOM killer
Cross-module specialisation of recursive functions
Compilation time/space regression in GHC 8.0/8.1 (search in type-level lists and -O)

Relevant Wiki Pages

Last modified 3 months ago Last modified on Aug 4, 2016 9:46:17 AM

Attachments (3)

  • unroll0.hs (1.6 KB) - added by claus 8 years ago. trivial loop, INLINE loop PEEL 1 UNROLL 4, plus reassociation RULES
  • unroll1.hs (1.6 KB) - added by claus 8 years ago. loop over bulk-array op, INLINE loop PEEL 1 UNROLL 4 activates array fusion RULES
  • unroll2.hs (729 bytes) - added by claus 8 years ago. non-strict foldl, INLINE foldl PEEL 1 (+SAT) prevents stackoverflow

Download all attachments as: .zip