- 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}
-%* *
-%************************************************************************
-
-ToDo: remove the dependency on 32-bit words.
-
-There are two ways to build a liveness mask, and both appear to have
-problems.
-
- 1) Find all the pointer words by searching through the binding list.
- Invert this to find the non-pointer words and build the bitmap.
-
- 2) Find all the non-pointer words by search through the binding list.
- Merge this with the list of currently free slots. Build the
- bitmap.
-
-Method (1) conflicts with update frames - these contain pointers but
-have no bindings in the environment. We could bind the updatee to its
-location in the update frame at the point when the update frame is
-pushed, but this binding would be dropped by the first case expression
-(nukeDeadBindings).
-
-Method (2) causes problems because we must make sure that every
-non-pointer word on the stack is either a free stack slot or has a
-binding in the environment. Things like cost centres break this (but
-only for case-of-case expressions - because that's when there's a cost
-centre on the stack from the outer case and we need to generate a
-bitmap for the inner case's continuation).
-
-This method also works "by accident" for update frames: since all
-unaccounted for slots on the stack are assumed to be pointers, and an
-update frame always occurs at virtual Sp offsets 0-3 (i.e. the bottom
-of the stack frame), the bitmap will simply end at the start of the
-update frame.
-
-We use method (2) at the moment.
-
-\begin{code}
-buildLivenessMask
- :: Unique -- unique for for large bitmap label
- -> VirtualSpOffset -- offset from which the bitmap should start
- -> FCode Liveness -- mask for free/unlifted slots
-
-buildLivenessMask uniq sp info_down
- state@(MkCgState abs_c binds ((vsp, free, _, _), heap_usage))
- = ASSERT(all (>=0) rel_slots)
- livenessToAbsC uniq liveness_mask info_down state
- where
- -- find all unboxed stack-resident ids
- unboxed_slots =
- [ (ofs, getPrimRepSize rep) |
- (MkCgIdInfo id _ (VirStkLoc ofs) _) <- rngVarEnv binds,
- let rep = idPrimRep id,
- not (isFollowableRep rep)
- ]
-
- -- flatten this list into a list of unboxed stack slots
- flatten_slots = foldr (\(ofs,size) r -> [ofs-size+1 .. ofs] ++ r) []
- unboxed_slots
-
- -- merge in the free slots
- all_slots = addFreeSlots flatten_slots free ++
- if vsp < sp then [vsp+1 .. sp] else []
-
- -- recalibrate the list to be sp-relative
- rel_slots = reverse (map (sp-) all_slots)
-
- -- build the bitmap
- liveness_mask = listToLivenessMask rel_slots
-
-{- ALTERNATE version that doesn't work because update frames aren't
- recorded in the environment.
-
- -- find all boxed stack-resident ids
- boxed_slots =
- [ ofs | (MkCgIdInfo id _ (VirStkLoc ofs) _) <- rngVarEnv binds,
- isFollowableRep (idPrimRep id)
- ]
- all_slots = [1..vsp]
-
- -- invert to get unboxed slots
- unboxed_slots = filter (`notElem` boxed_slots) all_slots
--}
-
-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 [] = returnFC (LvSmall emptyBS)
-livenessToAbsC uniq [one] = returnFC (LvSmall one)
-livenessToAbsC uniq many =
- absC (CBitmap lbl many) `thenC`
- returnFC (LvLarge lbl)
- where lbl = mkBitmapLabel uniq
-\end{code}
-
-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
- = getRealSp `thenFC` \ realSp ->
- buildLivenessMask uniq (realSp-1)