2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 \section[PrimOp]{Primitive operations (machine-level)}
8 PrimOp(..), allThePrimOps,
10 primOpTag, maxPrimOpTag, primOpOcc,
12 primOpOutOfLine, primOpNeedsWrapper,
13 primOpOkForSpeculation, primOpIsCheap, primOpIsDupable,
15 getPrimOpResultInfo, PrimOpResultInfo(..)
18 #include "HsVersions.h"
25 import OccName ( OccName, pprOccName, mkVarOccFS )
26 import TyCon ( TyCon, isPrimTyCon, tyConPrimRep, PrimRep(..) )
27 import Type ( Type, mkForAllTys, mkFunTy, mkFunTys, tyConAppTyCon,
29 import BasicTypes ( Arity, Boxity(..) )
34 %************************************************************************
36 \subsection[PrimOp-datatype]{Datatype for @PrimOp@ (an enumeration)}
38 %************************************************************************
40 These are in \tr{state-interface.verb} order.
46 #include "primop-data-decl.hs-incl"
49 Used for the Ord instance
52 primOpTag :: PrimOp -> Int
53 primOpTag op = iBox (tagOf_PrimOp op)
56 -- tagOf_PrimOp :: PrimOp -> FastInt
57 #include "primop-tag.hs-incl"
60 instance Eq PrimOp where
61 op1 == op2 = tagOf_PrimOp op1 ==# tagOf_PrimOp op2
63 instance Ord PrimOp where
64 op1 < op2 = tagOf_PrimOp op1 <# tagOf_PrimOp op2
65 op1 <= op2 = tagOf_PrimOp op1 <=# tagOf_PrimOp op2
66 op1 >= op2 = tagOf_PrimOp op1 >=# tagOf_PrimOp op2
67 op1 > op2 = tagOf_PrimOp op1 ># tagOf_PrimOp op2
68 op1 `compare` op2 | op1 < op2 = LT
72 instance Outputable PrimOp where
75 instance Show PrimOp where
76 showsPrec p op = showsPrecSDoc p (pprPrimOp op)
79 An @Enum@-derived list would be better; meanwhile... (ToDo)
82 allThePrimOps :: [PrimOp]
84 #include "primop-list.hs-incl"
87 %************************************************************************
89 \subsection[PrimOp-info]{The essential info about each @PrimOp@}
91 %************************************************************************
93 The @String@ in the @PrimOpInfos@ is the ``base name'' by which the user may
94 refer to the primitive operation. The conventional \tr{#}-for-
95 unboxed ops is added on later.
97 The reason for the funny characters in the names is so we do not
98 interfere with the programmer's Haskell name spaces.
100 We use @PrimKinds@ for the ``type'' information, because they're
101 (slightly) more convenient to use than @TyCons@.
104 = Dyadic OccName -- string :: T -> T -> T
106 | Monadic OccName -- string :: T -> T
108 | Compare OccName -- string :: T -> T -> Bool
111 | GenPrimOp OccName -- string :: \/a1..an . T1 -> .. -> Tk -> T
116 mkDyadic str ty = Dyadic (mkVarOccFS str) ty
117 mkMonadic str ty = Monadic (mkVarOccFS str) ty
118 mkCompare str ty = Compare (mkVarOccFS str) ty
119 mkGenPrimOp str tvs tys ty = GenPrimOp (mkVarOccFS str) tvs tys ty
122 %************************************************************************
124 \subsubsection{Strictness}
126 %************************************************************************
128 Not all primops are strict!
131 primOpStrictness :: PrimOp -> Arity -> StrictSig
132 -- See Demand.StrictnessInfo for discussion of what the results
133 -- The arity should be the arity of the primop; that's why
134 -- this function isn't exported.
135 #include "primop-strictness.hs-incl"
138 %************************************************************************
140 \subsubsection[PrimOp-comparison]{PrimOpInfo basic comparison ops}
142 %************************************************************************
144 @primOpInfo@ gives all essential information (from which everything
145 else, notably a type, can be constructed) for each @PrimOp@.
148 primOpInfo :: PrimOp -> PrimOpInfo
149 #include "primop-primop-info.hs-incl"
152 Here are a load of comments from the old primOp info:
154 A @Word#@ is an unsigned @Int#@.
156 @decodeFloat#@ is given w/ Integer-stuff (it's similar).
158 @decodeDouble#@ is given w/ Integer-stuff (it's similar).
160 Decoding of floating-point numbers is sorta Integer-related. Encoding
161 is done with plain ccalls now (see PrelNumExtra.lhs).
163 A @Weak@ Pointer is created by the @mkWeak#@ primitive:
165 mkWeak# :: k -> v -> f -> State# RealWorld
166 -> (# State# RealWorld, Weak# v #)
168 In practice, you'll use the higher-level
170 data Weak v = Weak# v
171 mkWeak :: k -> v -> IO () -> IO (Weak v)
173 The following operation dereferences a weak pointer. The weak pointer
174 may have been finalized, so the operation returns a result code which
175 must be inspected before looking at the dereferenced value.
177 deRefWeak# :: Weak# v -> State# RealWorld ->
178 (# State# RealWorld, v, Int# #)
180 Only look at v if the Int# returned is /= 0 !!
182 The higher-level op is
184 deRefWeak :: Weak v -> IO (Maybe v)
186 Weak pointers can be finalized early by using the finalize# operation:
188 finalizeWeak# :: Weak# v -> State# RealWorld ->
189 (# State# RealWorld, Int#, IO () #)
191 The Int# returned is either
193 0 if the weak pointer has already been finalized, or it has no
194 finalizer (the third component is then invalid).
196 1 if the weak pointer is still alive, with the finalizer returned
197 as the third component.
199 A {\em stable name/pointer} is an index into a table of stable name
200 entries. Since the garbage collector is told about stable pointers,
201 it is safe to pass a stable pointer to external systems such as C
205 makeStablePtr# :: a -> State# RealWorld -> (# State# RealWorld, StablePtr# a #)
206 freeStablePtr :: StablePtr# a -> State# RealWorld -> State# RealWorld
207 deRefStablePtr# :: StablePtr# a -> State# RealWorld -> (# State# RealWorld, a #)
208 eqStablePtr# :: StablePtr# a -> StablePtr# a -> Int#
211 It may seem a bit surprising that @makeStablePtr#@ is a @IO@
212 operation since it doesn't (directly) involve IO operations. The
213 reason is that if some optimisation pass decided to duplicate calls to
214 @makeStablePtr#@ and we only pass one of the stable pointers over, a
215 massive space leak can result. Putting it into the IO monad
216 prevents this. (Another reason for putting them in a monad is to
217 ensure correct sequencing wrt the side-effecting @freeStablePtr@
220 An important property of stable pointers is that if you call
221 makeStablePtr# twice on the same object you get the same stable
224 Note that we can implement @freeStablePtr#@ using @_ccall_@ (and,
225 besides, it's not likely to be used from Haskell) so it's not a
228 Question: Why @RealWorld@ - won't any instance of @_ST@ do the job? [ADR]
233 A stable name is like a stable pointer, but with three important differences:
235 (a) You can't deRef one to get back to the original object.
236 (b) You can convert one to an Int.
237 (c) You don't need to 'freeStableName'
239 The existence of a stable name doesn't guarantee to keep the object it
240 points to alive (unlike a stable pointer), hence (a).
244 (a) makeStableName always returns the same value for a given
245 object (same as stable pointers).
247 (b) if two stable names are equal, it implies that the objects
248 from which they were created were the same.
250 (c) stableNameToInt always returns the same Int for a given
254 -- HWL: The first 4 Int# in all par... annotations denote:
255 -- name, granularity info, size of result, degree of parallelism
256 -- Same structure as _seq_ i.e. returns Int#
257 -- KSW: v, the second arg in parAt# and parAtForNow#, is used only to determine
258 -- `the processor containing the expression v'; it is not evaluated
260 These primops are pretty wierd.
262 dataToTag# :: a -> Int (arg must be an evaluated data type)
263 tagToEnum# :: Int -> a (result type must be an enumerated type)
265 The constraints aren't currently checked by the front end, but the
266 code generator will fall over if they aren't satisfied.
270 primOpInfo op = pprPanic "primOpInfo:" (ppr op)
274 %************************************************************************
276 \subsubsection[PrimOp-ool]{Which PrimOps are out-of-line}
278 %************************************************************************
280 Some PrimOps need to be called out-of-line because they either need to
281 perform a heap check or they block.
285 primOpOutOfLine :: PrimOp -> Bool
286 #include "primop-out-of-line.hs-incl"
290 primOpOkForSpeculation
291 ~~~~~~~~~~~~~~~~~~~~~~
292 Sometimes we may choose to execute a PrimOp even though it isn't
293 certain that its result will be required; ie execute them
294 ``speculatively''. The same thing as ``cheap eagerness.'' Usually
295 this is OK, because PrimOps are usually cheap, but it isn't OK for
296 (a)~expensive PrimOps and (b)~PrimOps which can fail.
298 PrimOps that have side effects also should not be executed speculatively.
300 Ok-for-speculation also means that it's ok *not* to execute the
304 Here the result is not used, so we can discard the primop. Anything
305 that has side effects mustn't be dicarded in this way, of course!
307 See also @primOpIsCheap@ (below).
311 primOpOkForSpeculation :: PrimOp -> Bool
312 -- See comments with CoreUtils.exprOkForSpeculation
313 primOpOkForSpeculation op
314 = not (primOpHasSideEffects op || primOpOutOfLine op || primOpCanFail op)
320 @primOpIsCheap@, as used in \tr{SimplUtils.lhs}. For now (HACK
321 WARNING), we just borrow some other predicates for a
322 what-should-be-good-enough test. "Cheap" means willing to call it more
323 than once, and/or push it inside a lambda. The latter could change the
324 behaviour of 'seq' for primops that can fail, so we don't treat them as cheap.
327 primOpIsCheap :: PrimOp -> Bool
328 primOpIsCheap op = primOpOkForSpeculation op
329 -- In March 2001, we changed this to
330 -- primOpIsCheap op = False
331 -- thereby making *no* primops seem cheap. But this killed eta
332 -- expansion on case (x ==# y) of True -> \s -> ...
333 -- which is bad. In particular a loop like
336 -- loop i | i == n = return ()
337 -- | otherwise = bar i >> loop (i+1)
338 -- allocated a closure every time round because it doesn't eta expand.
340 -- The problem that originally gave rise to the change was
341 -- let x = a +# b *# c in x +# x
342 -- were we don't want to inline x. But primopIsCheap doesn't control
343 -- that (it's exprIsDupable that does) so the problem doesn't occur
344 -- even if primOpIsCheap sometimes says 'True'.
349 primOpIsDupable means that the use of the primop is small enough to
350 duplicate into different case branches. See CoreUtils.exprIsDupable.
353 primOpIsDupable :: PrimOp -> Bool
354 -- See comments with CoreUtils.exprIsDupable
355 -- We say it's dupable it isn't implemented by a C call with a wrapper
356 primOpIsDupable op = not (primOpNeedsWrapper op)
361 primOpCanFail :: PrimOp -> Bool
362 #include "primop-can-fail.hs-incl"
365 And some primops have side-effects and so, for example, must not be
369 primOpHasSideEffects :: PrimOp -> Bool
370 #include "primop-has-side-effects.hs-incl"
373 Inline primitive operations that perform calls need wrappers to save
374 any live variables that are stored in caller-saves registers.
377 primOpNeedsWrapper :: PrimOp -> Bool
378 #include "primop-needs-wrapper.hs-incl"
382 primOpType :: PrimOp -> Type -- you may want to use primOpSig instead
384 = case (primOpInfo op) of
385 Dyadic occ ty -> dyadic_fun_ty ty
386 Monadic occ ty -> monadic_fun_ty ty
387 Compare occ ty -> compare_fun_ty ty
389 GenPrimOp occ tyvars arg_tys res_ty ->
390 mkForAllTys tyvars (mkFunTys arg_tys res_ty)
392 primOpOcc :: PrimOp -> OccName
393 primOpOcc op = case (primOpInfo op) of
397 GenPrimOp occ _ _ _ -> occ
399 -- primOpSig is like primOpType but gives the result split apart:
400 -- (type variables, argument types, result type)
401 -- It also gives arity, strictness info
403 primOpSig :: PrimOp -> ([TyVar], [Type], Type, Arity, StrictSig)
405 = (tyvars, arg_tys, res_ty, arity, primOpStrictness op arity)
407 arity = length arg_tys
408 (tyvars, arg_tys, res_ty)
409 = case (primOpInfo op) of
410 Monadic occ ty -> ([], [ty], ty )
411 Dyadic occ ty -> ([], [ty,ty], ty )
412 Compare occ ty -> ([], [ty,ty], boolTy)
413 GenPrimOp occ tyvars arg_tys res_ty
414 -> (tyvars, arg_tys, res_ty)
418 data PrimOpResultInfo
419 = ReturnsPrim PrimRep
422 -- Some PrimOps need not return a manifest primitive or algebraic value
423 -- (i.e. they might return a polymorphic value). These PrimOps *must*
424 -- be out of line, or the code generator won't work.
426 getPrimOpResultInfo :: PrimOp -> PrimOpResultInfo
427 getPrimOpResultInfo op
428 = case (primOpInfo op) of
429 Dyadic _ ty -> ReturnsPrim (typePrimRep ty)
430 Monadic _ ty -> ReturnsPrim (typePrimRep ty)
431 Compare _ ty -> ReturnsAlg boolTyCon
432 GenPrimOp _ _ _ ty | isPrimTyCon tc -> ReturnsPrim (tyConPrimRep tc)
433 | otherwise -> ReturnsAlg tc
435 tc = tyConAppTyCon ty
436 -- All primops return a tycon-app result
437 -- The tycon can be an unboxed tuple, though, which
438 -- gives rise to a ReturnAlg
441 The commutable ops are those for which we will try to move constants
442 to the right hand side for strength reduction.
445 commutableOp :: PrimOp -> Bool
446 #include "primop-commutable.hs-incl"
451 dyadic_fun_ty ty = mkFunTys [ty, ty] ty
452 monadic_fun_ty ty = mkFunTy ty ty
453 compare_fun_ty ty = mkFunTys [ty, ty] boolTy
458 pprPrimOp :: PrimOp -> SDoc
459 pprPrimOp other_op = pprOccName (primOpOcc other_op)