diff options
Diffstat (limited to 'compiler/codeGen/SMRep.lhs')
-rw-r--r-- | compiler/codeGen/SMRep.lhs | 501 |
1 files changed, 0 insertions, 501 deletions
diff --git a/compiler/codeGen/SMRep.lhs b/compiler/codeGen/SMRep.lhs deleted file mode 100644 index fea9e4b2fc..0000000000 --- a/compiler/codeGen/SMRep.lhs +++ /dev/null @@ -1,501 +0,0 @@ -% -% (c) The University of Glasgow 2006 -% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 -% - -Storage manager representation of closures - -This is here, rather than in ClosureInfo, just to keep nhc happy. -Other modules should access this info through ClosureInfo. - -\begin{code} -module SMRep ( - -- Words and bytes - StgWord, StgHalfWord, - hALF_WORD_SIZE, hALF_WORD_SIZE_IN_BITS, - WordOff, ByteOff, - - -- Argument/return representations - CgRep(..), nonVoidArg, - argMachRep, primRepToCgRep, --- Temp primRepHint, typeHint, - isFollowableArg, isVoidArg, - isFloatingArg, is64BitArg, - separateByPtrFollowness, - cgRepSizeW, cgRepSizeB, - retAddrSizeW, - - typeCgRep, idCgRep, tyConCgRep, - - -- Closure repesentation - SMRep(..), -- CmmInfo sees the rep; no one else does - IsStatic, - ClosureTypeInfo(..), ArgDescr(..), Liveness, - ConstrDescription, - mkHeapRep, blackHoleRep, mkStackRep, - - isStaticRep, isStaticNoCafCon, - heapClosureSize, - fixedHdrSize, arrWordsHdrSize, arrPtrsHdrSize, - profHdrSize, thunkHdrSize, nonHdrSize, - - rtsClosureType, rET_SMALL, rET_BIG, - aRG_GEN, aRG_GEN_BIG, - - -- Operations over [Word8] strings - pprWord8String, stringToWord8s - ) where - -#include "../HsVersions.h" -#include "../includes/MachDeps.h" - -import CmmType -import Id -import Type -import TyCon -import StaticFlags -import Constants -import Outputable -import FastString - -import Data.Char( ord ) -import Data.Word -\end{code} - - -%************************************************************************ -%* * - 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 :: ByteOff -hALF_WORD_SIZE = 2 -hALF_WORD_SIZE_IN_BITS :: Int -hALF_WORD_SIZE_IN_BITS = 16 -#elif SIZEOF_HSWORD == 8 -type StgWord = Word64 -type StgHalfWord = Word32 -hALF_WORD_SIZE :: ByteOff -hALF_WORD_SIZE = 4 -hALF_WORD_SIZE_IN_BITS :: Int -hALF_WORD_SIZE_IN_BITS = 32 -#else -#error unknown SIZEOF_HSWORD -#endif -\end{code} - - -%************************************************************************ -%* * - CgRep -%* * -%************************************************************************ - -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 CgRep - = VoidArg -- Void - | PtrArg -- Word-sized heap pointer, followed - -- by the garbage collector - | NonPtrArg -- Word-sized non-pointer - -- (including addresses not followed by GC) - | 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 -> CmmType -argMachRep PtrArg = gcWord -argMachRep NonPtrArg = bWord -argMachRep LongArg = b64 -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 - -idCgRep :: Id -> CgRep -idCgRep x = typeCgRep . idType $ x - -tyConCgRep :: TyCon -> CgRep -tyConCgRep = primRepToCgRep . tyConPrimRep - -typeCgRep :: Type -> CgRep -typeCgRep = primRepToCgRep . typePrimRep -\end{code} - -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. - -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. - -\begin{code} -isFollowableArg :: CgRep -> Bool -- True <=> points to a heap object -isFollowableArg PtrArg = True -isFollowableArg _ = False - -isVoidArg :: CgRep -> Bool -isVoidArg VoidArg = True -isVoidArg _ = False - -nonVoidArg :: CgRep -> Bool -nonVoidArg VoidArg = False -nonVoidArg _ = 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 - -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} - -\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} --- | A description of the layout of a closure. Corresponds directly --- to the closure types in includes/rts/storage/ClosureTypes.h. -data SMRep - = HeapRep -- GC routines consult sizes in info tbl - IsStatic - !WordOff -- # ptr words - !WordOff -- # non-ptr words INCLUDING SLOP (see mkHeapRep below) - ClosureTypeInfo -- type-specific info - - | StackRep -- Stack frame (RET_SMALL or RET_BIG) - Liveness - --- | True <=> This is a static closure. Affects how we garbage-collect it. --- Static closure have an extra static link field at the end. -type IsStatic = Bool - --- From an SMRep you can get to the closure type defined in --- includes/rts/storage/ClosureTypes.h. Described by the function --- rtsClosureType below. - -data ClosureTypeInfo - = Constr ConstrTag ConstrDescription - | Fun FunArity ArgDescr - | Thunk - | ThunkSelector SelectorOffset - | BlackHole - -type ConstrTag = StgHalfWord -type ConstrDescription = [Word8] -- result of dataConIdentity -type FunArity = StgHalfWord -type SelectorOffset = StgWord - -------------------------- --- We represent liveness bitmaps as a Bitmap (whose internal --- representation really is a bitmap). These are pinned onto case return --- vectors to indicate the state of the stack for the garbage collector. --- --- In the compiled program, liveness bitmaps that fit inside a single --- word (StgWord) are stored as a single word, while larger bitmaps are --- stored as a pointer to an array of words. - -type Liveness = [Bool] -- One Bool per word; True <=> non-ptr or dead - -- False <=> ptr - -------------------------- --- An ArgDescr describes the argument pattern of a function - -data ArgDescr - = ArgSpec -- Fits one of the standard patterns - !StgHalfWord -- RTS type identifier ARG_P, ARG_N, ... - - | ArgGen -- General case - Liveness -- Details about the arguments - - ------------------------------------------------------------------------------ --- Construction - -mkHeapRep :: IsStatic -> WordOff -> WordOff -> ClosureTypeInfo -> SMRep -mkHeapRep is_static ptr_wds nonptr_wds cl_type_info - = HeapRep is_static - ptr_wds - (nonptr_wds + slop_wds) - cl_type_info - where - slop_wds - | is_static = 0 - | otherwise = max 0 (minClosureSize - (hdr_size + payload_size)) - - hdr_size = closureTypeHdrSize cl_type_info - payload_size = ptr_wds + nonptr_wds - - -mkStackRep :: [Bool] -> SMRep -mkStackRep = StackRep - -blackHoleRep :: SMRep -blackHoleRep = HeapRep False 0 0 BlackHole - ------------------------------------------------------------------------------ --- Size-related things - --- | Size of a closure header (StgHeader in includes/rts/storage/Closures.h) -fixedHdrSize :: WordOff -fixedHdrSize = sTD_HDR_SIZE + profHdrSize - --- | Size of the profiling part of a closure header --- (StgProfHeader in includes/rts/storage/Closures.h) -profHdrSize :: WordOff -profHdrSize | opt_SccProfilingOn = pROF_HDR_SIZE - | otherwise = 0 - --- | The garbage collector requires that every closure is at least as big as this. -minClosureSize :: WordOff -minClosureSize = fixedHdrSize + mIN_PAYLOAD_SIZE - -arrWordsHdrSize :: ByteOff -arrWordsHdrSize = fixedHdrSize*wORD_SIZE + sIZEOF_StgArrWords_NoHdr - -arrPtrsHdrSize :: ByteOff -arrPtrsHdrSize = fixedHdrSize*wORD_SIZE + sIZEOF_StgMutArrPtrs_NoHdr - --- Thunks have an extra header word on SMP, so the update doesn't --- splat the payload. -thunkHdrSize :: WordOff -thunkHdrSize = fixedHdrSize + smp_hdr - where smp_hdr = sIZEOF_StgSMPThunkHeader `quot` wORD_SIZE - - -isStaticRep :: SMRep -> IsStatic -isStaticRep (HeapRep is_static _ _ _) = is_static -isStaticRep (StackRep {}) = False - -nonHdrSize :: SMRep -> WordOff -nonHdrSize (HeapRep _ p np _) = p + np -nonHdrSize (StackRep bs) = length bs - -heapClosureSize :: SMRep -> WordOff -heapClosureSize (HeapRep _ p np ty) = closureTypeHdrSize ty + p + np -heapClosureSize _ = panic "SMRep.heapClosureSize" - -closureTypeHdrSize :: ClosureTypeInfo -> WordOff -closureTypeHdrSize ty = case ty of - Thunk{} -> thunkHdrSize - ThunkSelector{} -> thunkHdrSize - BlackHole{} -> thunkHdrSize - _ -> fixedHdrSize - -- All thunks use thunkHdrSize, even if they are non-updatable. - -- this is because we don't have separate closure types for - -- updatable vs. non-updatable thunks, so the GC can't tell the - -- difference. If we ever have significant numbers of non- - -- updatable thunks, it might be worth fixing this. - ------------------------------------------------------------------------------ --- deriving the RTS closure type from an SMRep - -#include "../includes/rts/storage/ClosureTypes.h" -#include "../includes/rts/storage/FunTypes.h" --- Defines CONSTR, CONSTR_1_0 etc - --- | Derives the RTS closure type from an 'SMRep' -rtsClosureType :: SMRep -> StgHalfWord -rtsClosureType (HeapRep False 1 0 Constr{}) = CONSTR_1_0 -rtsClosureType (HeapRep False 0 1 Constr{}) = CONSTR_0_1 -rtsClosureType (HeapRep False 2 0 Constr{}) = CONSTR_2_0 -rtsClosureType (HeapRep False 1 1 Constr{}) = CONSTR_1_1 -rtsClosureType (HeapRep False 0 2 Constr{}) = CONSTR_0_2 -rtsClosureType (HeapRep False _ _ Constr{}) = CONSTR - -rtsClosureType (HeapRep False 1 0 Fun{}) = FUN_1_0 -rtsClosureType (HeapRep False 0 1 Fun{}) = FUN_0_1 -rtsClosureType (HeapRep False 2 0 Fun{}) = FUN_2_0 -rtsClosureType (HeapRep False 1 1 Fun{}) = FUN_1_1 -rtsClosureType (HeapRep False 0 2 Fun{}) = FUN_0_2 -rtsClosureType (HeapRep False _ _ Fun{}) = FUN - -rtsClosureType (HeapRep False 1 0 Thunk{}) = THUNK_1_0 -rtsClosureType (HeapRep False 0 1 Thunk{}) = THUNK_0_1 -rtsClosureType (HeapRep False 2 0 Thunk{}) = THUNK_2_0 -rtsClosureType (HeapRep False 1 1 Thunk{}) = THUNK_1_1 -rtsClosureType (HeapRep False 0 2 Thunk{}) = THUNK_0_2 -rtsClosureType (HeapRep False _ _ Thunk{}) = THUNK - -rtsClosureType (HeapRep False _ _ ThunkSelector{}) = THUNK_SELECTOR - --- Approximation: we use the CONSTR_NOCAF_STATIC type for static constructors --- that have no pointer words only. -rtsClosureType (HeapRep True 0 _ Constr{}) = CONSTR_NOCAF_STATIC -- See isStaticNoCafCon below -rtsClosureType (HeapRep True _ _ Constr{}) = CONSTR_STATIC -rtsClosureType (HeapRep True _ _ Fun{}) = FUN_STATIC -rtsClosureType (HeapRep True _ _ Thunk{}) = THUNK_STATIC - -rtsClosureType (HeapRep False _ _ BlackHole{}) = BLACKHOLE - -rtsClosureType _ = panic "rtsClosureType" - -isStaticNoCafCon :: SMRep -> Bool --- This should line up exactly with CONSTR_NOCAF_STATIC above --- See Note [Static NoCaf constructors] -isStaticNoCafCon (HeapRep True 0 _ Constr{}) = True -isStaticNoCafCon _ = False - --- We export these ones -rET_SMALL, rET_BIG, aRG_GEN, aRG_GEN_BIG :: StgHalfWord -rET_SMALL = RET_SMALL -rET_BIG = RET_BIG -aRG_GEN = ARG_GEN -aRG_GEN_BIG = ARG_GEN_BIG -\end{code} - -Note [Static NoCaf constructors] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If we know that a top-level binding 'x' is not Caffy (ie no CAFs are -reachable from 'x'), then a statically allocated constructor (Just x) -is also not Caffy, and the garbage collector need not follow its -argument fields. Exploiting this would require two static info tables -for Just, for the two cases where the argument was Caffy or non-Caffy. - -Currently we don't do this; instead we treat nullary constructors -as non-Caffy, and the others as potentially Caffy. - - -%************************************************************************ -%* * - Pretty printing of SMRep and friends -%* * -%************************************************************************ - -\begin{code} -instance Outputable ClosureTypeInfo where - ppr = pprTypeInfo - -instance Outputable SMRep where - ppr (HeapRep static ps nps tyinfo) - = hang (header <+> lbrace) 2 (ppr tyinfo <+> rbrace) - where - header = ptext (sLit "HeapRep") - <+> if static then ptext (sLit "static") else empty - <+> pp_n "ptrs" ps <+> pp_n "nonptrs" nps - pp_n :: String -> Int -> SDoc - pp_n _ 0 = empty - pp_n s n = int n <+> text s - - ppr (StackRep bs) = ptext (sLit "StackRep") <+> ppr bs - -instance Outputable ArgDescr where - ppr (ArgSpec n) = ptext (sLit "ArgSpec") <+> integer (toInteger n) - ppr (ArgGen ls) = ptext (sLit "ArgGen") <+> ppr ls - -pprTypeInfo :: ClosureTypeInfo -> SDoc -pprTypeInfo (Constr tag descr) - = ptext (sLit "Con") <+> - braces (sep [ ptext (sLit "tag:") <+> integer (toInteger tag) - , ptext (sLit "descr:") <> text (show descr) ]) - -pprTypeInfo (Fun arity args) - = ptext (sLit "Fun") <+> - braces (sep [ ptext (sLit "arity:") <+> integer (toInteger arity) - , ptext (sLit ("fun_type:")) <+> ppr args ]) - -pprTypeInfo (ThunkSelector offset) - = ptext (sLit "ThunkSel") <+> integer (toInteger offset) - -pprTypeInfo Thunk = ptext (sLit "Thunk") -pprTypeInfo BlackHole = ptext (sLit "BlackHole") - - -stringToWord8s :: String -> [Word8] -stringToWord8s s = map (fromIntegral . ord) s - -pprWord8String :: [Word8] -> SDoc --- Debug printing. Not very clever right now. -pprWord8String ws = text (show ws) -\end{code} |