- replace_stable_fn (MkCgIdInfo i vol stab einfo)
- = MkCgIdInfo i vol (VirStkLoc offset) einfo
-\end{code}
-
-%************************************************************************
-%* *
-\subsection[CgBindery-liveness]{Build a liveness mask for the current stack}
-%* *
-%************************************************************************
-
-There are four kinds of things on the stack:
-
- - pointer variables (bound in the environment)
- - non-pointer variables (boudn in the environment)
- - 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).
-
-\begin{code}
-buildLivenessMask
- :: VirtualSpOffset -- size of the stack frame
- -> VirtualSpOffset -- offset from which the bitmap should start
- -> FCode LivenessMask -- 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 (listToLivenessMask 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.
-
-buildContLivenessMask :: Name -> FCode Liveness
-buildContLivenessMask name = do
- realSp <- getRealSp
-
- 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
-
- mask <- buildLivenessMask frame_size (realSp-1)
-
- let liveness = Liveness (mkBitmapLabel name) frame_size mask
- absC (CBitmap liveness)
- return liveness