eliminate ConInfo
authorSimon Marlow <marlowsd@gmail.com>
Wed, 24 Aug 2011 10:58:43 +0000 (11:58 +0100)
committerSimon Marlow <marlowsd@gmail.com>
Thu, 25 Aug 2011 10:12:33 +0000 (11:12 +0100)
compiler/cmm/SMRep.lhs
compiler/codeGen/StgCmm.hs
compiler/codeGen/StgCmmBind.hs
compiler/codeGen/StgCmmClosure.hs
compiler/codeGen/StgCmmCon.hs
compiler/codeGen/StgCmmHeap.hs
compiler/codeGen/StgCmmProf.hs
compiler/codeGen/StgCmmTicky.hs

index bc502a3..44b40a3 100644 (file)
@@ -25,7 +25,7 @@ module SMRep (
         mkHeapRep, blackHoleRep, mkStackRep, mkRTSRep,
 
         -- ** Predicates
-        isStaticRep, isConRep, isThunkRep, isStaticNoCafCon,
+        isStaticRep, isConRep, isThunkRep, isFunRep, isStaticNoCafCon,
 
         -- ** Size-related things
         heapClosureSize,
@@ -196,6 +196,10 @@ isThunkRep (HeapRep _ _ _ ThunkSelector{}) = True
 isThunkRep (HeapRep _ _ _ BlackHole{})     = True
 isThunkRep _                               = False
 
+isFunRep :: SMRep -> Bool
+isFunRep (HeapRep _ _ _ Fun{}) = True
+isFunRep _                     = False
+
 isStaticNoCafCon :: SMRep -> Bool
 -- This should line up exactly with CONSTR_NOCAF_STATIC above
 -- See Note [Static NoCaf constructors]
index f88541a..0928645 100644 (file)
@@ -24,7 +24,6 @@ import StgCmmTicky
 
 import Cmm
 import CLabel
-import PprCmm
 
 import StgSyn
 import DynFlags
index e8874fa..84b33ef 100644 (file)
@@ -298,7 +298,8 @@ mkRhsClosure bndr cc _ fvs upd_flag srt args body
        ; (use_cc, blame_cc) <- chooseDynCostCentres cc args body
         ; emit (mkComment $ mkFastString "calling allocDynClosure")
         ; let toVarArg (NonVoid a, off) = (NonVoid (StgVarArg a), off)
-       ; (tmp, init) <- allocDynClosure closure_info use_cc blame_cc
+        ; let info_tbl = mkCmmInfo closure_info
+        ; (tmp, init) <- allocDynClosure info_tbl lf_info use_cc blame_cc
                                         (map toVarArg fv_details)
 
        -- RETURN
@@ -334,7 +335,9 @@ cgStdThunk bndr cc _bndr_info body lf_info payload
   ; (use_cc, blame_cc) <- chooseDynCostCentres cc [{- no args-}] body
 
        -- BUILD THE OBJECT
-  ; (tmp, init) <- allocDynClosure closure_info use_cc blame_cc payload_w_offsets
+  ; let info_tbl = mkCmmInfo closure_info
+  ; (tmp, init) <- allocDynClosure info_tbl lf_info
+                                   use_cc blame_cc payload_w_offsets
 
        -- RETURN
   ; regIdInfo bndr lf_info tmp init }
@@ -555,7 +558,7 @@ setupUpdate closure_info node body
 
        ; if closureUpdReqd closure_info
          then do       -- Blackhole the (updatable) CAF:
-               { upd_closure <- link_caf closure_info True
+                { upd_closure <- link_caf True
                ; pushUpdateFrame [CmmReg (CmmLocal upd_closure),
                                      mkLblExpr mkUpdInfoLabel] body } -- XXX black hole
          else do {tickyUpdateFrameOmitted; body}
@@ -611,8 +614,7 @@ pushUpdateFrame es body
 -- be closer together, and the compiler wouldn't need to know
 -- about off_indirectee etc.
 
-link_caf :: ClosureInfo
-        -> Bool                -- True <=> updatable, False <=> single-entry
+link_caf :: Bool                -- True <=> updatable, False <=> single-entry
          -> FCode LocalReg      -- Returns amode for closure to be updated
 -- 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.
@@ -620,13 +622,14 @@ link_caf :: ClosureInfo
 -- updated with the new value when available.  The reason for all of this
 -- is that we only want to update dynamic heap objects, not static ones,
 -- so that generational GC is easier.
-link_caf cl_info _is_upd = do
+link_caf _is_upd = do
   {    -- Alloc black hole specifying CC_HDR(Node) as the cost centre
   ; let        use_cc   = costCentreFrom (CmmReg nodeReg)
         blame_cc = use_cc
         tso      = CmmReg (CmmGlobal CurrentTSO)
-    -- XXX ezyang: FIXME
-  ; (hp_rel, init) <- allocDynClosureCmm bh_cl_info use_cc blame_cc [(tso,fixedHdrSize)]
+
+  ; (hp_rel, init) <- allocDynClosureCmm cafBlackHoleInfoTable mkLFBlackHole
+                                         use_cc blame_cc [(tso,fixedHdrSize)]
   ; emit init
 
        -- Call the RTS function newCAF to add the CAF to the CafList
@@ -646,9 +649,6 @@ link_caf cl_info _is_upd = do
 
   ; return hp_rel }
   where
-    bh_cl_info :: ClosureInfo
-    bh_cl_info = cafBlackHoleClosureInfo cl_info
-
     ind_static_info :: CmmExpr
     ind_static_info = mkLblExpr mkIndStaticInfoLabel
 
index 58eb427..64e3e2b 100644 (file)
@@ -27,12 +27,13 @@ module StgCmmClosure (
        StandardFormInfo,       -- ...ditto...
        mkLFThunk, mkLFReEntrant, mkConLFInfo, mkSelectorLFInfo,
        mkApLFInfo, mkLFImported, mkLFArgument, mkLFLetNoEscape,
-       lfDynTag,
-        maybeIsLFCon, isLFThunk, isLFReEntrant,
+        mkLFBlackHole,
+        lfDynTag,
+        maybeIsLFCon, isLFThunk, isLFReEntrant, lfUpdatable,
 
        -----------------------------------
        ClosureInfo,
-       mkClosureInfo, mkConInfo, 
+        mkClosureInfo,
         mkCmmInfo,
 
         closureSize,
@@ -40,7 +41,7 @@ module StgCmmClosure (
        closureLabelFromCI, closureProf, closureSRT,
        closureLFInfo, closureSMRep, closureUpdReqd, 
         closureIsThunk,
-       closureSingleEntry, closureReEntrant, isConstrClosure_maybe,
+        closureSingleEntry, closureReEntrant,
        closureFunInfo, isStandardFormThunk, isKnownFun,
         funTag, tagForArity, 
 
@@ -53,11 +54,11 @@ module StgCmmClosure (
 
        isToplevClosure,
        isStaticClosure,
-       cafBlackHoleClosureInfo, 
 
-        staticClosureNeedsLink, clHasCafRefs, clProfInfo,
+        staticClosureNeedsLink, clHasCafRefs,
 
         mkDataConInfoTable,
+        cafBlackHoleInfoTable
     ) where
 
 #include "../includes/MachDeps.h"
@@ -152,6 +153,9 @@ data LambdaFormInfo
                        -- of a CAF.  We want the target of the update frame to
                        -- be in the heap, so we make a black hole to hold it.
 
+                        -- XXX we can very nearly get rid of this, but
+                        -- allocDynClosure needs a LambdaFormInfo
+
 
 -------------------------
 -- An ArgDsecr describes the argument pattern of a function
@@ -286,6 +290,10 @@ mkLFImported id
   where
     arity = idArity id
 
+------------
+mkLFBlackHole :: LambdaFormInfo
+mkLFBlackHole = LFBlackHole
+
 -----------------------------------------------------
 --             Dynamic pointer tagging
 -----------------------------------------------------
@@ -648,10 +656,8 @@ enough information
   b) to allocate a closure containing that info pointer (i.e.
        it knows the info table label)
 
-We make a ClosureInfo for
-  - each let binding (both top level and not)
-  - each data constructor (for its shared static and
-       dynamic info tables)
+We make a ClosureInfo for each let binding (both top level and not),
+but not bindings for data constructors.
 
 Note [Closure CAF info]
 ~~~~~~~~~~~~~~~~~~~~~~~
@@ -674,22 +680,10 @@ data ClosureInfo
        closureInfLcl :: Bool             -- Can the info pointer be a local symbol?
     }
 
-  -- Constructor closures don't have a unique info table label (they use
-  -- the constructor's info table), and they don't have an SRT.
-  | ConInfo {
-       closureCon   :: !DataCon,
-       closureSMRep :: !SMRep,
-        closureCafs  :: !CafInfo        -- See Note [Closure CAF info]
-    }
-
 clHasCafRefs :: ClosureInfo -> CafInfo
 -- Backward compatibility; remove
 clHasCafRefs = closureCafs
 
-clProfInfo :: ClosureInfo -> ProfilingInfo
-clProfInfo ClosureInfo{ closureProf = p } = p
-clProfInfo _                              = NoProfilingInfo
-
 --------------------------------------
 --     Building ClosureInfos
 --------------------------------------
@@ -719,32 +713,6 @@ mkClosureInfo is_static id lf_info tot_wds ptr_wds srt_info val_descr
     prof   = mkProfilingInfo id val_descr
     nonptr_wds = tot_wds - ptr_wds
 
-mkConInfo :: Bool      -- Is static
-         -> CafInfo 
-         -> DataCon    
-         -> Int -> Int -- Total and pointer words
-         -> ClosureInfo
-mkConInfo is_static cafs data_con tot_wds ptr_wds
-   = ConInfo { closureSMRep = sm_rep
-             , closureCafs = cafs
-            , closureCon = data_con }
-  where
-    sm_rep  = mkHeapRep is_static ptr_wds nonptr_wds (lfClosureType lf_info)
-    lf_info = mkConLFInfo data_con
-    nonptr_wds = tot_wds - ptr_wds
-
--- We need a black-hole closure info to pass to @allocDynClosure@ when we
--- want to allocate the black hole on entry to a CAF.  These are the only
--- ways to build an LFBlackHole, maintaining the invariant that it really
--- is a black hole and not something else.
-
-cafBlackHoleClosureInfo :: ClosureInfo -> ClosureInfo
-cafBlackHoleClosureInfo cl_info@(ClosureInfo {})
-  = cl_info { closureLFInfo = LFBlackHole
-           , closureSMRep  = blackHoleRep
-           , closureSRT    = NoC_SRT
-           , closureInfLcl = False }
-cafBlackHoleClosureInfo (ConInfo {}) = panic "cafBlackHoleClosureInfo"
 
 -- Convert from 'ClosureInfo' to 'CmmInfoTable'.
 -- Not used for return points.
@@ -752,7 +720,7 @@ mkCmmInfo :: ClosureInfo -> CmmInfoTable
 mkCmmInfo cl_info
   = CmmInfoTable { cit_lbl  = infoTableLabelFromCI cl_info,
                    cit_rep  = closureSMRep cl_info,
-                   cit_prof = clProfInfo cl_info,
+                   cit_prof = closureProf cl_info,
                    cit_srt  = closureSRT cl_info }
 
 
@@ -774,7 +742,6 @@ blackHoleOnEntry :: DynFlags -> ClosureInfo -> Bool
 -- Single-entry ones have no fvs to plug, and we trust they don't form part 
 -- of a loop.
 
-blackHoleOnEntry _ ConInfo{} = False
 blackHoleOnEntry dflags (ClosureInfo { closureLFInfo = lf_info, closureSMRep = rep })
   | isStaticRep rep
   = False      -- Never black-hole a static closure
@@ -797,7 +764,6 @@ isStaticClosure cl_info = isStaticRep (closureSMRep cl_info)
 
 closureUpdReqd :: ClosureInfo -> Bool
 closureUpdReqd ClosureInfo{ closureLFInfo = lf_info } = lfUpdatable lf_info
-closureUpdReqd ConInfo{} = False
 
 lfUpdatable :: LambdaFormInfo -> Bool
 lfUpdatable (LFThunk _ _ upd _ _)  = upd
@@ -808,7 +774,6 @@ lfUpdatable _ = False
 
 closureIsThunk :: ClosureInfo -> Bool
 closureIsThunk ClosureInfo{ closureLFInfo = lf_info } = isLFThunk lf_info
-closureIsThunk ConInfo{} = False
 
 closureSingleEntry :: ClosureInfo -> Bool
 closureSingleEntry (ClosureInfo { closureLFInfo = LFThunk _ _ upd _ _}) = not upd
@@ -818,13 +783,8 @@ closureReEntrant :: ClosureInfo -> Bool
 closureReEntrant (ClosureInfo { closureLFInfo = LFReEntrant _ _ _ _ }) = True
 closureReEntrant _ = False
 
-isConstrClosure_maybe :: ClosureInfo -> Maybe DataCon
-isConstrClosure_maybe (ConInfo { closureCon = data_con }) = Just data_con
-isConstrClosure_maybe _                                  = Nothing
-
 closureFunInfo :: ClosureInfo -> Maybe (Int, ArgDescr)
 closureFunInfo (ClosureInfo { closureLFInfo = lf_info }) = lfFunInfo lf_info
-closureFunInfo _ = Nothing
 
 lfFunInfo :: LambdaFormInfo ->  Maybe (Int, ArgDescr)
 lfFunInfo (LFReEntrant _ arity _ arg_desc)  = Just (arity, arg_desc)
@@ -832,7 +792,6 @@ lfFunInfo _                                 = Nothing
 
 funTag :: ClosureInfo -> DynTag
 funTag (ClosureInfo { closureLFInfo = lf_info }) = lfDynTag lf_info
-funTag (ConInfo {})                             = panic "funTag"
 
 isToplevClosure :: ClosureInfo -> Bool
 isToplevClosure (ClosureInfo { closureLFInfo = lf_info })
@@ -840,7 +799,6 @@ isToplevClosure (ClosureInfo { closureLFInfo = lf_info })
       LFReEntrant TopLevel _ _ _ -> True
       LFThunk TopLevel _ _ _ _   -> True
       _other                    -> False
-isToplevClosure _ = False
 
 --------------------------------------
 --   Label generation
@@ -871,14 +829,6 @@ infoTableLabelFromCI (ClosureInfo { closureName = name,
     std_mk_lbl | is_lcl    = mkLocalInfoTableLabel
                | otherwise = mkInfoTableLabel
 
-infoTableLabelFromCI (ConInfo { closureCon = con,
-                                closureSMRep = rep,
-                                closureCafs = cafs })
-  | isStaticRep rep = mkStaticInfoTableLabel name cafs
-  | otherwise       = mkConInfoTableLabel name cafs
-  where
-    name = dataConName con
-
 -- ClosureInfo for a closure (as opposed to a constructor) is always local
 closureLabelFromCI :: ClosureInfo -> CLabel
 closureLabelFromCI cl@(ClosureInfo { closureName = nm }) =
@@ -984,6 +934,15 @@ mkDataConInfoTable data_con is_static ptr_wds nonptr_wds
    ty_descr  = stringToWord8s $ occNameString $ getOccName $ dataConTyCon data_con
    val_descr = stringToWord8s $ occNameString $ getOccName data_con
 
+-- We need a black-hole closure info to pass to @allocDynClosure@ when we
+-- want to allocate the black hole on entry to a CAF.
+
+cafBlackHoleInfoTable :: CmmInfoTable
+cafBlackHoleInfoTable
+  = CmmInfoTable { cit_lbl  = mkCAFBlackHoleInfoTableLabel
+                 , cit_rep  = blackHoleRep
+                 , cit_prof = NoProfilingInfo
+                 , cit_srt  = NoC_SRT }
 
 staticClosureNeedsLink :: CmmInfoTable -> Bool
 -- A static closure needs a link field to aid the GC when traversing
@@ -996,3 +955,4 @@ staticClosureNeedsLink info_tbl@CmmInfoTable{ cit_rep = smrep }
   | isConRep smrep         = not (isStaticNoCafCon smrep)
   | otherwise              = needsSRT (cit_srt info_tbl)
 staticClosureNeedsLink _ = False
+
index ee7b0be..dd3c68e 100644 (file)
@@ -34,7 +34,6 @@ import Module
 import Constants
 import DataCon
 import FastString
-import IdInfo( CafInfo(..) )
 import Id
 import Literal
 import PrelInfo
@@ -202,8 +201,10 @@ buildDynCon binder ccs con args
   = do { let (tot_wds, ptr_wds, args_w_offsets) 
                 = mkVirtConstrOffsets (addArgReps args)
                -- No void args in args_w_offsets
-              cl_info = mkConInfo False NoCafRefs con tot_wds ptr_wds
-       ; (tmp, init) <- allocDynClosure cl_info use_cc blame_cc args_w_offsets
+              nonptr_wds = tot_wds - ptr_wds
+              info_tbl = mkDataConInfoTable con False ptr_wds nonptr_wds
+        ; (tmp, init) <- allocDynClosure info_tbl lf_info
+                                         use_cc blame_cc args_w_offsets
        ; regIdInfo binder lf_info tmp init }
   where
     lf_info = mkConLFInfo con
index d094337..ec0dd05 100644 (file)
@@ -49,7 +49,8 @@ import Constants
 -----------------------------------------------------------
 
 allocDynClosure
-        :: ClosureInfo
+        :: CmmInfoTable
+        -> LambdaFormInfo
         -> CmmExpr              -- Cost Centre to stick in the object
         -> CmmExpr              -- Cost Centre to blame for this alloc
                                 -- (usually the same; sometimes "OVERHEAD")
@@ -60,7 +61,7 @@ allocDynClosure
         -> FCode (LocalReg, CmmAGraph)
 
 allocDynClosureCmm
-        :: ClosureInfo -> CmmExpr -> CmmExpr
+        :: CmmInfoTable -> LambdaFormInfo -> CmmExpr -> CmmExpr
         -> [(CmmExpr, VirtualHpOffset)]
         -> FCode (LocalReg, CmmAGraph)
 
@@ -81,18 +82,20 @@ allocDynClosureCmm
 --         but Hp+8 means something quite different...
 
 
-allocDynClosure cl_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
         ; cmm_args <- mapM getArgAmode args     -- No void args
-        ; allocDynClosureCmm cl_info use_cc _blame_cc (zip cmm_args offsets)
+        ; allocDynClosureCmm info_tbl lf_info
+                             use_cc _blame_cc (zip cmm_args offsets)
         }
 
-allocDynClosureCmm cl_info use_cc _blame_cc amodes_w_offsets
+allocDynClosureCmm info_tbl lf_info use_cc _blame_cc amodes_w_offsets
   = do  { virt_hp <- getVirtHp
 
         -- SAY WHAT WE ARE ABOUT TO DO
-        ; tickyDynAlloc cl_info
-        ; profDynAlloc cl_info use_cc
+        ; let rep = cit_rep info_tbl
+        ; tickyDynAlloc rep lf_info
+        ; profDynAlloc rep use_cc
                 -- ToDo: This is almost certainly wrong
                 -- We're ignoring blame_cc. But until we've
                 -- fixed the boxing hack in chooseDynCostCentres etc,
@@ -106,7 +109,7 @@ allocDynClosureCmm cl_info use_cc _blame_cc amodes_w_offsets
                 -- Remember, virtHp points to last allocated word,
                 -- ie 1 *before* the info-ptr word of new object.
 
-                info_ptr = CmmLit (CmmLabel (infoTableLabelFromCI cl_info))
+                info_ptr = CmmLit (CmmLabel (cit_lbl info_tbl))
 
         -- ALLOCATE THE OBJECT
         ; base <- getHpRelOffset info_offset
@@ -116,7 +119,7 @@ allocDynClosureCmm cl_info use_cc _blame_cc amodes_w_offsets
         ; hpStore base cmm_args offsets
 
         -- BUMP THE VIRTUAL HEAP POINTER
-        ; setVirtHp (virt_hp + closureSize cl_info)
+        ; setVirtHp (virt_hp + heapClosureSize rep)
 
         -- Assign to a temporary and return
         -- Note [Return a LocalReg]
index ca116f2..b1aca6e 100644 (file)
@@ -156,10 +156,10 @@ restoreCurrentCostCentre (Just local_cc)
 
 -- | Record the allocation of a closure.  The CmmExpr is the cost
 -- centre stack to which to attribute the allocation.
-profDynAlloc :: ClosureInfo -> CmmExpr -> FCode ()
-profDynAlloc cl_info ccs
+profDynAlloc :: SMRep -> CmmExpr -> FCode ()
+profDynAlloc rep ccs
   = ifProfiling $
-    profAlloc (CmmLit (mkIntCLit (closureSize cl_info))) ccs
+    profAlloc (CmmLit (mkIntCLit (heapClosureSize rep))) ccs
 
 -- | Record the allocation of a closure (size is given by a CmmExpr)
 -- The size must be in words, because the allocation counter in a CCS counts
index 3775130..2da539b 100644 (file)
@@ -51,6 +51,7 @@ import CmmExpr
 import MkGraph
 import CmmUtils
 import CLabel
+import SMRep
 
 import Module
 import Name
@@ -266,25 +267,24 @@ argChar DoubleArg = 'd'
 -- -----------------------------------------------------------------------------
 -- Ticky allocation
 
-tickyDynAlloc :: ClosureInfo -> FCode ()
+tickyDynAlloc :: SMRep -> LambdaFormInfo -> FCode ()
 -- Called when doing a dynamic heap allocation
-tickyDynAlloc cl_info
+-- LambdaFormInfo only needed to distinguish between updatable/non-updatable thunks
+tickyDynAlloc rep lf
   = ifTicky $
     case () of
-      _ | Just _ <- maybeIsLFCon lf -> tick_alloc_con
-       | isLFThunk lf              -> tick_alloc_thk
-        | isLFReEntrant lf          -> tick_alloc_fun
-        | otherwise                 -> return ()
+      _ | isConRep rep   -> tick_alloc_con
+        | isThunkRep rep -> tick_alloc_thk
+        | isFunRep   rep -> tick_alloc_fun
+        | otherwise      -> return ()
   where
-    lf = closureLFInfo cl_info
-
-       -- will be needed when we fill in stubs
-    _cl_size   = closureSize cl_info
+        -- will be needed when we fill in stubs
+    _cl_size   = heapClosureSize rep
 --    _slop_size = slopSize cl_info
 
     tick_alloc_thk 
-       | closureUpdReqd cl_info = tick_alloc_up_thk
-       | otherwise              = tick_alloc_se_thk
+        | lfUpdatable lf = tick_alloc_up_thk
+        | otherwise      = tick_alloc_se_thk
 
     -- krc: changed from panic to return () 
     -- just to get something working