From: simonpj Date: Tue, 18 Jun 2002 13:58:23 +0000 (+0000) Subject: [project @ 2002-06-18 13:58:22 by simonpj] X-Git-Tag: nhc98-1-18-release~973 X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=3d2db48412b8f469ba4943f95b0dce9354de4afb;p=ghc-base.git [project @ 2002-06-18 13:58:22 by simonpj] --------------------------------------- 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 } --- diff --git a/GHC/Base.lhs b/GHC/Base.lhs index 45138d2..8abd593 100644 --- a/GHC/Base.lhs +++ b/GHC/Base.lhs @@ -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 diff --git a/GHC/Conc.lhs b/GHC/Conc.lhs index 54bdb25..e79662c 100644 --- a/GHC/Conc.lhs +++ b/GHC/Conc.lhs @@ -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} %************************************************************************ diff --git a/GHC/Err.lhs b/GHC/Err.lhs index 35b0716..43834aa 100644 --- a/GHC/Err.lhs +++ b/GHC/Err.lhs @@ -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}