Remove NOINLINE strictness hack
authorsimonpj@microsoft.com <unknown>
Mon, 8 May 2006 14:28:34 +0000 (14:28 +0000)
committersimonpj@microsoft.com <unknown>
Mon, 8 May 2006 14:28:34 +0000 (14:28 +0000)
commit302265d525004c7870864549f7a07a5759d32912
treeb649752f104b35710b370603db16fe43862a5acd
parent36b27193c994b4a267c8dfdbf833d73b455130aa
Remove NOINLINE strictness hack

The stricteness analyser used to have a HACK which ensured that NOINLNE things
were not strictness-analysed.  The reason was unsafePerformIO. Left to itself,
the strictness analyser would discover this strictness for unsafePerformIO:
unsafePerformIO:  C(U(AV))
But then consider this sub-expression
unsafePerformIO (\s -> let r = f x in
       case writeIORef v r s of (# s1, _ #) ->
       (# s1, r #)
The strictness analyser will now find that r is sure to be eval'd,
and may then hoist it out.  This makes tests/lib/should_run/memo002
deadlock.

Solving this by making all NOINLINE things have no strictness info is overkill.
In particular, it's overkill for runST, which is perfectly respectable.
Consider
f x = runST (return x)
This should be strict in x.

So the new plan is to define unsafePerformIO using the 'lazy' combinator:

unsafePerformIO (IO m) = lazy (case m realWorld# of (# _, r #) -> r)

Remember, 'lazy' is a wired-in identity-function Id, of type a->a, which is
magically NON-STRICT, and is inlined after strictness analysis.  So
unsafePerformIO will look non-strict, and that's what we want.

Now we don't need the hack in the strictness analyser.
compiler/basicTypes/MkId.lhs
compiler/stranal/DmdAnal.lhs
compiler/stranal/WorkWrap.lhs