[project @ 2003-06-27 18:28:31 by sof]
[ghc-hetmet.git] / ghc / compiler / codeGen / CgBindery.lhs
index acac740..c91bbee 100644 (file)
@@ -23,7 +23,7 @@ module CgBindery (
        getCAddrModeAndInfo, getCAddrMode,
        getCAddrModeIfVolatile, getVolatileRegs,
 
-       buildLivenessMask, buildContLivenessMask
+       buildContLivenessMask
     ) where
 
 #include "HsVersions.h"
@@ -32,11 +32,11 @@ import AbsCSyn
 import CgMonad
 
 import CgUsages                ( getHpRelOffset, getSpRelOffset, getRealSp )
-import CgStackery      ( freeStackSlots )
+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 )
@@ -44,7 +44,7 @@ import VarEnv
 import VarSet          ( varSetElems )
 import Literal         ( Literal )
 import Maybes          ( catMaybes, maybeToBool, seqMaybe )
-import Name            ( isInternalName, NamedThing(..) )
+import Name            ( Name, isInternalName, NamedThing(..) )
 #ifdef DEBUG
 import PprAbsC         ( pprAmode )
 #endif
@@ -85,7 +85,7 @@ data VolatileLoc
   | TempVarLoc Unique
 
   | RegLoc     MagicId                 -- in one of the magic registers
-                                       -- (probably {Int,Float,Char,etc}Reg
+                                       -- (probably {Int,Float,Char,etc}Reg)
 
   | VirHpLoc   VirtualHeapOffset       -- Hp+offset (address of closure)
 
@@ -361,7 +361,7 @@ bindNewToStack :: (Id, VirtualSpOffset) -> Code
 bindNewToStack (name, offset)
   = addBindC name info
   where
-    info = MkCgIdInfo name NoVolatileLoc (VirStkLoc offset) mkLFArgument
+    info = MkCgIdInfo name NoVolatileLoc (VirStkLoc offset) (mkLFArgument name)
 
 bindNewToNode :: Id -> VirtualHeapOffset -> LambdaFormInfo -> Code
 bindNewToNode name offset lf_info
@@ -374,7 +374,7 @@ bindNewToNode name offset lf_info
 -- temporary.
 bindNewToTemp :: Id -> FCode CAddrMode
 bindNewToTemp name
-  = let (temp_amode, id_info) = newTempAmodeAndIdInfo name mkLFArgument
+  = let (temp_amode, id_info) = newTempAmodeAndIdInfo name (mkLFArgument name)
                -- This is used only for things we don't know
                -- anything about; values returned by a case statement,
                -- for example.
@@ -392,7 +392,7 @@ bindArgsToRegs :: [Id] -> [MagicId] -> Code
 bindArgsToRegs args regs
   = listCs (zipWithEqual "bindArgsToRegs" bind args regs)
   where
-    arg `bind` reg = bindNewToReg arg reg mkLFArgument
+    arg `bind` reg = bindNewToReg arg reg (mkLFArgument arg)
 \end{code}
 
 @bindNewPrimToAmode@ works only for certain addressing modes.  Making
@@ -435,92 +435,51 @@ There are four kinds of things on the stack:
        - free slots (recorded in the stack free list)
        - non-pointer data slots (recorded in the stack free list)
 
-We build up a bitmap of non-pointer slots by looking down the
-environment for all the non-pointer variables, and merging this with
-the slots recorded in the stack free list.
-
-There's a bit of a hack here to do with update frames: since nothing
-is recorded in either the environment or the stack free list for an
-update frame, the code below defaults to assuming the slots taken up
-by an update frame contain pointers.  Furthermore, update frames are
-always in slots 0-2 at the bottom of the stack.  The bitmap will
-therefore end at slot 3, which is what we want (the update frame info
-pointer has its own bitmap to describe the update frame).
+We build up a bitmap of non-pointer slots by searching the environment
+for all the pointer variables, and subtracting these from a bitmap
+with initially all bits set (up to the size of the stack frame).
 
 \begin{code}
 buildLivenessMask 
-       :: Unique               -- unique for for large bitmap label
+       :: VirtualSpOffset      -- size of the stack frame
        -> VirtualSpOffset      -- offset from which the bitmap should start
-       -> FCode Liveness       -- mask for free/unlifted slots
+       -> FCode Bitmap         -- mask for free/unlifted slots
+
+buildLivenessMask size sp = do {
+    -- find all live stack-resident pointers
+    binds <- getBinds;
+    ((vsp, _, free, _, _), heap_usage) <- getUsage;
+
+    let {
+       rel_slots = sortLt (<) 
+           [ sp - ofs  -- get slots relative to top of frame
+           | (MkCgIdInfo id _ (VirStkLoc ofs) _) <- rngVarEnv binds,
+             isFollowableRep (idPrimRep id)
+           ];
+    };
+
+    ASSERT(all (>=0) rel_slots)
+     return (intsToReverseBitmap size rel_slots)
+  }
+
+-- In a continuation, we want a liveness mask that starts from just after
+-- the return address, which is on the stack at realSp.
+
+buildContLivenessMask :: Name -> FCode Liveness
+buildContLivenessMask name = do
+       realSp <- getRealSp
 
-buildLivenessMask uniq sp = do 
+       frame_sp <- getStackFrame
+       -- realSp points to the frame-header for the current stack frame,
+       -- and the end of this frame is frame_sp.  The size is therefore
+       -- realSp - frame_sp - 1 (subtract one for the frame-header).
+       let frame_size = realSp - frame_sp - 1
 
-       -- find all unboxed stack-resident ids
-       binds <- getBinds
-       ((vsp, free, _, _), heap_usage) <- getUsage
-       
-       let unboxed_slots = 
-               [ (ofs, size) | 
-               (MkCgIdInfo id _ (VirStkLoc ofs) _) <- rngVarEnv binds,
-               let rep = idPrimRep id; size = getPrimRepSize rep,
-               not (isFollowableRep rep),
-               size > 0
-               ]       
-               
-       -- flatten this list into a list of unboxed stack slots
-       let flatten_slots = sortLt (<) 
-               (foldr (\(ofs,size) r -> [ofs-size+1 .. ofs] ++ r) []
-                     unboxed_slots)
-
-       -- merge in the free slots
-       let all_slots = mergeSlots flatten_slots (map fst free) ++ 
-                   if vsp < sp then [vsp+1 .. sp] else []
-
-        -- recalibrate the list to be sp-relative
-       let rel_slots = reverse (map (sp-) all_slots)
-
-       -- build the bitmap
-       let liveness_mask 
-               = ASSERT(all (>=0) rel_slots 
-                        && rel_slots == sortLt (<) rel_slots) 
-                 (listToLivenessMask rel_slots)
-       
-       livenessToAbsC uniq liveness_mask
-
-mergeSlots :: [Int] -> [Int] -> [Int]
-mergeSlots cs [] = cs
-mergeSlots [] ns = ns
-mergeSlots (c:cs) (n:ns)
- = if c < n then
-       c : mergeSlots cs (n:ns)
-   else if c > n then
-       n : mergeSlots (c:cs) ns
-   else
-       panic ("mergeSlots: equal slots: " ++ show (c:cs) ++ show (n:ns))
-
-listToLivenessMask :: [Int] -> LivenessMask
-listToLivenessMask []    = []
-listToLivenessMask slots = 
-   mkBS this : listToLivenessMask (map (\x -> x-32) rest)
-   where (this,rest) = span (<32) slots
-
-livenessToAbsC :: Unique -> LivenessMask -> FCode Liveness
-livenessToAbsC uniq mask  =
-        absC (CBitmap lbl mask) `thenC`
-        returnFC (Liveness lbl mask)
-  where lbl = mkBitmapLabel uniq       
-\end{code}
+       mask <- buildLivenessMask frame_size (realSp-1)
 
-In a continuation, we want a liveness mask that starts from just after
-the return address, which is on the stack at realSp.
-
-\begin{code}
-buildContLivenessMask
-       :: Unique
-       -> FCode Liveness
-buildContLivenessMask uniq = do
-       realSp <- getRealSp
-       buildLivenessMask uniq (realSp-1)
+        let liveness = Liveness (mkBitmapLabel name) frame_size mask
+       absC (maybeLargeBitmap liveness)
+       return liveness
 \end{code}
 
 %************************************************************************