Commit a4b249c4 authored by Simon Marlow's avatar Simon Marlow

Small optimisation to the code generated for CAFs

parent 1cea9a51
...@@ -578,7 +578,7 @@ setupUpdate closure_info node body ...@@ -578,7 +578,7 @@ setupUpdate closure_info node body
; if closureUpdReqd closure_info ; if closureUpdReqd closure_info
then do -- Blackhole the (updatable) CAF: then do -- Blackhole the (updatable) CAF:
{ upd_closure <- link_caf True { upd_closure <- link_caf True
; pushUpdateFrame [CmmReg (CmmLocal upd_closure), ; pushUpdateFrame [upd_closure,
mkLblExpr mkBHUpdInfoLabel] body } mkLblExpr mkBHUpdInfoLabel] body }
else do {tickyUpdateFrameOmitted; body} else do {tickyUpdateFrameOmitted; body}
} }
...@@ -633,8 +633,8 @@ pushUpdateFrame es body ...@@ -633,8 +633,8 @@ pushUpdateFrame es body
-- be closer together, and the compiler wouldn't need to know -- be closer together, and the compiler wouldn't need to know
-- about off_indirectee etc. -- about off_indirectee etc.
link_caf :: Bool -- True <=> updatable, False <=> single-entry link_caf :: Bool -- True <=> updatable, False <=> single-entry
-> FCode LocalReg -- Returns amode for closure to be updated -> FCode CmmExpr -- Returns amode for closure to be updated
-- To update a CAF we must allocate a black hole, link the CAF onto the -- To update a CAF we must allocate a black hole, link the CAF onto the
-- CAF list, then update the CAF to point to the fresh black hole. -- CAF list, then update the CAF to point to the fresh black hole.
-- This function returns the address of the black hole, so it can be -- This function returns the address of the black hole, so it can be
...@@ -648,19 +648,24 @@ link_caf _is_upd = do ...@@ -648,19 +648,24 @@ link_caf _is_upd = do
blame_cc = use_cc blame_cc = use_cc
tso = CmmReg (CmmGlobal CurrentTSO) tso = CmmReg (CmmGlobal CurrentTSO)
; (hp_rel, init) <- allocDynClosureCmm cafBlackHoleInfoTable mkLFBlackHole ; hp_rel <- allocDynClosureCmm cafBlackHoleInfoTable mkLFBlackHole
use_cc blame_cc [(tso,fixedHdrSize dflags)] use_cc blame_cc [(tso,fixedHdrSize dflags)]
; emit init -- small optimisation: we duplicate the hp_rel expression in
-- both the newCAF call and the value returned below.
-- Call the RTS function newCAF to add the CAF to the CafList -- If we instead used allocDynClosureReg which assigns it to a reg,
-- so that the garbage collector can find them -- then the reg is live across the newCAF call and gets spilled,
-- which is stupid. Really we should have an optimisation pass to
-- fix this, but we don't yet. --SDM
-- Call the RTS function newCAF to add the CAF to the CafList
-- so that the garbage collector can find them
-- This must be done *before* the info table pointer is overwritten, -- This must be done *before* the info table pointer is overwritten,
-- because the old info table ptr is needed for reversion -- because the old info table ptr is needed for reversion
; ret <- newTemp bWord ; ret <- newTemp bWord
; emitRtsCallGen [(ret,NoHint)] rtsPackageId (fsLit "newCAF") ; emitRtsCallGen [(ret,NoHint)] rtsPackageId (fsLit "newCAF")
[ (CmmReg (CmmGlobal BaseReg), AddrHint), [ (CmmReg (CmmGlobal BaseReg), AddrHint),
(CmmReg nodeReg, AddrHint), (CmmReg nodeReg, AddrHint),
(CmmReg (CmmLocal hp_rel), AddrHint) ] (hp_rel, AddrHint) ]
(Just [node]) False (Just [node]) False
-- node is live, so save it. -- node is live, so save it.
......
...@@ -15,7 +15,8 @@ module StgCmmHeap ( ...@@ -15,7 +15,8 @@ module StgCmmHeap (
mkVirtHeapOffsets, mkVirtConstrOffsets, mkVirtHeapOffsets, mkVirtConstrOffsets,
mkStaticClosureFields, mkStaticClosure, mkStaticClosureFields, mkStaticClosure,
allocDynClosure, allocDynClosureCmm, emitSetDynHdr allocDynClosure, allocDynClosureReg, allocDynClosureCmm,
emitSetDynHdr
) where ) where
#include "HsVersions.h" #include "HsVersions.h"
...@@ -64,11 +65,16 @@ allocDynClosure ...@@ -64,11 +65,16 @@ allocDynClosure
-- No void args in here -- No void args in here
-> FCode (LocalReg, CmmAGraph) -> FCode (LocalReg, CmmAGraph)
allocDynClosureCmm allocDynClosureReg
:: CmmInfoTable -> LambdaFormInfo -> CmmExpr -> CmmExpr :: CmmInfoTable -> LambdaFormInfo -> CmmExpr -> CmmExpr
-> [(CmmExpr, VirtualHpOffset)] -> [(CmmExpr, VirtualHpOffset)]
-> FCode (LocalReg, CmmAGraph) -> FCode (LocalReg, CmmAGraph)
allocDynClosureCmm
:: CmmInfoTable -> LambdaFormInfo -> CmmExpr -> CmmExpr
-> [(CmmExpr, VirtualHpOffset)]
-> FCode CmmExpr -- returns Hp+n
-- allocDynClosure allocates the thing in the heap, -- allocDynClosure allocates the thing in the heap,
-- and modifies the virtual Hp to account for this. -- and modifies the virtual Hp to account for this.
-- The second return value is the graph that sets the value of the -- The second return value is the graph that sets the value of the
...@@ -89,10 +95,18 @@ allocDynClosureCmm ...@@ -89,10 +95,18 @@ allocDynClosureCmm
allocDynClosure info_tbl lf_info use_cc _blame_cc args_w_offsets allocDynClosure info_tbl lf_info use_cc _blame_cc args_w_offsets
= do { let (args, offsets) = unzip args_w_offsets = do { let (args, offsets) = unzip args_w_offsets
; cmm_args <- mapM getArgAmode args -- No void args ; cmm_args <- mapM getArgAmode args -- No void args
; allocDynClosureCmm info_tbl lf_info ; allocDynClosureReg info_tbl lf_info
use_cc _blame_cc (zip cmm_args offsets) use_cc _blame_cc (zip cmm_args offsets)
} }
allocDynClosureReg info_tbl lf_info use_cc _blame_cc amodes_w_offsets
= do { hp_rel <- allocDynClosureCmm info_tbl lf_info
use_cc _blame_cc amodes_w_offsets
-- Note [Return a LocalReg]
; getCodeR $ assignTemp hp_rel
}
allocDynClosureCmm info_tbl lf_info use_cc _blame_cc amodes_w_offsets allocDynClosureCmm info_tbl lf_info use_cc _blame_cc amodes_w_offsets
= do { virt_hp <- getVirtHp = do { virt_hp <- getVirtHp
...@@ -121,10 +135,8 @@ allocDynClosureCmm info_tbl lf_info use_cc _blame_cc amodes_w_offsets ...@@ -121,10 +135,8 @@ allocDynClosureCmm info_tbl lf_info use_cc _blame_cc amodes_w_offsets
; dflags <- getDynFlags ; dflags <- getDynFlags
; setVirtHp (virt_hp + heapClosureSize dflags rep) ; setVirtHp (virt_hp + heapClosureSize dflags rep)
-- Assign to a temporary and return ; getHpRelOffset info_offset
-- Note [Return a LocalReg] }
; hp_rel <- getHpRelOffset info_offset
; getCodeR $ assignTemp hp_rel }
emitSetDynHdr :: CmmExpr -> CmmExpr -> CmmExpr -> FCode () emitSetDynHdr :: CmmExpr -> CmmExpr -> CmmExpr -> FCode ()
emitSetDynHdr base info_ptr ccs emitSetDynHdr base info_ptr ccs
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment