wiki:Inlining

Inlining

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

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

Relevant Tickets

There are lots of old relevant tickets related to inlining. Perfect for a keen newcomer!

#3073
Avoid reconstructing dictionaries in recursive instance methods
#3755
Improve join point inlining
#3781
Improve inlining for local functions
#4960
Better inlining test in CoreUnfold
#5928
INLINABLE fails to specialize in presence of simple wrapper
#7109
Inlining depends on datatype size, even with INLINE pragmas
#7114
Cannot recover (good) inlining behaviour from 7.0.2 in 7.4.1
#7283
Specialise INLINE functions
#7511
Room for GHC runtime improvement >~5%, inlining related
#7803
Superclass methods are left unspecialized
#7829
make better/more robust loopbreaker choices
#8099
Alternate syntax for indicating when a function is "fully applied" for purposes of inlining
#8589
Bad choice of loop breaker with INLINABLE/INLINE
#8662
GHC does not inline cheap inner loop when used in two places
#8668
SPECIALIZE silently fails to apply
#8774
Transitivity of Auto-Specialization
#8814
7.8 optimizes attoparsec improperly
#9020
Massive blowup of code size on trivial program
#9320
Inlining regression/strangeness in 7.8
#9370
unfolding info as seen when building a module depends on flags in a previously-compiled module
#9418
Warnings about "INLINE binder is (non-rule) loop breaker"
#9701
GADTs not specialized properly
#9798
Frustrating behaviour of the INLINE pragma
#10371
GHC fails to inline and specialize a function
#10421
exponential blowup in inlining (without INLINE pragmas)
#10710
More self-explanatory pragmas for inlining phase control
#10766
user manual: INLINE's interaction with optimization levels is not clear
#11068
Make Generic/Generic1 methods inlinable
#11263
"Simplifier ticks exhausted" that resolves with fsimpl-tick-factor=200
#11791
Remove the `isInlinePragma prag` test
#12274
GHC panic: simplifier ticks exhausted
#12425
With -O1 and above causes ghc to use all available memory before being killed by OOM killer
#12454
Cross-module specialisation of recursive functions
#12463
SPECIALIZABLE pragma?

Relevant Wiki Pages

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

Attachments (3)

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

Download all attachments as: .zip