The Big INLINE Patch: totally reorganise way that INLINE pragmas work
[ghc-hetmet.git] / compiler / basicTypes / IdInfo.lhs
index fca1abd..9446f7d 100644 (file)
@@ -9,8 +9,8 @@ Haskell. [WDP 94/11])
 
 \begin{code}
 module IdInfo (
-        -- * The GlobalIdDetails type
-       GlobalIdDetails(..), notGlobalId,       -- Not abstract
+        -- * The IdDetails type
+       IdDetails(..), pprIdDetails,
 
         -- * The IdInfo type
        IdInfo,         -- Abstract
@@ -158,8 +158,8 @@ seqNewStrictnessInfo Nothing = ()
 seqNewStrictnessInfo (Just ty) = seqStrictSig ty
 
 pprNewStrictness :: Maybe StrictSig -> SDoc
-pprNewStrictness Nothing = empty
-pprNewStrictness (Just sig) = ftext (fsLit "Str:") <+> ppr sig
+pprNewStrictness Nothing    = empty
+pprNewStrictness (Just sig) = ppr sig
 
 #ifdef OLD_STRICTNESS
 oldStrictnessFromNew :: StrictSig -> Demand.StrictnessInfo
@@ -227,31 +227,23 @@ seqNewDemandInfo (Just dmd) = seqDemand dmd
 
 %************************************************************************
 %*                                                                     *
-\subsection{GlobalIdDetails}
+                     IdDetails
 %*                                                                     *
 %************************************************************************
 
-This type is here (rather than in Id.lhs) mainly because there's 
-an IdInfo.hi-boot, but no Id.hi-boot, and GlobalIdDetails is imported
-(recursively) by Var.lhs.
-
 \begin{code}
--- | Information pertaining to global 'Id's. See "Var#globalvslocal" for the distinction 
--- between global and local in this context
-data GlobalIdDetails
-  = VanillaGlobal              -- ^ The 'Id' is imported from elsewhere or is a default method 'Id'
+-- | The 'IdDetails' of an 'Id' give stable, and necessary, 
+-- information about the Id. 
+data IdDetails
+  = VanillaId  
 
   -- | The 'Id' for a record selector
-  | RecordSelId                 
+  | RecSelId                 
     { sel_tycon   :: TyCon     -- ^ For a data type family, this is the /instance/ 'TyCon'
                                --   not the family 'TyCon'
-    , sel_label   :: FieldLabel
     , sel_naughty :: Bool       -- True <=> a "naughty" selector which can't actually exist, for example @x@ in:
-                                -- 
-                                -- > data T = forall a. MkT { x :: a }
-    }                          
-                               -- See Note [Naughty record selectors]
-                               -- with MkId.mkRecordSelectorId
+                                --    data T = forall a. MkT { x :: a }
+    }                          -- See Note [Naughty record selectors] in TcTyClsDecls
 
   | DataConWorkId DataCon      -- ^ The 'Id' is for a data constructor /worker/
   | DataConWrapId DataCon      -- ^ The 'Id' is for a data constructor /wrapper/
@@ -261,29 +253,38 @@ data GlobalIdDetails
                                --  b) when desugaring a RecordCon we can get 
                                --     from the Id back to the data con]
 
-  | ClassOpId Class            -- ^ The 'Id' is an operation of a class
+  | ClassOpId Class            -- ^ The 'Id' is an superclass selector or class operation of a class
 
   | PrimOpId PrimOp            -- ^ The 'Id' is for a primitive operator
   | FCallId ForeignCall                -- ^ The 'Id' is for a foreign call
 
   | TickBoxOpId TickBoxOp      -- ^ The 'Id' is for a HPC tick box (both traditional and binary)
 
-  | NotGlobalId                        -- ^ Used as a convenient extra return value from 'globalIdDetails'
-
--- | An entirely unhelpful 'GlobalIdDetails'
-notGlobalId :: GlobalIdDetails
-notGlobalId = NotGlobalId
-
-instance Outputable GlobalIdDetails where
-    ppr NotGlobalId       = ptext (sLit "[***NotGlobalId***]")
-    ppr VanillaGlobal     = ptext (sLit "[GlobalId]")
-    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 (TickBoxOpId _)   = ptext (sLit "[TickBoxOp]")
-    ppr (RecordSelId {})  = ptext (sLit "[RecSel]")
+  | DFunId Bool                        -- ^ A dictionary function.  
+                               --   True <=> the class has only one method, so may be 
+                               --            implemented with a newtype, so it might be bad 
+                               --            to be strict on this dictionary
+
+
+instance Outputable IdDetails where
+    ppr = pprIdDetails
+
+pprIdDetails :: IdDetails -> SDoc
+pprIdDetails VanillaId = empty
+pprIdDetails other     = brackets (pp other)
+ where
+   pp VanillaId         = panic "pprIdDetails"
+   pp (DataConWorkId _) = ptext (sLit "DataCon")
+   pp (DataConWrapId _) = ptext (sLit "DataConWrapper")
+   pp (ClassOpId {})    = ptext (sLit "ClassOp")
+   pp (PrimOpId _)      = ptext (sLit "PrimOp")
+   pp (FCallId _)       = ptext (sLit "ForeignCall")
+   pp (TickBoxOpId _)   = ptext (sLit "TickBoxOp")
+   pp (DFunId b)        = ptext (sLit "DFunId") <> 
+                            ppWhen b (ptext (sLit "(newtype)"))
+   pp (RecSelId { sel_naughty = is_naughty })
+                        = brackets $ ptext (sLit "RecSel") 
+                           <> ppWhen is_naughty (ptext (sLit "(naughty)"))
 \end{code}
 
 
@@ -309,6 +310,7 @@ data IdInfo
   = IdInfo {
        arityInfo       :: !ArityInfo,          -- ^ 'Id' arity
        specInfo        :: SpecInfo,            -- ^ Specialisations of the 'Id's function which exist
+                                               -- See Note [Specialisations and RULES in IdInfo]
 #ifdef OLD_STRICTNESS
        cprInfo         :: CprInfo,             -- ^ If the 'Id's function always constructs a product result
        demandInfo      :: Demand.Demand,       -- ^ Whether or not the 'Id' is definitely demanded
@@ -317,7 +319,7 @@ data IdInfo
        unfoldingInfo   :: Unfolding,           -- ^ The 'Id's unfolding
        cafInfo         :: CafInfo,             -- ^ 'Id' CAF info
         lbvarInfo      :: LBVarInfo,           -- ^ Info about a lambda-bound variable, if the 'Id' is one
-       inlinePragInfo  :: InlinePragInfo,      -- ^ Any inline pragma atached to the 'Id'
+       inlinePragInfo  :: InlinePragma,        -- ^ Any inline pragma atached to the 'Id'
        occInfo         :: OccInfo,             -- ^ How the 'Id' occurs in the program
 
        newStrictnessInfo :: Maybe StrictSig,   -- ^ Id strictness information. Reason for Maybe: 
@@ -363,7 +365,7 @@ Setters
 \begin{code}
 setSpecInfo :: IdInfo -> SpecInfo -> IdInfo
 setSpecInfo      info sp = sp `seq` info { specInfo = sp }
-setInlinePragInfo :: IdInfo -> InlinePragInfo -> IdInfo
+setInlinePragInfo :: IdInfo -> InlinePragma -> IdInfo
 setInlinePragInfo info pr = pr `seq` info { inlinePragInfo = pr }
 setOccInfo :: IdInfo -> OccInfo -> IdInfo
 setOccInfo       info oc = oc `seq` info { occInfo = oc }
@@ -418,7 +420,7 @@ vanillaIdInfo
            specInfo            = emptySpecInfo,
            unfoldingInfo       = noUnfolding,
            lbvarInfo           = NoLBVarInfo,
-           inlinePragInfo      = AlwaysActive,
+           inlinePragInfo      = defaultInlinePragma,
            occInfo             = NoOccInfo,
            newDemandInfo       = Nothing,
            newStrictnessInfo   = Nothing
@@ -477,7 +479,7 @@ ppArityInfo n = hsep [ptext (sLit "Arity"), int n]
 --
 -- The default 'InlinePragInfo' is 'AlwaysActive', so the info serves
 -- entirely as a way to inhibit inlining until we want it
-type InlinePragInfo = Activation
+type InlinePragInfo = InlinePragma
 \end{code}
 
 
@@ -487,6 +489,25 @@ type InlinePragInfo = Activation
 %*                                                                     *
 %************************************************************************
 
+Note [Specialisations and RULES in IdInfo]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Generally speaking, a GlobalIdshas an *empty* SpecInfo.  All their
+RULES are contained in the globally-built rule-base.  In principle,
+one could attach the to M.f the RULES for M.f that are defined in M.
+But we don't do that for instance declarations and so we just treat
+them all uniformly.
+
+The EXCEPTION is PrimOpIds, which do have rules in their IdInfo. That is
+jsut for convenience really.
+
+However, LocalIds may have non-empty SpecInfo.  We treat them 
+differently because:
+  a) they might be nested, in which case a global table won't work
+  b) the RULE might mention free variables, which we use to keep things alive
+
+In TidyPgm, when the LocalId becomes a GlobalId, its RULES are stripped off
+and put in the global list.
+
 \begin{code}
 -- | Records the specializations of this 'Id' that we know about
 -- in the form of rewrite 'CoreRule's that target them
@@ -555,6 +576,9 @@ mayHaveCafRefs _           = False
 seqCaf :: CafInfo -> ()
 seqCaf c = c `seq` ()
 
+instance Outputable CafInfo where
+   ppr = ppCafInfo
+
 ppCafInfo :: CafInfo -> SDoc
 ppCafInfo NoCafRefs = ptext (sLit "NoCafRefs")
 ppCafInfo MayHaveCafRefs = empty