From a811a863f58dd1521893c251466e8d3c8bb457e2 Mon Sep 17 00:00:00 2001 From: Takano Akio Date: Fri, 17 Feb 2017 05:12:35 +0000 Subject: [PATCH] Make sure that 'length' can be inlined (Fixes #97) Previously there was a cycle in the dependency graph of functions, consisting of {stream, clone, length, unsafeCopy}. This was causing GHC to mark one of these functions, length, as a loop breaker. This commit breaks this down this strongly-connected component by removing the edge from length to stream. --- Data/Vector/Generic.hs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Data/Vector/Generic.hs b/Data/Vector/Generic.hs index 0e022144..066c07fd 100644 --- a/Data/Vector/Generic.hs +++ b/Data/Vector/Generic.hs @@ -228,7 +228,7 @@ import qualified Data.Traversable as T (Traversable(mapM)) -- | /O(1)/ Yield the length of the vector length :: Vector v a => v a -> Int {-# INLINE length #-} -length = Bundle.length . stream +length = Bundle.length . stream' -- | /O(1)/ Test whether a vector is empty null :: Vector v a => v a -> Bool @@ -1995,7 +1995,13 @@ unsafeCopy dst src = UNSAFE_CHECK(check) "unsafeCopy" "length mismatch" -- | /O(1)/ Convert a vector to a 'Bundle' stream :: Vector v a => v a -> Bundle v a {-# INLINE_FUSED stream #-} -stream v = Bundle.fromVector v +stream v = stream' v + +-- Same as 'stream', but can be used to avoid having a cycle in the dependency +-- graph of functions, which forces GHC to create a loop breaker. +stream' :: Vector v a => v a -> Bundle v a +{-# INLINE stream' #-} +stream' v = Bundle.fromVector v {- stream v = v `seq` n `seq` (Bundle.unfoldr get 0 `Bundle.sized` Exact n)