diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2011-08-22 15:24:29 +0100 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2011-08-25 11:12:30 +0100 |
commit | 493c12ff54673679a79c242f3f0e224019d7117f (patch) | |
tree | c943d4ee8524349b7a78fd615cdec4a5f43e8f4b /compiler/codeGen | |
parent | 5b167f5edad7d3268de20452da7af05c38972f7c (diff) | |
download | haskell-493c12ff54673679a79c242f3f0e224019d7117f.tar.gz |
More refactoring (CgRep)
* Move CgRep (private to old codgen) from SMRep to ClosureInfo
* Avoid using CgRep in new codegen
* Move SMRep and Bitmap from codeGen/ to cmm/
Diffstat (limited to 'compiler/codeGen')
-rw-r--r-- | compiler/codeGen/Bitmap.hs | 85 | ||||
-rw-r--r-- | compiler/codeGen/CgCallConv.hs | 1 | ||||
-rw-r--r-- | compiler/codeGen/CgCase.lhs | 1 | ||||
-rw-r--r-- | compiler/codeGen/CgForeignCall.hs | 1 | ||||
-rw-r--r-- | compiler/codeGen/CgLetNoEscape.lhs | 1 | ||||
-rw-r--r-- | compiler/codeGen/CgStackery.lhs | 1 | ||||
-rw-r--r-- | compiler/codeGen/CgTailCall.lhs | 1 | ||||
-rw-r--r-- | compiler/codeGen/CgTicky.hs | 1 | ||||
-rw-r--r-- | compiler/codeGen/ClosureInfo.lhs | 154 | ||||
-rw-r--r-- | compiler/codeGen/SMRep.lhs | 501 | ||||
-rw-r--r-- | compiler/codeGen/StgCmmBind.hs | 2 | ||||
-rw-r--r-- | compiler/codeGen/StgCmmClosure.hs | 11 | ||||
-rw-r--r-- | compiler/codeGen/StgCmmExpr.hs | 3 | ||||
-rw-r--r-- | compiler/codeGen/StgCmmLayout.hs | 6 | ||||
-rw-r--r-- | compiler/codeGen/StgCmmTicky.hs | 1 |
15 files changed, 164 insertions, 606 deletions
diff --git a/compiler/codeGen/Bitmap.hs b/compiler/codeGen/Bitmap.hs deleted file mode 100644 index acd398c8d5..0000000000 --- a/compiler/codeGen/Bitmap.hs +++ /dev/null @@ -1,85 +0,0 @@ --- --- (c) The University of Glasgow 2003-2006 --- - --- Functions for constructing bitmaps, which are used in various --- places in generated code (stack frame liveness masks, function --- argument liveness masks, SRT bitmaps). - -module Bitmap ( - Bitmap, mkBitmap, - intsToBitmap, intsToReverseBitmap, - mAX_SMALL_BITMAP_SIZE, - seqBitmap, - ) where - -#include "HsVersions.h" -#include "../includes/MachDeps.h" - -import SMRep -import Constants -import Util - -import Data.Bits - -{-| -A bitmap represented by a sequence of 'StgWord's on the /target/ -architecture. These are used for bitmaps in info tables and other -generated code which need to be emitted as sequences of StgWords. --} -type Bitmap = [StgWord] - --- | Make a bitmap from a sequence of bits -mkBitmap :: [Bool] -> Bitmap -mkBitmap [] = [] -mkBitmap stuff = chunkToBitmap chunk : mkBitmap rest - where (chunk, rest) = splitAt wORD_SIZE_IN_BITS stuff - -chunkToBitmap :: [Bool] -> StgWord -chunkToBitmap chunk = - foldr (.|.) 0 [ 1 `shiftL` n | (True,n) <- zip chunk [0..] ] - --- | Make a bitmap where the slots specified are the /ones/ in the bitmap. --- eg. @[0,1,3], size 4 ==> 0xb@. --- --- The list of @Int@s /must/ be already sorted. -intsToBitmap :: Int -> [Int] -> Bitmap -intsToBitmap size slots{- must be sorted -} - | size <= 0 = [] - | otherwise = - (foldr (.|.) 0 (map (1 `shiftL`) these)) : - intsToBitmap (size - wORD_SIZE_IN_BITS) - (map (\x -> x - wORD_SIZE_IN_BITS) rest) - where (these,rest) = span (<wORD_SIZE_IN_BITS) slots - --- | Make a bitmap where the slots specified are the /zeros/ in the bitmap. --- eg. @[0,1,3], size 4 ==> 0x4@ (we leave any bits outside the size as zero, --- just to make the bitmap easier to read). --- --- The list of @Int@s /must/ be already sorted. -intsToReverseBitmap :: Int -> [Int] -> Bitmap -intsToReverseBitmap size slots{- must be sorted -} - | size <= 0 = [] - | otherwise = - (foldr xor init (map (1 `shiftL`) these)) : - intsToReverseBitmap (size - wORD_SIZE_IN_BITS) - (map (\x -> x - wORD_SIZE_IN_BITS) rest) - where (these,rest) = span (<wORD_SIZE_IN_BITS) slots - init - | size >= wORD_SIZE_IN_BITS = complement 0 - | otherwise = (1 `shiftL` size) - 1 - -{- | -Magic number, must agree with @BITMAP_BITS_SHIFT@ in InfoTables.h. -Some kinds of bitmap pack a size\/bitmap into a single word if -possible, or fall back to an external pointer when the bitmap is too -large. This value represents the largest size of bitmap that can be -packed into a single word. --} -mAX_SMALL_BITMAP_SIZE :: Int -mAX_SMALL_BITMAP_SIZE | wORD_SIZE == 4 = 27 - | otherwise = 58 - -seqBitmap :: Bitmap -> a -> a -seqBitmap = seqList - diff --git a/compiler/codeGen/CgCallConv.hs b/compiler/codeGen/CgCallConv.hs index 1001969592..32f6727b04 100644 --- a/compiler/codeGen/CgCallConv.hs +++ b/compiler/codeGen/CgCallConv.hs @@ -35,6 +35,7 @@ import CLabel import Constants import CgStackery +import ClosureInfo( CgRep(..), nonVoidArg, idCgRep, cgRepSizeW, isFollowableArg ) import OldCmmUtils import Maybes import Id diff --git a/compiler/codeGen/CgCase.lhs b/compiler/codeGen/CgCase.lhs index 649bda87ef..0eace0d577 100644 --- a/compiler/codeGen/CgCase.lhs +++ b/compiler/codeGen/CgCase.lhs @@ -26,7 +26,6 @@ import CgProf import CgInfoTbls import ClosureInfo -import SMRep import OldCmmUtils import OldCmm diff --git a/compiler/codeGen/CgForeignCall.hs b/compiler/codeGen/CgForeignCall.hs index 73db412bbe..493b3a181b 100644 --- a/compiler/codeGen/CgForeignCall.hs +++ b/compiler/codeGen/CgForeignCall.hs @@ -24,6 +24,7 @@ import CgMonad import CgUtils import Type import TysPrim +import ClosureInfo( nonVoidArg ) import CLabel import OldCmm import OldCmmUtils diff --git a/compiler/codeGen/CgLetNoEscape.lhs b/compiler/codeGen/CgLetNoEscape.lhs index ed21833f8c..9f878dcf60 100644 --- a/compiler/codeGen/CgLetNoEscape.lhs +++ b/compiler/codeGen/CgLetNoEscape.lhs @@ -30,7 +30,6 @@ import CLabel import ClosureInfo import CostCentre import Id -import SMRep import BasicTypes \end{code} diff --git a/compiler/codeGen/CgStackery.lhs b/compiler/codeGen/CgStackery.lhs index 0d45b6eb90..e6024e7410 100644 --- a/compiler/codeGen/CgStackery.lhs +++ b/compiler/codeGen/CgStackery.lhs @@ -25,6 +25,7 @@ module CgStackery ( import CgMonad import CgUtils import CgProf +import ClosureInfo( CgRep(..), cgRepSizeW ) import SMRep import OldCmm import OldCmmUtils diff --git a/compiler/codeGen/CgTailCall.lhs b/compiler/codeGen/CgTailCall.lhs index a3dbe6a1a8..994ad105ec 100644 --- a/compiler/codeGen/CgTailCall.lhs +++ b/compiler/codeGen/CgTailCall.lhs @@ -27,7 +27,6 @@ import CgHeapery import CgUtils import CgTicky import ClosureInfo -import SMRep import OldCmm import OldCmmUtils import CLabel diff --git a/compiler/codeGen/CgTicky.hs b/compiler/codeGen/CgTicky.hs index daeba9274b..ef6d301923 100644 --- a/compiler/codeGen/CgTicky.hs +++ b/compiler/codeGen/CgTicky.hs @@ -42,7 +42,6 @@ module CgTicky ( import ClosureInfo import CgUtils import CgMonad -import SMRep import OldCmm import OldCmmUtils diff --git a/compiler/codeGen/ClosureInfo.lhs b/compiler/codeGen/ClosureInfo.lhs index 443e0ccf89..c55a9f936f 100644 --- a/compiler/codeGen/ClosureInfo.lhs +++ b/compiler/codeGen/ClosureInfo.lhs @@ -52,6 +52,17 @@ module ClosureInfo ( cafBlackHoleClosureInfo, staticClosureNeedsLink, + + -- CgRep and its functions + CgRep(..), nonVoidArg, + argMachRep, primRepToCgRep, + isFollowableArg, isVoidArg, + isFloatingArg, is64BitArg, + separateByPtrFollowness, + cgRepSizeW, cgRepSizeB, + retAddrSizeW, + typeCgRep, idCgRep, tyConCgRep, + ) where #include "../includes/MachDeps.h" @@ -75,6 +86,7 @@ import TcType import TyCon import BasicTypes import Outputable +import FastString import Constants import DynFlags \end{code} @@ -195,6 +207,148 @@ data StandardFormInfo Int -- Arity, n \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} + %************************************************************************ %* * \subsection[ClosureInfo-construction]{Functions which build LFInfos} 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} diff --git a/compiler/codeGen/StgCmmBind.hs b/compiler/codeGen/StgCmmBind.hs index ef432ae6d2..3823fa15b0 100644 --- a/compiler/codeGen/StgCmmBind.hs +++ b/compiler/codeGen/StgCmmBind.hs @@ -241,7 +241,7 @@ mkRhsClosure bndr cc bi body@(StgApp fun_id args) | args `lengthIs` (arity-1) - && all isFollowableArg (map (idCgRep . stripNV) fvs) + && all (isGcPtrRep . idPrimRep . stripNV) fvs && isUpdatable upd_flag && arity <= mAX_SPEC_AP_SIZE diff --git a/compiler/codeGen/StgCmmClosure.hs b/compiler/codeGen/StgCmmClosure.hs index 88d1498728..1bf726c7c3 100644 --- a/compiler/codeGen/StgCmmClosure.hs +++ b/compiler/codeGen/StgCmmClosure.hs @@ -358,17 +358,6 @@ isLFReEntrant _ = False -- Choosing SM reps ----------------------------------------------------------------------------- -chooseSMRep - :: Bool -- True <=> static closure - -> LambdaFormInfo - -> WordOff -> WordOff -- Tot wds, ptr wds - -> SMRep - -chooseSMRep is_static lf_info tot_wds ptr_wds - = mkHeapRep is_static ptr_wds nonptr_wds (lfClosureType lf_info) - where - nonptr_wds = tot_wds - ptr_wds - lfClosureType :: LambdaFormInfo -> ClosureTypeInfo lfClosureType (LFReEntrant _ arity _ argd) = Fun (fromIntegral arity) argd lfClosureType (LFCon con) = Constr (fromIntegral (dataConTagZ con)) diff --git a/compiler/codeGen/StgCmmExpr.hs b/compiler/codeGen/StgCmmExpr.hs index d9ae62e206..cb68f51bd4 100644 --- a/compiler/codeGen/StgCmmExpr.hs +++ b/compiler/codeGen/StgCmmExpr.hs @@ -35,7 +35,6 @@ import DataCon import ForeignCall import Id import PrimOp -import SMRep import TyCon import Type import CostCentre ( CostCentreStack, currentCCS ) @@ -317,7 +316,7 @@ cgCase (StgApp v []) bndr _ alt_type@(PrimAlt _) alts ; _ <- bindArgsToRegs [NonVoid bndr] ; cgAlts NoGcInAlts (NonVoid bndr) alt_type alts } where - reps_compatible = idCgRep v == idCgRep bndr + reps_compatible = idPrimRep v == idPrimRep bndr cgCase scrut@(StgApp v []) _ _ (PrimAlt _) _ = -- fail at run-time, not compile-time diff --git a/compiler/codeGen/StgCmmLayout.hs b/compiler/codeGen/StgCmmLayout.hs index e9f7394b8b..89d764a51b 100644 --- a/compiler/codeGen/StgCmmLayout.hs +++ b/compiler/codeGen/StgCmmLayout.hs @@ -38,7 +38,6 @@ import StgCmmUtils import MkGraph import SMRep import Cmm -import CmmUtils import CLabel import StgSyn import Id @@ -240,6 +239,9 @@ lRepSizeW L = wORD64_SIZE `quot` wORD_SIZE lRepSizeW D = dOUBLE_SIZE `quot` wORD_SIZE lRepSizeW V = 0 +idLRep :: Id -> LRep +idLRep = toLRep . idPrimRep + ------------------------------------------------------------------------- ---- Laying out objects on the heap and stack ------------------------------------------------------------------------- @@ -314,7 +316,7 @@ mkArgDescr _nm args Nothing -> return (ArgGen arg_bits) where arg_bits = argBits arg_reps - arg_reps = filter isNonV (map (toLRep . idPrimRep) args) + arg_reps = filter isNonV (map idLRep args) -- Getting rid of voids eases matching of standard patterns argBits :: [LRep] -> [Bool] -- True for non-ptr, False for ptr diff --git a/compiler/codeGen/StgCmmTicky.hs b/compiler/codeGen/StgCmmTicky.hs index 8db4d3e829..3775130aaf 100644 --- a/compiler/codeGen/StgCmmTicky.hs +++ b/compiler/codeGen/StgCmmTicky.hs @@ -247,6 +247,7 @@ tickySlowCallPat _args = return () (str, True) -> bumpTickyCounter' (mkRtsSlowTickyCtrLabel pat) (str, False) -> bumpTickyCounter (sLit "TICK_SLOW_CALL_OTHER") +-- Don't use CgRep; put this function in StgCmmLayout callPattern :: [CgRep] -> (String,Bool) callPattern reps | match == length reps = (chars, True) |