X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2FcodeGen%2FSMRep.lhs;h=92b9513d565793d1805f52e540f04ad987235e27;hb=423d477bfecd490de1449c59325c8776f91d7aac;hp=4adcfd7f13b79e1409d55002935239ec61cb9878;hpb=6c381e873e222417d9a67aeec77b9555eca7b7a8;p=ghc-hetmet.git diff --git a/ghc/compiler/codeGen/SMRep.lhs b/ghc/compiler/codeGen/SMRep.lhs index 4adcfd7..92b9513 100644 --- a/ghc/compiler/codeGen/SMRep.lhs +++ b/ghc/compiler/codeGen/SMRep.lhs @@ -1,5 +1,5 @@ % -% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996 +% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 % \section[SMRep]{Storage manager representations of closure} @@ -7,244 +7,348 @@ This is here, rather than in ClosureInfo, just to keep nhc happy. Other modules should access this info through ClosureInfo. \begin{code} -#include "HsVersions.h" - module SMRep ( - SMRep(..), SMSpecRepKind(..), SMUpdateKind(..), - getSMInfoStr, getSMInitHdrStr, getSMUpdInplaceHdrStr, - ltSMRepHdr + -- Words and bytes + StgWord, StgHalfWord, + hALF_WORD_SIZE, hALF_WORD_SIZE_IN_BITS, + WordOff, ByteOff, + + -- Argument/return representations + CgRep(..), nonVoidArg, + argMachRep, primRepToCgRep, primRepHint, + isFollowableArg, isVoidArg, + isFloatingArg, isNonPtrArg, is64BitArg, + separateByPtrFollowness, + cgRepSizeW, cgRepSizeB, + retAddrSizeW, + + typeCgRep, idCgRep, tyConCgRep, typeHint, + + -- Closure repesentation + SMRep(..), ClosureType(..), + isStaticRep, + fixedHdrSize, arrWordsHdrSize, arrPtrsHdrSize, + profHdrSize, + tablesNextToCode, + smRepClosureType, smRepClosureTypeInt, + + rET_SMALL, rET_VEC_SMALL, rET_BIG, rET_VEC_BIG ) where -import Ubiq{-uitous-} +#include "HsVersions.h" +#include "../includes/MachDeps.h" -import Pretty ( ppStr ) -import Util ( panic ) +import Id ( Id, idType ) +import Type ( Type, typePrimRep, PrimRep(..) ) +import TyCon ( TyCon, tyConPrimRep ) +import MachOp ( MachRep(..), MachHint(..), wordRep ) +import CmdLineOpts ( opt_SccProfilingOn, opt_GranMacros, opt_Unregisterised ) +import Constants +import Outputable + +import DATA_WORD \end{code} + %************************************************************************ %* * -\subsubsection[SMRep-datatype]{@SMRep@---storage manager representation} + Words and bytes +%* * +%************************************************************************ + +\begin{code} +type WordOff = Int -- Word offset, or word count +type ByteOff = Int -- Byte offset, or byte count +\end{code} + +StgWord is a type representing an StgWord on the target platform. + +\begin{code} +#if SIZEOF_HSWORD == 4 +type StgWord = Word32 +type StgHalfWord = Word16 +hALF_WORD_SIZE = 2 :: ByteOff +hALF_WORD_SIZE_IN_BITS = 16 :: Int +#elif SIZEOF_HSWORD == 8 +type StgWord = Word64 +type StgHalfWord = Word32 +hALF_WORD_SIZE = 4 :: ByteOff +hALF_WORD_SIZE_IN_BITS = 32 :: Int +#else +#error unknown SIZEOF_HSWORD +#endif +\end{code} + + +%************************************************************************ +%* * + CgRep %* * %************************************************************************ -Ways in which a closure may be represented by the storage manager; -this list slavishly follows the storage-manager interface document. +An CgRep is an abstraction of a Type which tells the code generator +all it needs to know about the calling convention for arguments (and +results) of that type. In particular, the ArgReps of a function's +arguments are used to decide which of the RTS's generic apply +functions to call when applying an unknown function. + +It contains more information than the back-end data type MachRep, +so one can easily convert from CgRep -> MachRep. (Except that +there's no MachRep for a VoidRep.) + +It distinguishes + pointers from non-pointers (we sort the pointers together + when building closures) + + void from other types: a void argument is different from no argument + +All 64-bit types map to the same CgRep, because they're passed in the +same register, but a PtrArg is still different from an NonPtrArg +because the function's entry convention has to take into account the +pointer-hood of arguments for the purposes of describing the stack on +entry to the garbage collector. \begin{code} -data SMSpecRepKind - = SpecRep -- Normal Spec representation +data CgRep + = VoidArg -- Void + | PtrArg -- Word-sized Ptr + | NonPtrArg -- Word-sized non-pointer + | LongArg -- 64-bit non-pointer + | FloatArg -- 32-bit float + | DoubleArg -- 64-bit float + deriving Eq + +instance Outputable CgRep where + ppr VoidArg = ptext SLIT("V_") + ppr PtrArg = ptext SLIT("P_") + ppr NonPtrArg = ptext SLIT("I_") + ppr LongArg = ptext SLIT("L_") + ppr FloatArg = ptext SLIT("F_") + ppr DoubleArg = ptext SLIT("D_") + +argMachRep :: CgRep -> MachRep +argMachRep PtrArg = wordRep +argMachRep NonPtrArg = wordRep +argMachRep LongArg = I64 +argMachRep FloatArg = F32 +argMachRep DoubleArg = F64 +argMachRep VoidArg = panic "argMachRep:VoidRep" + +primRepToCgRep :: PrimRep -> CgRep +primRepToCgRep VoidRep = VoidArg +primRepToCgRep PtrRep = PtrArg +primRepToCgRep IntRep = NonPtrArg +primRepToCgRep WordRep = NonPtrArg +primRepToCgRep Int64Rep = LongArg +primRepToCgRep Word64Rep = LongArg +primRepToCgRep AddrRep = NonPtrArg +primRepToCgRep FloatRep = FloatArg +primRepToCgRep DoubleRep = DoubleArg + +primRepHint :: PrimRep -> MachHint +primRepHint VoidRep = panic "primRepHint:VoidRep" +primRepHint PtrRep = PtrHint +primRepHint IntRep = SignedHint +primRepHint WordRep = NoHint +primRepHint Int64Rep = SignedHint +primRepHint Word64Rep = NoHint +primRepHint AddrRep = PtrHint -- NB! PtrHint, but NonPtrArg +primRepHint FloatRep = FloatHint +primRepHint DoubleRep = FloatHint + +idCgRep :: Id -> CgRep +idCgRep = typeCgRep . idType + +tyConCgRep :: TyCon -> CgRep +tyConCgRep = primRepToCgRep . tyConPrimRep + +typeCgRep :: Type -> CgRep +typeCgRep = primRepToCgRep . typePrimRep + +typeHint :: Type -> MachHint +typeHint = primRepHint . typePrimRep +\end{code} - | ConstantRep -- Common me up with single global copy - -- Used for nullary constructors +Whether or not the thing is a pointer that the garbage-collector +should follow. Or, to put it another (less confusing) way, whether +the object in question is a heap object. - | CharLikeRep -- Common me up with entry from global table +Depending on the outcome, this predicate determines what stack +the pointer/object possibly will have to be saved onto, and the +computation of GC liveness info. - | IntLikeRep -- Common me up with entry from global table, - -- if the intlike field is in range. +\begin{code} +isFollowableArg :: CgRep -> Bool -- True <=> points to a heap object +isFollowableArg PtrArg = True +isFollowableArg other = False + +isVoidArg :: CgRep -> Bool +isVoidArg VoidArg = True +isVoidArg other = False + +nonVoidArg :: CgRep -> Bool +nonVoidArg VoidArg = False +nonVoidArg other = True + +-- isFloatingArg is used to distinguish @Double@ and @Float@ which +-- cause inadvertent numeric conversions if you aren't jolly careful. +-- See codeGen/CgCon:cgTopRhsCon. + +isFloatingArg :: CgRep -> Bool +isFloatingArg DoubleArg = True +isFloatingArg FloatArg = True +isFloatingArg _ = False + +isNonPtrArg :: CgRep -> Bool +-- Identify anything which is one word large and not a pointer. +isNonPtrArg NonPtrArg = True +isNonPtrArg other = False + +is64BitArg :: CgRep -> Bool +is64BitArg LongArg = True +is64BitArg _ = False +\end{code} + +\begin{code} +separateByPtrFollowness :: [(CgRep,a)] -> ([(CgRep,a)], [(CgRep,a)]) +-- Returns (ptrs, non-ptrs) +separateByPtrFollowness things + = sep_things things [] [] + -- accumulating params for follow-able and don't-follow things... + where + sep_things [] bs us = (reverse bs, reverse us) + sep_things ((PtrArg,a):ts) bs us = sep_things ts ((PtrArg,a):bs) us + sep_things (t :ts) bs us = sep_things ts bs (t:us) +\end{code} -data SMUpdateKind - = SMNormalForm -- Normal form, no update - | SMSingleEntry -- Single entry thunk, non-updatable - | SMUpdatable -- Shared thunk, updatable +\begin{code} +cgRepSizeB :: CgRep -> ByteOff +cgRepSizeB DoubleArg = dOUBLE_SIZE +cgRepSizeB LongArg = wORD64_SIZE +cgRepSizeB VoidArg = 0 +cgRepSizeB _ = wORD_SIZE + +cgRepSizeW :: CgRep -> ByteOff +cgRepSizeW DoubleArg = dOUBLE_SIZE `quot` wORD_SIZE +cgRepSizeW LongArg = wORD64_SIZE `quot` wORD_SIZE +cgRepSizeW VoidArg = 0 +cgRepSizeW _ = 1 + +retAddrSizeW :: WordOff +retAddrSizeW = 1 -- One word +\end{code} + +%************************************************************************ +%* * +\subsubsection[SMRep-datatype]{@SMRep@---storage manager representation} +%* * +%************************************************************************ +\begin{code} data SMRep - = StaticRep -- Don't move me, Oh garbage collector! - -- Used for all statically-allocated closures. - Int -- # ptr words (useful for interpreter, debugger, etc) - Int -- # non-ptr words - - | SpecialisedRep -- GC routines know size etc - -- All have same _HS = SPEC_HS and no _VHS - SMSpecRepKind -- Which kind of specialised representation - Int -- # ptr words - Int -- # non-ptr words - SMUpdateKind -- Updatable? - - | GenericRep -- GC routines consult sizes in info tbl - Int -- # ptr words - Int -- # non-ptr words - SMUpdateKind -- Updatable? - - | BigTupleRep -- All ptrs, size in var-hdr field - -- Used for big tuples - Int -- # ptr words - - | DataRep -- All non-ptrs, size in var-hdr field - -- Used for arbitrary-precision integers, strings - Int -- # non-ptr words - - | DynamicRep -- Size and # ptrs in var-hdr field - -- Used by RTS for partial applications - - | BlackHoleRep -- for black hole closures - - | PhantomRep -- for "phantom" closures that only exist in registers - - | MuTupleRep -- All ptrs, size in var-hdr field - -- Used for mutable tuples - Int -- # ptr words - -{- Mattson review: - -To: simonpj@dcs.gla.ac.uk, partain@dcs.gla.ac.uk -Cc: kh@dcs.gla.ac.uk, trinder@dcs.gla.ac.uk, areid@dcs.gla.ac.uk -Subject: Correct me if I'm wrong... -Date: Fri, 17 Feb 1995 18:09:00 +0000 -From: Jim Mattson - -BigTupleRep == TUPLE - - Never generated by the compiler, and only used in the RTS when - mutuples don't require special attention at GC time (e.g. 2s) - When it is used, it is a primitive object (never entered). - May be mutable...probably should never be used in the parallel - system, since we need to distinguish mutables from immutables when - deciding whether to copy or move closures across processors. - -DataRep == DATA (aka MutableByteArray & ByteArray) - Never generated by the compiler, and only used in the RTS for - ArrayOfData. Always a primitive object (never entered). May - be mutable...though we don't distinguish between mutable and - immutable data arrays in the sequential world, it would probably - be useful in the parallel world to know when it is safe to just - copy one of these. I believe the hooks are in place for changing - the InfoPtr on a MutableByteArray when it's frozen to a ByteArray - if we want to do so. - -DynamicRep == DYN - Never generated by the compiler, and only used in the RTS for - PAPs and the Stable Pointer table. PAPs are non-primitive, - non-updatable, normal-form objects, but the SPT is a primitive, - mutable object. At the moment, there is no SPT in the parallel - world. Presumably, it would be possible to have an SPT on each - processor, and we could identify a stable pointer as a (processor, - SPT-entry) pair, but would it be worth it? - -MuTupleRep == MUTUPLE - Never generated by the compiler, and only used in the RTS when - mutuples *do* require special attention at GC time. - When it is used, it is a primitive object (never entered). - Always mutable...there is an IMMUTUPLE in the RTS, but no - corresponding type in the compiler. - ---jim --} - -instance Eq SMRep where - (SpecialisedRep k1 a1 b1 _) == (SpecialisedRep k2 a2 b2 _) = (tagOf_SMSpecRepKind k1) _EQ_ (tagOf_SMSpecRepKind k2) - && a1 == a2 && b1 == b2 - (GenericRep a1 b1 _) == (GenericRep a2 b2 _) = a1 == a2 && b1 == b2 - (BigTupleRep a1) == (BigTupleRep a2) = a1 == a2 - (MuTupleRep a1) == (MuTupleRep a2) = a1 == a2 - (DataRep a1) == (DataRep a2) = a1 == a2 - a == b = (tagOf_SMRep a) _EQ_ (tagOf_SMRep b) - -ltSMRepHdr :: SMRep -> SMRep -> Bool -a `ltSMRepHdr` b = (tagOf_SMRep a) _LT_ (tagOf_SMRep b) - -instance Ord SMRep where - -- ToDo: cmp-ify? This instance seems a bit weird (WDP 94/10) - rep1 <= rep2 = rep1 < rep2 || rep1 == rep2 - rep1 < rep2 - = let tag1 = tagOf_SMRep rep1 - tag2 = tagOf_SMRep rep2 - in - if tag1 _LT_ tag2 then True - else if tag1 _GT_ tag2 then False - else {- tags equal -} rep1 `lt` rep2 - where - (SpecialisedRep k1 a1 b1 _) `lt` (SpecialisedRep k2 a2 b2 _) = - t1 _LT_ t2 || (t1 _EQ_ t2 && (a1 < a2 || (a1 == a2 && b1 < b2))) - where t1 = tagOf_SMSpecRepKind k1 - t2 = tagOf_SMSpecRepKind k2 - (GenericRep a1 b1 _) `lt` (GenericRep a2 b2 _) = a1 < a2 || (a1 == a2 && b1 < b2) - (BigTupleRep a1) `lt` (BigTupleRep a2) = a1 < a2 - (MuTupleRep a1) `lt` (MuTupleRep a2) = a1 < a2 - (DataRep a1) `lt` (DataRep a2) = a1 < a2 - a `lt` b = True - -tagOf_SMSpecRepKind SpecRep = (ILIT(1) :: FAST_INT) -tagOf_SMSpecRepKind ConstantRep = ILIT(2) -tagOf_SMSpecRepKind CharLikeRep = ILIT(3) -tagOf_SMSpecRepKind IntLikeRep = ILIT(4) - -tagOf_SMRep (StaticRep _ _) = (ILIT(1) :: FAST_INT) -tagOf_SMRep (SpecialisedRep k _ _ _) = ILIT(2) -tagOf_SMRep (GenericRep _ _ _) = ILIT(3) -tagOf_SMRep (BigTupleRep _) = ILIT(4) -tagOf_SMRep (DataRep _) = ILIT(5) -tagOf_SMRep DynamicRep = ILIT(6) -tagOf_SMRep BlackHoleRep = ILIT(7) -tagOf_SMRep PhantomRep = ILIT(8) -tagOf_SMRep (MuTupleRep _) = ILIT(9) - -instance Text SMRep where - showsPrec d rep - = showString (case rep of - StaticRep _ _ -> "STATIC" - SpecialisedRep kind _ _ SMNormalForm -> "SPEC_N" - SpecialisedRep kind _ _ SMSingleEntry -> "SPEC_S" - SpecialisedRep kind _ _ SMUpdatable -> "SPEC_U" - GenericRep _ _ SMNormalForm -> "GEN_N" - GenericRep _ _ SMSingleEntry -> "GEN_S" - GenericRep _ _ SMUpdatable -> "GEN_U" - BigTupleRep _ -> "TUPLE" - DataRep _ -> "DATA" - DynamicRep -> "DYN" - BlackHoleRep -> "BH" - PhantomRep -> "INREGS" - MuTupleRep _ -> "MUTUPLE") - -instance Outputable SMRep where - ppr sty rep = ppStr (show rep) - -getSMInfoStr :: SMRep -> String -getSMInfoStr (StaticRep _ _) = "STATIC" -getSMInfoStr (SpecialisedRep ConstantRep _ _ _) = "CONST" -getSMInfoStr (SpecialisedRep CharLikeRep _ _ _) = "CHARLIKE" -getSMInfoStr (SpecialisedRep IntLikeRep _ _ _) = "INTLIKE" -getSMInfoStr (SpecialisedRep SpecRep _ _ SMNormalForm) = "SPEC_N" -getSMInfoStr (SpecialisedRep SpecRep _ _ SMSingleEntry) = "SPEC_S" -getSMInfoStr (SpecialisedRep SpecRep _ _ SMUpdatable) = "SPEC_U" -getSMInfoStr (GenericRep _ _ SMNormalForm) = "GEN_N" -getSMInfoStr (GenericRep _ _ SMSingleEntry) = "GEN_S" -getSMInfoStr (GenericRep _ _ SMUpdatable) = "GEN_U" -getSMInfoStr (BigTupleRep _) = "TUPLE" -getSMInfoStr (DataRep _ ) = "DATA" -getSMInfoStr DynamicRep = "DYN" -getSMInfoStr BlackHoleRep = panic "getSMInfoStr.BlackHole" -getSMInfoStr PhantomRep = "INREGS" -getSMInfoStr (MuTupleRep _) = "MUTUPLE" - -getSMInitHdrStr :: SMRep -> String -getSMInitHdrStr (SpecialisedRep IntLikeRep _ _ _) = "SET_INTLIKE" -getSMInitHdrStr (SpecialisedRep SpecRep _ _ _) = "SET_SPEC" -getSMInitHdrStr (GenericRep _ _ _) = "SET_GEN" -getSMInitHdrStr (BigTupleRep _) = "SET_TUPLE" -getSMInitHdrStr (DataRep _ ) = "SET_DATA" -getSMInitHdrStr DynamicRep = "SET_DYN" -getSMInitHdrStr BlackHoleRep = "SET_BH" -#ifdef DEBUG -getSMInitHdrStr (StaticRep _ _) = panic "getSMInitHdrStr.Static" -getSMInitHdrStr PhantomRep = panic "getSMInitHdrStr.Phantom" -getSMInitHdrStr (MuTupleRep _) = panic "getSMInitHdrStr.Mutuple" -getSMInitHdrStr (SpecialisedRep ConstantRep _ _ _) = panic "getSMInitHdrStr.Constant" -getSMInitHdrStr (SpecialisedRep CharLikeRep _ _ _) = panic "getSMInitHdrStr.CharLike" -#endif + -- static closure have an extra static link field at the end. + = GenericRep -- GC routines consult sizes in info tbl + Bool -- True <=> This is a static closure. Affects how + -- we garbage-collect it + !Int -- # ptr words + !Int -- # non-ptr words + ClosureType -- closure type + + | BlackHoleRep + +data ClosureType -- Corresponds 1-1 with the varieties of closures + -- implemented by the RTS. Compare with ghc/includes/ClosureTypes.h + = Constr + | ConstrNoCaf + | Fun + | Thunk + | ThunkSelector +\end{code} -getSMUpdInplaceHdrStr :: SMRep -> String -getSMUpdInplaceHdrStr (SpecialisedRep ConstantRep _ _ _) = "INPLACE_UPD" -getSMUpdInplaceHdrStr (SpecialisedRep CharLikeRep _ _ _) = "INPLACE_UPD" -getSMUpdInplaceHdrStr (SpecialisedRep IntLikeRep _ _ _) = "INPLACE_UPD" -getSMUpdInplaceHdrStr (SpecialisedRep SpecRep _ _ _) = "INPLACE_UPD" -#ifdef DEBUG -getSMUpdInplaceHdrStr (StaticRep _ _) = panic "getSMUpdInplaceHdrStr.Static" -getSMUpdInplaceHdrStr (GenericRep _ _ _) = panic "getSMUpdInplaceHdrStr.Generic" -getSMUpdInplaceHdrStr (BigTupleRep _ ) = panic "getSMUpdInplaceHdrStr.BigTuple" -getSMUpdInplaceHdrStr (DataRep _ ) = panic "getSMUpdInplaceHdrStr.Data" -getSMUpdInplaceHdrStr DynamicRep = panic "getSMUpdInplaceHdrStr.Dynamic" -getSMUpdInplaceHdrStr BlackHoleRep = panic "getSMUpdInplaceHdrStr.BlackHole" -getSMUpdInplaceHdrStr PhantomRep = panic "getSMUpdInplaceHdrStr.Phantom" -getSMUpdInplaceHdrStr (MuTupleRep _ ) = panic "getSMUpdInplaceHdrStr.MuTuple" +Size of a closure header. + +\begin{code} +fixedHdrSize :: WordOff +fixedHdrSize = sTD_HDR_SIZE + profHdrSize + granHdrSize + +profHdrSize :: WordOff +profHdrSize | opt_SccProfilingOn = pROF_HDR_SIZE + | otherwise = 0 + +granHdrSize :: WordOff +granHdrSize | opt_GranMacros = gRAN_HDR_SIZE + | otherwise = 0 + +arrWordsHdrSize :: ByteOff +arrWordsHdrSize = fixedHdrSize*wORD_SIZE + sIZEOF_StgArrWords_NoHdr + +arrPtrsHdrSize :: ByteOff +arrPtrsHdrSize = fixedHdrSize*wORD_SIZE + sIZEOF_StgMutArrPtrs_NoHdr +\end{code} + +\begin{code} +-- IA64 mangler doesn't place tables next to code +tablesNextToCode :: Bool +#ifdef ia64_TARGET_ARCH +tablesNextToCode = False +#else +tablesNextToCode = not opt_Unregisterised #endif \end{code} + +\begin{code} +isStaticRep :: SMRep -> Bool +isStaticRep (GenericRep is_static _ _ _) = is_static +isStaticRep BlackHoleRep = False +\end{code} + +\begin{code} +#include "../includes/ClosureTypes.h" +-- Defines CONSTR, CONSTR_1_0 etc + + +smRepClosureType :: SMRep -> ClosureType +smRepClosureType (GenericRep _ _ _ ty) = ty +smRepClosureType BlackHoleRep = panic "smRepClosureType: black hole" + +smRepClosureTypeInt :: SMRep -> Int +smRepClosureTypeInt (GenericRep False 1 0 Constr) = CONSTR_1_0 +smRepClosureTypeInt (GenericRep False 0 1 Constr) = CONSTR_0_1 +smRepClosureTypeInt (GenericRep False 2 0 Constr) = CONSTR_2_0 +smRepClosureTypeInt (GenericRep False 1 1 Constr) = CONSTR_1_1 +smRepClosureTypeInt (GenericRep False 0 2 Constr) = CONSTR_0_2 +smRepClosureTypeInt (GenericRep False _ _ Constr) = CONSTR + +smRepClosureTypeInt (GenericRep False 1 0 Fun) = FUN_1_0 +smRepClosureTypeInt (GenericRep False 0 1 Fun) = FUN_0_1 +smRepClosureTypeInt (GenericRep False 2 0 Fun) = FUN_2_0 +smRepClosureTypeInt (GenericRep False 1 1 Fun) = FUN_1_1 +smRepClosureTypeInt (GenericRep False 0 2 Fun) = FUN_0_2 +smRepClosureTypeInt (GenericRep False _ _ Fun) = FUN + +smRepClosureTypeInt (GenericRep False 1 0 Thunk) = THUNK_1_0 +smRepClosureTypeInt (GenericRep False 0 1 Thunk) = THUNK_0_1 +smRepClosureTypeInt (GenericRep False 2 0 Thunk) = THUNK_2_0 +smRepClosureTypeInt (GenericRep False 1 1 Thunk) = THUNK_1_1 +smRepClosureTypeInt (GenericRep False 0 2 Thunk) = THUNK_0_2 +smRepClosureTypeInt (GenericRep False _ _ Thunk) = THUNK + +smRepClosureTypeInt (GenericRep False _ _ ThunkSelector) = THUNK_SELECTOR + +smRepClosureTypeInt (GenericRep True _ _ Constr) = CONSTR_STATIC +smRepClosureTypeInt (GenericRep True _ _ ConstrNoCaf) = CONSTR_NOCAF_STATIC +smRepClosureTypeInt (GenericRep True _ _ Fun) = FUN_STATIC +smRepClosureTypeInt (GenericRep True _ _ Thunk) = THUNK_STATIC + +smRepClosureTypeInt BlackHoleRep = BLACKHOLE + +smRepClosureTypeInt rep = panic "smRepClosuretypeint" + + +-- We export these ones +rET_SMALL = (RET_SMALL :: Int) +rET_VEC_SMALL = (RET_VEC_SMALL :: Int) +rET_BIG = (RET_BIG :: Int) +rET_VEC_BIG = (RET_VEC_BIG :: Int) +\end{code} +