import StgCmmExpr
import StgCmmMonad
-import StgCmmExpr
import StgCmmEnv
import StgCmmCon
import StgCmmHeap
import StgSyn
import CostCentre
import Id
-import Monad (foldM, liftM)
+import Control.Monad
import Name
import Module
import ListSetOps
import FastString
import Maybes
-import Data.List
-
------------------------------------------------------------------------
-- Top-level bindings
------------------------------------------------------------------------
-- Emit the main entry code
; emitClosureProcAndInfoTable top_lvl bndr cl_info args $ \(node, arg_regs) -> do
- -- Emit the slow-entry code (for entering a closure through a PAP)
- { mkSlowEntryCode cl_info arg_regs
-
- ; let lf_info = closureLFInfo cl_info
- node_points = nodeMustPointToIt lf_info
- ; tickyEnterFun cl_info
- ; whenC node_points (ldvEnterClosure cl_info)
- ; granYield arg_regs node_points
-
- -- Main payload
- ; entryHeapCheck node arity arg_regs $ do
- { enterCostCentre cl_info cc body
+ -- Emit the slow-entry code (for entering a closure through a PAP)
+ { mkSlowEntryCode cl_info arg_regs
+
+ ; let lf_info = closureLFInfo cl_info
+ node_points = nodeMustPointToIt lf_info
+ ; tickyEnterFun cl_info
+ ; whenC node_points (ldvEnterClosure cl_info)
+ ; granYield arg_regs node_points
+
+ -- Main payload
+ ; entryHeapCheck (if node_points then Just node else Nothing) arity arg_regs $ do
+ { enterCostCentre cl_info cc body
; fv_bindings <- mapM bind_fv fv_details
- ; load_fvs node lf_info fv_bindings -- Load free vars out of closure *after*
- ; cgExpr body }} -- heap check, to reduce live vars over check
+ -- Load free vars out of closure *after*
+ ; if node_points then load_fvs node lf_info fv_bindings else return ()
+ ; cgExpr body }} -- heap check, to reduce live vars over check
}
; granThunk node_points
-- Heap overflow check
- ; entryHeapCheck node arity [] $ do
+ ; entryHeapCheck (if node_points then Just node else Nothing) arity [] $ do
{ -- Overwrite with black hole if necessary
-- but *after* the heap-overflow check
- whenC (blackHoleOnEntry cl_info && node_points)
+ dflags <- getDynFlags
+ ; whenC (blackHoleOnEntry dflags cl_info && node_points)
(blackHoleIt cl_info)
-- Push update frame
| otherwise =
nopC
where
- bh_lbl | is_single_entry = mkRtsDataLabel (sLit "stg_SE_BLACKHOLE_info")
- | otherwise = mkRtsDataLabel (sLit "stg_BLACKHOLE_info")
+ bh_lbl | is_single_entry = mkCmmDataLabel rtsPackageId (fsLit "stg_SE_BLACKHOLE_info")
+ | otherwise = mkCmmDataLabel rtsPackageId (fsLit "stg_BLACKHOLE_info")
-- If we wanted to do eager blackholing with slop filling,
-- we'd need to do it at the *end* of a basic block, otherwise
-- so that the garbage collector can find them
-- This must be done *before* the info table pointer is overwritten,
-- because the old info table ptr is needed for reversion
- ; emitRtsCallWithVols (sLit "newCAF") [(CmmReg nodeReg,AddrHint)] [node] False
+ ; emitRtsCallWithVols rtsPackageId (fsLit "newCAF")
+ [ (CmmReg (CmmGlobal BaseReg), AddrHint),
+ (CmmReg nodeReg, AddrHint) ]
+ [node] False
-- node is live, so save it.
-- Overwrite the closure with a (static) indirection