remove empty dir
[ghc-hetmet.git] / ghc / compiler / basicTypes / IdInfo.lhs
index 7555cc2..d53bf56 100644 (file)
@@ -11,12 +11,11 @@ module IdInfo (
        GlobalIdDetails(..), notGlobalId,       -- Not abstract
 
        IdInfo,         -- Abstract
-       vanillaIdInfo, noCafIdInfo, hasCafIdInfo,
+       vanillaIdInfo, noCafIdInfo,
        seqIdInfo, megaSeqIdInfo,
 
        -- Zapping
        zapLamInfo, zapDemandInfo,
-       shortableIdInfo, copyIdInfo,
 
        -- Arity
        ArityInfo,
@@ -26,12 +25,14 @@ module IdInfo (
        -- New demand and strictness info
        newStrictnessInfo, setNewStrictnessInfo, 
        newDemandInfo, setNewDemandInfo, pprNewStrictness,
+       setAllStrictnessInfo,
 
+#ifdef OLD_STRICTNESS
        -- Strictness; imported from Demand
        StrictnessInfo(..),
        mkStrictnessInfo, noStrictnessInfo,
        ppStrictnessInfo,isBottomingStrictness, 
-       setAllStrictnessInfo,
+#endif
 
         -- Worker
         WorkerInfo(..), workerExists, wrapperArity, workerId,
@@ -62,15 +63,11 @@ module IdInfo (
        occInfo, setOccInfo, 
 
        -- Specialisation
-       specInfo, setSpecInfo,
-
-       -- CG info
-       CgInfo(..), cgInfo, setCgInfo,  pprCgInfo,
-       cgCafInfo, vanillaCgInfo,
-       CgInfoEnv, lookupCgInfo,
+       SpecInfo(..), specInfo, setSpecInfo, isEmptySpecInfo, 
+       specInfoFreeVars, specInfoRules, seqSpecInfo,
 
        -- CAF info
-       CafInfo(..), ppCafInfo, setCafInfo, mayHaveCafRefs,
+       CafInfo(..), cafInfo, ppCafInfo, setCafInfo, mayHaveCafRefs,
 
         -- Lambda-bound variable info
         LBVarInfo(..), lbvarInfo, setLBVarInfo, noLBVarInfo, hasNoLBVarInfo
@@ -80,11 +77,10 @@ module IdInfo (
 
 
 import CoreSyn
-import Type            ( Type )
+import Class           ( Class )
 import PrimOp          ( PrimOp )
-import NameEnv         ( NameEnv, lookupNameEnv )
-import Name            ( Name )
 import Var              ( Id )
+import VarSet          ( VarSet, emptyVarSet, seqVarSet )
 import BasicTypes      ( OccInfo(..), isFragileOcc, isDeadOcc, seqOccInfo, isLoopBreaker,
                          InsideLam, insideLam, notInsideLam, 
                          OneBranch, oneBranch, notOneBranch,
@@ -92,14 +88,16 @@ import BasicTypes   ( OccInfo(..), isFragileOcc, isDeadOcc, seqOccInfo, isLoopBrea
                          Activation(..)
                        )
 import DataCon         ( DataCon )
+import TyCon           ( TyCon, FieldLabel )
 import ForeignCall     ( ForeignCall )
-import FieldLabel      ( FieldLabel )
-import Demand          hiding( Demand, seqDemand )
-import qualified Demand
 import NewDemand
 import Outputable      
 import Maybe           ( isJust )
+
 #ifdef OLD_STRICTNESS
+import Name            ( Name )
+import Demand          hiding( Demand, seqDemand )
+import qualified Demand
 import Util            ( listLengthCmp )
 import List            ( replicate )
 #endif
@@ -112,7 +110,6 @@ infixl      1 `setSpecInfo`,
          `setWorkerInfo`,
          `setLBVarInfo`,
          `setOccInfo`,
-         `setCgInfo`,
          `setCafInfo`,
          `setNewStrictnessInfo`,
          `setAllStrictnessInfo`,
@@ -234,13 +231,21 @@ an IdInfo.hi-boot, but no Id.hi-boot, and GlobalIdDetails is imported
 data GlobalIdDetails
   = VanillaGlobal              -- Imported from elsewhere, a default method Id.
 
-  | RecordSelId FieldLabel     -- The Id for a record selector
-  | DataConId DataCon          -- The Id for a data constructor *worker*
+  | RecordSelId                 -- The Id for a record selector
+    { sel_tycon   :: TyCon
+    , sel_label   :: FieldLabel
+    , sel_naughty :: Bool       -- True <=> naughty
+    }                          -- See Note [Naughty record selectors]
+                               -- with MkId.mkRecordSelectorId
+
+  | DataConWorkId DataCon      -- The Id for a data constructor *worker*
   | DataConWrapId DataCon      -- The Id for a data constructor *wrapper*
                                -- [the only reasons we need to know is so that
-                               --  a) we can  suppress printing a definition in the interface file
-                               --  b) when typechecking a pattern we can get from the
-                               --     Id back to the data con]
+                               --  a) to support isImplicitId
+                               --  b) when desugaring a RecordCon we can get 
+                               --     from the Id back to the data con]
+
+  | ClassOpId Class            -- An operation of a class
 
   | PrimOpId PrimOp            -- The Id for a primitive operator
   | FCallId ForeignCall                -- The Id for a foreign call
@@ -252,11 +257,12 @@ notGlobalId = NotGlobalId
 instance Outputable GlobalIdDetails where
     ppr NotGlobalId       = ptext SLIT("[***NotGlobalId***]")
     ppr VanillaGlobal     = ptext SLIT("[GlobalId]")
-    ppr (DataConId _)     = ptext SLIT("[DataCon]")
+    ppr (DataConWorkId _) = ptext SLIT("[DataCon]")
     ppr (DataConWrapId _) = ptext SLIT("[DataConWrapper]")
+    ppr (ClassOpId _)     = ptext SLIT("[ClassOp]")
     ppr (PrimOpId _)      = ptext SLIT("[PrimOp]")
     ppr (FCallId _)       = ptext SLIT("[ForeignCall]")
-    ppr (RecordSelId _)   = ptext SLIT("[RecSel]")
+    ppr (RecordSelId {})  = ptext SLIT("[RecSel]")
 \end{code}
 
 
@@ -283,15 +289,22 @@ case.  KSW 1999-04).
 data IdInfo
   = IdInfo {
        arityInfo       :: !ArityInfo,          -- Its arity
-       specInfo        :: CoreRules,           -- Specialisations of this function which exist
+       specInfo        :: SpecInfo,            -- Specialisations of this function which exist
 #ifdef OLD_STRICTNESS
        cprInfo         :: CprInfo,             -- Function always constructs a product result
        demandInfo      :: Demand.Demand,       -- Whether or not it is definitely demanded
        strictnessInfo  :: StrictnessInfo,      -- Strictness properties
 #endif
         workerInfo      :: WorkerInfo,          -- Pointer to Worker Function
+                                               -- Within one module this is irrelevant; the 
+                                               -- inlining of a worker is handled via the Unfolding
+                                               -- WorkerInfo is used *only* to indicate the form of
+                                               -- the RHS, so that interface files don't actually 
+                                               -- need to contain the RHS; it can be derived from
+                                               -- the strictness info
+
        unfoldingInfo   :: Unfolding,           -- Its unfolding
-       cgInfo          :: CgInfo,              -- Code generator info (arity, CAF info)
+       cafInfo         :: CafInfo,             -- CAF info
         lbvarInfo      :: LBVarInfo,           -- Info about a lambda-bound variable
        inlinePragInfo  :: InlinePragInfo,      -- Inline pragma
        occInfo         :: OccInfo,             -- How it occurs
@@ -311,7 +324,7 @@ seqIdInfo (IdInfo {}) = ()
 
 megaSeqIdInfo :: IdInfo -> ()
 megaSeqIdInfo info
-  = seqRules (specInfo info)                   `seq`
+  = seqSpecInfo (specInfo info)                        `seq`
     seqWorker (workerInfo info)                        `seq`
 
 -- Omitting this improves runtimes a little, presumably because
@@ -327,10 +340,8 @@ megaSeqIdInfo info
     seqCpr (cprInfo info)                      `seq`
 #endif
 
--- CgInfo is involved in a loop, so we have to be careful not to seq it
--- too early.
---    seqCg (cgInfo info)                      `seq`
-    seqLBVar (lbvarInfo info)          `seq`
+    seqCaf (cafInfo info)                      `seq`
+    seqLBVar (lbvarInfo info)                  `seq`
     seqOccInfo (occInfo info) 
 \end{code}
 
@@ -351,19 +362,6 @@ setUnfoldingInfoLazily info uf     -- Lazy variant to avoid looking at the
     info { unfoldingInfo = uf }        -- (In this case the demand-zapping is redundant.)
 
 setUnfoldingInfo info uf 
-  | isEvaldUnfolding uf
-       -- If the unfolding is a value, the demand info may
-       -- go pear-shaped, so we nuke it.  Example:
-       --      let x = (a,b) in
-       --      case x of (p,q) -> h p q x
-       -- Here x is certainly demanded. But after we've nuked
-       -- the case, we'll get just
-       --      let x = (a,b) in h a b x
-       -- and now x is not demanded (I'm assuming h is lazy)
-       -- This really happens.  The solution here is a bit ad hoc...
-  = info { unfoldingInfo = uf, newDemandInfo = Nothing }
-
-  | otherwise
        -- We do *not* seq on the unfolding info, For some reason, doing so 
        -- actually increases residency significantly. 
   = info { unfoldingInfo = uf }
@@ -373,8 +371,8 @@ setDemandInfo         info dd = info { demandInfo = dd }
 setCprInfo        info cp = info { cprInfo = cp }
 #endif
 
-setArityInfo     info ar = info { arityInfo = ar  }
-setCgInfo         info cg = info { cgInfo = cg }
+setArityInfo     info ar  = info { arityInfo = ar  }
+setCafInfo        info caf = info { cafInfo = caf }
 
 setLBVarInfo      info lb = {-lb `seq`-} info { lbvarInfo = lb }
 
@@ -387,14 +385,14 @@ setNewStrictnessInfo info dd = dd `seq` info { newStrictnessInfo = dd }
 vanillaIdInfo :: IdInfo
 vanillaIdInfo 
   = IdInfo {
-           cgInfo              = noCgInfo,
+           cafInfo             = vanillaCafInfo,
            arityInfo           = unknownArity,
 #ifdef OLD_STRICTNESS
            cprInfo             = NoCPRInfo,
            demandInfo          = wwLazy,
            strictnessInfo      = NoStrictnessInfo,
 #endif
-           specInfo            = emptyCoreRules,
+           specInfo            = emptySpecInfo,
            workerInfo          = NoWorker,
            unfoldingInfo       = noUnfolding,
            lbvarInfo           = NoLBVarInfo,
@@ -404,11 +402,8 @@ vanillaIdInfo
            newStrictnessInfo   = Nothing
           }
 
-hasCafIdInfo = vanillaIdInfo `setCgInfo`    CgInfo MayHaveCafRefs
-noCafIdInfo  = vanillaIdInfo `setCgInfo`    CgInfo NoCafRefs
+noCafIdInfo  = vanillaIdInfo `setCafInfo`    NoCafRefs
        -- Used for built-in type Ids in MkId.
-       -- These must have a valid CgInfo set, so you can't
-       --      use vanillaIdInfo!
 \end{code}
 
 
@@ -452,6 +447,36 @@ type InlinePragInfo = Activation
        --
        -- If there was an INLINE pragma, then as a separate matter, the
        -- RHS will have been made to look small with a CoreSyn Inline Note
+
+       -- The default InlinePragInfo is AlwaysActive, so the info serves
+       -- entirely as a way to inhibit inlining until we want it
+\end{code}
+
+
+%************************************************************************
+%*                                                                     *
+       SpecInfo
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+-- CoreRules is used only in an idSpecialisation (move to IdInfo?)
+data SpecInfo 
+  = SpecInfo [CoreRule] VarSet -- Locally-defined free vars of RHSs
+
+emptySpecInfo :: SpecInfo
+emptySpecInfo = SpecInfo [] emptyVarSet
+
+isEmptySpecInfo :: SpecInfo -> Bool
+isEmptySpecInfo (SpecInfo rs _) = null rs
+
+specInfoFreeVars :: SpecInfo -> VarSet
+specInfoFreeVars (SpecInfo _ fvs) = fvs
+
+specInfoRules :: SpecInfo -> [CoreRule]
+specInfoRules (SpecInfo rules _) = rules
+
+seqSpecInfo (SpecInfo rules fvs) = seqRules rules `seq` seqVarSet fvs
 \end{code}
 
 
@@ -492,14 +517,14 @@ this to".
 data WorkerInfo = NoWorker
                | HasWorker Id Arity
        -- The Arity is the arity of the *wrapper* at the moment of the
-       -- w/w split. See comments in MkIface.ifaceId, with the 'Worker' code.
+       -- w/w split.  See notes above.
 
 seqWorker :: WorkerInfo -> ()
 seqWorker (HasWorker id a) = id `seq` a `seq` ()
 seqWorker NoWorker        = ()
 
 ppWorkerInfo NoWorker            = empty
-ppWorkerInfo (HasWorker wk_id _) = ptext SLIT("__P") <+> ppr wk_id
+ppWorkerInfo (HasWorker wk_id _) = ptext SLIT("Worker") <+> ppr wk_id
 
 workerExists :: WorkerInfo -> Bool
 workerExists NoWorker        = False
@@ -519,31 +544,7 @@ wrapperArity (HasWorker _ a) = a
 %*                                                                     *
 %************************************************************************
 
-CgInfo encapsulates calling-convention information produced by the code 
-generator.  It is pasted into the IdInfo of each emitted Id by CoreTidy,
-but only as a thunk --- the information is only actually produced further
-downstream, by the code generator.
-
 \begin{code}
-#ifndef OLD_STRICTNESS
-newtype CgInfo = CgInfo CafInfo        -- We are back to only having CafRefs in CgInfo
-noCgInfo = panic "NoCgInfo!"
-#else
-data CgInfo = CgInfo CafInfo
-           | NoCgInfo          -- In debug mode we don't want a black hole here
-                               -- See Id.idCgInfo
-       -- noCgInfo is used for local Ids, which shouldn't need any CgInfo
-noCgInfo = NoCgInfo
-#endif
-
-cgCafInfo (CgInfo caf_info) = caf_info
-
-setCafInfo info caf_info = info `setCgInfo` CgInfo caf_info 
-
-seqCg c = c `seq` ()  -- fields are strict anyhow
-
-vanillaCgInfo = CgInfo MayHaveCafRefs          -- Definitely safe
-
 -- CafInfo is used to build Static Reference Tables (see simplStg/SRT.lhs).
 
 data CafInfo 
@@ -555,30 +556,17 @@ data CafInfo
        | NoCafRefs                     -- A function or static constructor
                                        -- that refers to no CAFs.
 
+vanillaCafInfo = MayHaveCafRefs                -- Definitely safe
+
 mayHaveCafRefs  MayHaveCafRefs = True
 mayHaveCafRefs _              = False
 
 seqCaf c = c `seq` ()
 
-pprCgInfo (CgInfo caf_info) = ppCafInfo caf_info
-
-ppArity 0 = empty
-ppArity n = hsep [ptext SLIT("__A"), int n]
-
-ppCafInfo NoCafRefs = ptext SLIT("__C")
+ppCafInfo NoCafRefs = ptext SLIT("NoCafRefs")
 ppCafInfo MayHaveCafRefs = empty
 \end{code}
 
-\begin{code}
-type CgInfoEnv = NameEnv CgInfo
-
-lookupCgInfo :: NameEnv CgInfo -> Name -> CgInfo
-lookupCgInfo env n = case lookupNameEnv env n of
-                       Just info -> info
-                       Nothing   -> pprTrace "Urk! Not in CgInfo env" (ppr n) vanillaCgInfo
-\end{code}
-
-
 %************************************************************************
 %*                                                                     *
 \subsection[cpr-IdInfo]{Constructed Product Result info about an @Id@}
@@ -691,12 +679,12 @@ zapLamInfo info@(IdInfo {occInfo = occ, newDemandInfo = demand})
   where
        -- The "unsafe" occ info is the ones that say I'm not in a lambda
        -- because that might not be true for an unsaturated lambda
-    is_safe_occ (OneOcc in_lam once) = in_lam
-    is_safe_occ other               = True
+    is_safe_occ (OneOcc in_lam _ _) = in_lam
+    is_safe_occ other              = True
 
     safe_occ = case occ of
-                OneOcc _ once -> OneOcc insideLam once
-                other         -> occ
+                OneOcc _ once int_cxt -> OneOcc insideLam once int_cxt
+                other                 -> occ
 
     is_safe_dmd Nothing    = True
     is_safe_dmd (Just dmd) = not (isStrictDmd dmd)
@@ -709,70 +697,3 @@ zapDemandInfo info@(IdInfo {newDemandInfo = dmd})
   | otherwise  = Nothing
 \end{code}
 
-
-copyIdInfo is used when shorting out a top-level binding
-       f_local = BIG
-       f = f_local
-where f is exported.  We are going to swizzle it around to
-       f = BIG
-       f_local = f
-
-BUT (a) we must be careful about messing up rules
-    (b) we must ensure f's IdInfo ends up right
-
-(a) Messing up the rules
-~~~~~~~~~~~~~~~~~~~~
-The example that went bad on me was this one:
-       
-    iterate :: (a -> a) -> a -> [a]
-    iterate = iterateList
-    
-    iterateFB c f x = x `c` iterateFB c f (f x)
-    iterateList f x =  x : iterateList f (f x)
-    
-    {-# RULES
-    "iterate"  forall f x.     iterate f x = build (\c _n -> iterateFB c f x)
-    "iterateFB"                iterateFB (:) = iterateList
-     #-}
-
-This got shorted out to:
-
-    iterateList :: (a -> a) -> a -> [a]
-    iterateList = iterate
-    
-    iterateFB c f x = x `c` iterateFB c f (f x)
-    iterate f x =  x : iterate f (f x)
-    
-    {-# RULES
-    "iterate"  forall f x.     iterate f x = build (\c _n -> iterateFB c f x)
-    "iterateFB"                iterateFB (:) = iterate
-     #-}
-
-And now we get an infinite loop in the rule system 
-       iterate f x -> build (\cn -> iterateFB c f x)
-                   -> iterateFB (:) f x
-                   -> iterate f x
-
-Tiresome solution: don't do shorting out if f has rewrite rules.
-Hence shortableIdInfo.
-
-(b) Keeping the IdInfo right
-~~~~~~~~~~~~~~~~~~~~~~~~
-We want to move strictness/worker info from f_local to f, but keep the rest.
-Hence copyIdInfo.
-
-\begin{code}
-shortableIdInfo :: IdInfo -> Bool
-shortableIdInfo info = isEmptyCoreRules (specInfo info)
-
-copyIdInfo :: IdInfo   -- f_local
-          -> IdInfo    -- f (the exported one)
-          -> IdInfo    -- New info for f
-copyIdInfo f_local f = f { newStrictnessInfo = newStrictnessInfo f_local,
-#ifdef OLD_STRICTNESS
-                          strictnessInfo = strictnessInfo f_local,
-                          cprInfo        = cprInfo        f_local,
-#endif
-                          workerInfo     = workerInfo     f_local
-                         }
-\end{code}