[project @ 2002-06-18 13:58:22 by simonpj]
authorsimonpj <unknown>
Tue, 18 Jun 2002 13:58:23 +0000 (13:58 +0000)
committersimonpj <unknown>
Tue, 18 Jun 2002 13:58:23 +0000 (13:58 +0000)
---------------------------------------
    Rehash the handling of SeqOp
---------------------------------------

See the comments in the commentary (Cunning Prelude Code).

* Expunge SeqOp altogether

* Add GHC.Base.lazy :: a -> a
  to GHC.Base

* Add GHC.Base.lazy
  to basicTypes/MkId.  The idea is that this defn will over-ride
  the info from GHC.Base.hi, thereby hiding strictness and
  unfolding

* Make stranal/WorkWrap do a "manual inlining" for GHC.Base.lazy
  This happens nicely after the strictness analyser has run.

* Expunge the SeqOp/ParOp magic in CorePrep

* Expunge the RULE for seq in PrelRules

* Change the defns of pseq/par in GHC.Conc to:

{-# INLINE pseq  #-}
        pseq :: a -> b -> b
        pseq  x y = x `seq` lazy y

        {-# INLINE par  #-}
        par :: a -> b -> b
        par  x y = case (par# x) of { _ -> lazy y }

GHC/Base.lhs
GHC/Conc.lhs
GHC/Err.lhs

index 45138d2..8abd593 100644 (file)
@@ -564,6 +564,14 @@ compareInt# x# y#
 id                     :: a -> a
 id x                   =  x
 
+-- lazy function; this is just the same as id, but its unfolding
+-- and strictness are over-ridden by the definition in MkId.lhs
+-- That way, it does not get inlined, and the strictness analyser
+-- sees it as lazy.  Then the worker/wrapper phase inlines it.
+-- Result: happiness
+lazy :: a -> a
+lazy x = x
+
 -- constant function
 const                  :: a -> b -> a
 const x _              =  x
index 54bdb25..e79662c 100644 (file)
@@ -48,7 +48,6 @@ module GHC.Conc
 import Data.Maybe
 
 import GHC.Base
-import GHC.Err         ( parError, seqError )
 import GHC.IOBase      ( IO(..), MVar(..) )
 import GHC.Base                ( Int(..) )
 import GHC.Exception    ( Exception(..), AsyncException(..) )
@@ -138,22 +137,19 @@ forkProcess = IO $ \s -> case (forkProcess# s) of (# s1, id #) -> (# s1, (I# id)
 --
 -- "pseq" is defined a bit weirdly (see below)
 --
--- The reason for the strange "0# -> parError" case is that
--- it fools the compiler into thinking that seq is non-strict in
--- its second argument (even if it inlines seq at the call site).
--- If it thinks seq is strict in "y", then it often evaluates
+-- The reason for the strange "lazy" call is that
+-- it fools the compiler into thinking that pseq  and par are non-strict in
+-- their second argument (even if it inlines pseq at the call site).
+-- If it thinks pseq is strict in "y", then it often evaluates
 -- "y" before "x", which is totally wrong.  
---
--- Just before converting from Core to STG there's a bit of magic
--- that recognises the seq# and eliminates the duff case.
 
 {-# INLINE pseq  #-}
 pseq :: a -> b -> b
-pseq  x y = case (seq#  x) of { 0# -> seqError; _ -> y }
+pseq  x y = x `seq` lazy y
 
 {-# INLINE par  #-}
 par :: a -> b -> b
-par  x y = case (par# x) of { 0# -> parError; _ -> y }
+par  x y = case (par# x) of { _ -> lazy y }
 \end{code}
 
 %************************************************************************
index 35b0716..43834aa 100644 (file)
@@ -29,8 +29,7 @@ module GHC.Err
        , recConError
        , runtimeError              -- :: Addr#  -> a   -- Addr# points to UTF8 encoded C string
 
-       , absentErr, parError       -- :: a
-       , seqError                  -- :: a
+       , absentErr                -- :: a
 
        , error                    -- :: String -> a
        , assertError              -- :: String -> Bool -> a -> a
@@ -74,11 +73,9 @@ Used for compiler-generated error message;
 encoding saves bytes of string junk.
 
 \begin{code}
-absentErr, parError, seqError :: a
+absentErr :: a
 
 absentErr = error "Oops! The program has entered an `absent' argument!\n"
-parError  = error "Oops! Entered GHCerr.parError (a GHC bug -- please report it!)\n"
-seqError  = error "Oops! Entered seqError (a GHC bug -- please report it!)\n"
 \end{code}
 
 \begin{code}