Skip to content
  • Simon Peyton Jones's avatar
    Remove NOINLINE strictness hack · 302265d5
    Simon Peyton Jones authored
    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.
    302265d5