root/compiler/prelude/PrimOp.lhs

Revision 395ef284545bb5e7a57c180cc1f2a1b66fa30f37, 20.0 KB (checked in by Simon Marlow <marlowsd@…>, 4 months ago)

Revert "Add -faggressive-primops plus refactoring in CoreUtils?" (#5780)

This reverts commit 601c983dd0bada6b49bdadd8f172fd4eacac4b0c.

  • Property mode set to 100644
Line 
1%
2% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3%
4\section[PrimOp]{Primitive operations (machine-level)}
5
6\begin{code}
7module PrimOp (
8        PrimOp(..), allThePrimOps,
9        primOpType, primOpSig,
10        primOpTag, maxPrimOpTag, primOpOcc,
11
12        tagToEnumKey,
13
14        primOpOutOfLine, primOpCodeSize,
15        primOpOkForSpeculation, primOpOkForSideEffects,
16        primOpIsCheap,
17
18        getPrimOpResultInfo,  PrimOpResultInfo(..),
19
20        PrimCall(..)
21    ) where
22
23#include "HsVersions.h"
24
25import TysPrim
26import TysWiredIn
27
28import Demand
29import Var              ( TyVar )
30import OccName          ( OccName, pprOccName, mkVarOccFS )
31import TyCon            ( TyCon, isPrimTyCon, tyConPrimRep, PrimRep(..) )
32import Type             ( Type, mkForAllTys, mkFunTy, mkFunTys, tyConAppTyCon,
33                          typePrimRep )
34import BasicTypes       ( Arity, TupleSort(..) )
35import ForeignCall      ( CLabelString )
36import Unique           ( Unique, mkPrimOpIdUnique )
37import Outputable
38import FastTypes
39import FastString
40import Module           ( PackageId )
41\end{code}
42
43%************************************************************************
44%*                                                                      *
45\subsection[PrimOp-datatype]{Datatype for @PrimOp@ (an enumeration)}
46%*                                                                      *
47%************************************************************************
48
49These are in \tr{state-interface.verb} order.
50
51\begin{code}
52
53-- supplies:
54-- data PrimOp = ...
55#include "primop-data-decl.hs-incl"
56\end{code}
57
58Used for the Ord instance
59
60\begin{code}
61primOpTag :: PrimOp -> Int
62primOpTag op = iBox (tagOf_PrimOp op)
63
64-- supplies
65-- tagOf_PrimOp :: PrimOp -> FastInt
66#include "primop-tag.hs-incl"
67
68
69instance Eq PrimOp where
70    op1 == op2 = tagOf_PrimOp op1 ==# tagOf_PrimOp op2
71
72instance Ord PrimOp where
73    op1 <  op2 =  tagOf_PrimOp op1 <# tagOf_PrimOp op2
74    op1 <= op2 =  tagOf_PrimOp op1 <=# tagOf_PrimOp op2
75    op1 >= op2 =  tagOf_PrimOp op1 >=# tagOf_PrimOp op2
76    op1 >  op2 =  tagOf_PrimOp op1 ># tagOf_PrimOp op2
77    op1 `compare` op2 | op1 < op2  = LT
78                      | op1 == op2 = EQ
79                      | otherwise  = GT
80
81instance Outputable PrimOp where
82    ppr op = pprPrimOp op
83
84instance Show PrimOp where
85    showsPrec p op = showsPrecSDoc p (pprPrimOp op)
86\end{code}
87
88An @Enum@-derived list would be better; meanwhile... (ToDo)
89
90\begin{code}
91allThePrimOps :: [PrimOp]
92allThePrimOps =
93#include "primop-list.hs-incl"
94\end{code}
95
96\begin{code}
97tagToEnumKey :: Unique
98tagToEnumKey = mkPrimOpIdUnique (primOpTag TagToEnumOp)
99\end{code}
100
101
102
103%************************************************************************
104%*                                                                      *
105\subsection[PrimOp-info]{The essential info about each @PrimOp@}
106%*                                                                      *
107%************************************************************************
108
109The @String@ in the @PrimOpInfos@ is the ``base name'' by which the user may
110refer to the primitive operation.  The conventional \tr{#}-for-
111unboxed ops is added on later.
112
113The reason for the funny characters in the names is so we do not
114interfere with the programmer's Haskell name spaces.
115
116We use @PrimKinds@ for the ``type'' information, because they're
117(slightly) more convenient to use than @TyCons@.
118\begin{code}
119data PrimOpInfo
120  = Dyadic      OccName         -- string :: T -> T -> T
121                Type
122  | Monadic     OccName         -- string :: T -> T
123                Type
124  | Compare     OccName         -- string :: T -> T -> Bool
125                Type
126
127  | GenPrimOp   OccName         -- string :: \/a1..an . T1 -> .. -> Tk -> T
128                [TyVar]
129                [Type]
130                Type
131
132mkDyadic, mkMonadic, mkCompare :: FastString -> Type -> PrimOpInfo
133mkDyadic str  ty = Dyadic  (mkVarOccFS str) ty
134mkMonadic str ty = Monadic (mkVarOccFS str) ty
135mkCompare str ty = Compare (mkVarOccFS str) ty
136
137mkGenPrimOp :: FastString -> [TyVar] -> [Type] -> Type -> PrimOpInfo
138mkGenPrimOp str tvs tys ty = GenPrimOp (mkVarOccFS str) tvs tys ty
139\end{code}
140
141%************************************************************************
142%*                                                                      *
143\subsubsection{Strictness}
144%*                                                                      *
145%************************************************************************
146
147Not all primops are strict!
148
149\begin{code}
150primOpStrictness :: PrimOp -> Arity -> StrictSig
151        -- See Demand.StrictnessInfo for discussion of what the results
152        -- The arity should be the arity of the primop; that's why
153        -- this function isn't exported.
154#include "primop-strictness.hs-incl"
155\end{code}
156
157%************************************************************************
158%*                                                                      *
159\subsubsection[PrimOp-comparison]{PrimOpInfo basic comparison ops}
160%*                                                                      *
161%************************************************************************
162
163@primOpInfo@ gives all essential information (from which everything
164else, notably a type, can be constructed) for each @PrimOp@.
165
166\begin{code}
167primOpInfo :: PrimOp -> PrimOpInfo
168#include "primop-primop-info.hs-incl"
169\end{code}
170
171Here are a load of comments from the old primOp info:
172
173A @Word#@ is an unsigned @Int#@.
174
175@decodeFloat#@ is given w/ Integer-stuff (it's similar).
176
177@decodeDouble#@ is given w/ Integer-stuff (it's similar).
178
179Decoding of floating-point numbers is sorta Integer-related.  Encoding
180is done with plain ccalls now (see PrelNumExtra.lhs).
181
182A @Weak@ Pointer is created by the @mkWeak#@ primitive:
183
184        mkWeak# :: k -> v -> f -> State# RealWorld
185                        -> (# State# RealWorld, Weak# v #)
186
187In practice, you'll use the higher-level
188
189        data Weak v = Weak# v
190        mkWeak :: k -> v -> IO () -> IO (Weak v)
191
192The following operation dereferences a weak pointer.  The weak pointer
193may have been finalized, so the operation returns a result code which
194must be inspected before looking at the dereferenced value.
195
196        deRefWeak# :: Weak# v -> State# RealWorld ->
197                        (# State# RealWorld, v, Int# #)
198
199Only look at v if the Int# returned is /= 0 !!
200
201The higher-level op is
202
203        deRefWeak :: Weak v -> IO (Maybe v)
204
205Weak pointers can be finalized early by using the finalize# operation:
206
207        finalizeWeak# :: Weak# v -> State# RealWorld ->
208                           (# State# RealWorld, Int#, IO () #)
209
210The Int# returned is either
211
212        0 if the weak pointer has already been finalized, or it has no
213          finalizer (the third component is then invalid).
214
215        1 if the weak pointer is still alive, with the finalizer returned
216          as the third component.
217
218A {\em stable name/pointer} is an index into a table of stable name
219entries.  Since the garbage collector is told about stable pointers,
220it is safe to pass a stable pointer to external systems such as C
221routines.
222
223\begin{verbatim}
224makeStablePtr#  :: a -> State# RealWorld -> (# State# RealWorld, StablePtr# a #)
225freeStablePtr   :: StablePtr# a -> State# RealWorld -> State# RealWorld
226deRefStablePtr# :: StablePtr# a -> State# RealWorld -> (# State# RealWorld, a #)
227eqStablePtr#    :: StablePtr# a -> StablePtr# a -> Int#
228\end{verbatim}
229
230It may seem a bit surprising that @makeStablePtr#@ is a @IO@
231operation since it doesn't (directly) involve IO operations.  The
232reason is that if some optimisation pass decided to duplicate calls to
233@makeStablePtr#@ and we only pass one of the stable pointers over, a
234massive space leak can result.  Putting it into the IO monad
235prevents this.  (Another reason for putting them in a monad is to
236ensure correct sequencing wrt the side-effecting @freeStablePtr@
237operation.)
238
239An important property of stable pointers is that if you call
240makeStablePtr# twice on the same object you get the same stable
241pointer back.
242
243Note that we can implement @freeStablePtr#@ using @_ccall_@ (and,
244besides, it's not likely to be used from Haskell) so it's not a
245primop.
246
247Question: Why @RealWorld@ - won't any instance of @_ST@ do the job? [ADR]
248
249Stable Names
250~~~~~~~~~~~~
251
252A stable name is like a stable pointer, but with three important differences:
253
254        (a) You can't deRef one to get back to the original object.
255        (b) You can convert one to an Int.
256        (c) You don't need to 'freeStableName'
257
258The existence of a stable name doesn't guarantee to keep the object it
259points to alive (unlike a stable pointer), hence (a).
260
261Invariants:
262
263        (a) makeStableName always returns the same value for a given
264            object (same as stable pointers).
265
266        (b) if two stable names are equal, it implies that the objects
267            from which they were created were the same.
268
269        (c) stableNameToInt always returns the same Int for a given
270            stable name.
271
272
273-- HWL: The first 4 Int# in all par... annotations denote:
274--   name, granularity info, size of result, degree of parallelism
275--      Same  structure as _seq_ i.e. returns Int#
276-- KSW: v, the second arg in parAt# and parAtForNow#, is used only to determine
277--   `the processor containing the expression v'; it is not evaluated
278
279These primops are pretty wierd.
280
281        dataToTag# :: a -> Int    (arg must be an evaluated data type)
282        tagToEnum# :: Int -> a    (result type must be an enumerated type)
283
284The constraints aren't currently checked by the front end, but the
285code generator will fall over if they aren't satisfied.
286
287%************************************************************************
288%*                                                                      *
289            Which PrimOps are out-of-line
290%*                                                                      *
291%************************************************************************
292
293Some PrimOps need to be called out-of-line because they either need to
294perform a heap check or they block.
295
296
297\begin{code}
298primOpOutOfLine :: PrimOp -> Bool
299#include "primop-out-of-line.hs-incl"
300\end{code}
301
302
303%************************************************************************
304%*                                                                      *
305            Failure and side effects
306%*                                                                      *
307%************************************************************************
308
309Note [PrimOp can_fail and has_side_effects]
310~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
311Both can_fail and has_side_effects mean that the primop has
312some effect that is not captured entirely by its result value.
313
314   ----------  has_side_effects ---------------------
315   Has some imperative side effect, perhaps on the world (I/O),
316   or perhaps on some mutable data structure (writeIORef).
317   Generally speaking all such primops have a type like
318      State -> input -> (State, output)
319   so the state token guarantees ordering, and also ensures
320   that the primop is executed even if 'output' is discarded.
321
322   ----------  can_fail ----------------------------
323   Can fail with a seg-fault or divide-by-zero error on some elements
324   of its input domain.  Main examples:
325      division (fails on zero demoninator
326      array indexing (fails if the index is out of bounds)
327   However (ASSUMPTION), these can_fail primops are ALWAYS surrounded
328   with a test that checks for the bad cases. 
329
330Consequences:
331
332* You can discard a can_fail primop, or float it _inwards_.
333  But you cannot float it _outwards_, lest you escape the
334  dynamic scope of the test.  Example:
335      case d ># 0# of
336        True  -> case x /# d of r -> r +# 1
337        False -> 0
338  Here we must not float the case outwards to give
339      case x/# d of r ->
340      case d ># 0# of
341        True  -> r +# 1
342        False -> 0
343
344* I believe that exactly the same rules apply to a has_side_effects
345  primop; you can discard it (remember, the state token will keep
346  it alive if necessary), or float it in, but not float it out.
347
348  Example of the latter
349       if blah then let! s1 = writeMutVar s0 v True in s1
350               else s0
351  Notice that s0 is mentioned in both branches of the 'if', but
352  only one of these two will actually be consumed.  But if we
353  float out to
354      let! s1 = writeMutVar s0 v True
355      in if blah then s1 else s0
356  the writeMutVar will be performed in both branches, which is
357  utterly wrong.
358
359* You cannot duplicate a has_side_effect primop.  You might wonder
360  how this can occur given the state token threading, but just look
361  at Control.Monad.ST.Lazy.Imp.strictToLazy!  We get something like
362  this
363        p = case readMutVar# s v of
364              (# s', r #) -> (S# s', r)
365        s' = case p of (s', r) -> s'
366        r  = case p of (s', r) -> r
367
368  (All these bindings are boxed.)  If we inline p at its two call
369  sites, we get a catastrophe: because the read is performed once when
370  s' is demanded, and once when 'r' is demanded, which may be much
371  later.  Utterly wrong.  Trac #3207 is real example of this happening.
372
373  However, it's fine to duplicate a can_fail primop.  That is
374  the difference between can_fail and has_side_effects.
375
376            can_fail     has_side_effects
377Discard        YES           YES
378Float in       YES           YES
379Float out      NO            NO
380Duplicate      YES           NO
381
382How do we achieve these effects?
383
384Note [primOpOkForSpeculation]
385  * The "no-float-out" thing is achieved by ensuring that we never
386    let-bind a can_fail or has_side_effects primop.  The RHS of a
387    let-binding (which can float in and out freely) satisfies
388    exprOkForSpeculation.  And exprOkForSpeculation is false of
389    can_fail and no_side_effect.
390
391  * So can_fail and no_side_effect primops will appear only as the
392    scrutinees of cases, and that's why the FloatIn pass is capable
393    of floating case bindings inwards.
394
395  * The no-duplicate thing is done via primOpIsCheap, by making
396    has_side_effects things (very very very) not-cheap!
397
398
399\begin{code}
400primOpHasSideEffects :: PrimOp -> Bool
401#include "primop-has-side-effects.hs-incl"
402
403primOpCanFail :: PrimOp -> Bool
404#include "primop-can-fail.hs-incl"
405
406primOpOkForSpeculation :: PrimOp -> Bool
407  -- See Note [primOpOkForSpeculation and primOpOkForFloatOut]
408  -- See comments with CoreUtils.exprOkForSpeculation
409primOpOkForSpeculation op
410  = not (primOpHasSideEffects op || primOpOutOfLine op || primOpCanFail op)
411
412primOpOkForSideEffects :: PrimOp -> Bool
413primOpOkForSideEffects op
414  = not (primOpHasSideEffects op)
415\end{code}
416
417
418Note [primOpIsCheap]
419~~~~~~~~~~~~~~~~~~~~
420@primOpIsCheap@, as used in \tr{SimplUtils.lhs}.  For now (HACK
421WARNING), we just borrow some other predicates for a
422what-should-be-good-enough test.  "Cheap" means willing to call it more
423than once, and/or push it inside a lambda.  The latter could change the
424behaviour of 'seq' for primops that can fail, so we don't treat them as cheap.
425
426\begin{code}
427primOpIsCheap :: PrimOp -> Bool
428primOpIsCheap op = primOpOkForSpeculation op
429-- In March 2001, we changed this to
430--      primOpIsCheap op = False
431-- thereby making *no* primops seem cheap.  But this killed eta
432-- expansion on case (x ==# y) of True -> \s -> ...
433-- which is bad.  In particular a loop like
434--      doLoop n = loop 0
435--     where
436--         loop i | i == n    = return ()
437--                | otherwise = bar i >> loop (i+1)
438-- allocated a closure every time round because it doesn't eta expand.
439--
440-- The problem that originally gave rise to the change was
441--      let x = a +# b *# c in x +# x
442-- were we don't want to inline x. But primopIsCheap doesn't control
443-- that (it's exprIsDupable that does) so the problem doesn't occur
444-- even if primOpIsCheap sometimes says 'True'.
445\end{code}
446
447
448%************************************************************************
449%*                                                                      *
450               PrimOp code size
451%*                                                                      *
452%************************************************************************
453
454primOpCodeSize
455~~~~~~~~~~~~~~
456Gives an indication of the code size of a primop, for the purposes of
457calculating unfolding sizes; see CoreUnfold.sizeExpr.
458
459\begin{code}
460primOpCodeSize :: PrimOp -> Int
461#include "primop-code-size.hs-incl"
462
463primOpCodeSizeDefault :: Int
464primOpCodeSizeDefault = 1
465  -- CoreUnfold.primOpSize already takes into account primOpOutOfLine
466  -- and adds some further costs for the args in that case.
467
468primOpCodeSizeForeignCall :: Int
469primOpCodeSizeForeignCall = 4
470\end{code}
471
472
473%************************************************************************
474%*                                                                      *
475               PrimOp types
476%*                                                                      *
477%************************************************************************
478
479\begin{code}
480primOpType :: PrimOp -> Type  -- you may want to use primOpSig instead
481primOpType op
482  = case primOpInfo op of
483    Dyadic  _occ ty -> dyadic_fun_ty ty
484    Monadic _occ ty -> monadic_fun_ty ty
485    Compare _occ ty -> compare_fun_ty ty
486
487    GenPrimOp _occ tyvars arg_tys res_ty ->
488        mkForAllTys tyvars (mkFunTys arg_tys res_ty)
489
490primOpOcc :: PrimOp -> OccName
491primOpOcc op = case primOpInfo op of
492               Dyadic    occ _     -> occ
493               Monadic   occ _     -> occ
494               Compare   occ _     -> occ
495               GenPrimOp occ _ _ _ -> occ
496
497-- primOpSig is like primOpType but gives the result split apart:
498-- (type variables, argument types, result type)
499-- It also gives arity, strictness info
500
501primOpSig :: PrimOp -> ([TyVar], [Type], Type, Arity, StrictSig)
502primOpSig op
503  = (tyvars, arg_tys, res_ty, arity, primOpStrictness op arity)
504  where
505    arity = length arg_tys
506    (tyvars, arg_tys, res_ty)
507      = case (primOpInfo op) of
508        Monadic   _occ ty                    -> ([],     [ty],    ty    )
509        Dyadic    _occ ty                    -> ([],     [ty,ty], ty    )
510        Compare   _occ ty                    -> ([],     [ty,ty], boolTy)
511        GenPrimOp _occ tyvars arg_tys res_ty -> (tyvars, arg_tys, res_ty)
512\end{code}
513
514\begin{code}
515data PrimOpResultInfo
516  = ReturnsPrim     PrimRep
517  | ReturnsAlg      TyCon
518
519-- Some PrimOps need not return a manifest primitive or algebraic value
520-- (i.e. they might return a polymorphic value).  These PrimOps *must*
521-- be out of line, or the code generator won't work.
522
523getPrimOpResultInfo :: PrimOp -> PrimOpResultInfo
524getPrimOpResultInfo op
525  = case (primOpInfo op) of
526      Dyadic  _ ty                        -> ReturnsPrim (typePrimRep ty)
527      Monadic _ ty                        -> ReturnsPrim (typePrimRep ty)
528      Compare _ _                         -> ReturnsAlg boolTyCon
529      GenPrimOp _ _ _ ty | isPrimTyCon tc -> ReturnsPrim (tyConPrimRep tc)
530                         | otherwise      -> ReturnsAlg tc
531                         where
532                           tc = tyConAppTyCon ty
533                        -- All primops return a tycon-app result
534                        -- The tycon can be an unboxed tuple, though, which
535                        -- gives rise to a ReturnAlg
536\end{code}
537
538We do not currently make use of whether primops are commutable.
539
540We used to try to move constants to the right hand side for strength
541reduction.
542
543\begin{code}
544{-
545commutableOp :: PrimOp -> Bool
546#include "primop-commutable.hs-incl"
547-}
548\end{code}
549
550Utils:
551\begin{code}
552dyadic_fun_ty, monadic_fun_ty, compare_fun_ty :: Type -> Type
553dyadic_fun_ty  ty = mkFunTys [ty, ty] ty
554monadic_fun_ty ty = mkFunTy  ty ty
555compare_fun_ty ty = mkFunTys [ty, ty] boolTy
556\end{code}
557
558Output stuff:
559\begin{code}
560pprPrimOp  :: PrimOp -> SDoc
561pprPrimOp other_op = pprOccName (primOpOcc other_op)
562\end{code}
563
564
565%************************************************************************
566%*                                                                      *
567\subsubsection[PrimCall]{User-imported primitive calls}
568%*                                                                      *
569%************************************************************************
570
571\begin{code}
572data PrimCall = PrimCall CLabelString PackageId
573
574instance Outputable PrimCall where
575  ppr (PrimCall lbl pkgId)
576        = text "__primcall" <+> ppr pkgId <+> ppr lbl
577
578\end{code}
Note: See TracBrowser for help on using the browser.