Commit 0da4a69
committed
Make 'length' fusible
This change makes fusible 'Data.Vector.Generic.length',
which currently can be inlined but doesn't fuse well.
Before this revision, 'length' uses non-fusible 'stream''.
This revision replaces 'stream'' with fusible 'stream',
and at the same time substitute the mutually-recursive
occurrences of 'length' with 'basicLength'.
Rationale:
The current definition was introduced in the commit
a811a86.
Prior to that commit,
'length' could not even be inlined with older GHCs,
which elected 'length' to be a loop-breaker due to the cyclic
references among 'clone', 'unsafeCopy', 'length' and 'stream':
* 'clone' refers to 'length' and 'unsafeCopy' in its definition;
* 'unsafeCopy' refers to 'length' in its definition;
* 'length' referred to 'stream' in its definition;
* 'stream' refers to none of the above in its definition,
but the rule 'New.unstream/stream' rewrites
@'New.unstream' ('stream' v)@ with @'clone' v@.
This failure of inlining was reported as
haskell#97.
To be precise, this cycle of references is immaterial with newer
GHCs like GHC 8.8.3.
Since 'New.unstream' does not occur in the definitions of
'clone', 'unsafeCopy', and 'length',
indefinite inlining will not happen anyway.
GHC 8.8.3 seems to detect this immateriality of the
referencial loop in question and refrains from setting 'length' as a
loop-breaker, even with
acdcff3
(the parent commit of a811a86).
However with older GHCs, including GHC 8.0.2, regarded
the cyclic references fatal and marked 'length' as a loop-breaker.
Note that GHC 8.0.2 was current at the time a811a86 was introduced.
The commit a811a86 resolved this by replacing 'stream'
with 'stream'' in the definition of 'length'. The function
'stream' refers to 'clone' in its fusion rule, but 'stream''
doesn't possess any rule. This cut open the cycle of references
and made 'length' inlinable.
However, since 'stream'' doesn't possess any rule, defining
'length' = 'Bundle.length' . 'stream''
is all the same as setting
'length' = 'basicLength'.
This prevents any stream fusion from happening.
This commit resolves this problem by resetting 'length' back
to be @'Bundle.length' . 'stream'@, and instead replacing
cyclic occurrence of 'length' with 'basicLength'
(Just *inlined the simplification result of the definition*).
Now 'length' is both inlinable and fusible, even with older GHCs.
Fixes: haskell#306
See also: haskell#97
haskell#111
haskell#1551 parent eeb42ad commit 0da4a69
1 file changed
+5
-11
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
222 | 222 | | |
223 | 223 | | |
224 | 224 | | |
225 | | - | |
| 225 | + | |
226 | 226 | | |
227 | 227 | | |
228 | 228 | | |
| |||
1986 | 1986 | | |
1987 | 1987 | | |
1988 | 1988 | | |
1989 | | - | |
| 1989 | + | |
1990 | 1990 | | |
1991 | 1991 | | |
1992 | 1992 | | |
| |||
1995 | 1995 | | |
1996 | 1996 | | |
1997 | 1997 | | |
1998 | | - | |
| 1998 | + | |
1999 | 1999 | | |
2000 | 2000 | | |
2001 | 2001 | | |
| |||
2004 | 2004 | | |
2005 | 2005 | | |
2006 | 2006 | | |
2007 | | - | |
2008 | | - | |
2009 | | - | |
2010 | | - | |
2011 | | - | |
2012 | | - | |
2013 | | - | |
| 2007 | + | |
2014 | 2008 | | |
2015 | 2009 | | |
2016 | 2010 | | |
| |||
2133 | 2127 | | |
2134 | 2128 | | |
2135 | 2129 | | |
2136 | | - | |
| 2130 | + | |
2137 | 2131 | | |
2138 | 2132 | | |
2139 | 2133 | | |
| |||
0 commit comments