[project @ 2003-11-17 14:23:30 by simonmar]
[ghc-hetmet.git] / ghc / compiler / codeGen / ClosureInfo.lhs
index a237173..2de8802 100644 (file)
@@ -1,7 +1,7 @@
 %
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
-% $Id: ClosureInfo.lhs,v 1.54 2002/12/11 15:36:28 simonmar Exp $
+% $Id: ClosureInfo.lhs,v 1.61 2003/11/17 14:23:31 simonmar Exp $
 %
 \section[ClosureInfo]{Data structures which describe closures}
 
@@ -17,7 +17,6 @@ module ClosureInfo (
 
        mkClosureLFInfo, mkConLFInfo, mkSelectorLFInfo,
        mkApLFInfo, mkLFImported, mkLFArgument, mkLFLetNoEscape,
-       UpdateFlag,
 
        closureSize, closureNonHdrSize,
        closureGoodStuffSize, closurePtrsSize,
@@ -40,7 +39,6 @@ module ClosureInfo (
        closureLFInfo, closureSMRep, closureUpdReqd,
        closureSingleEntry, closureReEntrant, closureSemiTag,
        closureFunInfo, isStandardFormThunk,
-       GenStgArg,
 
        isToplevClosure,
        closureTypeDescr,               -- profiling
@@ -72,24 +70,25 @@ import Id           ( Id, idType, idArity, idName, idPrimRep )
 import DataCon         ( DataCon, dataConTag, fIRST_TAG, dataConTyCon,
                          isNullaryDataCon, dataConName
                        )
-import Name            ( Name, nameUnique, getOccName, getName )
+import Name            ( Name, nameUnique, getOccName, getName, getOccString )
 import OccName         ( occNameUserString )
-import PprType         ( getTyDescription )
 import PrimRep
 import SMRep           -- all of it
 import Type            ( isUnLiftedType, Type, repType, splitTyConApp_maybe )
+import TcType          ( tcSplitSigmaTy )
 import TyCon           ( isFunTyCon )
-import BasicTypes      ( TopLevelFlag(..), isNotTopLevel, isTopLevel )
+import BasicTypes      ( TopLevelFlag(..), isNotTopLevel, isTopLevel, ipNameName )
 import Util            ( mapAccumL, listLengthCmp, lengthIs )
 import FastString
 import Outputable
 import Literal
 import Constants
-import BitSet
+import Bitmap
 
 import Maybe           ( isJust )
-import DATA_WORD
 import DATA_BITS
+
+import TypeRep -- TEMP
 \end{code}
 
 %************************************************************************
@@ -518,11 +517,11 @@ chooseSMRep is_static lf_info tot_wds ptr_wds
 getClosureType :: Bool -> Int -> Int -> LambdaFormInfo -> ClosureType
 getClosureType is_static tot_wds ptr_wds lf_info
   = case lf_info of
-       LFCon con | is_static && ptr_wds == 0   -> CONSTR_NOCAF
-                 | otherwise                   -> CONSTR
-       LFReEntrant _ _ _ _                     -> FUN
-       LFThunk _ _ _ (SelectorThunk _) _       -> THUNK_SELECTOR
-       LFThunk _ _ _ _ _                       -> THUNK
+       LFCon con | is_static && ptr_wds == 0   -> ConstrNoCaf
+                 | otherwise                   -> Constr
+       LFReEntrant _ _ _ _                     -> Fun
+       LFThunk _ _ _ (SelectorThunk _) _       -> ThunkSelector
+       LFThunk _ _ _ _ _                       -> Thunk
        _ -> panic "getClosureType"
 \end{code}
 
@@ -801,8 +800,8 @@ staticClosureNeedsLink (ConInfo { closureSMRep = sm_rep, closureCon = con })
   where
     not_nocaf_constr = 
        case sm_rep of 
-          GenericRep _ _ _ CONSTR_NOCAF -> False
-          _other                        -> True
+          GenericRep _ _ _ ConstrNoCaf -> False
+          _other                       -> True
 \end{code}
 
 Avoiding generating entries and info tables
@@ -1055,6 +1054,27 @@ closureTypeDescr (ClosureInfo { closureType = ty })
   = getTyDescription ty
 closureTypeDescr (ConInfo { closureCon = data_con })
   = occNameUserString (getOccName (dataConTyCon data_con))
+
+getTyDescription :: Type -> String
+getTyDescription ty
+  = case (tcSplitSigmaTy ty) of { (_, _, tau_ty) ->
+    case tau_ty of
+      TyVarTy _                     -> "*"
+      AppTy fun _                   -> getTyDescription fun
+      FunTy _ res                   -> '-' : '>' : fun_result res
+      NewTcApp tycon _              -> getOccString tycon
+      TyConApp tycon _              -> getOccString tycon
+      NoteTy (FTVNote _) ty  -> getTyDescription ty
+      NoteTy (SynNote ty1) _ -> getTyDescription ty1
+      PredTy sty            -> getPredTyDescription sty
+      ForAllTy _ ty          -> getTyDescription ty
+    }
+  where
+    fun_result (FunTy _ res) = '>' : fun_result res
+    fun_result other        = getTyDescription other
+
+getPredTyDescription (ClassP cl tys) = getOccString cl
+getPredTyDescription (IParam ip ty)  = getOccString (ipNameName ip)
 \end{code}
 
 %************************************************************************
@@ -1106,19 +1126,12 @@ argDescr nm [PtrRep,PtrRep,PtrRep,PtrRep,PtrRep,PtrRep] = ArgSpec ARG_PPPPPP
 argDescr name reps = ArgGen (mkSlowEntryLabel name) liveness
  where bitmap = argBits reps
        lbl = mkBitmapLabel name
-       liveness = Liveness lbl (length bitmap) 
-                       (map chunkToLiveness (mkChunks bitmap))
+       liveness = Liveness lbl (length bitmap) (mkBitmap bitmap) 
 
 argBits [] = []
 argBits (rep : args)
   | isFollowableRep rep = False : argBits args
   | otherwise = take (getPrimRepSize rep) (repeat True) ++ argBits args
-
-mkChunks [] = []
-mkChunks stuff = chunk : mkChunks rest
-  where (chunk, rest) = splitAt 32 stuff
-
-chunkToLiveness chunk = mkBS [ n | (True,n) <- zip chunk [0..] ]
 \end{code}
 
 
@@ -1133,18 +1146,10 @@ Here we make a concrete info table, represented as a list of CAddrMode
 represented by a label+offset expression).
 
 \begin{code}
-#if SIZEOF_HSWORD == 4
-type StgWord = Word32
-#define HALF_WORD 16
-#elif SIZEOF_HSWORD == 8
-type StgWord = Word64
-#define HALF_WORD 32
-#endif
-
 mkInfoTable :: ClosureInfo -> [CAddrMode]
 mkInfoTable cl_info
- | opt_Unregisterised = std_info ++ extra_bits
- | otherwise          = extra_bits ++ std_info
+ | tablesNextToCode = extra_bits ++ std_info
+ | otherwise        = std_info ++ extra_bits
  where
     std_info = mkStdInfoTable entry_amode
                  ty_descr_amode cl_descr_amode cl_type srt_len layout_amode
@@ -1168,13 +1173,13 @@ mkInfoTable cl_info
     is_con = isJust semi_tag
 
     (srt_label,srt_len)
-       | Just tag <- semi_tag = (mkIntCLit 0, tag) -- constructor
+       | Just tag <- semi_tag = (mkIntCLit 0, fromIntegral tag) -- constructor
        | otherwise = 
          case srt of
            NoC_SRT -> (mkIntCLit 0, 0)
-           C_SRT lbl off len -> 
+           C_SRT lbl off bitmap -> 
              (CAddr (CIndex (CLbl lbl DataPtrRep) (mkIntCLit off) WordRep),
-              len)
+              bitmap)
 
     ptrs  = closurePtrsSize cl_info
     nptrs = size - ptrs
@@ -1182,12 +1187,12 @@ mkInfoTable cl_info
 
     layout_info :: StgWord
 #ifdef WORDS_BIGENDIAN
-    layout_info = (fromIntegral ptrs `shiftL` HALF_WORD) .|. fromIntegral nptrs
+    layout_info = (fromIntegral ptrs `shiftL` hALF_WORD) .|. fromIntegral nptrs
 #else 
-    layout_info = (fromIntegral ptrs) .|. (fromIntegral nptrs `shiftL` HALF_WORD)
+    layout_info = (fromIntegral ptrs) .|. (fromIntegral nptrs `shiftL` hALF_WORD)
 #endif      
 
-    layout_amode = CLit (MachWord (fromIntegral layout_info))
+    layout_amode = mkWordCLit layout_info
 
     extra_bits
        | is_fun    = fun_extra_bits
@@ -1200,8 +1205,8 @@ mkInfoTable cl_info
     (Just (arity, arg_descr)) = maybe_fun_stuff
 
     fun_extra_bits
-       | opt_Unregisterised = reverse reg_fun_extra_bits
-       | otherwise          = reg_fun_extra_bits
+       | tablesNextToCode = reg_fun_extra_bits
+       | otherwise        = reverse reg_fun_extra_bits
 
     reg_fun_extra_bits
        | ArgGen slow_lbl liveness <- arg_descr
@@ -1209,16 +1214,18 @@ mkInfoTable cl_info
                   CLbl slow_lbl CodePtrRep, 
                   livenessToAddrMode liveness,
                   srt_label,
-                  mkIntCLit fun_desc
+                  fun_amode
                  ]
-       | needs_srt = [srt_label, mkIntCLit fun_desc]
-       | otherwise = [mkIntCLit fun_desc]
+       | needs_srt = [srt_label, fun_amode]
+       | otherwise = [fun_amode]
 
 #ifdef WORDS_BIGENDIAN
-    fun_desc = (fromIntegral fun_type `shiftL` HALF_WORD) .|. fromIntegral arity
+    fun_desc = (fromIntegral fun_type `shiftL` hALF_WORD) .|. fromIntegral arity
 #else 
-    fun_desc = (fromIntegral fun_type) .|. (fromIntegral arity `shiftL` HALF_WORD)
-#endif      
+    fun_desc = (fromIntegral fun_type) .|. (fromIntegral arity `shiftL` hALF_WORD)
+#endif
+
+    fun_amode = mkWordCLit fun_desc
 
     fun_type = case arg_descr of
                ArgSpec n -> n
@@ -1243,20 +1250,20 @@ mkBitmapInfoTable
    -> [CAddrMode]
    -> [CAddrMode]
 mkBitmapInfoTable entry_amode srt liveness vector
- | opt_Unregisterised = std_info ++ extra_bits
- | otherwise          = extra_bits ++ std_info
+ | tablesNextToCode = extra_bits ++ std_info
+ | otherwise        = std_info ++ extra_bits
  where
    std_info = mkStdInfoTable entry_amode zero_amode zero_amode 
                cl_type srt_len liveness_amode
 
    liveness_amode = livenessToAddrMode liveness
-   
+
    (srt_label,srt_len) =
          case srt of
            NoC_SRT -> (mkIntCLit 0, 0)
-           C_SRT lbl off len -> 
-             (CAddr (CIndex (CLbl lbl DataPtrRep) (mkIntCLit off) WordRep),
-              len)
+           C_SRT lbl off bitmap -> 
+                   (CAddr (CIndex (CLbl lbl DataPtrRep) (mkIntCLit off) WordRep),
+                    bitmap)
 
    cl_type = case (null vector, isBigLiveness liveness) of
                (True, True)   -> rET_BIG
@@ -1267,8 +1274,8 @@ mkBitmapInfoTable entry_amode srt liveness vector
    srt_bit | needsSRT srt || not (null vector) = [srt_label]
           | otherwise = []
 
-   extra_bits | opt_Unregisterised = srt_bit ++ vector
-             | otherwise          = reverse vector ++ srt_bit
+   extra_bits | tablesNextToCode = reverse vector ++ srt_bit
+              | otherwise        = srt_bit ++ vector
 
 -- The standard bits of an info table.  This part of the info table
 -- corresponds to the StgInfoTable type defined in InfoTables.h.
@@ -1278,15 +1285,15 @@ mkStdInfoTable
    -> CAddrMode                                -- closure type descr (profiling)
    -> CAddrMode                                -- closure descr (profiling)
    -> Int                              -- closure type
-   -> Int                              -- SRT length
+   -> StgHalfWord                      -- SRT length
    -> CAddrMode                                -- layout field
    -> [CAddrMode]
 mkStdInfoTable entry_lbl type_descr closure_descr cl_type srt_len layout_amode
  = std_info
  where  
     std_info
-       | opt_Unregisterised  = entry_lbl : std_info'
-       | otherwise           = std_info'
+       | tablesNextToCode = std_info'
+       | otherwise        = entry_lbl : std_info'
 
     std_info' =
          -- par info
@@ -1305,11 +1312,11 @@ mkStdInfoTable entry_lbl type_descr closure_descr cl_type srt_len layout_amode
     -- ToDo: do this using .byte and .word directives.
     type_info :: StgWord
 #ifdef WORDS_BIGENDIAN
-    type_info = (fromIntegral cl_type `shiftL` HALF_WORD) .|.
+    type_info = (fromIntegral cl_type `shiftL` hALF_WORD) .|.
                (fromIntegral srt_len)
 #else 
     type_info = (fromIntegral cl_type) .|.
-               (fromIntegral srt_len `shiftL` HALF_WORD)
+               (fromIntegral srt_len `shiftL` hALF_WORD)
 #endif
 
 isBigLiveness (Liveness _ size _) = size > mAX_SMALL_BITMAP_SIZE
@@ -1319,13 +1326,19 @@ livenessToAddrMode (Liveness lbl size bits)
        | size <= mAX_SMALL_BITMAP_SIZE = small
        | otherwise = CLbl lbl DataPtrRep
        where
-         small = mkIntCLit (fromIntegral size .|. (small_bits `shiftL` bITMAP_BITS_SHIFT))
+         small = mkWordCLit (fromIntegral size .|. (small_bits `shiftL` bITMAP_BITS_SHIFT))
          small_bits = case bits of 
                        []  -> 0
-                       [b] -> intBS b
+                       [b] -> fromIntegral b
                        _   -> panic "livenessToAddrMode"
 
-mAX_SMALL_BITMAP_SIZE = (wORD_SIZE * 8) - bITMAP_BITS_SHIFT
-
 zero_amode = mkIntCLit 0
+
+-- 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}