import BasicTypes ( Arity, StrictnessMark(..), isMarkedUnboxed, isMarkedStrict )
-import TysPrim ( openAlphaTyVars, alphaTyVar, alphaTy,
+import TysPrim ( openAlphaTyVars, alphaTyVar, alphaTy, betaTyVar, betaTy,
intPrimTy, realWorldStatePrimTy, addrPrimTy
)
import TysWiredIn ( charTy, mkListTy )
-import PrelRules ( primOpRule )
+import PrelRules ( primOpRules )
import Rules ( addRule )
import TcType ( Type, ThetaType, mkDictTy, mkPredTys, mkTyConApp,
mkTyVarTys, mkClassPred, tcEqPred,
, realWorldPrimId
, unsafeCoerceId
, getTagId
+ , seqId
]
\end{code}
`setArityInfo` arity
`setNewStrictnessInfo` Just strict_sig
- arity = dataConRepArity data_con
+ arity = dataConRepArity data_con
+
strict_sig = mkStrictSig (mkTopDmdType (replicate arity topDmd) cpr_info)
+ -- Notice that we do *not* say the worker is strict
+ -- even if the data constructor is declared strict
+ -- e.g. data T = MkT !(Int,Int)
+ -- Why? Because the *wrapper* is strict (and its unfolding has case
+ -- expresssions that do the evals) but the *worker* itself is not.
+ -- If we pretend it is strict then when we see
+ -- case x of y -> $wMkT y
+ -- the simplifier thinks that y is "sure to be evaluated" (because
+ -- $wMkT is strict) and drops the case. No, $wMkT is not strict.
+ --
+ -- When the simplifer sees a pattern
+ -- case e of MkT x -> ...
+ -- it uses the dataConRepStrictness of MkT to mark x as evaluated;
+ -- but that's fine... dataConRepStrictness comes from the data con
+ -- not from the worker Id.
tycon = dataConTyCon data_con
cpr_info | isProductTyCon tycon &&
-- applications are treated as values
`setNewStrictnessInfo` Just wrap_sig
- wrap_ty = mkForAllTys all_tyvars $
- mkFunTys all_arg_tys
- result_ty
+ wrap_ty = mkForAllTys all_tyvars (mkFunTys all_arg_tys result_ty)
res_info = strictSigResInfo (idNewStrictness work_id)
wrap_sig = mkStrictSig (mkTopDmdType (replicate arity topDmd) res_info)
`setNewStrictnessInfo` Just (mkNewStrictnessInfo id arity strict_info NoCPRInfo)
-- Until we modify the primop generation code
- rules = maybe emptyCoreRules (addRule emptyCoreRules id)
- (primOpRule prim_op)
+ rules = foldl (addRule id) emptyCoreRules (primOpRules prim_op)
-- For each ccall we manufacture a separate CCallOpId, giving it
%* *
%************************************************************************
-These two can't be defined in Haskell.
+These Ids can't be defined in Haskell. They could be defined in
+unfoldings in PrelGHC.hi-boot, but we'd have to ensure that they
+were definitely, definitely inlined, because there is no curried
+identifier for them. Thats what mkCompulsoryUnfolding does.
+If we had a way to get a compulsory unfolding from an interface file,
+we could do that, but we don't right now.
unsafeCoerce# isn't so much a PrimOp as a phantom identifier, that
just gets expanded into a type coercion wherever it occurs. Hence we
[x] = mkTemplateLocals [openAlphaTy]
rhs = mkLams [openAlphaTyVar,openBetaTyVar,x] $
Note (Coerce openBetaTy openAlphaTy) (Var x)
-\end{code}
+seqId
+ = pcMiscPrelId seqIdKey pREL_GHC SLIT("seq") ty info
+ where
+ info = noCafNoTyGenIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs
+
+
+ ty = mkForAllTys [alphaTyVar,betaTyVar]
+ (mkFunTy alphaTy (mkFunTy betaTy betaTy))
+ [x,y] = mkTemplateLocals [alphaTy, betaTy]
+ rhs = mkLams [alphaTyVar,betaTyVar,x] (Case (Var x) x [(DEFAULT, [], Var y)])
+\end{code}
@getTag#@ is another function which can't be defined in Haskell. It needs to
evaluate its argument and call the dataToTag# primitive.
% -----------------------------------------------------------------------------
-% $Id: PrelConc.lhs,v 1.24 2001/05/18 16:54:05 simonmar Exp $
+% $Id: PrelConc.lhs,v 1.25 2001/09/14 15:49:56 simonpj Exp $
%
% (c) The University of Glasgow, 1994-2000
%
, killThread -- :: ThreadId -> IO ()
, throwTo -- :: ThreadId -> Exception -> IO ()
, par -- :: a -> b -> b
- , seq -- :: a -> b -> b
+ , pseq -- :: a -> b -> b
, yield -- :: IO ()
-- Waiting
import PrelBase ( Int(..) )
import PrelException ( Exception(..), AsyncException(..) )
-infixr 0 `par`, `seq`
+infixr 0 `par`, `pseq`
\end{code}
%************************************************************************
yield = IO $ \s ->
case (yield# s) of s1 -> (# s1, () #)
--- "seq" is defined a bit weirdly (see below)
+-- Nota Bene: 'pseq' used to be 'seq'
+-- but 'seq' is now defined in PrelGHC
+--
+-- "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
-- Just before converting from Core to STG there's a bit of magic
-- that recognises the seq# and eliminates the duff case.
-{-# INLINE seq #-}
-seq :: a -> b -> b
-seq x y = case (seq# x) of { 0# -> seqError; _ -> y }
+{-# INLINE pseq #-}
+pseq :: a -> b -> b
+pseq x y = case (seq# x) of { 0# -> seqError; _ -> y }
{-# INLINE par #-}
par :: a -> b -> b