[GHC] #12620: Allow the user to prevent floating and CSE
GHC
ghc-devs at haskell.org
Sat Sep 24 23:28:27 UTC 2016
#12620: Allow the user to prevent floating and CSE
-------------------------------------+-------------------------------------
Reporter: nomeata | Owner:
Type: feature | Status: new
request |
Priority: normal | Milestone:
Component: Compiler | Version: 8.0.1
Keywords: | Operating System: Unknown/Multiple
Architecture: | Type of failure: None/Unknown
Unknown/Multiple |
Test Case: | Blocked By:
Blocking: | Related Tickets:
Differential Rev(s): | Wiki Page:
-------------------------------------+-------------------------------------
This is a write-up of a rough idea that Andres Löw and me had at ICFP 2016
in order to address some Real World problems Andres noticed and that are
currently hard to avoid.
The goal is to give the user more control about expressions that the
compiler would like to float out (or CSE), but the programmer knows
better. Example (assume no list fusion exists):
{{{
enum xs = zip [1..] xs
}}}
This leads to a horrible space leak, as GHC will float out `[1..]` to the
top.
Our idea is to have a magic function `nofloat :: a -> a` (magic in the
same sense as `inline` and `lazy`) that the programmer would use here:
{{{
enum xs = zip (nofloat [1..]) xs
}}}
With these effects:
* Sub expressions are not floated out of a `nofloat`.
* An expression of the form `nofloat e` would not be floated beyond the
innermost enclosing lambda.
* Two expressions of the form `nofloat e` would not be commoned up by
CSE.
This way, unwanted sharing is prevented.
In contrast to a hypothetical `veryCheap` function, it does ''not'' mean
that the compiler should float it into lambda (no unwanted duplication
either).
Two open questions (among many others, I am sure:)
* Likely, rule matching should look through `nofloat`. At least in this
example (and similar ones like `map (nofloat [1..])`, the rules in
question will avoid the spaceleaks).
* Possibly, nothing should be floated (inlined) ''into'' a `nofloat`.
Rationale: Assume the library is changed so that
{{{
[n..] = nofloat (realEnumFrom n)
{-# INLINE [n..] #-}
}}}
Then `zip [fib 1000..]` would be rewritten by the inliner to `zip (let x
= fib 1000 in (nofloat [x..]))`. Moving the `fib 1000` into the `nofloat`
would change the behaviour in a possibly surprising way.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/12620>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list