[project @ 2003-05-14 09:13:52 by simonmar]
authorsimonmar <unknown>
Wed, 14 May 2003 09:14:02 +0000 (09:14 +0000)
committersimonmar <unknown>
Wed, 14 May 2003 09:14:02 +0000 (09:14 +0000)
Change the way SRTs are represented:

Previously, the SRT associated with a function or thunk would be a
sub-list of the enclosing top-level function's SRT.  But this approach
can lead to lots of duplication: if a CAF is referenced in several
different thunks, then it may appear several times in the SRT.
Let-no-escapes compound the problem, because the occurrence of a
let-no-escape-bound variable would expand to all the CAFs referred to
by the let-no-escape.

The new way is to describe the SRT associated with a function or thunk
as a (pointer+offset,bitmap) pair, where the pointer+offset points
into some SRT table (the enclosing function's SRT), and the bitmap
indicates which entries in this table are "live" for this closure.
The bitmap is stored in the 16 bits previously used for the length
field, but this rarely overflows.  When it does overflow, we store the
bitmap externally in a new "SRT descriptor".

Now the enclosing SRT can be a set, hence eliminating the duplicates.

Also, we now have one SRT per top-level function in a recursive group,
where previously we used to have one SRT for the whole group.  This
helps keep the size of SRTs down.

Bottom line: very little difference most of the time.  GHC itself got
slightly smaller.  One bad case of a module in GHC which had a huge
SRT has gone away.

While I was in the area:

  - Several parts of the back-end require bitmaps.  Functions for
    creating bitmaps are now centralised in the Bitmap module.

  - We were trying to be independent of word-size in a couple of
    places in the back end, but we've now abandoned that strategy so I
    simplified things a bit.

39 files changed:
ghc/compiler/absCSyn/AbsCSyn.lhs
ghc/compiler/absCSyn/AbsCUtils.lhs
ghc/compiler/absCSyn/CLabel.lhs
ghc/compiler/absCSyn/PprAbsC.lhs
ghc/compiler/codeGen/Bitmap.hs [new file with mode: 0644]
ghc/compiler/codeGen/CgBindery.lhs
ghc/compiler/codeGen/CgCase.lhs
ghc/compiler/codeGen/CgClosure.lhs
ghc/compiler/codeGen/CgCon.lhs
ghc/compiler/codeGen/CgExpr.lhs
ghc/compiler/codeGen/CgLetNoEscape.lhs
ghc/compiler/codeGen/CgMonad.lhs
ghc/compiler/codeGen/CgTailCall.lhs
ghc/compiler/codeGen/ClosureInfo.lhs
ghc/compiler/codeGen/CodeGen.lhs
ghc/compiler/codeGen/SMRep.lhs
ghc/compiler/ghci/ByteCodeAsm.lhs
ghc/compiler/ghci/ByteCodeGen.lhs
ghc/compiler/ghci/ByteCodeInstr.lhs
ghc/compiler/main/Constants.lhs
ghc/compiler/nativeGen/AbsCStixGen.lhs
ghc/compiler/nativeGen/StixPrim.lhs
ghc/compiler/simplStg/SRT.lhs
ghc/compiler/simplStg/SimplStg.lhs
ghc/compiler/simplStg/StgStats.lhs
ghc/compiler/stgSyn/CoreToStg.lhs
ghc/compiler/stgSyn/StgLint.lhs
ghc/compiler/stgSyn/StgSyn.lhs
ghc/driver/mangler/ghc-asm.lprl
ghc/includes/ClosureMacros.h
ghc/includes/InfoMacros.h
ghc/includes/InfoTables.h
ghc/rts/Exception.hc
ghc/rts/GC.c
ghc/rts/HeapStackCheck.hc
ghc/rts/Printer.c
ghc/rts/StgMiscClosures.hc
ghc/rts/StgStartup.hc
ghc/rts/Updates.hc

index 6a3d0eb..2b8a0e4 100644 (file)
@@ -1,7 +1,7 @@
 %
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
-% $Id: AbsCSyn.lhs,v 1.51 2002/12/11 15:36:21 simonmar Exp $
+% $Id: AbsCSyn.lhs,v 1.52 2003/05/14 09:13:52 simonmar Exp $
 %
 \section[AbstractC]{Abstract C: the last stop before machine code}
 
@@ -51,7 +51,8 @@ import MachOp         ( MachOp(..) )
 import Unique           ( Unique )
 import StgSyn          ( StgOp )
 import TyCon           ( TyCon )
-import BitSet                          -- for liveness masks
+import Bitmap          ( Bitmap, mAX_SMALL_BITMAP_SIZE )
+import SMRep           ( StgWord, StgHalfWord )
 import FastTypes
 import FastString
 \end{code}
@@ -199,8 +200,15 @@ stored in a mixed type location.)
   | CSRT CLabel [CLabel]       -- SRT declarations: basically an array of 
                                -- pointers to static closures.
   
-  | CBitmap Liveness           -- A bitmap to be emitted if and only if
-                               -- it is larger than a target machine word.
+  | CBitmap Liveness           -- A "large" bitmap to be emitted
+
+  | CSRTDesc                   -- A "large" SRT descriptor (one that doesn't
+                               -- fit into the half-word bitmap in the itbl).
+       !CLabel                 -- Label for this SRT descriptor
+       !CLabel                 -- Pointer to the SRT
+       !Int                    -- Offset within the SRT
+       !Int                    -- Length
+       !Bitmap                 -- Bitmap
 
   | CClosureInfoAndCode
        ClosureInfo             -- Explains placement and layout of closure
@@ -236,7 +244,7 @@ stored in a mixed type location.)
 -- we add a label for the table, and expect only the 'offset/length' form
 
 data C_SRT = NoC_SRT
-          | C_SRT CLabel !Int{-offset-} !Int{-length-}
+          | C_SRT !CLabel !Int{-offset-} !StgHalfWord{-bitmap or escape-}
 
 needsSRT :: C_SRT -> Bool
 needsSRT NoC_SRT       = False
@@ -365,10 +373,6 @@ data CAddrMode
        !PrimRep        -- the kind of the result
        CExprMacro      -- the macro to generate a value
        [CAddrMode]     -- and its arguments
-
-  | CBytesPerWord      -- Word size, in bytes, on this platform
-                       -- required for: half-word loads (used in fishing tags
-                       -- out of info tables), and sizeofByteArray#.
 \end{code}
 
 Various C macros for values which are dependent on the back-end layout.
@@ -392,6 +396,9 @@ Convenience functions:
 mkIntCLit :: Int -> CAddrMode
 mkIntCLit i = CLit (mkMachInt (toInteger i))
 
+mkWordCLit :: StgWord -> CAddrMode
+mkWordCLit wd = CLit (MachWord (fromIntegral wd))
+
 mkCString :: FastString -> CAddrMode
 mkCString s = CLit (MachStr s)
 
@@ -449,16 +456,15 @@ 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.  When we compile via C
-(especially when we bootstrap via HC files), we generate identical C
-code regardless of whether words are 32- or 64-bit on the target
-machine, by postponing the decision of how to store each liveness
-bitmap to C compilation time (or rather, C preprocessing time).
+stored as a pointer to an array of words. 
 
 \begin{code}
-type LivenessMask = [BitSet]
+data Liveness = Liveness CLabel !Int Bitmap
 
-data Liveness = Liveness CLabel !Int LivenessMask
+maybeLargeBitmap :: Liveness -> AbstractC
+maybeLargeBitmap liveness@(Liveness _ size _)
+  | size <= mAX_SMALL_BITMAP_SIZE = AbsCNop
+  | otherwise                     = CBitmap liveness
 \end{code}
 
 %************************************************************************
index 36e74ef..ac75ca1 100644 (file)
@@ -38,6 +38,7 @@ import SMRep          ( arrPtrsHdrSize, arrWordsHdrSize, fixedHdrSize )
 import Outputable
 import Panic           ( panic )
 import FastTypes
+import Constants       ( wORD_SIZE, wORD_SIZE_IN_BITS )
 
 import Maybe           ( isJust )
 
@@ -419,6 +420,7 @@ flatAbsC (CSequential abcs)
 flatAbsC stmt@(CStaticClosure _ _ _ _)                 = returnFlt (AbsCNop, stmt)
 flatAbsC stmt@(CClosureTbl _)                  = returnFlt (AbsCNop, stmt)
 flatAbsC stmt@(CSRT _ _)                       = returnFlt (AbsCNop, stmt)
+flatAbsC stmt@(CSRTDesc _ _ _ _ _)             = returnFlt (AbsCNop, stmt)
 flatAbsC stmt@(CBitmap _)                      = returnFlt (AbsCNop, stmt)
 flatAbsC stmt@(CCostCentreDecl _ _)            = returnFlt (AbsCNop, stmt)
 flatAbsC stmt@(CCostCentreStackDecl _)         = returnFlt (AbsCNop, stmt)
@@ -605,27 +607,24 @@ rrConflictsWithRR s1b s2b rr1 rr2 = rr rr1 rr2
 -- why it needs to take into account endianness.
 --
 mkHalfWord_HIADDR res arg
-   = mkTemp IntRep                     `thenFlt` \ t_hw_shift ->
-     mkTemp WordRep                    `thenFlt` \ t_hw_mask1 ->
+   = mkTemp WordRep                    `thenFlt` \ t_hw_mask1 ->
      mkTemp WordRep                    `thenFlt` \ t_hw_mask2 ->
-     let a_hw_shift 
-            = CMachOpStmt t_hw_shift
-                          MO_Nat_Shl [CBytesPerWord, CLit (mkMachInt 2)] Nothing
+     let 
+        hw_shift = mkIntCLit (wORD_SIZE_IN_BITS `quot` 2)
+
          a_hw_mask1
             = CMachOpStmt t_hw_mask1
-                          MO_Nat_Shl [CLit (mkMachWord 1), t_hw_shift] Nothing
+                          MO_Nat_Shl [CLit (mkMachWord 1), hw_shift] Nothing
          a_hw_mask2
             = CMachOpStmt t_hw_mask2
                           MO_Nat_Sub [t_hw_mask1, CLit (mkMachWord 1)] Nothing
          final
 #        if WORDS_BIGENDIAN
-            = CSequential [ a_hw_shift, a_hw_mask1, a_hw_mask2,
+            = CSequential [ a_hw_mask1, a_hw_mask2,
                  CMachOpStmt res MO_Nat_And [arg, t_hw_mask2] Nothing
               ]
 #        else
-            = CSequential [ a_hw_shift,
-                 CMachOpStmt res MO_Nat_Shr [arg, t_hw_shift] Nothing
-              ]
+            = CMachOpStmt res MO_Nat_Shr [arg, hw_shift] Nothing
 #        endif
      in
          returnFlt final
@@ -726,19 +725,6 @@ translateOp_dyadic_cast1 mop res cast_arg1_to arg1 arg2 vols
            (if isDefinitelyInlineMachOp mop then Nothing else Just vols)
      ]
 
-getBitsPerWordMinus1 :: FlatM (AbstractC, CAddrMode)
-getBitsPerWordMinus1
-   = mkTemps [IntRep, IntRep]          `thenFlt` \ [t1,t2] ->
-     returnFlt (
-        CSequential [
-           CMachOpStmt t1 MO_Nat_Shl 
-                       [CBytesPerWord, CLit (mkMachInt 3)] Nothing,
-           CMachOpStmt t2 MO_Nat_Sub
-                       [t1, CLit (mkMachInt 1)] Nothing
-        ],
-        t2
-     )
-
 -- IA64 mangler doesn't place tables next to code
 tablesNextToCode :: Bool
 #ifdef ia64_TARGET_ARCH
@@ -790,15 +776,14 @@ dscCOpStmt [res_r,res_c] IntAddCOp [aa,bb] vols
    c  = t4 >>unsigned BITS_IN(I_)-1
 -}
    = mkTemps [IntRep,IntRep,IntRep,IntRep]     `thenFlt` \ [t1,t2,t3,t4] ->
-     getBitsPerWordMinus1                      `thenFlt` \ (bpw1_code,bpw1_t) ->
+     let bpw1 = mkIntCLit (wORD_SIZE_IN_BITS - 1) in
      (returnFlt . CSequential) [
         CMachOpStmt res_r MO_Nat_Add [aa,bb] Nothing,
         CMachOpStmt t1 MO_Nat_Xor [aa,bb] Nothing,
         CMachOpStmt t2 MO_Nat_Not [t1] Nothing,
         CMachOpStmt t3 MO_Nat_Xor [aa,res_r] Nothing,
         CMachOpStmt t4 MO_Nat_And [t2,t3] Nothing,
-        bpw1_code,
-        CMachOpStmt res_c MO_Nat_Shr [t4, bpw1_t] Nothing
+        CMachOpStmt res_c MO_Nat_Shr [t4, bpw1] Nothing
      ]
 
 
@@ -818,14 +803,13 @@ dscCOpStmt [res_r,res_c] IntSubCOp [aa,bb] vols
    c  = t3 >>unsigned BITS_IN(I_)-1
 -}
    = mkTemps [IntRep,IntRep,IntRep]            `thenFlt` \ [t1,t2,t3] ->
-     getBitsPerWordMinus1                      `thenFlt` \ (bpw1_code,bpw1_t) ->
+     let bpw1 = mkIntCLit (wORD_SIZE_IN_BITS - 1) in
      (returnFlt . CSequential) [
         CMachOpStmt res_r MO_Nat_Sub [aa,bb] Nothing,
         CMachOpStmt t1 MO_Nat_Xor [aa,bb] Nothing,
         CMachOpStmt t2 MO_Nat_Xor [aa,res_r] Nothing,
         CMachOpStmt t3 MO_Nat_And [t1,t2] Nothing,
-        bpw1_code,
-        CMachOpStmt res_c MO_Nat_Shr [t3, bpw1_t] Nothing
+        CMachOpStmt res_c MO_Nat_Shr [t3, bpw1] Nothing
      ]
 
 
@@ -864,7 +848,7 @@ dscCOpStmt [res] SizeofByteArrayOp [arg] vols
    = mkTemp WordRep                    `thenFlt` \ w ->
      (returnFlt . CSequential) [
         CAssign w (mkDerefOff WordRep arg fixedHdrSize),
-        CMachOpStmt w MO_NatU_Mul [w, CBytesPerWord] (Just vols),
+        CMachOpStmt w MO_NatU_Mul [w, mkIntCLit wORD_SIZE] (Just vols),
         CAssign res w
      ]
 
index 437e5df..75e67e8 100644 (file)
@@ -9,6 +9,7 @@ module CLabel (
 
        mkClosureLabel,
        mkSRTLabel,
+       mkSRTDescLabel,
        mkInfoTableLabel,
        mkEntryLabel,
        mkSlowEntryLabel,
@@ -151,6 +152,7 @@ data CLabel
 data IdLabelInfo
   = Closure            -- Label for (static???) closure
   | SRT                 -- Static reference table
+  | SRTDesc             -- Static reference table descriptor
   | InfoTbl            -- Info tables for closures; always read-only
   | Entry              -- entry point
   | Slow               -- slow entry point
@@ -223,6 +225,7 @@ data CLabelType
 \begin{code}
 mkClosureLabel         id              = IdLabel id  Closure
 mkSRTLabel             id              = IdLabel id  SRT
+mkSRTDescLabel         id              = IdLabel id  SRTDesc
 mkInfoTableLabel       id              = IdLabel id  InfoTbl
 mkEntryLabel           id              = IdLabel id  Entry
 mkSlowEntryLabel       id              = IdLabel id  Slow
@@ -320,6 +323,7 @@ let-no-escapes, which can be recursive.
   -- don't bother declaring SRT & Bitmap labels, we always make sure
   -- they are defined before use.
 needsCDecl (IdLabel _ SRT)             = False
+needsCDecl (IdLabel _ SRTDesc)         = False
 needsCDecl (IdLabel _ Bitmap)          = False
 needsCDecl (IdLabel _ _)               = True
 needsCDecl (CaseLabel _ CaseReturnPt)  = True
@@ -446,6 +450,7 @@ internal names. <type> is one of the following:
 
         info                   Info table
         srt                    Static reference table
+        srtd                   Static reference table descriptor
         entry                  Entry code
         slow                   Slow entry code (if any)
         ret                    Direct return address    
@@ -572,6 +577,7 @@ ppIdFlavor x = pp_cSEP <>
               (case x of
                       Closure          -> ptext SLIT("closure")
                       SRT              -> ptext SLIT("srt")
+                      SRTDesc          -> ptext SLIT("srtd")
                       InfoTbl          -> ptext SLIT("info")
                       Entry            -> ptext SLIT("entry")
                       Slow             -> ptext SLIT("slow")
index 7094fbb..0d700a8 100644 (file)
@@ -53,11 +53,9 @@ import UniqSet               ( emptyUniqSet, elementOfUniqSet,
                          addOneToUniqSet, UniqSet
                        )
 import StgSyn          ( StgOp(..) )
-import BitSet          ( BitSet, intBS )
 import Outputable
 import FastString
 import Util            ( lengthExceeds )
-import Constants       ( wORD_SIZE )
 
 #if __GLASGOW_HASKELL__ >= 504
 import Data.Array.ST
@@ -299,11 +297,14 @@ pprAbsC stmt@(CSRT lbl closures) c
   }
 
 pprAbsC stmt@(CBitmap liveness@(Liveness lbl size mask)) c
-  = pp_liveness_switch liveness semi $
-    hcat [ ptext SLIT("BITMAP"), lparen,
-           pprCLabel lbl, comma,
-           int size, comma,
-           pp_bitmap mask, rparen ]
+  = pprWordArray lbl (mkWordCLit (fromIntegral size) : bitmapAddrModes mask)
+
+pprAbsC stmt@(CSRTDesc desc_lbl srt_lbl off len bitmap) c
+  = pprWordArray desc_lbl (
+       CAddr (CIndex (CLbl srt_lbl DataPtrRep) (mkIntCLit off) WordRep) :
+       mkWordCLit (fromIntegral len) :
+       bitmapAddrModes bitmap
+     )
 
 pprAbsC (CSimultaneous abs_c) c
   = hcat [ptext SLIT("{{"), pprAbsC abs_c c, ptext SLIT("}}")]
@@ -460,7 +461,7 @@ pprAbsC stmt@(CStaticClosure closure_lbl cl_info cost_centre amodes) _
        rep  = getAmodeRep item
 
 pprAbsC stmt@(CClosureInfoAndCode cl_info entry) _
-  =  pprInfoTable info_lbl (mkInfoTable cl_info)
+  =  pprWordArray info_lbl (mkInfoTable cl_info)
   $$ let stuff = CCodeBlock entry_lbl entry in
      pprAbsC stuff (costs stuff)
   where
@@ -477,7 +478,7 @@ pprAbsC stmt@(CClosureTbl tycon) _
    ) $$ ptext SLIT("};")
 
 pprAbsC stmt@(CRetDirect uniq code srt liveness) _
-  =  pprInfoTable info_lbl (mkRetInfoTable entry_lbl srt liveness)
+  =  pprWordArray info_lbl (mkRetInfoTable entry_lbl srt liveness)
   $$ let stuff = CCodeBlock entry_lbl code in
      pprAbsC stuff (costs stuff)
   where
@@ -485,7 +486,7 @@ pprAbsC stmt@(CRetDirect uniq code srt liveness) _
      entry_lbl = mkReturnPtLabel uniq
 
 pprAbsC stmt@(CRetVector lbl amodes srt liveness) _
-  = pprInfoTable lbl (mkVecInfoTable amodes srt liveness)
+  = pprWordArray lbl (mkVecInfoTable amodes srt liveness)
 
 pprAbsC stmt@(CModuleInitBlock plain_lbl lbl code) _
   = vcat [
@@ -504,12 +505,12 @@ Info tables... just arrays of words (the translation is done in
 ClosureInfo).
 
 \begin{code}
-pprInfoTable info_lbl amodes
+pprWordArray lbl amodes
   = (case snd (initTE (ppr_decls_Amodes amodes)) of
        Just pp -> pp
        Nothing -> empty)
-  $$ hcat [ ppLocalness info_lbl, ptext SLIT("StgWord "), 
-           pprCLabel info_lbl, ptext SLIT("[] = {") ]
+  $$ hcat [ ppLocalness lbl, ptext SLIT("StgWord "), 
+           pprCLabel lbl, ptext SLIT("[] = {") ]
   $$ hcat (punctuate comma (map (castToWord.pprAmode) amodes))
   $$ ptext SLIT("};")
 
@@ -1128,9 +1129,6 @@ That is, the indexing is done in units of kind1, but the resulting
 amode has kind2.
 
 \begin{code}
-ppr_amode CBytesPerWord
-  = text "(sizeof(void*))"
-
 ppr_amode (CVal reg_rel@(CIndex _ _ _) kind)
   = case (pprRegRelative False{-no sign wanted-} reg_rel) of
        (pp_reg, Nothing)     -> panic "ppr_amode: CIndex"
@@ -1213,9 +1211,6 @@ cCheckMacroText   HP_CHK_L1               = SLIT("HP_CHK_L1")
 cCheckMacroText        HP_CHK_UNBX_TUPLE       = SLIT("HP_CHK_UNBX_TUPLE")
 \end{code}
 
-\begin{code}
-\end{code}
-
 %************************************************************************
 %*                                                                     *
 \subsection[ppr-liveness-masks]{Liveness Masks}
@@ -1223,34 +1218,8 @@ cCheckMacroText  HP_CHK_UNBX_TUPLE       = SLIT("HP_CHK_UNBX_TUPLE")
 %************************************************************************
 
 \begin{code}
-pp_bitmap_switch :: Int -> SDoc -> SDoc -> SDoc
-pp_bitmap_switch size small large 
-  | size <= mAX_SMALL_BITMAP_SIZE = small
-  | otherwise = large
-
--- magic numbers, must agree with BITMAP_BITS_SHIFT in InfoTables.h
-mAX_SMALL_BITMAP_SIZE  | wORD_SIZE == 4 = 27
-                      | otherwise      = 58
-
-pp_liveness_switch :: Liveness -> SDoc -> SDoc -> SDoc
-pp_liveness_switch (Liveness _ size _) = pp_bitmap_switch size
-
-pp_bitset :: BitSet -> SDoc
-pp_bitset s
-    | i < -1    = int (i + 1) <> text "-1"
-    | otherwise = int i
-    where i = intBS s
-
-pp_bitmap :: [BitSet] -> SDoc
-pp_bitmap [] = int 0
-pp_bitmap ss = hcat (punctuate (ptext SLIT(" COMMA ")) (bundle ss)) where
-  bundle []         = []
-  bundle [s]        = [hcat bitmap32]
-     where bitmap32 = [ptext SLIT("BITMAP32"), lparen,
-                       pp_bitset s, rparen]
-  bundle (s1:s2:ss) = hcat bitmap64 : bundle ss
-     where bitmap64 = [ptext SLIT("BITMAP64"), lparen,
-                       pp_bitset s1, comma, pp_bitset s2, rparen]
+bitmapAddrModes [] = [mkWordCLit 0]
+bitmapAddrModes xs = map mkWordCLit xs
 \end{code}
 
 %************************************************************************
diff --git a/ghc/compiler/codeGen/Bitmap.hs b/ghc/compiler/codeGen/Bitmap.hs
new file mode 100644 (file)
index 0000000..ce0aa54
--- /dev/null
@@ -0,0 +1,79 @@
+--
+-- (c) The University of Glasgow 2003
+-- 
+
+-- 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
+  ) where
+
+#include "HsVersions.h"
+#include "../includes/MachDeps.h"
+
+import SMRep
+import Constants
+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. @[1,2,4], 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. @[1,2,4], size 4 ==> 0x8@  (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)) : 
+       intsToBitmap (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
+
index edfe45e..c91bbee 100644 (file)
@@ -36,7 +36,7 @@ import CgStackery     ( freeStackSlots, getStackFrame )
 import CLabel          ( mkClosureLabel,
                          mkBitmapLabel, pprCLabel )
 import ClosureInfo     ( mkLFImported, mkLFArgument, LambdaFormInfo )
-import BitSet
+import Bitmap
 import PrimRep         ( isFollowableRep, getPrimRepSize )
 import Id              ( Id, idPrimRep, idType )
 import Type            ( typePrimRep )
@@ -443,7 +443,7 @@ with initially all bits set (up to the size of the stack frame).
 buildLivenessMask 
        :: VirtualSpOffset      -- size of the stack frame
        -> VirtualSpOffset      -- offset from which the bitmap should start
-       -> FCode LivenessMask   -- mask for free/unlifted slots
+       -> FCode Bitmap         -- mask for free/unlifted slots
 
 buildLivenessMask size sp = do {
     -- find all live stack-resident pointers
@@ -459,24 +459,9 @@ buildLivenessMask size sp = do {
     };
 
     ASSERT(all (>=0) rel_slots)
-     return (listToLivenessMask size rel_slots)
+     return (intsToReverseBitmap size rel_slots)
   }
 
--- make a bitmap where the slots specified are the *zeros* in the bitmap.
--- eg. [1,2,4], size 4 ==> 0x8  (we leave any bits outside the size as zero,
--- just to make the bitmap easier to read).
-listToLivenessMask :: Int -> [Int] -> [BitSet]
-listToLivenessMask size slots{- must be sorted -}
-  | size <= 0 = []
-  | otherwise = init `minusBS` mkBS these : 
-       listToLivenessMask (size - 32) (map (\x -> x - 32) rest)
-   where (these,rest) = span (<32) slots
-        init
-          | size >= 32 = all_ones
-          | otherwise  = mkBS [0..size-1]
-
-        all_ones = mkBS [0..31]
-
 -- In a continuation, we want a liveness mask that starts from just after
 -- the return address, which is on the stack at realSp.
 
@@ -493,7 +478,7 @@ buildContLivenessMask name = do
        mask <- buildLivenessMask frame_size (realSp-1)
 
         let liveness = Liveness (mkBitmapLabel name) frame_size mask
-       absC (CBitmap liveness)
+       absC (maybeLargeBitmap liveness)
        return liveness
 \end{code}
 
index 10dc2c1..8c67334 100644 (file)
@@ -1,7 +1,7 @@
 %
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
-% $Id: CgCase.lhs,v 1.61 2002/12/11 15:36:25 simonmar Exp $
+% $Id: CgCase.lhs,v 1.62 2003/05/14 09:13:53 simonmar Exp $
 %
 %********************************************************
 %*                                                     *
@@ -53,7 +53,7 @@ import PrimOp         ( primOpOutOfLine, PrimOp(..) )
 import PrimRep         ( getPrimRepSize, retPrimRepSize, PrimRep(..)
                        )
 import TyCon           ( isEnumerationTyCon, isUnboxedTupleTyCon, tyConPrimRep )
-import Name            ( getName )
+import Name            ( Name, getName )
 import Unique           ( Unique, Uniquable(..), newTagUnique )
 import Maybes          ( maybeToBool )
 import Util            ( only )
@@ -389,9 +389,9 @@ cgEvalAlts :: Maybe VirtualSpOffset -- Offset of cost-centre to be restored, if
 
 cgEvalAlts cc_slot bndr srt alts
   =    
-    let uniq = getUnique bndr in
+    let uniq = getUnique bndr; name = getName bndr in
 
-    buildContLivenessMask (getName bndr)  `thenFC` \ liveness ->
+    buildContLivenessMask name  `thenFC` \ liveness ->
 
     case alts of
 
@@ -427,7 +427,7 @@ cgEvalAlts cc_slot bndr srt alts
                lbl = mkReturnInfoLabel uniq
            in
            cgUnboxedTupleAlt uniq cc_slot True alt             `thenFC` \ abs_c ->
-           getSRTInfo srt                                      `thenFC` \ srt_info -> 
+           getSRTInfo name srt                                 `thenFC` \ srt_info -> 
            absC (CRetDirect uniq abs_c srt_info liveness) `thenC`
            returnFC (CaseAlts (CLbl lbl RetRep) Nothing False)
 
@@ -450,7 +450,7 @@ cgEvalAlts cc_slot bndr srt alts
        cgAlgAlts GCMayHappen (not is_alg) uniq cc_slot use_labelled_alts
                alts deflt True `thenFC` \ (tagged_alt_absCs, deflt_absC) ->
 
-       mkReturnVector uniq tagged_alt_absCs deflt_absC srt liveness 
+       mkReturnVector name tagged_alt_absCs deflt_absC srt liveness 
                ret_conv  `thenFC` \ return_vec ->
 
        returnFC (CaseAlts return_vec semi_tagged_stuff False)
@@ -465,7 +465,7 @@ cgEvalAlts cc_slot bndr srt alts
        getAbsC (cgPrimEvalAlts bndr tycon alts deflt)  `thenFC` \ abs_c ->
 
        -- Generate the labelled block, starting with restore-cost-centre
-       getSRTInfo srt                                  `thenFC` \srt_info ->
+       getSRTInfo name srt                             `thenFC` \srt_info ->
        absC (CRetDirect uniq (cc_restore `mkAbsCStmts` abs_c) 
                         srt_info liveness)     `thenC`
 
@@ -810,7 +810,7 @@ Build a return vector, and return a suitable label addressing
 mode for it.
 
 \begin{code}
-mkReturnVector :: Unique
+mkReturnVector :: Name
               -> [(ConTag, AbstractC)] -- Branch codes
               -> AbstractC             -- Default case
               -> SRT                   -- continuation's SRT
@@ -818,8 +818,8 @@ mkReturnVector :: Unique
               -> CtrlReturnConvention
               -> FCode CAddrMode
 
-mkReturnVector uniq tagged_alt_absCs deflt_absC srt liveness ret_conv
-  = getSRTInfo srt             `thenFC` \ srt_info ->
+mkReturnVector name tagged_alt_absCs deflt_absC srt liveness ret_conv
+  = getSRTInfo name srt                `thenFC` \ srt_info ->
     let
      (return_vec_amode, vtbl_body) = case ret_conv of {
 
@@ -858,6 +858,7 @@ mkReturnVector uniq tagged_alt_absCs deflt_absC srt liveness ret_conv
     returnFC return_vec_amode
     -- )
   where
+    uniq = getUnique name 
 
     vtbl_label = mkVecTblLabel uniq
     ret_label = mkReturnInfoLabel uniq
index 20166c8..ee6dfd4 100644 (file)
@@ -1,7 +1,7 @@
 %
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
-% $Id: CgClosure.lhs,v 1.59 2002/12/11 15:36:25 simonmar Exp $
+% $Id: CgClosure.lhs,v 1.60 2003/05/14 09:13:53 simonmar Exp $
 %
 \section[CgClosure]{Code generation for closures}
 
@@ -70,8 +70,11 @@ cgTopRhsClosure :: Id
 
 cgTopRhsClosure id ccs binder_info srt args body lf_info
   = 
+    let
+       name          = idName id
+    in
     -- LAY OUT THE OBJECT
-    getSRTInfo srt             `thenFC` \ srt_info ->
+    getSRTInfo name srt                `thenFC` \ srt_info ->
     moduleName                 `thenFC` \ mod_name ->
     let
        name          = idName id
@@ -177,10 +180,12 @@ cgRhsClosure binder cc binder_info srt fvs args body lf_info
        reduced_fvs    = if binder_is_a_fv
                         then fvs `minusList` [binder]
                         else fvs
+
+       name = idName binder
     in
 
     mapFCs getCAddrModeAndInfo reduced_fvs     `thenFC` \ fvs_w_amodes_and_info ->
-    getSRTInfo srt                             `thenFC` \ srt_info ->
+    getSRTInfo name srt                                `thenFC` \ srt_info ->
     moduleName                                 `thenFC` \ mod_name ->
     let
        descr = closureDescription mod_name (idName binder)
@@ -303,7 +308,7 @@ closureCodeBody binder_info closure_info cc all_args body
     --
     (case closureFunInfo closure_info of
        Just (_, ArgGen slow_lbl liveness) -> 
-               absC (CBitmap liveness) `thenC`
+               absC (maybeLargeBitmap liveness) `thenC`
                absC (mkSlowEntryCode name slow_lbl arg_regs arg_reps) `thenC`
                returnFC (mkRegSaveCode arg_regs arg_reps)
 
index 324c5cc..9b654b9 100644 (file)
@@ -66,9 +66,8 @@ import List           ( partition )
 cgTopRhsCon :: Id              -- Name of thing bound to this RHS
            -> DataCon          -- Id
            -> [StgArg]         -- Args
-           -> SRT
            -> FCode (Id, CgIdInfo)
-cgTopRhsCon id con args srt
+cgTopRhsCon id con args
   = ASSERT( not (isDllConApp con args) )       -- checks for litlit args too
     ASSERT( args `lengthIs` dataConRepArity con )
 
@@ -81,6 +80,7 @@ cgTopRhsCon id con args srt
        closure_label = mkClosureLabel name
        (closure_info, amodes_w_offsets) 
                = layOutStaticConstr con getAmodeRep amodes
+       caffy = any stgArgHasCafRefs args
     in
 
        -- BUILD THE OBJECT
@@ -89,7 +89,7 @@ cgTopRhsCon id con args srt
            closure_info
            dontCareCCS                 -- because it's static data
            (map fst amodes_w_offsets)  -- Sorted into ptrs first, then nonptrs
-           (nonEmptySRT srt)           -- has CAF refs
+           caffy                       -- has CAF refs
          )                                     `thenC`
                -- NOTE: can't use idCafInfo instead of nonEmptySRT above,
                -- because top-level constructors that were floated by
index c5fa38a..14e2758 100644 (file)
@@ -1,7 +1,7 @@
 %
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
-% $Id: CgExpr.lhs,v 1.52 2002/12/11 15:36:26 simonmar Exp $
+% $Id: CgExpr.lhs,v 1.53 2003/05/14 09:13:55 simonmar Exp $
 %
 %********************************************************
 %*                                                     *
@@ -212,14 +212,14 @@ cgExpr (StgCase expr live_vars save_vars bndr srt alts)
 \subsection[let-and-letrec-codegen]{Converting @StgLet@ and @StgLetrec@}
 
 \begin{code}
-cgExpr (StgLet (StgNonRec srt name rhs) expr)
-  = cgRhs srt name rhs `thenFC` \ (name, info) ->
+cgExpr (StgLet (StgNonRec name rhs) expr)
+  = cgRhs name rhs     `thenFC` \ (name, info) ->
     addBindC name info         `thenC`
     cgExpr expr
 
-cgExpr (StgLet (StgRec srt pairs) expr)
+cgExpr (StgLet (StgRec pairs) expr)
   = fixC (\ new_bindings -> addBindsC new_bindings `thenC`
-                           listFCs [ cgRhs srt b e | (b,e) <- pairs ]
+                           listFCs [ cgRhs b e | (b,e) <- pairs ]
     ) `thenFC` \ new_bindings ->
 
     addBindsC new_bindings `thenC`
@@ -278,15 +278,15 @@ We rely on the support code in @CgCon@ (to do constructors) and
 in @CgClosure@ (to do closures).
 
 \begin{code}
-cgRhs :: SRT -> Id -> StgRhs -> FCode (Id, CgIdInfo)
+cgRhs :: Id -> StgRhs -> FCode (Id, CgIdInfo)
        -- the Id is passed along so a binding can be set up
 
-cgRhs srt name (StgRhsCon maybe_cc con args)
+cgRhs name (StgRhsCon maybe_cc con args)
   = getArgAmodes args                          `thenFC` \ amodes ->
     buildDynCon name maybe_cc con amodes       `thenFC` \ idinfo ->
     returnFC (name, idinfo)
 
-cgRhs srt name (StgRhsClosure cc bi fvs upd_flag args body)
+cgRhs name (StgRhsClosure cc bi fvs upd_flag srt args body)
   = mkRhsClosure name cc bi srt fvs upd_flag args body
 \end{code}
 
@@ -395,18 +395,17 @@ mkRhsClosure bndr cc bi srt fvs upd_flag args body
 %********************************************************
 \begin{code}
 cgLetNoEscapeBindings live_in_rhss rhs_eob_info maybe_cc_slot 
-       (StgNonRec srt binder rhs)
+       (StgNonRec binder rhs)
   = cgLetNoEscapeRhs live_in_rhss rhs_eob_info maybe_cc_slot   
-                       NonRecursive srt binder rhs 
+                       NonRecursive binder rhs 
                                `thenFC` \ (binder, info) ->
     addBindC binder info
 
-cgLetNoEscapeBindings live_in_rhss rhs_eob_info maybe_cc_slot 
-       (StgRec srt pairs)
+cgLetNoEscapeBindings live_in_rhss rhs_eob_info maybe_cc_slot (StgRec pairs)
   = fixC (\ new_bindings ->
                addBindsC new_bindings  `thenC`
                listFCs [ cgLetNoEscapeRhs full_live_in_rhss 
-                               rhs_eob_info maybe_cc_slot Recursive srt b e 
+                               rhs_eob_info maybe_cc_slot Recursive b e 
                        | (b,e) <- pairs ]
     ) `thenFC` \ new_bindings ->
 
@@ -421,13 +420,12 @@ cgLetNoEscapeRhs
     -> EndOfBlockInfo
     -> Maybe VirtualSpOffset
     -> RecFlag
-    -> SRT
     -> Id
     -> StgRhs
     -> FCode (Id, CgIdInfo)
 
-cgLetNoEscapeRhs full_live_in_rhss rhs_eob_info maybe_cc_slot rec srt binder
-                (StgRhsClosure cc bi _ upd_flag args body)
+cgLetNoEscapeRhs full_live_in_rhss rhs_eob_info maybe_cc_slot rec binder
+                (StgRhsClosure cc bi _ upd_flag srt args body)
   = -- We could check the update flag, but currently we don't switch it off
     -- for let-no-escaped things, so we omit the check too!
     -- case upd_flag of
@@ -439,9 +437,9 @@ cgLetNoEscapeRhs full_live_in_rhss rhs_eob_info maybe_cc_slot rec srt binder
 -- For a constructor RHS we want to generate a single chunk of code which
 -- can be jumped to from many places, which will return the constructor.
 -- It's easy; just behave as if it was an StgRhsClosure with a ConApp inside!
-cgLetNoEscapeRhs full_live_in_rhss rhs_eob_info maybe_cc_slot rec srt binder
+cgLetNoEscapeRhs full_live_in_rhss rhs_eob_info maybe_cc_slot rec binder
                 (StgRhsCon cc con args)
-  = cgLetNoEscapeClosure binder cc noBinderInfo{-safe-} srt
+  = cgLetNoEscapeClosure binder cc noBinderInfo{-safe-} NoSRT
                         full_live_in_rhss rhs_eob_info maybe_cc_slot rec
        []      --No args; the binder is data structure, not a function
        (StgConApp con args)
index 66c46e9..a7521a3 100644 (file)
@@ -1,7 +1,7 @@
 %
 % (c) The GRASP/AQUA Project, Glasgow University, 1993-1998
 %
-% $Id: CgLetNoEscape.lhs,v 1.19 2002/12/11 15:36:26 simonmar Exp $
+% $Id: CgLetNoEscape.lhs,v 1.20 2003/05/14 09:13:56 simonmar Exp $
 %
 %********************************************************
 %*                                                     *
@@ -33,7 +33,7 @@ import CLabel         ( mkReturnInfoLabel )
 import ClosureInfo     ( mkLFLetNoEscape )
 import CostCentre       ( CostCentreStack )
 import Name            ( getName )
-import Id              ( idPrimRep, Id )
+import Id              ( Id, idPrimRep, idName )
 import Var             ( idUnique )
 import PrimRep         ( PrimRep(..), retPrimRepSize, isFollowableRep )
 import BasicTypes      ( RecFlag(..) )
@@ -178,7 +178,7 @@ cgLetNoEscapeClosure
         buildContLivenessMask (getName binder) `thenFC` \ liveness ->
         forkAbsC (cgLetNoEscapeBody binder cc args body uniq) 
                                                `thenFC` \ code ->
-        getSRTInfo srt                         `thenFC` \ srt_info -> 
+        getSRTInfo (idName binder) srt         `thenFC` \ srt_info -> 
         absC (CRetDirect uniq code srt_info liveness)
                `thenC` returnFC ())
                                        `thenFC` \ (vSp, _) ->
index a14b77a..99c776e 100644 (file)
@@ -1,7 +1,7 @@
 %
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
-% $Id: CgMonad.lhs,v 1.37 2003/01/07 14:31:20 simonmar Exp $
+% $Id: CgMonad.lhs,v 1.38 2003/05/14 09:13:56 simonmar Exp $
 %
 \section[CgMonad]{The code generation monad}
 
@@ -60,8 +60,10 @@ import CmdLineOpts   ( opt_SccProfilingOn, opt_DoTickyProfiling )
 import Module          ( Module )
 import DataCon         ( ConTag )
 import Id              ( Id )
+import Name            ( Name )
 import VarEnv
 import PrimRep         ( PrimRep(..) )
+import SMRep           ( StgHalfWord, hALF_WORD )
 import FastString
 import Outputable
 
@@ -605,16 +607,25 @@ bindings use sub-sections of this SRT.  The label is passed down to
 the nested bindings via the monad.
 
 \begin{code}
-getSRTInfo :: SRT -> FCode C_SRT
-getSRTInfo NoSRT        = return NoC_SRT
-getSRTInfo (SRT off len) = do srt_lbl <- getSRTLabel
-                             return (C_SRT srt_lbl off len)
+getSRTInfo :: Name -> SRT -> FCode C_SRT
+getSRTInfo id NoSRT = return NoC_SRT
+getSRTInfo id (SRT off len bmp)
+  | len > hALF_WORD || bmp == [fromIntegral srt_escape] = do 
+       srt_lbl <- getSRTLabel
+       let srt_desc_lbl = mkSRTDescLabel id
+       absC (CSRTDesc srt_desc_lbl srt_lbl off len bmp)
+       return (C_SRT srt_desc_lbl 0 srt_escape)
+  | otherwise = do
+       srt_lbl <- getSRTLabel
+       return (C_SRT srt_lbl off (fromIntegral (head bmp)))
+
+srt_escape = (-1) :: StgHalfWord
 
 getSRTLabel :: FCode CLabel    -- Used only by cgPanic
 getSRTLabel = do MkCgInfoDown _ _ srt_lbl _ _ <- getInfoDown
                 return srt_lbl
 
-setSRTLabel :: CLabel -> Code -> Code
+setSRTLabel :: CLabel -> FCode a -> FCode a
 setSRTLabel srt_lbl code
   = do  MkCgInfoDown c_info statics _ ticky eob_info <- getInfoDown
        withInfoDown code (MkCgInfoDown c_info statics srt_lbl ticky eob_info)
index 02bdd47..9965895 100644 (file)
@@ -1,7 +1,7 @@
 %
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
-% $Id: CgTailCall.lhs,v 1.36 2002/12/11 15:36:27 simonmar Exp $
+% $Id: CgTailCall.lhs,v 1.37 2003/05/14 09:13:56 simonmar Exp $
 %
 %********************************************************
 %*                                                     *
@@ -346,12 +346,6 @@ mkStaticAlgReturnCode con sequel
 
        -- Generate the right jump or return
     (case sequel of
-       UpdateCode ->   -- Ha!  We can go direct to the update code,
-                       -- (making sure to jump to the *correct* update
-                       --  code.)
-                       absC (CReturn (CLbl mkUpdInfoLabel CodePtrRep)
-                                     return_info)
-
        CaseAlts _ (Just (alts, _)) False -> -- Ho! We know the constructor so
                                        -- we can go right to the alternative
 
@@ -363,7 +357,8 @@ mkStaticAlgReturnCode con sequel
                                -- it's the subject of a wad of special-case 
                                -- code in cgReturnCon
 
-       other ->        -- OnStack, or (CaseAlts ret_amode Nothing)
+       other ->        -- OnStack, or (CaseAlts ret_amode Nothing),
+                       -- or UpdateCode.
                    sequelToAmode sequel        `thenFC` \ ret_amode ->
                    absC (CReturn ret_amode return_info)
     )
index 2ce87b7..651c007 100644 (file)
@@ -1,7 +1,7 @@
 %
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
-% $Id: ClosureInfo.lhs,v 1.56 2002/12/12 11:53:11 simonmar Exp $
+% $Id: ClosureInfo.lhs,v 1.57 2003/05/14 09:13:56 simonmar Exp $
 %
 \section[ClosureInfo]{Data structures which describe closures}
 
@@ -85,10 +85,9 @@ import FastString
 import Outputable
 import Literal
 import Constants
-import BitSet
+import Bitmap
 
 import Maybe           ( isJust )
-import DATA_WORD
 import DATA_BITS
 \end{code}
 
@@ -1106,19 +1105,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,14 +1125,6 @@ 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
@@ -1168,13 +1152,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,9 +1166,9 @@ 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 = mkWordCLit layout_info
@@ -1215,10 +1199,10 @@ mkInfoTable cl_info
        | 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
 
@@ -1252,13 +1236,13 @@ mkBitmapInfoTable entry_amode srt liveness vector
                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
@@ -1280,7 +1264,7 @@ 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
@@ -1307,11 +1291,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
@@ -1324,13 +1308,8 @@ livenessToAddrMode (Liveness lbl size bits)
          small = mkWordCLit (fromIntegral size .|. (small_bits `shiftL` bITMAP_BITS_SHIFT))
          small_bits = case bits of 
                        []  -> 0
-                       [b] -> fromIntegral (intBS b)
+                       [b] -> fromIntegral b
                        _   -> panic "livenessToAddrMode"
 
-mAX_SMALL_BITMAP_SIZE = (wORD_SIZE * 8) - bITMAP_BITS_SHIFT
-
-mkWordCLit :: StgWord -> CAddrMode
-mkWordCLit wd = CLit (MachWord (fromIntegral wd)) 
-
 zero_amode = mkIntCLit 0
 \end{code}
index 5bcfc69..724352c 100644 (file)
@@ -29,7 +29,7 @@ import StgSyn
 import CgMonad
 import AbsCSyn
 import PrelNames       ( gHC_PRIM )
-import CLabel          ( CLabel, mkSRTLabel, mkClosureLabel, 
+import CLabel          ( mkSRTLabel, mkClosureLabel, 
                          mkPlainModuleInitLabel, mkModuleInitLabel )
 import PprAbsC         ( dumpRealC )
 import AbsCUtils       ( mkAbstractCs, flattenAbsC )
@@ -40,8 +40,7 @@ import CgConTbls      ( genStaticConBits )
 import ClosureInfo     ( mkClosureLFInfo )
 import CmdLineOpts     ( DynFlags, DynFlag(..),
                          opt_SccProfilingOn, opt_EnsureSplittableC )
-import HscTypes                ( ModGuts(..), ModGuts, ForeignStubs(..), TypeEnv,
-                         typeEnvTyCons )
+import HscTypes                ( ForeignStubs(..), TypeEnv, typeEnvTyCons )
 import CostCentre       ( CollectedCCs )
 import Id               ( Id, idName, setIdName )
 import Name            ( nameSrcLoc, nameOccName, nameUnique, isInternalName, mkExternalName )
@@ -68,7 +67,7 @@ codeGen :: DynFlags
        -> ForeignStubs
        -> [Module]             -- directly-imported modules
        -> CollectedCCs         -- (Local/global) cost-centres needing declaring/registering.
-       -> [(StgBinding,[Id])]  -- Bindings to convert, with SRTs
+       -> [(StgBinding,[(Id,[Id])])]   -- Bindings to convert, with SRTs
        -> IO AbstractC         -- Output
 
 codeGen dflags this_mod type_env foreign_stubs imported_mods 
@@ -202,43 +201,39 @@ style, with the increasing static environment being plumbed as a state
 variable.
 
 \begin{code}
-cgTopBinding :: (StgBinding,[Id]) -> Code
-cgTopBinding (StgNonRec srt_info id rhs, srt)
+cgTopBinding :: (StgBinding,[(Id,[Id])]) -> Code
+cgTopBinding (StgNonRec id rhs, srts)
   = absC maybeSplitCode                `thenC`
-    maybeExternaliseId id              `thenFC` \ id' ->
-    let
-       srt_label = mkSRTLabel (idName id')
-    in
-    mkSRT srt_label srt []     `thenC`
-    setSRTLabel srt_label (
-    cgTopRhs id' rhs srt_info          `thenFC` \ (id, info) ->
-    addBindC id info   -- Add the un-externalised Id to the envt, so we
-                       -- find it when we look up occurrences
-    )
-
-cgTopBinding (StgRec srt_info pairs, srt)
+    maybeExternaliseId id      `thenFC` \ id' ->
+    mapM_ (mkSRT [id']) srts   `thenC`
+    cgTopRhs id' rhs           `thenFC` \ (id, info) ->
+    addBindC id info           `thenC`
+       -- Add the un-externalised Id to the envt, so we
+       -- find it when we look up occurrences
+    nopC
+
+cgTopBinding (StgRec pairs, srts)
   = absC maybeSplitCode                        `thenC`
     let
         (bndrs, rhss) = unzip pairs
     in
-    mapFCs maybeExternaliseId bndrs    `thenFC` \ bndrs'@(id:_) ->
+    mapFCs maybeExternaliseId bndrs    `thenFC` \ bndrs' ->
     let
-       srt_label = mkSRTLabel (idName id)
-       pairs'    = zip bndrs' rhss
+       pairs' = zip bndrs' rhss
     in
-    mkSRT srt_label srt bndrs'         `thenC`
-    setSRTLabel srt_label (
-       fixC (\ new_binds -> 
+    mapM_ (mkSRT bndrs')  srts         `thenC`
+    fixC (\ new_binds -> 
                addBindsC new_binds             `thenC`
-               mapFCs ( \ (b,e) -> cgTopRhs b e srt_info ) pairs'
-       )  `thenFC` \ new_binds -> nopC
-    )
+               mapFCs ( \ (b,e) -> cgTopRhs b e ) pairs'
+     )  `thenFC` \ new_binds -> 
+     nopC
 
-mkSRT :: CLabel -> [Id] -> [Id] -> Code
-mkSRT lbl []  these = nopC
-mkSRT lbl ids these
+mkSRT :: [Id] -> (Id,[Id]) -> Code
+mkSRT these (id,[])  = nopC
+mkSRT these (id,ids)
   = mapFCs remap ids `thenFC` \ ids ->
-    absC (CSRT lbl (map (mkClosureLabel . idName) ids))
+    remap id        `thenFC` \ id ->
+    absC (CSRT (mkSRTLabel (idName id)) (map (mkClosureLabel . idName) ids))
   where
        -- sigh, better map all the ids against the environment in case they've
        -- been externalised (see maybeExternaliseId below).
@@ -251,19 +246,21 @@ mkSRT lbl ids these
 -- to enclose the listFCs in cgTopBinding, but that tickled the
 -- statics "error" call in initC.  I DON'T UNDERSTAND WHY!
 
-cgTopRhs :: Id -> StgRhs -> SRT -> FCode (Id, CgIdInfo)
+cgTopRhs :: Id -> StgRhs -> FCode (Id, CgIdInfo)
        -- The Id is passed along for setting up a binding...
        -- It's already been externalised if necessary
 
-cgTopRhs bndr (StgRhsCon cc con args) srt
-  = forkStatics (cgTopRhsCon bndr con args srt)
+cgTopRhs bndr (StgRhsCon cc con args)
+  = forkStatics (cgTopRhsCon bndr con args)
 
-cgTopRhs bndr (StgRhsClosure cc bi fvs upd_flag args body) srt
+cgTopRhs bndr (StgRhsClosure cc bi fvs upd_flag srt args body)
   = ASSERT(null fvs)    -- There should be no free variables
     let 
+       srt_label = mkSRTLabel (idName bndr)
        lf_info = mkClosureLFInfo bndr TopLevel [{-no fvs-}] upd_flag args
     in
-    forkStatics (cgTopRhsClosure bndr cc bi srt args body lf_info)
+    setSRTLabel srt_label $ 
+      forkStatics (cgTopRhsClosure bndr cc bi srt args body lf_info)
 \end{code}
 
 
index 6838287..4f53f4b 100644 (file)
@@ -12,20 +12,21 @@ module SMRep (
        isStaticRep,
        fixedHdrSize, arrWordsHdrSize, arrPtrsHdrSize,
         stdItblSize, retItblSize,
-       getSMRepClosureTypeInt
+       getSMRepClosureTypeInt,
 
-       , rET_SMALL
-       , rET_VEC_SMALL
-       , rET_BIG
-       , rET_VEC_BIG
+       rET_SMALL, rET_VEC_SMALL, rET_BIG, rET_VEC_BIG,
 
+       StgWord, StgHalfWord, hALF_WORD,
     ) where
 
 #include "HsVersions.h"
+#include "../includes/MachDeps.h"
 
 import CmdLineOpts
 import Constants
 import Outputable
+
+import DATA_WORD
 \end{code}
 
 %************************************************************************
@@ -148,3 +149,19 @@ rET_VEC_SMALL = (RET_VEC_SMALL :: Int)
 rET_BIG       = (RET_BIG       :: Int)
 rET_VEC_BIG   = (RET_VEC_BIG   :: Int)
 \end{code}
+
+A type representing an StgWord on the target platform.
+
+\begin{code}
+#if SIZEOF_HSWORD == 4
+type StgWord     = Word32
+type StgHalfWord = Word16
+hALF_WORD = 16 :: Int
+#elif SIZEOF_HSWORD == 8
+type StgWord     = Word64
+type StgHalfWord = Word32
+hALF_WORD = 32 :: Int
+#else
+#error unknown SIZEOF_HSWORD
+#endif
+\end{code}
index 599eb1c..d1a737a 100644 (file)
@@ -29,6 +29,7 @@ import PrimOp         ( PrimOp )
 import PrimRep         ( PrimRep(..), isFollowableRep, is64BitRep )
 import Constants       ( wORD_SIZE )
 import FastString      ( FastString(..), unpackFS )
+import SMRep           ( StgWord )
 import FiniteMap
 import Outputable
 
index d5dca0e..3a704a7 100644 (file)
@@ -52,7 +52,8 @@ import Unique         ( mkPseudoUnique3 )
 import FastString      ( FastString(..), unpackFS )
 import Panic           ( GhcException(..) )
 import PprType         ( pprType )
-import SMRep           ( arrWordsHdrSize, arrPtrsHdrSize )
+import SMRep           ( arrWordsHdrSize, arrPtrsHdrSize, StgWord )
+import Bitmap          ( intsToReverseBitmap, mkBitmap )
 import OrdList
 import Constants       ( wORD_SIZE )
 import BasicTypes      ( TopLevelFlag(..), isTopLevel, isNotTopLevel )
@@ -206,32 +207,6 @@ argBits (rep : args)
   | isFollowableRep rep = False : argBits args
   | otherwise = take (getPrimRepSize rep) (repeat True) ++ argBits args
 
-mkBitmap :: [Bool] -> [StgWord]
-mkBitmap [] = []
-mkBitmap stuff = chunkToLiveness chunk : mkBitmap rest
-  where (chunk, rest) = splitAt wORD_SIZE_IN_BITS stuff
-
-chunkToLiveness :: [Bool] -> StgWord
-chunkToLiveness chunk = 
-  foldr (.|.) 0 [ 1 `shiftL` n | (True,n) <- zip chunk [0..] ]
-
--- make a bitmap where the slots specified are the *zeros* in the bitmap.
--- eg. [1,2,4], size 4 ==> 0x8  (we leave any bits outside the size as zero,
--- just to make the bitmap easier to read).
-intsToBitmap :: Int -> [Int] -> [StgWord]
-intsToBitmap size slots{- must be sorted -}
-  | size <= 0 = []
-  | otherwise = 
-    (foldr xor init (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
-        init
-          | size >= wORD_SIZE_IN_BITS = complement 0
-          | otherwise                 = (1 `shiftL` size) - 1
-
-wORD_SIZE_IN_BITS = wORD_SIZE * 8 :: Int
-
 -- -----------------------------------------------------------------------------
 -- schemeTopBind
 
@@ -759,7 +734,7 @@ doCase d s p (_,scrut)
        -- things that are pointers, whereas in CgBindery the code builds the
        -- bitmap from the free slots and unboxed bindings.
        -- (ToDo: merge?)
-       bitmap = intsToBitmap d{-size-} (sortLt (<) rel_slots)
+       bitmap = intsToReverseBitmap d{-size-} (sortLt (<) rel_slots)
          where
          binds = fmToList p
          rel_slots = concat (map spread binds)
index 0d812e4..05c4fe4 100644 (file)
@@ -5,11 +5,11 @@
 
 \begin{code}
 module ByteCodeInstr ( 
-       BCInstr(..), ProtoBCO(..), StgWord, bciStackUse
+       BCInstr(..), ProtoBCO(..), bciStackUse
   ) where
 
 #include "HsVersions.h"
-#include "MachDeps.h"
+#include "../includes/MachDeps.h"
 
 import Outputable
 import Name            ( Name )
@@ -21,20 +21,12 @@ import PrimRep              ( PrimRep )
 import DataCon         ( DataCon )
 import VarSet          ( VarSet )
 import PrimOp          ( PrimOp )
+import SMRep           ( StgWord )
 import GHC.Ptr
 
-import Data.Word
-
 -- ----------------------------------------------------------------------------
 -- Bytecode instructions
 
--- The appropriate StgWord type for this platform (needed for bitmaps)
-#if SIZEOF_HSWORD == 4
-type StgWord = Word32
-#else
-type StgWord = Word64
-#endif
-
 data ProtoBCO a 
    = ProtoBCO { 
        protoBCOName       :: a,          -- name, in some sense
index 9c32fa1..5c35e58 100644 (file)
@@ -61,6 +61,7 @@ module Constants (
        wORD64_SIZE,
        
        wORD_SIZE,
+       wORD_SIZE_IN_BITS,
 
        bLOCK_SIZE,
        bLOCK_SIZE_W,
@@ -220,6 +221,7 @@ Size of a word, in bytes
 
 \begin{code}
 wORD_SIZE = (SIZEOF_HSWORD :: Int)
+wORD_SIZE_IN_BITS = wORD_SIZE * 8 :: Int
 \end{code}
 
 Size of a storage manager block (in bytes).
index 05e0a5d..08fb706 100644 (file)
@@ -38,7 +38,6 @@ import Constants      ( wORD_SIZE, bITMAP_BITS_SHIFT )
 import Name             ( NamedThing(..) )
 import CmdLineOpts     ( opt_Static, opt_EnsureSplittableC )
 import Outputable      ( assertPanic )
-import BitSet          ( BitSet, intBS )
 
 -- DEBUGGING ONLY
 --import TRACE         ( trace )
@@ -83,14 +82,9 @@ Here we handle top-level things, like @CCodeBlock@s and
 
  gentopcode stmt@(CStaticClosure lbl closure_info _ _)
   = genCodeStaticClosure stmt                  `thenUs` \ code ->
-    returnUs (
-       if   opt_Static
-       then StSegment DataSegment 
-            : StLabel lbl : code []
-       else StSegment DataSegment 
-            : StData PtrRep [StInt 0] -- DLLised world, need extra zero word
-            : StLabel lbl : code []
-    )
+    returnUs ( StSegment DataSegment 
+             : StLabel lbl : code []
+             )
 
  gentopcode stmt@(CRetVector lbl amodes srt liveness)
   = returnUs ( StSegment TextSegment
@@ -139,18 +133,21 @@ Here we handle top-level things, like @CCodeBlock@s and
           = StCLbl label
 
  gentopcode stmt@(CBitmap l@(Liveness lbl size mask))
-  | isBigLiveness l
   = returnUs 
        [ StSegment TextSegment 
        , StLabel lbl 
-       , StData WordRep (map StInt (toInteger size : bitmapToIntegers mask))
+       , StData WordRep (map StInt (toInteger size : map toInteger mask))
+       ]
+
+ gentopcode stmt@(CSRTDesc lbl srt_lbl off len bitmap)
+  = returnUs 
+       [ StSegment TextSegment 
+       , StLabel lbl 
+       , StData WordRep (
+               StIndex PtrRep (StCLbl srt_lbl) (StInt (toInteger off)) :
+               map StInt (toInteger len : map toInteger bitmap)
+           )
        ]
-  | otherwise
-  = returnUs []
-  where
-    -- ToDo: translate out bitmaps earlier, like info tables
-    isBigLiveness (Liveness _ size _) = size > mAX_SMALL_BITMAP_SIZE
-    mAX_SMALL_BITMAP_SIZE = (wORD_SIZE * 8) - bITMAP_BITS_SHIFT
 
  gentopcode stmt@(CClosureTbl tycon)
   = returnUs [ StSegment TextSegment
@@ -658,25 +655,6 @@ mkJoin code lbl
 
 %---------------------------------------------------------------------------
 
-\begin{code}
-bitmapToIntegers :: [BitSet] -> [Integer]
-bitmapToIntegers = bundle . map (toInteger . intBS)
-  where
-#if BYTES_PER_WORD == 4
-    bundle = id
-#else
-    bundle [] = []
-    bundle is = case splitAt (BYTES_PER_WORD/4) is of
-                (these, those) ->
-                   ( foldr1 (\x y -> x + 4294967296 * y)
-                            [x `mod` 4294967296 | x <- these]
-                   : bundle those
-                   )
-#endif
-\end{code}
-
-%---------------------------------------------------------------------------
-
 This answers the question: Can the code fall through to the next
 line(s) of code?  This errs towards saying True if it can't choose,
 because it is used for eliminating needless jumps.  In other words, if
index 40a2ad4..1721e73 100644 (file)
@@ -142,9 +142,6 @@ amodeToStix am@(CVal rr CharRep)
 
 amodeToStix (CVal rr pk) = StInd pk (amodeToStix (CAddr rr))
 
-amodeToStix CBytesPerWord
-  = StInt (toInteger wORD_SIZE)
-
 amodeToStix (CAddr (SpRel off))
   = StIndex PtrRep (StReg stgSp) (StInt (toInteger (iBox off)))
 
index 86fb305..89ef8e4 100644 (file)
@@ -14,233 +14,170 @@ module SRT( computeSRTs ) where
 import StgSyn
 import Id              ( Id )
 import VarSet
-import BasicTypes      ( TopLevelFlag(..), isTopLevel )
-import Util            ( mapAccumL )
+import VarEnv
+import Util            ( sortLt )
+import Maybes          ( orElse )
+import Maybes          ( expectJust )
+import Bitmap          ( intsToBitmap )
 
 #ifdef DEBUG
-import Util            ( lengthIs )
 import Outputable
 #endif
-\end{code}
 
-\begin{code}
-computeSRTs :: [StgBinding] -> [(StgBinding,[Id])]
-  -- The incoming bindingd are filled with SRTEntries in their SRT slots
-  -- the outgoing ones have NoSRT/SRT values instead
+import List
 
-computeSRTs binds = map srtTopBind binds
+import Util
+import Outputable
 \end{code}
 
------------------------------------------------------------------------------
-Algorithm for figuring out SRT layout.
-
-Our functions have type
-
-srtExpr        :: SrtOffset            -- Next free offset within the SRT
-       -> StgExpr              -- Expression to analyse
-       -> (StgExpr,            -- (e) newly annotated expression
-           SrtIds,             -- (s) SRT required for this expression (reversed)
-           SrtOffset)          -- (o) new offset
-
-We build a single SRT for a recursive binding group, which is why the
-SRT building is done at the binding level rather than the
-StgRhsClosure level.
-
-The SRT is built up in reverse order, to avoid too many expensive
-appends.  We therefore reverse the SRT before returning it, so that
-the offsets will be from the beginning of the SRT.
-
------------------------------------------------------------------------------
-Top-level Bindings
-
-A function whose CafInfo is NoCafRefs will have an empty SRT, and its
-closure will not appear in the SRT of any other function (unless we're
-compiling without optimisation and the CafInfos haven't been emitted
-in the interface files).
-
-Top-Level recursive groups
-
-This gets a bit complicated, but the general idea is that we want a
-single SRT for the whole group, and we'd rather not have recursive
-references in it if at all possible.
-
-We collect all the global references for the group, and filter out
-those that are binders in the group and not CAFs themselves.  Why is
-it done this way?
-
-       - if all the bindings in the group just refer to each other,
-         and none of them are CAFs, we'd like to get an empty SRT.
-
-       - if any of the bindings in the group refer to a CAF, this will
-         appear in the SRT.
-
-Hmm, that probably makes no sense.
-
 \begin{code}
-type SrtOffset = Int
-type SrtIds    = [Id]  -- An *reverse-ordered* list of the Ids needed in the SRT
-
-srtTopBind :: StgBinding -> (StgBinding, SrtIds)
-
-srtTopBind bind
-  = srtBind TopLevel 0 bind    =: \ (bind', srt, off) ->
-    if isConBind bind'
-       then (bind', [])           -- Don't need an SRT for a static constructor
-       else (bind', reverse srt)  -- The 'reverse' is because the SRT is 
-                                  -- built up reversed, for efficiency's sake
+computeSRTs :: [StgBinding] -> [(StgBinding,[(Id,[Id])])]
+  -- The incoming bindingd are filled with SRTEntries in their SRT slots
+  -- the outgoing ones have NoSRT/SRT values instead
 
-isConBind (StgNonRec _ _ r) = isConRhs r
-isConBind (StgRec _ bs)     = all isConRhs (map snd bs)
+computeSRTs binds = srtTopBinds emptyVarEnv binds
 
-isConRhs (StgRhsCon _ _ _) = True
-isConRhs _                = False
+-- --------------------------------------------------------------------------
+-- Top-level Bindings
 
-srtBind :: TopLevelFlag -> SrtOffset -> StgBinding
-        -> (StgBinding, SrtIds, SrtOffset)
+srtTopBinds :: IdEnv Id -> [StgBinding] -> [(StgBinding, [(Id,[Id])])]
 
-srtBind top off (StgNonRec (SRTEntries rhs_cafs) binder rhs) 
-  = (StgNonRec srt_info binder new_rhs, this_srt, body_off)
+srtTopBinds env [] = []
+srtTopBinds env (StgNonRec b rhs : binds) = 
+  (StgNonRec b rhs', [(b,srt')]) : srtTopBinds env' binds
   where
-    (new_rhs,  rhs_srt,  rhs_off)  = srtRhs off rhs
-    (srt_info, this_srt, body_off) = constructSRT rhs_cafs rhs_srt off rhs_off
-    
-
-srtBind top off (StgRec (SRTEntries rhss_cafs) pairs)
-  = (StgRec srt_info new_pairs, this_srt, body_off)
+    (rhs', srt) = srtTopRhs b rhs
+    env' = maybeExtendEnv env b rhs
+    srt' = applyEnvList env srt
+srtTopBinds env (StgRec bs : binds) = 
+  (StgRec (zip bndrs rhss), zip bndrs srts') : srtTopBinds env binds
+  where
+    (rhss, srts) = unzip [ srtTopRhs b r | (b,r) <- bs ]
+    bndrs = map fst bs
+    srts' = map (applyEnvList env) srts
+
+-- Shorting out indirections in SRTs:  if a binding has an SRT with a single
+-- element in it, we just inline it with that element everywhere it occurs
+-- in other SRTs.
+--
+-- This is in a way a generalisation of the CafInfo.  CafInfo says
+-- whether a top-level binding has *zero* CAF references, allowing us
+-- to omit it from SRTs.  Here, we pick up bindings with *one* CAF
+-- reference, and inline its SRT everywhere it occurs.  We could pass
+-- this information across module boundaries too, but we currently
+-- don't.
+
+maybeExtendEnv env bndr (StgRhsClosure _ _ _ ReEntrant (SRTEntries cafs) _ _)
+  | [one] <- varSetElems cafs
+  = extendVarEnv env bndr (applyEnv env one)
+maybeExtendEnv env bndr _ = env
+
+applyEnvList :: IdEnv Id -> [Id] -> [Id]
+applyEnvList env = map (applyEnv env)
+
+applyEnv env id = lookupVarEnv env id `orElse` id
+
+-- ----  Top-level right hand sides:
+
+srtTopRhs :: Id -> StgRhs -> (StgRhs, [Id])
+
+srtTopRhs binder rhs@(StgRhsCon _ _ _) = (rhs, [])
+srtTopRhs binder rhs@(StgRhsClosure _ _ _ _  (SRTEntries cafs) _ _)
+  = (srtRhs table rhs, elems)
   where
-    ((rhss_off, rhss_srt), new_pairs) = mapAccumL do_bind (off, []) pairs
+       elems = varSetElems cafs
+        table = mkVarEnv (zip elems [0..])
 
-    do_bind (off,srt) (bndr,rhs)
-       = srtRhs off rhs                =: \(rhs', srt', off') ->
-         ((off', srt'++srt), (bndr, rhs'))
+-- ---- Binds:
 
-    non_caf_binders = [ b | (b, rhs) <- pairs, not (caf_rhs rhs) ]
+srtBind :: IdEnv Int -> StgBinding -> StgBinding
 
-    filtered_rhss_cafs
-       | isTopLevel top = filterVarSet (`notElem` non_caf_binders) rhss_cafs
-       | otherwise      = rhss_cafs
+srtBind table (StgNonRec binder rhs) = StgNonRec binder (srtRhs table rhs)
+srtBind table (StgRec pairs) = StgRec [ (b, srtRhs table r) | (b,r) <- pairs ]
 
-    (srt_info, this_srt, body_off)
-        = constructSRT filtered_rhss_cafs rhss_srt off rhss_off
+-- ---- Right Hand Sides:
 
-caf_rhs (StgRhsClosure _ _ free_vars _ [] body) = True
-caf_rhs _ = False
-\end{code}
+srtRhs :: IdEnv Int -> StgRhs -> StgRhs
 
------------------------------------------------------------------------------
-Right Hand Sides
+srtRhs table e@(StgRhsCon cc con args) = e
+srtRhs table (StgRhsClosure cc bi free_vars u (SRTEntries cafs) args body)
+  = StgRhsClosure cc bi free_vars u (constructSRT table cafs) args 
+       $! (srtExpr table body)
 
-\begin{code}
-srtRhs         :: SrtOffset -> StgRhs -> (StgRhs, SrtIds, SrtOffset)
+-- ---------------------------------------------------------------------------
+-- Expressions
 
-srtRhs off (StgRhsClosure cc bi free_vars u args body)
-  = srtExpr off body                   =: \(body, srt, off) ->
-    (StgRhsClosure cc bi free_vars u args body, srt, off)
+srtExpr :: IdEnv Int -> StgExpr -> StgExpr
 
-srtRhs off e@(StgRhsCon cc con args) = (e, [], off)
-\end{code}
+srtExpr table e@(StgApp f args)        = e
+srtExpr table e@(StgLit l)             = e
+srtExpr table e@(StgConApp con args)    = e
+srtExpr table e@(StgOpApp op args ty)   = e
 
------------------------------------------------------------------------------
-Expressions
+srtExpr table (StgSCC cc expr) = StgSCC cc $! srtExpr table expr
 
-\begin{code}
-srtExpr :: SrtOffset -> StgExpr -> (StgExpr, SrtIds, SrtOffset)
-
-srtExpr off e@(StgApp f args)      = (e, [], off)
-srtExpr off e@(StgLit l)           = (e, [], off)
-srtExpr off e@(StgConApp con args)  = (e, [], off)
-srtExpr off e@(StgOpApp op args ty) = (e, [], off)
-
-srtExpr off (StgSCC cc expr) =
-   srtExpr off expr    =: \(expr, srt, off) ->
-   (StgSCC cc expr, srt, off)
-
-srtExpr off (StgCase scrut live1 live2 uniq (SRTEntries cafs_in_alts) alts)
- = srtCaseAlts off alts        =: \(alts, alts_srt, alts_off) ->
-   let
-       (srt_info, this_srt, scrut_off) 
-               = constructSRT cafs_in_alts alts_srt off alts_off
+srtExpr table (StgCase scrut live1 live2 uniq (SRTEntries cafs_in_alts) alts)
+ = let 
+       expr' = srtExpr table scrut
+       srt_info = constructSRT table cafs_in_alts
+       alts' = srtCaseAlts table alts
    in
-   srtExpr scrut_off scrut     =: \(scrut, scrut_srt, case_off) ->
+       StgCase expr' live1 live2 uniq srt_info alts'
 
-   (StgCase scrut live1 live2 uniq srt_info alts, 
-    scrut_srt ++ this_srt, 
-    case_off)
-
-srtExpr off (StgLet bind body)
-  = srtBind NotTopLevel off bind =: \ (bind', bind_srt, body_off) ->
-    srtExpr body_off body      =: \ (body', expr_srt, let_off) ->
-    (StgLet bind' body', expr_srt ++ bind_srt, let_off)
+srtExpr table (StgLet bind body)
+  = srtBind table bind =: \ bind' ->
+    srtExpr table body            =: \ body' ->
+    StgLet bind' body'
      
-srtExpr off (StgLetNoEscape live1 live2 bind body)
-  = srtBind NotTopLevel off bind =: \ (bind', bind_srt, body_off) ->
-    srtExpr body_off body      =: \ (body', expr_srt, let_off) ->
-    (StgLetNoEscape live1 live2 bind' body', expr_srt ++ bind_srt, let_off)
+srtExpr table (StgLetNoEscape live1 live2 bind body)
+  = srtBind table bind =: \ bind' ->
+    srtExpr table body            =: \ body' ->
+    StgLetNoEscape live1 live2 bind' body'
 
 #ifdef DEBUG
-srtExpr off expr = pprPanic "srtExpr" (ppr expr)
+srtExpr table expr = pprPanic "srtExpr" (ppr expr)
 #endif
-\end{code}
 
------------------------------------------------------------------------------
-Construct an SRT.
 
-Construct the SRT at this point from its sub-SRTs and any new global
-references which aren't already contained in one of the sub-SRTs (and
-which are "live").
+-- Case Alternatives
 
-\begin{code}
-constructSRT caf_refs sub_srt initial_offset current_offset
-   = let
-       extra_refs = filter (`notElem` sub_srt) (varSetElems caf_refs)
-       this_srt   = extra_refs ++ sub_srt
+srtCaseAlts :: IdEnv Int -> StgCaseAlts -> StgCaseAlts
 
-       -- Add the length of the new entries to the     
-        -- current offset to get the next free offset in the global SRT.
-       new_offset = current_offset + length extra_refs
-       srt_length = new_offset - initial_offset
+srtCaseAlts table (StgAlgAlts t alts dflt)
+  = (StgAlgAlts t $! map (srtAlgAlt table) alts) $! srtDefault table dflt
 
-       srt_info | srt_length == 0 = NoSRT
-               | otherwise       = SRT initial_offset srt_length
+srtCaseAlts table (StgPrimAlts t alts dflt)
+  = (StgPrimAlts t $! map (srtPrimAlt table) alts) $! srtDefault table dflt
 
-   in ASSERT( this_srt `lengthIs` srt_length )
-      (srt_info, this_srt, new_offset)
-\end{code}
+srtAlgAlt table (con,args,used,rhs)
+  = (,,,) con args used $! srtExpr table rhs
 
------------------------------------------------------------------------------
-Case Alternatives
+srtPrimAlt table (lit,rhs)
+  = (,) lit $! srtExpr table rhs
 
-\begin{code}
-srtCaseAlts :: SrtOffset -> StgCaseAlts -> (StgCaseAlts, SrtIds, SrtOffset)
-
-srtCaseAlts off (StgAlgAlts t alts dflt)
-  = srtDefault off dflt                                        =: \ ((dflt_off, dflt_srt), dflt') ->
-    mapAccumL srtAlgAlt (dflt_off, dflt_srt) alts      =: \ ((alts_off, alts_srt), alts') ->
-    (StgAlgAlts t alts' dflt', alts_srt, alts_off)
-
-srtCaseAlts off (StgPrimAlts t alts dflt)
-  = srtDefault off dflt                                        =: \ ((dflt_off, dflt_srt), dflt') ->
-    mapAccumL srtPrimAlt (dflt_off, dflt_srt) alts     =: \ ((alts_off, alts_srt), alts') ->
-    (StgPrimAlts t alts' dflt', alts_srt, alts_off)
-
-srtAlgAlt (off,srt) (con,args,used,rhs)
-  = srtExpr off rhs    =: \(rhs', rhs_srt, rhs_off) ->
-    ((rhs_off, rhs_srt ++ srt), (con,args,used,rhs'))
-
-srtPrimAlt (off,srt) (lit,rhs)
-  = srtExpr off rhs    =: \(rhs', rhs_srt, rhs_off) ->
-    ((rhs_off, rhs_srt ++ srt), (lit, rhs'))
-
-srtDefault off StgNoDefault
-  = ((off,[]), StgNoDefault)
-srtDefault off (StgBindDefault rhs)
-  = srtExpr off rhs    =: \(rhs', srt, off) ->
-    ((off,srt), StgBindDefault rhs')
-\end{code}
+srtDefault table StgNoDefault  = StgNoDefault
+srtDefault table (StgBindDefault rhs)
+  = StgBindDefault $! srtExpr table rhs
 
 -----------------------------------------------------------------------------
-Misc stuff
+-- Construct an SRT bitmap.
+
+constructSRT :: IdEnv Int -> IdSet -> SRT
+constructSRT table entries
+ | isEmptyVarSet entries = NoSRT
+ | otherwise  = SRT offset len bitmap
+  where
+    ints = map (expectJust "constructSRT" . lookupVarEnv table) 
+               (varSetElems entries)
+    sorted_ints = sortLt (<) ints
+    offset = head sorted_ints
+    bitmap_entries = map (subtract offset) sorted_ints
+    len = last bitmap_entries + 1
+    bitmap = intsToBitmap len bitmap_entries
+
+-- ---------------------------------------------------------------------------
+-- Misc stuff
 
-\begin{code}
 a =: k  = k a
+
 \end{code}
index cc918b7..dc945f5 100644 (file)
@@ -30,7 +30,7 @@ import Outputable
 stg2stg :: DynFlags                 -- includes spec of what stg-to-stg passes to do
        -> Module                    -- module name (profiling only)
        -> [StgBinding]              -- input...
-       -> IO ( [(StgBinding,[Id])]  -- output program...
+       -> IO ( [(StgBinding,[(Id,[Id])])]  -- output program...
              , CollectedCCs)        -- cost centre information (declared and used)
 
 stg2stg dflags module_name binds
index 824c112..0e5a75b 100644 (file)
@@ -117,10 +117,10 @@ statBinding :: Bool -- True <=> top-level; False <=> nested
            -> StgBinding
            -> StatEnv
 
-statBinding top (StgNonRec _srt b rhs)
+statBinding top (StgNonRec b rhs)
   = statRhs top (b, rhs)
 
-statBinding top (StgRec _srt pairs)
+statBinding top (StgRec pairs)
   = combineSEs (map (statRhs top) pairs)
 
 statRhs :: Bool -> (Id, StgRhs) -> StatEnv
@@ -128,7 +128,7 @@ statRhs :: Bool -> (Id, StgRhs) -> StatEnv
 statRhs top (b, StgRhsCon cc con args)
   = countOne (ConstructorBinds top)
 
-statRhs top (b, StgRhsClosure cc bi fv u args body)
+statRhs top (b, StgRhsClosure cc bi fv u _srt args body)
   = statExpr body                      `combineSE`
     countN FreeVariables (length fv)   `combineSE`
     countOne (
index ab4d0e0..c23eb9d 100644 (file)
@@ -174,14 +174,13 @@ coreTopBindToStg env body_fvs (NonRec id rhs)
        env'      = extendVarEnv env id how_bound
        how_bound = LetBound TopLet (manifestArity rhs)
 
-        (stg_rhs, fvs', lv_info) = 
+        (stg_rhs, fvs') = 
            initLne env (
               coreToTopStgRhs body_fvs (id,rhs)        `thenLne` \ (stg_rhs, fvs') ->
-             freeVarsToLiveVars fvs'           `thenLne` \ lv_info ->
-             returnLne (stg_rhs, fvs', lv_info)
+             returnLne (stg_rhs, fvs')
            )
        
-       bind = StgNonRec (mkSRT lv_info) id stg_rhs
+       bind = StgNonRec id stg_rhs
     in
     ASSERT2(manifestArity rhs == stgRhsArity stg_rhs, ppr id)
     ASSERT2(consistentCafInfo id bind, ppr id)
@@ -196,16 +195,15 @@ coreTopBindToStg env body_fvs (Rec pairs)
                     | (b, rhs) <- pairs ]
        env' = extendVarEnvList env extra_env'
 
-        (stg_rhss, fvs', lv_info)
+        (stg_rhss, fvs')
          = initLne env' (
               mapAndUnzipLne (coreToTopStgRhs body_fvs) pairs
                                                `thenLne` \ (stg_rhss, fvss') ->
               let fvs' = unionFVInfos fvss' in
-              freeVarsToLiveVars fvs'                  `thenLne` \ lv_info ->
-              returnLne (stg_rhss, fvs', lv_info)
+              returnLne (stg_rhss, fvs')
            )
 
-       bind = StgRec (mkSRT lv_info) (zip binders stg_rhss)
+       bind = StgRec (zip binders stg_rhss)
     in
     ASSERT2(and [manifestArity rhs == stgRhsArity stg_rhs | (rhs,stg_rhs) <- rhss `zip` stg_rhss], ppr binders)
     ASSERT2(consistentCafInfo (head binders) bind, ppr binders)
@@ -237,29 +235,33 @@ coreToTopStgRhs
 
 coreToTopStgRhs scope_fv_info (bndr, rhs)
   = coreToStgExpr rhs          `thenLne` \ (new_rhs, rhs_fvs, _) ->
-    returnLne (mkTopStgRhs upd rhs_fvs bndr_info new_rhs, rhs_fvs)
+    freeVarsToLiveVars rhs_fvs `thenLne` \ lv_info ->
+    returnLne (mkTopStgRhs upd rhs_fvs (mkSRT lv_info) bndr_info new_rhs, rhs_fvs)
   where
     bndr_info = lookupFVInfo scope_fv_info bndr
 
     upd  | rhsIsNonUpd rhs = SingleEntry
         | otherwise       = Updatable
 
-mkTopStgRhs :: UpdateFlag -> FreeVarsInfo -> StgBinderInfo -> StgExpr -> StgRhs
+mkTopStgRhs :: UpdateFlag -> FreeVarsInfo -> SRT -> StgBinderInfo -> StgExpr
+       -> StgRhs
 
-mkTopStgRhs upd rhs_fvs binder_info (StgLam _ bndrs body)
+mkTopStgRhs upd rhs_fvs srt binder_info (StgLam _ bndrs body)
   = StgRhsClosure noCCS binder_info
                  (getFVs rhs_fvs)               
                  ReEntrant
+                 srt
                  bndrs body
        
-mkTopStgRhs upd rhs_fvs binder_info (StgConApp con args)
+mkTopStgRhs upd rhs_fvs srt binder_info (StgConApp con args)
   | not (isUpdatable upd) -- StgConApps can be updatable (see isCrossDllConApp)
   = StgRhsCon noCCS con args
 
-mkTopStgRhs upd rhs_fvs binder_info rhs
+mkTopStgRhs upd rhs_fvs srt binder_info rhs
   = StgRhsClosure noCCS binder_info
                  (getFVs rhs_fvs)               
                  upd
+                 srt
                  [] rhs
 \end{code}
 
@@ -647,14 +649,12 @@ coreToStgLet let_no_escape bind body
                                         
 
     vars_bind body_fvs (NonRec binder rhs)
-      = coreToStgRhs body_fvs (binder,rhs)
-                               `thenLne` \ (rhs2, bind_fvs, escs) ->
-
-       freeVarsToLiveVars bind_fvs `thenLne` \ bind_lv_info ->
+      = coreToStgRhs body_fvs [] (binder,rhs)
+                               `thenLne` \ (rhs2, bind_fvs, bind_lv_info, escs) ->
        let
            env_ext_item = mk_binding bind_lv_info binder rhs
        in
-       returnLne (StgNonRec (mkSRT bind_lv_info) binder rhs2, 
+       returnLne (StgNonRec binder rhs2, 
                   bind_fvs, escs, bind_lv_info, [env_ext_item])
 
 
@@ -667,16 +667,14 @@ coreToStgLet let_no_escape bind body
                          | (b,rhs) <- pairs ]
           in
           extendVarEnvLne env_ext (
-             mapAndUnzip3Lne (coreToStgRhs rec_scope_fvs) pairs 
-                                       `thenLne` \ (rhss2, fvss, escss) ->
+             mapAndUnzip4Lne (coreToStgRhs rec_scope_fvs binders) pairs 
+                                       `thenLne` \ (rhss2, fvss, lv_infos, escss) ->
              let
                        bind_fvs = unionFVInfos fvss
+                       bind_lv_info = foldr unionLiveInfo emptyLiveInfo lv_infos
                        escs     = unionVarSets escss
              in
-             freeVarsToLiveVars (binders `minusFVBinders` bind_fvs)
-                                       `thenLne` \ bind_lv_info ->
-
-             returnLne (StgRec (mkSRT bind_lv_info) (binders `zip` rhss2), 
+             returnLne (StgRec (binders `zip` rhss2),
                         bind_fvs, escs, bind_lv_info, env_ext)
           )
        )
@@ -689,32 +687,34 @@ is_join_var j = occNameUserString (getOccName j) == "$j"
 
 \begin{code}
 coreToStgRhs :: FreeVarsInfo           -- Free var info for the scope of the binding
+            -> [Id]
             -> (Id,CoreExpr)
-            -> LneM (StgRhs, FreeVarsInfo, EscVarsSet)
+            -> LneM (StgRhs, FreeVarsInfo, LiveInfo, EscVarsSet)
 
-coreToStgRhs scope_fv_info (bndr, rhs)
+coreToStgRhs scope_fv_info binders (bndr, rhs)
   = coreToStgExpr rhs          `thenLne` \ (new_rhs, rhs_fvs, rhs_escs) ->
     getEnvLne                  `thenLne` \ env ->    
-    returnLne (mkStgRhs env rhs_fvs bndr_info new_rhs,
-              rhs_fvs, rhs_escs)
+    freeVarsToLiveVars (binders `minusFVBinders` rhs_fvs) `thenLne` \ lv_info ->
+    returnLne (mkStgRhs rhs_fvs (mkSRT lv_info) bndr_info new_rhs,
+              rhs_fvs, lv_info, rhs_escs)
   where
     bndr_info = lookupFVInfo scope_fv_info bndr
 
-mkStgRhs :: IdEnv HowBound -> FreeVarsInfo -> StgBinderInfo -> StgExpr -> StgRhs
+mkStgRhs :: FreeVarsInfo -> SRT -> StgBinderInfo -> StgExpr -> StgRhs
 
-mkStgRhs env rhs_fvs binder_info (StgConApp con args)
+mkStgRhs rhs_fvs srt binder_info (StgConApp con args)
   = StgRhsCon noCCS con args
 
-mkStgRhs env rhs_fvs binder_info (StgLam _ bndrs body)
+mkStgRhs rhs_fvs srt binder_info (StgLam _ bndrs body)
   = StgRhsClosure noCCS binder_info
                  (getFVs rhs_fvs)               
                  ReEntrant
-                 bndrs body
+                 srt bndrs body
        
-mkStgRhs env rhs_fvs binder_info rhs
+mkStgRhs rhs_fvs srt binder_info rhs
   = StgRhsClosure noCCS binder_info
                  (getFVs rhs_fvs)               
-                 upd_flag [] rhs
+                 upd_flag srt [] rhs
   where
    upd_flag = Updatable
   {-
@@ -896,6 +896,14 @@ mapAndUnzip3Lne f (x:xs)
     mapAndUnzip3Lne f xs `thenLne` \ (rs1, rs2, rs3) ->
     returnLne (r1:rs1, r2:rs2, r3:rs3)
 
+mapAndUnzip4Lne :: (a -> LneM (b,c,d,e)) -> [a] -> LneM ([b],[c],[d],[e])
+
+mapAndUnzip4Lne f []   = returnLne ([],[],[],[])
+mapAndUnzip4Lne f (x:xs)
+  = f x                         `thenLne` \ (r1,  r2,  r3, r4)  ->
+    mapAndUnzip4Lne f xs `thenLne` \ (rs1, rs2, rs3, rs4) ->
+    returnLne (r1:rs1, r2:rs2, r3:rs3, r4:rs4)
+
 fixLne :: (a -> LneM a) -> LneM a
 fixLne expr env lvs_cont
   = result
index 22ef750..28b02a9 100644 (file)
@@ -89,11 +89,11 @@ lintStgVar v  = checkInScope v      `thenL_`
 
 \begin{code}
 lintStgBinds :: StgBinding -> LintM [Id]               -- Returns the binders
-lintStgBinds (StgNonRec _srt binder rhs)
+lintStgBinds (StgNonRec binder rhs)
   = lint_binds_help (binder,rhs)       `thenL_`
     returnL [binder]
 
-lintStgBinds (StgRec _srt pairs)
+lintStgBinds (StgRec pairs)
   = addInScopeVars binders (
        mapL lint_binds_help pairs `thenL_`
        returnL binders
@@ -127,10 +127,10 @@ lint_binds_help (binder, rhs)
 \begin{code}
 lintStgRhs :: StgRhs -> LintM (Maybe Type)
 
-lintStgRhs (StgRhsClosure _ _ _ _ [] expr)
+lintStgRhs (StgRhsClosure _ _ _ _ _ [] expr)
   = lintStgExpr expr
 
-lintStgRhs (StgRhsClosure _ _ _ _ binders expr)
+lintStgRhs (StgRhsClosure _ _ _ _ _ binders expr)
   = addLoc (LambdaBodyOf binders) (
     addInScopeVars binders (
        lintStgExpr expr   `thenMaybeL` \ body_ty ->
index 293aa94..31e2057 100644 (file)
@@ -34,7 +34,7 @@ module StgSyn (
        SRT(..), noSRT, nonEmptySRT,
 
        -- utils
-       stgBindHasCafRefs,  stgRhsArity, getArgPrimRep, 
+       stgBindHasCafRefs,  stgArgHasCafRefs, stgRhsArity, getArgPrimRep, 
        isLitLitArg, isDllConApp, isStgTypeArg,
        stgArgType, stgBinders,
 
@@ -50,7 +50,8 @@ module StgSyn (
 import CostCentre      ( CostCentreStack, CostCentre )
 import VarSet          ( IdSet, isEmptyVarSet )
 import Var             ( isId )
-import Id              ( Id, idName, idPrimRep, idType )
+import Id              ( Id, idName, idPrimRep, idType, idCafInfo )
+import IdInfo          ( mayHaveCafRefs )
 import Name            ( isDllName )
 import Literal         ( Literal, literalType, isLitLitLit, literalPrimRep )
 import ForeignCall     ( ForeignCall )
@@ -62,6 +63,7 @@ import Type             ( Type )
 import TyCon            ( TyCon )
 import UniqSet         ( isEmptyUniqSet, uniqSetToList, UniqSet )
 import Unique          ( Unique )
+import Bitmap
 import CmdLineOpts     ( opt_SccProfilingOn )
 \end{code}
 
@@ -80,12 +82,12 @@ There is one SRT for each group of bindings.
 
 \begin{code}
 data GenStgBinding bndr occ
-  = StgNonRec  SRT bndr (GenStgRhs bndr occ)
-  | StgRec     SRT [(bndr, GenStgRhs bndr occ)]
+  = StgNonRec  bndr (GenStgRhs bndr occ)
+  | StgRec     [(bndr, GenStgRhs bndr occ)]
 
 stgBinders :: GenStgBinding bndr occ -> [bndr]
-stgBinders (StgNonRec _ b _) = [b]
-stgBinders (StgRec _ bs)     = map fst bs
+stgBinders (StgNonRec b _) = [b]
+stgBinders (StgRec bs)     = map fst bs
 \end{code}
 
 %************************************************************************
@@ -370,6 +372,7 @@ data GenStgRhs bndr occ
        [occ]                   -- non-global free vars; a list, rather than
                                -- a set, because order is important
        !UpdateFlag             -- ReEntrant | Updatable | SingleEntry
+       SRT                     -- The SRT reference
        [bndr]                  -- arguments; if empty, then not a function;
                                -- as above, order is important.
        (GenStgExpr bndr occ)   -- body
@@ -400,7 +403,7 @@ The second flavour of right-hand-side is for constructors (simple but important)
 
 \begin{code}
 stgRhsArity :: StgRhs -> Int
-stgRhsArity (StgRhsClosure _ _ _ _ bndrs _) = count isId bndrs
+stgRhsArity (StgRhsClosure _ _ _ _ _ bndrs _) = count isId bndrs
   -- The arity never includes type parameters, so
   -- when keeping type arguments and binders in the Stg syntax 
   -- (opt_RuntimeTypes) we have to fliter out the type binders.
@@ -408,14 +411,17 @@ stgRhsArity (StgRhsCon _ _ _) = 0
 \end{code}
 
 \begin{code}
-stgBindHasCafRefs :: GenStgBinding bndr occ -> Bool
-stgBindHasCafRefs (StgNonRec srt _ rhs)
-  = nonEmptySRT srt || rhsIsUpdatable rhs
-stgBindHasCafRefs (StgRec srt binds)
-  = nonEmptySRT srt || any rhsIsUpdatable (map snd binds)
-
-rhsIsUpdatable (StgRhsClosure _ _ _ upd _ _) = isUpdatable upd
-rhsIsUpdatable _ = False
+stgBindHasCafRefs :: GenStgBinding bndr Id -> Bool
+stgBindHasCafRefs (StgNonRec _ rhs) = rhsHasCafRefs rhs
+stgBindHasCafRefs (StgRec binds)    = any rhsHasCafRefs (map snd binds)
+
+rhsHasCafRefs (StgRhsClosure _ _ _ upd srt _ _) 
+  = isUpdatable upd || nonEmptySRT srt
+rhsHasCafRefs (StgRhsCon _ _ args)
+  = any stgArgHasCafRefs args
+
+stgArgHasCafRefs (StgVarArg id) = mayHaveCafRefs (idCafInfo id)
+stgArgHasCafRefs _ = False
 \end{code}
 
 Here's the @StgBinderInfo@ type, and its combining op:
@@ -578,8 +584,10 @@ converted into the length and offset form by the SRT pass.
 
 \begin{code}
 data SRT = NoSRT
-        | SRTEntries IdSet                     -- generated by CoreToStg
-         | SRT !Int{-offset-} !Int{-length-}   -- generated by computeSRTs
+        | SRTEntries IdSet
+               -- generated by CoreToStg
+         | SRT !Int{-offset-} !Int{-length-} !Bitmap{-bitmap-}
+               -- generated by computeSRTs
 
 noSRT :: SRT
 noSRT = NoSRT
@@ -590,7 +598,7 @@ nonEmptySRT _               = True
 
 pprSRT (NoSRT) = ptext SLIT("_no_srt_")
 pprSRT (SRTEntries ids) = text "SRT:" <> ppr ids
-pprSRT (SRT off len) = parens (ppr off <> comma <> ppr len)
+pprSRT (SRT off length bitmap) = parens (ppr off <> comma <> text "*bitmap*")
 \end{code}
 
 %************************************************************************
@@ -606,13 +614,12 @@ hoping he likes terminators instead...  Ditto for case alternatives.
 pprGenStgBinding :: (Outputable bndr, Outputable bdee, Ord bdee)
                 => GenStgBinding bndr bdee -> SDoc
 
-pprGenStgBinding (StgNonRec srt bndr rhs)
-  = pprMaybeSRT srt $$ hang (hsep [ppr bndr, equals])
-                       4 ((<>) (ppr rhs) semi)
+pprGenStgBinding (StgNonRec bndr rhs)
+  = hang (hsep [ppr bndr, equals])
+       4 ((<>) (ppr rhs) semi)
 
-pprGenStgBinding (StgRec srt pairs)
+pprGenStgBinding (StgRec pairs)
   = vcat ((ifPprDebug (ptext SLIT("{- StgRec (begin) -}"))) :
-          pprMaybeSRT srt :
           (map (ppr_bind) pairs) ++ [(ifPprDebug (ptext SLIT("{- StgRec (end) -}")))])
   where
     ppr_bind (bndr, expr)
@@ -627,13 +634,14 @@ pprStgBindings binds = vcat (map pprGenStgBinding binds)
 
 pprGenStgBindingWithSRT         
        :: (Outputable bndr, Outputable bdee, Ord bdee) 
-       => (GenStgBinding bndr bdee,[Id]) -> SDoc
+       => (GenStgBinding bndr bdee,[(Id,[Id])]) -> SDoc
 
-pprGenStgBindingWithSRT (bind,srt)  
-  = vcat [ pprGenStgBinding bind,
-          ptext SLIT("SRT: ") <> ppr srt ]
+pprGenStgBindingWithSRT (bind,srts)
+  = vcat (pprGenStgBinding bind : map pprSRT srts)
+  where pprSRT (id,srt) = 
+          ptext SLIT("SRT") <> parens (ppr id) <> ptext SLIT(": ") <> ppr srt
 
-pprStgBindingsWithSRTs :: [(StgBinding,[Id])] -> SDoc
+pprStgBindingsWithSRTs :: [(StgBinding,[(Id,[Id])])] -> SDoc
 pprStgBindingsWithSRTs binds = vcat (map pprGenStgBindingWithSRT binds)
 \end{code}
 
@@ -797,18 +805,18 @@ pprStgRhs :: (Outputable bndr, Outputable bdee, Ord bdee)
          => GenStgRhs bndr bdee -> SDoc
 
 -- special case
-pprStgRhs (StgRhsClosure cc bi [free_var] upd_flag [{-no args-}] (StgApp func []))
+pprStgRhs (StgRhsClosure cc bi [free_var] upd_flag srt [{-no args-}] (StgApp func []))
   = hcat [ ppr cc,
           pp_binder_info bi,
           brackets (ifPprDebug (ppr free_var)),
-          ptext SLIT(" \\"), ppr upd_flag, ptext SLIT(" [] "), ppr func ]
+          ptext SLIT(" \\"), ppr upd_flag, pprMaybeSRT srt, ptext SLIT(" [] "), ppr func ]
 
 -- general case
-pprStgRhs (StgRhsClosure cc bi free_vars upd_flag args body)
+pprStgRhs (StgRhsClosure cc bi free_vars upd_flag srt args body)
   = hang (hsep [if opt_SccProfilingOn then ppr cc else empty,
                pp_binder_info bi,
                ifPprDebug (brackets (interppSP free_vars)),
-               char '\\' <> ppr upd_flag, brackets (interppSP args)])
+               char '\\' <> ppr upd_flag, pprMaybeSRT srt, brackets (interppSP args)])
         4 (ppr body)
 
 pprStgRhs (StgRhsCon cc con args)
@@ -816,5 +824,5 @@ pprStgRhs (StgRhsCon cc con args)
           space, ppr con, ptext SLIT("! "), brackets (interppSP args)]
 
 pprMaybeSRT (NoSRT) = empty
-pprMaybeSRT srt     = ptext SLIT("srt: ") <> pprSRT srt
+pprMaybeSRT srt     = ptext SLIT("srt:") <> pprSRT srt
 \end{code}
index b1a97b6..43c22f0 100644 (file)
@@ -598,6 +598,7 @@ sub mangle_asm {
                    || /^${T_US}.*_slow${T_POST_LBL}$/o         # slow entry
                    || /^${T_US}__stginit.*${T_POST_LBL}$/o     # __stginit<module>
                    || /^${T_US}.*_btm${T_POST_LBL}$/o          # large bitmaps
+                   || /^${T_US}.*_srtd${T_POST_LBL}$/o          # large bitmaps
                    || /^${T_US}.*_fast${T_POST_LBL}$/o         # primops
                    || /^${T_US}.*_closure_tbl${T_POST_LBL}$/o  # closure tables
                     || /^_uname:/o;                            # x86/Solaris2
index 7b3a6d5..35140fc 100644 (file)
@@ -1,5 +1,5 @@
 /* ----------------------------------------------------------------------------
- * $Id: ClosureMacros.h,v 1.35 2002/12/11 15:36:37 simonmar Exp $
+ * $Id: ClosureMacros.h,v 1.36 2003/05/14 09:14:01 simonmar Exp $
  *
  * (c) The GHC Team, 1998-1999
  *
@@ -234,6 +234,6 @@ extern StgWord flip;
    -------------------------------------------------------------------------- */
 
 /* constructors don't have SRTs */
-#define GET_TAG(info) (INFO_PTR_TO_STRUCT(info)->srt_len)
+#define GET_TAG(info) (INFO_PTR_TO_STRUCT(info)->srt_bitmap)
 
 #endif /* CLOSUREMACROS_H */
index 0964da7..5aa4835 100644 (file)
@@ -1,5 +1,5 @@
 /* ----------------------------------------------------------------------------
- * $Id: InfoMacros.h,v 1.21 2002/12/11 15:36:37 simonmar Exp $
+ * $Id: InfoMacros.h,v 1.22 2003/05/14 09:14:01 simonmar Exp $
  * 
  * (c) The GHC Team, 1998-2002
  *
@@ -10,8 +10,8 @@
 #ifndef INFOMACROS_H
 #define INFOMACROS_H
 
-#define STD_INFO(srt_len_, type_)              \
-               srt_len : srt_len_,             \
+#define STD_INFO(srt_bitmap_, type_)           \
+               srt_bitmap : srt_bitmap_,               \
                type : type_
 
 #define THUNK_INFO(srt_, srt_off_)                     \
@@ -65,7 +65,7 @@
 INFO_TABLE_THUNK(info,                         /* info-table label */  \
               entry,                           /* entry code label */  \
               ptrs, nptrs,                     /* closure layout info */\
-              srt_, srt_off_, srt_len_,        /* SRT info */          \
+              srt_, srt_off_, srt_bitmap_,     /* SRT info */          \
               type,                            /* closure type */      \
               info_class, entry_class,         /* C storage classes */ \
               prof_descr, prof_type)           /* profiling info */    \
@@ -75,7 +75,7 @@ INFO_TABLE_THUNK(info,                                /* info-table label */  \
        info_class const StgInfoTable stg_RBH_##info = {                \
                layout : { payload : {ptrs,nptrs} },                    \
                 PROF_INFO(prof_type, prof_descr)                       \
-               SRT_INFO(RBH,srt_,srt_off_,srt_len_),                   \
+               SRT_INFO(RBH,srt_,srt_off_,srt_bitmap_),                        \
                 INCLUDE_RBH_INFO(info),                                        \
                 INIT_ENTRY(stg_RBH_##entry)                            \
        } ;                                                             \
@@ -87,7 +87,7 @@ INFO_TABLE_THUNK(info,                                /* info-table label */  \
        info_class const StgInfoTable info = {                  \
                layout : { payload : {ptrs,nptrs} },                    \
                 PROF_INFO(prof_type, prof_descr)                       \
-               SRT_INFO(type,srt_,srt_off_,srt_len_),                  \
+               SRT_INFO(type,srt_,srt_off_,srt_bitmap_),                       \
                 INCLUDE_RBH_INFO(stg_RBH_##info),                      \
                 INIT_ENTRY(entry)                                       \
        }
@@ -98,7 +98,7 @@ INFO_TABLE_THUNK(info,                                /* info-table label */  \
 INFO_TABLE_THUNK(info,                         /* info-table label */  \
               entry,                           /* entry code label */  \
               ptrs, nptrs,                     /* closure layout info */\
-              srt_, srt_off_, srt_len_,        /* SRT info */          \
+              srt_, srt_off_, srt_bitmap_,     /* SRT info */          \
               type_,                           /* closure type */      \
               info_class, entry_class,         /* C storage classes */ \
               prof_descr, prof_type)           /* profiling info */    \
@@ -107,7 +107,7 @@ INFO_TABLE_THUNK(info,                              /* info-table label */  \
                i : {                                                   \
                  layout : { payload : {ptrs,nptrs} },                  \
                   PROF_INFO(prof_type, prof_descr)                     \
-                 STD_INFO(srt_len_, type_),                            \
+                 STD_INFO(srt_bitmap_, type_),                         \
                   INIT_ENTRY(entry)                                     \
                },                                                      \
                THUNK_INFO(srt_,srt_off_),                              \
@@ -120,7 +120,7 @@ INFO_TABLE_THUNK(info,                              /* info-table label */  \
 #if defined(GRAN) || defined(PAR)
 
 #define                                                                        \
-INFO_TABLE_RET(info, entry, bitmap_, srt_, srt_off_, srt_len_,         \
+INFO_TABLE_RET(info, entry, bitmap_, srt_, srt_off_, srt_bitmap_,              \
                      type, info_class, entry_class,                    \
                      prof_descr, prof_type)                            \
         entry_class(stg_RBH_##entry);                                  \
@@ -129,7 +129,7 @@ INFO_TABLE_RET(info, entry, bitmap_, srt_, srt_off_, srt_len_,              \
        info_class const StgInfoTable stg_RBH_##info = {        \
                layout : { bitmap : (StgWord)bitmap_ },                 \
                 PROF_INFO(prof_type, prof_descr)                       \
-               SRT_INFO(RBH,srt_,srt_off_,srt_len_),                   \
+               SRT_INFO(RBH,srt_,srt_off_,srt_bitmap_),                        \
                 INCLUDE_RBH_INFO(info),                                        \
                 INIT_ENTRY(stg_RBH_##entry)                            \
        };                                                              \
@@ -141,7 +141,7 @@ INFO_TABLE_RET(info, entry, bitmap_, srt_, srt_off_, srt_len_,              \
        info_class const StgInfoTable info = {                  \
                layout : { bitmap : (StgWord)bitmap_ },                 \
                 PROF_INFO(prof_type, prof_descr)                       \
-               SRT_INFO(type,srt_,srt_off_,srt_len_),                  \
+               SRT_INFO(type,srt_,srt_off_,srt_bitmap_),                       \
                 INCLUDE_RBH_INFO(stg_RBH_##info),                      \
                 INIT_ENTRY(entry)                                      \
        }
@@ -149,7 +149,7 @@ INFO_TABLE_RET(info, entry, bitmap_, srt_, srt_off_, srt_len_,              \
 #else
 
 #define                                                                        \
-INFO_TABLE_RET(info, entry, bitmap_, srt_, srt_off_, srt_len_,         \
+INFO_TABLE_RET(info, entry, bitmap_, srt_, srt_off_, srt_bitmap_,              \
                      type_, info_class, entry_class,                   \
                      prof_descr, prof_type)                            \
         entry_class(entry);                                            \
@@ -157,7 +157,7 @@ INFO_TABLE_RET(info, entry, bitmap_, srt_, srt_off_, srt_len_,              \
                i : {                                                   \
                    layout : { bitmap : (StgWord)bitmap_ },             \
                    PROF_INFO(prof_type, prof_descr)                    \
-                   STD_INFO(srt_len_,type_),                           \
+                   STD_INFO(srt_bitmap_,type_),                                \
                     INIT_ENTRY(entry)                                  \
                },                                                      \
                RET_INFO(srt_,srt_off_)                                 \
@@ -267,7 +267,7 @@ INFO_TABLE_CONSTR(info, entry, ptrs, nptrs, tag_,type_,info_class,  \
                 INIT_ENTRY(entry)                                      \
        }
 
-#define constrTag(con) (get_itbl(con)->srt_len)
+#define constrTag(con) (get_itbl(con)->srt_bitmap)
 
 /* function info table -----------------------------------------------------*/
 
@@ -275,7 +275,7 @@ INFO_TABLE_CONSTR(info, entry, ptrs, nptrs, tag_,type_,info_class,  \
 INFO_TABLE_FUN_GEN(info,                       /* info-table label */  \
               entry,                           /* entry code label */  \
               ptrs, nptrs,                     /* closure layout info */\
-              srt_, srt_off_, srt_len_,        /* SRT info */          \
+              srt_, srt_off_, srt_bitmap_,     /* SRT info */          \
               fun_type_, arity_, bitmap_, slow_apply_,                 \
                                                /* Function info */     \
               type_,                           /* closure type */      \
@@ -286,7 +286,7 @@ INFO_TABLE_FUN_GEN(info,                    /* info-table label */  \
                 i : {                                                  \
                   layout : { payload : {ptrs,nptrs} },                 \
                    PROF_INFO(prof_type, prof_descr)                    \
-                  STD_INFO(srt_len_,type_),                            \
+                  STD_INFO(srt_bitmap_,type_),                         \
                   INIT_ENTRY(entry)                                    \
                },                                                      \
                srt : (StgSRT *)((StgClosure **)srt_+srt_off_),         \
@@ -342,7 +342,7 @@ typedef struct {
   StgRetInfoTable i;
 } vec_info_8;
 
-#define VEC_INFO_2(info,bitmap_,srt_,srt_off_,srt_len_,                \
+#define VEC_INFO_2(info,bitmap_,srt_,srt_off_,srt_bitmap_,             \
                   type_, info_class,                           \
                   alt_1, alt_2)                                \
        info_class const vec_info_2 info = {            \
@@ -350,13 +350,13 @@ typedef struct {
                i : {                                           \
                   i : {                                        \
                      layout : { bitmap : (StgWord)bitmap_ },   \
-                     STD_INFO(srt_len_,type_)                  \
+                     STD_INFO(srt_bitmap_,type_)                       \
                   },                                           \
                   RET_INFO(srt_,srt_off_)                      \
                }                                               \
        }
 
-#define VEC_INFO_3(info,bitmap_,srt_,srt_off_,srt_len_,                \
+#define VEC_INFO_3(info,bitmap_,srt_,srt_off_,srt_bitmap_,             \
                   type_, info_class,                           \
                   alt_1, alt_2, alt_3                          \
                  )                                             \
@@ -365,13 +365,13 @@ typedef struct {
                i : {                                           \
                   i : {                                        \
                      layout : { bitmap : (StgWord)bitmap_ },   \
-                     STD_INFO(srt_len_,type_)                  \
+                     STD_INFO(srt_bitmap_,type_)                       \
                   },                                           \
                   RET_INFO(srt_,srt_off_)                      \
                }                                               \
        }
 
-#define VEC_INFO_4(info,bitmap_,srt_,srt_off_,srt_len_,                \
+#define VEC_INFO_4(info,bitmap_,srt_,srt_off_,srt_bitmap_,             \
                   type_, info_class,                           \
                   alt_1, alt_2, alt_3, alt_4                   \
                  )                                             \
@@ -380,13 +380,13 @@ typedef struct {
                i : {                                           \
                   i : {                                        \
                      layout : { bitmap : (StgWord)bitmap_ },   \
-                     STD_INFO(srt_len_,type_)                  \
+                     STD_INFO(srt_bitmap_,type_)                       \
                   },                                           \
                   RET_INFO(srt_,srt_off_)                      \
                }                                               \
        }
 
-#define VEC_INFO_5(info,bitmap_,srt_,srt_off_,srt_len_,                \
+#define VEC_INFO_5(info,bitmap_,srt_,srt_off_,srt_bitmap_,             \
                   type_, info_class,                           \
                   alt_1, alt_2, alt_3, alt_4,                  \
                   alt_5                                        \
@@ -397,13 +397,13 @@ typedef struct {
                i : {                                           \
                   i : {                                        \
                      layout : { bitmap : (StgWord)bitmap_ },   \
-                     STD_INFO(srt_len_,type_)                  \
+                     STD_INFO(srt_bitmap_,type_)                       \
                   },                                           \
                   RET_INFO(srt_,srt_off_)                      \
                }                                               \
        }
 
-#define VEC_INFO_6(info,bitmap_,srt_,srt_off_,srt_len_,                \
+#define VEC_INFO_6(info,bitmap_,srt_,srt_off_,srt_bitmap_,             \
                   type_, info_class,                           \
                   alt_1, alt_2, alt_3, alt_4,                  \
                   alt_5, alt_6                                 \
@@ -414,13 +414,13 @@ typedef struct {
                i : {                                           \
                   i : {                                        \
                      layout : { bitmap : (StgWord)bitmap_ },   \
-                     STD_INFO(srt_len_,type_)                  \
+                     STD_INFO(srt_bitmap_,type_)                       \
                   },                                           \
                   RET_INFO(srt_,srt_off_)                      \
                }                                               \
        }
 
-#define VEC_INFO_7(info,bitmap_,srt_,srt_off_,srt_len_,                \
+#define VEC_INFO_7(info,bitmap_,srt_,srt_off_,srt_bitmap_,             \
                   type_, info_class,                           \
                   alt_1, alt_2, alt_3, alt_4,                  \
                   alt_5, alt_6, alt_7                          \
@@ -431,13 +431,13 @@ typedef struct {
                i : {                                           \
                   i : {                                        \
                      layout : { bitmap : (StgWord)bitmap_ },   \
-                     STD_INFO(srt_len_,type_)                  \
+                     STD_INFO(srt_bitmap_,type_)                       \
                   },                                           \
                   RET_INFO(srt_,srt_off_)                      \
                }                                               \
        }
 
-#define VEC_INFO_8(info,bitmap_,srt_,srt_off_,srt_len_,                \
+#define VEC_INFO_8(info,bitmap_,srt_,srt_off_,srt_bitmap_,             \
                   type_, info_class,                           \
                   alt_1, alt_2, alt_3, alt_4,                  \
                   alt_5, alt_6, alt_7, alt_8                   \
@@ -448,7 +448,7 @@ typedef struct {
                i : {                                           \
                   i : {                                        \
                      layout : { bitmap : (StgWord)bitmap_ },   \
-                     STD_INFO(srt_len_,type_)                  \
+                     STD_INFO(srt_bitmap_,type_)                       \
                   },                                           \
                   RET_INFO(srt_,srt_off_)                      \
                }                                               \
@@ -498,20 +498,20 @@ typedef struct {
   StgFunPtr vec[8];
 } vec_info_8;
 
-#define VEC_INFO_2(info,bitmap_,srt_,srt_off_,srt_len_,                \
+#define VEC_INFO_2(info,bitmap_,srt_,srt_off_,srt_bitmap_,             \
                   type_, info_class,                           \
                   alt_1, alt_2)                                \
        info_class const vec_info_2 info = {            \
                i : {                                           \
                   i : {                                        \
                      layout : { bitmap : (StgWord)bitmap_ },   \
-                     STD_INFO(srt_len_,type_)                  \
+                     STD_INFO(srt_bitmap_,type_)                       \
                   },                                           \
                   RET_INFO(srt_,srt_off_)                      \
                }                                               \
        }
 
-#define VEC_INFO_3(info,bitmap_,srt_,srt_off_,srt_len_,                \
+#define VEC_INFO_3(info,bitmap_,srt_,srt_off_,srt_bitmap_,             \
                   type_, info_class,                           \
                   alt_1, alt_2, alt_3                          \
                  )                                             \
@@ -519,14 +519,14 @@ typedef struct {
                i : {                                           \
                   i : {                                        \
                      layout : { bitmap : (StgWord)bitmap_ },   \
-                     STD_INFO(srt_len_,type_)                  \
+                     STD_INFO(srt_bitmap_,type_)                       \
                   },                                           \
                   RET_INFO(srt_,srt_off_)                      \
                },                                              \
                 vec : { alt_1, alt_2, alt_3 }                  \
        }
 
-#define VEC_INFO_4(info,bitmap_,srt_,srt_off_,srt_len_,                \
+#define VEC_INFO_4(info,bitmap_,srt_,srt_off_,srt_bitmap_,             \
                   type_, info_class,                           \
                   alt_1, alt_2, alt_3, alt_4                   \
                  )                                             \
@@ -534,14 +534,14 @@ typedef struct {
                i : {                                           \
                   i : {                                        \
                      layout : { bitmap : (StgWord)bitmap_ },   \
-                     STD_INFO(srt_len_,type_)                  \
+                     STD_INFO(srt_bitmap_,type_)                       \
                   },                                           \
                   RET_INFO(srt_,srt_off_)                      \
                },                                              \
                 vec : { alt_1, alt_2, alt_3, alt_4 }           \
        }
 
-#define VEC_INFO_5(info,bitmap_,srt_,srt_off_,srt_len_,                \
+#define VEC_INFO_5(info,bitmap_,srt_,srt_off_,srt_bitmap_,             \
                   type_, info_class,                           \
                   alt_1, alt_2, alt_3, alt_4,                  \
                   alt_5                                        \
@@ -550,7 +550,7 @@ typedef struct {
                i : {                                           \
                   i : {                                        \
                      layout : { bitmap : (StgWord)bitmap_ },   \
-                     STD_INFO(srt_len_,type_)                  \
+                     STD_INFO(srt_bitmap_,type_)                       \
                   },                                           \
                   RET_INFO(srt_,srt_off_)                      \
                },                                              \
@@ -558,7 +558,7 @@ typedef struct {
                        alt_5 }                                 \
        }
 
-#define VEC_INFO_6(info,bitmap_,srt_,srt_off_,srt_len_,                \
+#define VEC_INFO_6(info,bitmap_,srt_,srt_off_,srt_bitmap_,             \
                   type_, info_class,                           \
                   alt_1, alt_2, alt_3, alt_4,                  \
                   alt_5, alt_6                                 \
@@ -567,7 +567,7 @@ typedef struct {
                i : {                                           \
                   i : {                                        \
                      layout : { bitmap : (StgWord)bitmap_ },   \
-                     STD_INFO(srt_len_,type_)                  \
+                     STD_INFO(srt_bitmap_,type_)                       \
                   },                                           \
                   RET_INFO(srt_,srt_off_)                      \
                },                                              \
@@ -575,7 +575,7 @@ typedef struct {
                        alt_5, alt_6 }                          \
        }
 
-#define VEC_INFO_7(info,bitmap_,srt_,srt_off_,srt_len_,                \
+#define VEC_INFO_7(info,bitmap_,srt_,srt_off_,srt_bitmap_,             \
                   type_, info_class,                           \
                   alt_1, alt_2, alt_3, alt_4,                  \
                   alt_5, alt_6, alt_7                          \
@@ -584,7 +584,7 @@ typedef struct {
                i : {                                           \
                   i : {                                        \
                      layout : { bitmap : (StgWord)bitmap_ },   \
-                     STD_INFO(srt_len_,type_)                  \
+                     STD_INFO(srt_bitmap_,type_)                       \
                   },                                           \
                   RET_INFO(srt_,srt_off_)                      \
                },                                              \
@@ -592,7 +592,7 @@ typedef struct {
                        alt_5, alt_6, alt_7 }                   \
        }
 
-#define VEC_INFO_8(info,bitmap_,srt_,srt_off_,srt_len_,                \
+#define VEC_INFO_8(info,bitmap_,srt_,srt_off_,srt_bitmap_,             \
                   type_, info_class,                           \
                   alt_1, alt_2, alt_3, alt_4,                  \
                   alt_5, alt_6, alt_7, alt_8                   \
@@ -601,7 +601,7 @@ typedef struct {
                i : {                                           \
                   i : {                                        \
                      layout : { bitmap : (StgWord)bitmap_ },   \
-                     STD_INFO(srt_len_,type_)                  \
+                     STD_INFO(srt_bitmap_,type_)                       \
                   },                                           \
                   RET_INFO(srt_,srt_off_)                      \
                },                                              \
@@ -620,7 +620,7 @@ typedef vec_info_8 StgPolyInfoTable;
 #ifndef TABLES_NEXT_TO_CODE
 
 #define VEC_POLY_INFO_TABLE(nm, bitmap_,                       \
-                          srt_, srt_off_, srt_len_,            \
+                          srt_, srt_off_, srt_bitmap_,         \
                           type_, info_class, entry_class       \
                           )                                    \
   info_class const vec_info_8 nm##_info = {                    \
@@ -628,7 +628,7 @@ typedef vec_info_8 StgPolyInfoTable;
                    i : {                                       \
                        layout : {                              \
                        bitmap : (StgWord)bitmap_ },            \
-                       STD_INFO(srt_len_, type_),              \
+                       STD_INFO(srt_bitmap_, type_),           \
                        INIT_ENTRY(nm##_ret)                    \
                    },                                          \
                    RET_INFO(srt_,srt_off_)                     \
@@ -647,7 +647,7 @@ typedef vec_info_8 StgPolyInfoTable;
 #else
 
 #define VEC_POLY_INFO_TABLE(nm, bitmap_,                       \
-                          srt_, srt_off_, srt_len_,            \
+                          srt_, srt_off_, srt_bitmap_,         \
                           type_, info_class, entry_class       \
                           )                                    \
        info_class const vec_info_8 nm##_info = {       \
@@ -665,7 +665,7 @@ typedef vec_info_8 StgPolyInfoTable;
                    i : {                                       \
                        layout : {                              \
                        bitmap : (StgWord)bitmap_ },            \
-                       STD_INFO(srt_len_, type_),              \
+                       STD_INFO(srt_bitmap_, type_),           \
                        INIT_ENTRY(nm##_ret)                    \
                    },                                          \
                    RET_INFO(srt_,srt_off_)                     \
@@ -677,18 +677,6 @@ typedef vec_info_8 StgPolyInfoTable;
 #define SRT(lbl) \
   static const StgSRT lbl = {
 
-#define BITMAP(lbl,size,contents) \
-  static const StgLargeBitmap lbl = { size, { contents } };
-
-#if SIZEOF_VOID_P == 8
-#define BITMAP64(first, second)                \
-  (((StgWord32)(first)) | ((StgWord)(StgWord32)(second) << 32))
-#else
-#define BITMAP64(first, second)                first, second
-#endif
-#define BITMAP32(x)                    ((StgWord32)(x))
-#define COMMA                          ,
-
 /* DLL_SRT_ENTRY is used on the Win32 side when filling initialising
    an entry in an SRT table with a reference to a closure that's
    living in a DLL. See elsewhere for reasons as to why we need
index 97c3bec..79b3de1 100644 (file)
@@ -1,5 +1,5 @@
 /* ----------------------------------------------------------------------------
- * $Id: InfoTables.h,v 1.28 2002/12/11 15:36:37 simonmar Exp $
+ * $Id: InfoTables.h,v 1.29 2003/05/14 09:14:02 simonmar Exp $
  * 
  * (c) The GHC Team, 1998-2002
  *
@@ -185,6 +185,29 @@ typedef struct {
   StgWord bitmap[FLEXIBLE_ARRAY];
 } StgLargeBitmap;
 
+/* -----------------------------------------------------------------------------
+   SRTs  (Static Reference Tables)
+
+   These tables are used to keep track of the static objects referred
+   to by the code for a closure or stack frame, so that we can follow
+   static data references from code and thus accurately
+   garbage-collect CAFs.
+   -------------------------------------------------------------------------- */
+
+// An SRT is just an array of closure pointers:
+typedef StgClosure* StgSRT[];
+
+// Each info table refers to some subset of the closure pointers in an
+// SRT.  It does this using a pair of an StgSRT pointer and a
+// half-word bitmap.  If the half-word bitmap isn't large enough, then
+// we fall back to a large SRT, including an unbounded bitmap.  If the
+// half-word bitmap is set to all ones (0xffff), then the StgSRT
+// pointer instead points to an StgLargeSRT:
+typedef struct StgLargeSRT_ {
+    StgSRT *srt;
+    StgLargeBitmap l;
+} StgLargeSRT;
+
 /* ----------------------------------------------------------------------------
    Info Tables
    ------------------------------------------------------------------------- */
@@ -211,11 +234,6 @@ typedef union {
 
 
 //
-// An SRT.
-//
-typedef StgClosure* StgSRT[];
-
-//
 // The "standard" part of an info table.  Every info table has this bit.
 //
 typedef struct _StgInfoTable {
@@ -240,7 +258,7 @@ typedef struct _StgInfoTable {
     StgClosureInfo  layout;    // closure layout info (one word)
 
     StgHalfWord     type;      // closure type
-    StgHalfWord     srt_len;    // number of entries in SRT (or constructor tag)
+    StgHalfWord     srt_bitmap;    // number of entries in SRT (or constructor tag)
 
 #ifdef TABLES_NEXT_TO_CODE
     StgCode         code[FLEXIBLE_ARRAY];
@@ -258,7 +276,7 @@ typedef struct _StgInfoTable {
       and bitmap fields may be left out (they are at the end, so omitting
       them doesn't affect the layout).
       
-   -  If srt_len (in the std info table part) is zero, then the srt
+   -  If srt_bitmap (in the std info table part) is zero, then the srt
       field may be omitted.  This only applies if the slow_apply and
       bitmap fields have also been omitted.
    -------------------------------------------------------------------------- */
@@ -286,7 +304,7 @@ typedef struct _StgFunInfoTable {
    -------------------------------------------------------------------------- */
 
 // When info tables are laid out backwards, we can omit the SRT
-// pointer iff srt_len is zero.
+// pointer iff srt_bitmap is zero.
 
 typedef struct _StgRetInfoTable {
 #if !defined(TABLES_NEXT_TO_CODE)
@@ -306,7 +324,7 @@ typedef struct _StgRetInfoTable {
    -------------------------------------------------------------------------- */
 
 // When info tables are laid out backwards, we can omit the SRT
-// pointer iff srt_len is zero.
+// pointer iff srt_bitmap is zero.
 
 typedef struct _StgThunkInfoTable {
 #if !defined(TABLES_NEXT_TO_CODE)
index fea85dd..a62f62e 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: Exception.hc,v 1.26 2002/12/11 15:36:42 simonmar Exp $
+ * $Id: Exception.hc,v 1.27 2003/05/14 09:13:59 simonmar Exp $
  *
  * (c) The GHC Team, 1998-2000
  *
@@ -280,7 +280,7 @@ CATCH_FRAME_ENTRY_TEMPLATE(stg_catch_frame_7_ret,RET_VEC(Sp[SP_OFF],7));
 
 VEC_POLY_INFO_TABLE(stg_catch_frame, \
        MK_SMALL_BITMAP(CATCH_FRAME_WORDS, CATCH_FRAME_BITMAP), \
-       NULL/*srt*/, 0/*srt_off*/, 0/*srt_len*/, CATCH_FRAME,, EF_);
+       NULL/*srt*/, 0/*srt_off*/, 0/*srt_bitmap*/, CATCH_FRAME,, EF_);
 
 /* -----------------------------------------------------------------------------
  * The catch infotable
index 1c11938..3ab057a 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: GC.c,v 1.154 2003/04/22 16:25:09 simonmar Exp $
+ * $Id: GC.c,v 1.155 2003/05/14 09:13:59 simonmar Exp $
  *
  * (c) The GHC Team 1998-2003
  *
@@ -1637,6 +1637,23 @@ mkMutCons(StgClosure *ptr, generation *gen)
    if  M <  evac_gen     set failed_to_evac flag to indicate that we
                          didn't manage to evacuate this object into evac_gen.
 
+
+   OPTIMISATION NOTES:
+
+   evacuate() is the single most important function performance-wise
+   in the GC.  Various things have been tried to speed it up, but as
+   far as I can tell the code generated by gcc 3.2 with -O2 is about
+   as good as it's going to get.  We pass the argument to evacuate()
+   in a register using the 'regparm' attribute (see the prototype for
+   evacuate() near the top of this file).
+
+   Changing evacuate() to take an (StgClosure **) rather than
+   returning the new pointer seems attractive, because we can avoid
+   writing back the pointer when it hasn't changed (eg. for a static
+   object, or an object in a generation > N).  However, I tried it and
+   it doesn't help.  One reason is that the (StgClosure **) pointer
+   gets spilled to the stack inside evacuate(), resulting in far more
+   extra reads/writes than we save.
    -------------------------------------------------------------------------- */
 
 static StgClosure *
@@ -1810,7 +1827,7 @@ loop:
     goto loop;
 
   case THUNK_STATIC:
-    if (info->srt_len > 0 && major_gc && 
+    if (info->srt_bitmap != 0 && major_gc && 
        THUNK_STATIC_LINK((StgClosure *)q) == NULL) {
       THUNK_STATIC_LINK((StgClosure *)q) = static_objects;
       static_objects = (StgClosure *)q;
@@ -1818,7 +1835,7 @@ loop:
     return q;
 
   case FUN_STATIC:
-    if (info->srt_len > 0 && major_gc && 
+    if (info->srt_bitmap != 0 && major_gc && 
        FUN_STATIC_LINK((StgClosure *)q) == NULL) {
       FUN_STATIC_LINK((StgClosure *)q) = static_objects;
       static_objects = (StgClosure *)q;
@@ -2153,36 +2170,75 @@ move_TSO (StgTSO *src, StgTSO *dest)
     dest->sp = (StgPtr)dest->sp + diff;
 }
 
-/* evacuate the SRT.  If srt_len is zero, then there isn't an
+/* Similar to scavenge_large_bitmap(), but we don't write back the
+ * pointers we get back from evacuate().
+ */
+static void
+scavenge_large_srt_bitmap( StgLargeSRT *large_srt )
+{
+    nat i, b, size;
+    StgWord bitmap;
+    StgClosure **p;
+    
+    b = 0;
+    bitmap = large_srt->l.bitmap[b];
+    size   = (nat)large_srt->l.size;
+    p      = large_srt->srt;
+    for (i = 0; i < size; ) {
+       if ((bitmap & 1) != 0) {
+           evacuate(*p);
+       }
+       i++;
+       p++;
+       if (i % BITS_IN(W_) == 0) {
+           b++;
+           bitmap = large_srt->l.bitmap[b];
+       } else {
+           bitmap = bitmap >> 1;
+       }
+    }
+}
+
+/* evacuate the SRT.  If srt_bitmap is zero, then there isn't an
  * srt field in the info table.  That's ok, because we'll
  * never dereference it.
  */
 static inline void
-scavenge_srt (StgClosure **srt, nat srt_len)
+scavenge_srt (StgClosure **srt, nat srt_bitmap)
 {
-  StgClosure **srt_end;
+  nat bitmap;
+  StgClosure **p;
 
-  srt_end = srt + srt_len;
+  bitmap = srt_bitmap;
+  p = srt;
 
-  for (; srt < srt_end; srt++) {
-    /* Special-case to handle references to closures hiding out in DLLs, since
-       double indirections required to get at those. The code generator knows
-       which is which when generating the SRT, so it stores the (indirect)
-       reference to the DLL closure in the table by first adding one to it.
-       We check for this here, and undo the addition before evacuating it.
+  if (bitmap == (StgHalfWord)(-1)) {  
+      scavenge_large_srt_bitmap( (StgLargeSRT *)srt );
+      return;
+  }
 
-       If the SRT entry hasn't got bit 0 set, the SRT entry points to a
-       closure that's fixed at link-time, and no extra magic is required.
-    */
+  while (bitmap != 0) {
+      if ((bitmap & 1) != 0) {
 #ifdef ENABLE_WIN32_DLL_SUPPORT
-    if ( (unsigned long)(*srt) & 0x1 ) {
-       evacuate(*stgCast(StgClosure**,(stgCast(unsigned long, *srt) & ~0x1)));
-    } else {
-       evacuate(*srt);
-    }
+         // Special-case to handle references to closures hiding out in DLLs, since
+         // double indirections required to get at those. The code generator knows
+         // which is which when generating the SRT, so it stores the (indirect)
+         // reference to the DLL closure in the table by first adding one to it.
+         // We check for this here, and undo the addition before evacuating it.
+         // 
+         // If the SRT entry hasn't got bit 0 set, the SRT entry points to a
+         // closure that's fixed at link-time, and no extra magic is required.
+         if ( (unsigned long)(*srt) & 0x1 ) {
+             evacuate(*stgCast(StgClosure**,(stgCast(unsigned long, *srt) & ~0x1)));
+         } else {
+             evacuate(*p);
+         }
 #else
-       evacuate(*srt);
+         evacuate(*p);
 #endif
+      }
+      p++;
+      bitmap = bitmap >> 1;
   }
 }
 
@@ -2193,7 +2249,7 @@ scavenge_thunk_srt(const StgInfoTable *info)
     StgThunkInfoTable *thunk_info;
 
     thunk_info = itbl_to_thunk_itbl(info);
-    scavenge_srt((StgClosure **)thunk_info->srt, thunk_info->i.srt_len);
+    scavenge_srt((StgClosure **)thunk_info->srt, thunk_info->i.srt_bitmap);
 }
 
 static inline void
@@ -2202,7 +2258,7 @@ scavenge_fun_srt(const StgInfoTable *info)
     StgFunInfoTable *fun_info;
 
     fun_info = itbl_to_fun_itbl(info);
-    scavenge_srt((StgClosure **)fun_info->srt, fun_info->i.srt_len);
+    scavenge_srt((StgClosure **)fun_info->srt, fun_info->i.srt_bitmap);
 }
 
 static inline void
@@ -2211,7 +2267,7 @@ scavenge_ret_srt(const StgInfoTable *info)
     StgRetInfoTable *ret_info;
 
     ret_info = itbl_to_ret_itbl(info);
-    scavenge_srt((StgClosure **)ret_info->srt, ret_info->i.srt_len);
+    scavenge_srt((StgClosure **)ret_info->srt, ret_info->i.srt_bitmap);
 }
 
 /* -----------------------------------------------------------------------------
@@ -2371,7 +2427,7 @@ scavenge(step *stp)
 
     q = p;
     switch (info->type) {
-       
+
     case MVAR:
        /* treat MVars specially, because we don't want to evacuate the
         * mut_link field in the middle of the closure.
@@ -3646,7 +3702,7 @@ scavenge_stack(StgPtr p, StgPtr stack_end)
        p = scavenge_small_bitmap(p, size, bitmap);
 
     follow_srt:
-       scavenge_srt((StgClosure **)info->srt, info->i.srt_len);
+       scavenge_srt((StgClosure **)info->srt, info->i.srt_bitmap);
        continue;
 
     case RET_BCO: {
index a3aa5bf..2254b5c 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: HeapStackCheck.hc,v 1.30 2003/04/22 16:25:10 simonmar Exp $
+ * $Id: HeapStackCheck.hc,v 1.31 2003/05/14 09:13:59 simonmar Exp $
  *
  * (c) The GHC Team, 1998-2002
  *
 
 INFO_TABLE_RET( stg_enter_info, stg_enter_ret, 
                MK_SMALL_BITMAP(1/*framesize*/, 0/*bitmap*/),
-               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_LEN*/, 
+               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_BITMAP*/, 
                RET_SMALL,, EF_, 0, 0);
 EXTFUN(stg_enter_ret)
 {
@@ -496,7 +496,7 @@ EXTFUN(stg_gc_noregs)
 
 INFO_TABLE_RET( stg_gc_void_info, stg_gc_void_ret, 
                MK_SMALL_BITMAP(0/*framesize*/, 0/*bitmap*/),
-               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_LEN*/, 
+               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_BITMAP*/, 
                RET_SMALL,, EF_, 0, 0);
 
 EXTFUN(stg_gc_void_ret)
@@ -511,7 +511,7 @@ EXTFUN(stg_gc_void_ret)
 
 INFO_TABLE_RET( stg_gc_unpt_r1_info, stg_gc_unpt_r1_ret, 
                MK_SMALL_BITMAP(1/*framesize*/, 0/*bitmap*/),
-               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_LEN*/, 
+               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_BITMAP*/, 
                RET_SMALL,, EF_, 0, 0);
 
 EXTFUN(stg_gc_unpt_r1_ret)
@@ -537,7 +537,7 @@ EXTFUN(stg_gc_unpt_r1)
 
 INFO_TABLE_RET(        stg_gc_unbx_r1_info, stg_gc_unbx_r1_ret, 
                MK_SMALL_BITMAP(1/*framesize*/, 1/*bitmap*/),
-               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_LEN*/, 
+               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_BITMAP*/, 
                RET_SMALL,, EF_, 0, 0);
 
 /* the 1 is a bitmap - i.e. 1 non-pointer word on the stack. */
@@ -565,7 +565,7 @@ EXTFUN(stg_gc_unbx_r1)
 
 INFO_TABLE_RET(        stg_gc_f1_info, stg_gc_f1_ret, 
                MK_SMALL_BITMAP(1/*framesize*/, 1/*bitmap*/),
-               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_LEN*/, 
+               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_BITMAP*/, 
                RET_SMALL,, EF_, 0, 0);
 
 EXTFUN(stg_gc_f1_ret)
@@ -601,7 +601,7 @@ EXTFUN(stg_gc_f1)
 
 INFO_TABLE_RET(        stg_gc_d1_info, stg_gc_d1_ret, 
                MK_SMALL_BITMAP(DBL_WORDS/*framesize*/, DBL_BITMAP/*bitmap*/),
-               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_LEN*/, 
+               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_BITMAP*/, 
                RET_SMALL,, EF_, 0, 0);
 
 EXTFUN(stg_gc_d1_ret)
@@ -638,7 +638,7 @@ EXTFUN(stg_gc_d1)
 
 INFO_TABLE_RET( stg_gc_l1_info, stg_gc_l1_ret, 
                MK_SMALL_BITMAP(LLI_WORDS/*framesize*/, LLI_BITMAP/*bitmap*/),
-               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_LEN*/, 
+               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_BITMAP*/, 
                RET_SMALL,, EF_, 0, 0);
 
 EXTFUN(stg_gc_l1_ret)
@@ -664,7 +664,7 @@ EXTFUN(stg_gc_l1)
 
 INFO_TABLE_RET( stg_ut_1_0_unreg_info, stg_ut_1_0_unreg_ret, 
                MK_SMALL_BITMAP(1/*size*/, 0/*BITMAP*/),
-               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_LEN*/, 
+               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_BITMAP*/, 
                RET_SMALL,, EF_, 0, 0);
 
 EXTFUN(stg_ut_1_0_unreg_ret)
@@ -758,7 +758,7 @@ EXTFUN(__stg_gc_fun)
 
 INFO_TABLE_RET( stg_gc_fun_info,stg_gc_fun_ret,
                MK_SMALL_BITMAP(0/*framesize*/, 0/*bitmap*/),
-               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_LEN*/, 
+               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_BITMAP*/, 
                RET_FUN,, EF_, 0, 0);
 
 EXTFUN(stg_gc_fun_ret)
@@ -852,7 +852,7 @@ EXTFUN(stg_gc_fun_ret)
 
 INFO_TABLE_RET( stg_gc_gen_info, stg_gc_gen_ret, 
                0/*bitmap*/,
-               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_LEN*/, 
+               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_BITMAP*/, 
                RET_DYN,, EF_, 0, 0);
 
 /* bitmap in the above info table is unused, the real one is on the stack. 
@@ -980,7 +980,7 @@ FN_(stg_block_1)
 
 INFO_TABLE_RET( stg_block_takemvar_info,  stg_block_takemvar_ret,
                MK_SMALL_BITMAP(1/*framesize*/, 0/*bitmap*/),
-               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_LEN*/, 
+               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_BITMAP*/, 
                RET_SMALL,, IF_, 0, 0);
 
 IF_(stg_block_takemvar_ret)
@@ -1004,7 +1004,7 @@ FN_(stg_block_takemvar)
 
 INFO_TABLE_RET( stg_block_putmvar_info,  stg_block_putmvar_ret,
                MK_SMALL_BITMAP(2/*framesize*/, 0/*bitmap*/),
-               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_LEN*/, 
+               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_BITMAP*/, 
                RET_SMALL,, IF_, 0, 0);
 
 IF_(stg_block_putmvar_ret)
@@ -1031,7 +1031,7 @@ FN_(stg_block_putmvar)
 #ifdef mingw32_TARGET_OS
 INFO_TABLE_RET( stg_block_async_info,  stg_block_async_ret,
                MK_SMALL_BITMAP(0/*framesize*/, 0/*bitmap*/),
-               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_LEN*/, 
+               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_BITMAP*/, 
                RET_SMALL,, IF_, 0, 0);
 
 IF_(stg_block_async_ret)
index 38ade81..b73b79e 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: Printer.c,v 1.59 2003/04/22 16:25:12 simonmar Exp $
+ * $Id: Printer.c,v 1.60 2003/05/14 09:13:59 simonmar Exp $
  *
  * (c) The GHC Team, 1994-2000.
  *
@@ -134,7 +134,7 @@ printClosure( StgClosure *obj )
 #else
             fprintf(stderr,"CONSTR(");
             printPtr((StgPtr)obj->header.info);
-            fprintf(stderr,"(tag=%d)",info->srt_len);
+            fprintf(stderr,"(tag=%d)",info->srt_bitmap);
 #endif
             for (i = 0; i < info->layout.payload.ptrs; ++i) {
                fprintf(stderr,", ");
index 5f4c6ce..8bf5dbb 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: StgMiscClosures.hc,v 1.84 2003/03/27 13:54:32 simonmar Exp $
+ * $Id: StgMiscClosures.hc,v 1.85 2003/05/14 09:14:00 simonmar Exp $
  *
  * (c) The GHC Team, 1998-2002
  *
@@ -127,13 +127,13 @@ STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_6_ret);
 STG_CtoI_RET_R1p_Template(stg_ctoi_ret_R1p_7_ret);
 
 VEC_POLY_INFO_TABLE( stg_ctoi_ret_R1p, 0/* special layout */,
-                    0/*srt*/, 0/*srt_off*/, 0/*srt_len*/, 
+                    0/*srt*/, 0/*srt_off*/, 0/*srt_bitmap*/, 
                     RET_BCO,, EF_);
 
 // When the returned value is a pointer, but unlifted, in R1 ...
 INFO_TABLE_RET( stg_ctoi_ret_R1unpt_info, stg_ctoi_ret_R1unpt_entry,
                0/* special layout */,
-               0/*srt*/, 0/*srt_off*/, 0/*srt_len*/, RET_BCO,, IF_, 0, 0);
+               0/*srt*/, 0/*srt_off*/, 0/*srt_bitmap*/, RET_BCO,, IF_, 0, 0);
 IF_(stg_ctoi_ret_R1unpt_entry)
 {
    FB_
@@ -147,7 +147,7 @@ IF_(stg_ctoi_ret_R1unpt_entry)
 // When the returned value is a non-pointer in R1 ...
 INFO_TABLE_RET( stg_ctoi_ret_R1n_info, stg_ctoi_ret_R1n_entry,
                0/* special layout */,
-               0/*srt*/, 0/*srt_off*/, 0/*srt_len*/, RET_BCO,, IF_, 0, 0);
+               0/*srt*/, 0/*srt_off*/, 0/*srt_bitmap*/, RET_BCO,, IF_, 0, 0);
 IF_(stg_ctoi_ret_R1n_entry)
 {
    FB_
@@ -162,7 +162,7 @@ IF_(stg_ctoi_ret_R1n_entry)
 // When the returned value is in F1 ...
 INFO_TABLE_RET( stg_ctoi_ret_F1_info, stg_ctoi_ret_F1_entry, 
                0/* special layout */,
-               0/*srt*/, 0/*srt_off*/, 0/*srt_len*/, RET_BCO,, IF_, 0, 0);
+               0/*srt*/, 0/*srt_off*/, 0/*srt_bitmap*/, RET_BCO,, IF_, 0, 0);
 IF_(stg_ctoi_ret_F1_entry)
 {
    FB_
@@ -176,7 +176,7 @@ IF_(stg_ctoi_ret_F1_entry)
 // When the returned value is in D1 ...
 INFO_TABLE_RET( stg_ctoi_ret_D1_info, stg_ctoi_ret_D1_entry,
                0/* special layout */,
-               0/*srt*/, 0/*srt_off*/, 0/*srt_len*/, RET_BCO,, IF_, 0, 0);
+               0/*srt*/, 0/*srt_off*/, 0/*srt_bitmap*/, RET_BCO,, IF_, 0, 0);
 IF_(stg_ctoi_ret_D1_entry)
 {
    FB_
@@ -190,7 +190,7 @@ IF_(stg_ctoi_ret_D1_entry)
 // When the returned value is in L1 ...
 INFO_TABLE_RET( stg_ctoi_ret_L1_info, stg_ctoi_ret_L1_entry,
                0/* special layout */,
-               0/*srt*/, 0/*srt_off*/, 0/*srt_len*/, RET_BCO,, IF_, 0, 0);
+               0/*srt*/, 0/*srt_off*/, 0/*srt_bitmap*/, RET_BCO,, IF_, 0, 0);
 IF_(stg_ctoi_ret_L1_entry)
 {
    FB_
@@ -204,7 +204,7 @@ IF_(stg_ctoi_ret_L1_entry)
 // When the returned value a VoidRep ...
 INFO_TABLE_RET( stg_ctoi_ret_V_info, stg_ctoi_ret_V_entry,
                0/* special layout */,
-               0/*srt*/, 0/*srt_off*/, 0/*srt_len*/, RET_BCO,, IF_, 0, 0);
+               0/*srt*/, 0/*srt_off*/, 0/*srt_bitmap*/, RET_BCO,, IF_, 0, 0);
 IF_(stg_ctoi_ret_V_entry)
 {
    FB_
@@ -218,7 +218,7 @@ IF_(stg_ctoi_ret_V_entry)
 // should apply the BCO on the stack to its arguments, also on the stack.
 INFO_TABLE_RET( stg_apply_interp_info, stg_apply_interp_entry,
                0/* special layout */,
-               0/*srt*/, 0/*srt_off*/, 0/*srt_len*/, RET_BCO,, IF_, 0, 0);
+               0/*srt*/, 0/*srt_off*/, 0/*srt_bitmap*/, RET_BCO,, IF_, 0, 0);
 IF_(stg_apply_interp_entry)
 {
     FB_
index c9afaa8..d3e4c2f 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: StgStartup.hc,v 1.20 2002/12/11 15:36:54 simonmar Exp $
+ * $Id: StgStartup.hc,v 1.21 2003/05/14 09:14:00 simonmar Exp $
  *
  * (c) The GHC Team, 1998-2002
  *
@@ -135,7 +135,7 @@ STGFUN(stg_returnToStackTop)
 
 INFO_TABLE_RET( stg_forceIO_info,stg_forceIO_ret,
                MK_SMALL_BITMAP(0/*size*/, 0/*BITMAP*/),
-               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_LEN*/, 
+               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_BITMAP*/, 
                RET_SMALL,, EF_, 0, 0);
 
 #ifdef REG_R1
@@ -168,7 +168,7 @@ STGFUN(stg_forceIO_ret)
 
 INFO_TABLE_RET( stg_noforceIO_info,stg_noforceIO_ret,
                MK_SMALL_BITMAP(0/*size*/, 0/*BITMAP*/),
-               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_LEN*/, 
+               0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_BITMAP*/, 
                RET_SMALL,, EF_, 0, 0);
 
 #ifdef REG_R1
index ac5b948..b47b7c6 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: Updates.hc,v 1.39 2003/03/27 13:54:32 simonmar Exp $
+ * $Id: Updates.hc,v 1.40 2003/05/14 09:14:00 simonmar Exp $
  *
  * (c) The GHC Team, 1998-2002
  *
@@ -95,7 +95,7 @@ UPD_FRAME_ENTRY_TEMPLATE(stg_upd_frame_7_ret,&stg_IND_7_info,RET_VEC(Sp[0],7));
 
 VEC_POLY_INFO_TABLE( stg_upd_frame, 
                     MK_SMALL_BITMAP(UPD_FRAME_WORDS, UPD_FRAME_BITMAP),
-                    0/*srt*/, 0/*srt_off*/, 0/*srt_len*/,
+                    0/*srt*/, 0/*srt_off*/, 0/*srt_bitmap*/,
                     UPDATE_FRAME,, EF_);
 
 /*-----------------------------------------------------------------------------
@@ -128,7 +128,7 @@ IF_(stg_seq_frame_ret);
 
 VEC_POLY_INFO_TABLE( stg_seq_frame,
                     MK_SMALL_BITMAP(0, 0),
-                    0/*srt*/, 0/*srt_off*/, 0/*srt_len*/,
+                    0/*srt*/, 0/*srt_off*/, 0/*srt_bitmap*/,
                     RET_SMALL,, EF_);
 
 IF_(stg_seq_frame_ret)