Commit 14817621 authored by KevinBuhr's avatar KevinBuhr Committed by Ben Gamari

base: Mark `findIndices` as INLINABLE instead of INLINE (fixes #15426)

If `findIndices` is marked INLINE in `Data.OldList`, then the unfolded
versions of `elemIndex` and `findIndex` included in the interface file
are unfusible (even though `findIndices` itself remains fusible).  By
marking it INLINABLE instead, elemIndex` and `findIndex` will fuse
properly.

Test Plan: make TEST=T15426

Reviewers: hvr, bgamari

Reviewed By: bgamari

Subscribers: rwbarton, carter

GHC Trac Issues: #15426

Differential Revision: https://phabricator.haskell.org/D5063
parent 2bacf6f8
...@@ -310,7 +310,9 @@ findIndices :: (a -> Bool) -> [a] -> [Int] ...@@ -310,7 +310,9 @@ findIndices :: (a -> Bool) -> [a] -> [Int]
findIndices p xs = [ i | (x,i) <- zip xs [0..], p x] findIndices p xs = [ i | (x,i) <- zip xs [0..], p x]
#else #else
-- Efficient definition, adapted from Data.Sequence -- Efficient definition, adapted from Data.Sequence
{-# INLINE findIndices #-} -- (Note that making this INLINABLE instead of INLINE allows
-- 'findIndex' to fuse, fixing #15426.)
{-# INLINABLE findIndices #-}
findIndices p ls = build $ \c n -> findIndices p ls = build $ \c n ->
let go x r k | p x = I# k `c` r (k +# 1#) let go x r k | p x = I# k `c` r (k +# 1#)
| otherwise = r (k +# 1#) | otherwise = r (k +# 1#)
......
import Control.Exception (evaluate)
import Data.List
-- The following will fuse with minimal heap usage provided
-- `findIndices` is marked `INLINABLE` instead of `INLINE`.
unsafeFindIndex p = head . findIndices p
main = do evaluate $ elemIndex 999999 [(1::Int)..1000000]
evaluate $ elemIndices 999999 [(1::Int)..1000000]
evaluate $ findIndex (>=999999) [(1::Int)..1000000]
evaluate $ findIndices (>=999999) [(1::Int)..1000000]
evaluate $ unsafeFindIndex (>=999999) [(1::Int)..1000000]
...@@ -595,3 +595,12 @@ test('T15226a', ...@@ -595,3 +595,12 @@ test('T15226a',
only_ways(['normal'])], only_ways(['normal'])],
compile_and_run, compile_and_run,
['-O']) ['-O'])
test('T15426',
[stats_num_field('bytes allocated',
[ (wordsize(64), 41272, 20) ]),
# 2018-08-10 41272 Change findIndices from INLINE to INLINABLE
# initial 160041176
only_ways(['normal'])],
compile_and_run,
['-O2'])
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment