
#12603: INLINE and manually inlining produce different code -------------------------------------+------------------------------------- Reporter: bgamari | Owner: bgamari Type: task | Status: new Priority: normal | Milestone: 8.2.1 Component: Compiler | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by MikolajKonarski): Replying to [comment:8 simonpj]:
When I INLINE[...], when I NOINLINE it [...] and when I leave it alone [...
This isn't necessarily surprising. Consider [...]
Thank you for the example. I've fixed the inlining status of all enclosing or competing functions in the module, but the strange behaviour persists. Now I suspect the complaints I have may not be related after all: 1. not floating out constants with INLINE as opposed to identical manual inlining; 2. erratic/unpredictable/surprising/buggy behaviour of INLINE vs NOINLINE vs <nothing> 3. three different figures for these, instead of two. I've just opened a feature request ticket for 3: https://ghc.haskell.org/trac/ghc/ticket/12747#ticket. This comment is about 2. If I find a smaller or simpler example for 2 and it's still as surprising, I will open a new bug report for it. As you point out, it's possible that 2 is not a bug, but just an exemplification of GHC being smarter than either us.
But if you add an `INLINE` pragma to `f`, then `g` becomes big, so GHC won't inline it. [...] These effects can be large, and are very hard to predict. GHC makes no guarantees, I'm afraid.
The guarantee that would help greatly would be that the behaviour of the program with neither INLINE nor NOINLINE for function `f` is the same as the behaviour with INLINE or that with NOINLINE. It would help tremendously with profiling experiments, because then I could fix the state of inlining of `f` and tune `g` and `h` without worry that inlining of `f` changes silently. But if `f` has the lowest allocation only without any pragmas at all, I can't fix it. See the feature request.
It's a bit more puzzling that you say your big function is called only once
I meant syntactically (even taking into account inlining of any other functions). But it's called inside a loop. It's referenced exactly once and fully applied, here: https://github.com/LambdaHack/LambdaHack/blob/master/Game/LambdaHack/Client/...
However a difference between 2.9G and 4.3G is very large, and it would be great to get more insight into why. I use `-ticky` to investigate this kind of thing.
Thank you for the tips. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/12603#comment:10 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler