Add data type information to VectInfo
[ghc-hetmet.git] / compiler / iface / TcIface.lhs
index 5af949e..bae0405 100644 (file)
@@ -8,8 +8,8 @@ Type checking of type signatures in interface files
 \begin{code}
 module TcIface ( 
        tcImportDecl, checkWiredInTyCon, tcHiBootIface, typecheckIface, 
-       tcIfaceDecl, tcIfaceInst, tcIfaceFamInst, tcIfaceRules, tcIfaceGlobal, 
-       tcExtCoreBindings
+       tcIfaceDecl, tcIfaceInst, tcIfaceFamInst, tcIfaceRules,
+       tcIfaceVectInfo, tcIfaceGlobal, tcExtCoreBindings
  ) where
 
 #include "HsVersions.h"
@@ -38,6 +38,7 @@ import DataCon
 import TysWiredIn
 import Var              ( TyVar )
 import qualified Var
+import VarEnv
 import Name
 import NameEnv
 import OccName
@@ -48,9 +49,7 @@ import Outputable
 import ErrUtils
 import Maybes
 import SrcLoc
-import Util
 import DynFlags
-import Breakpoints
 import Control.Monad
 
 import Data.List
@@ -200,6 +199,10 @@ typecheckIface iface
        ; fam_insts <- mapM tcIfaceFamInst (mi_fam_insts iface)
        ; rules     <- tcIfaceRules ignore_prags (mi_rules iface)
 
+                -- Vectorisation information
+        ; vect_info <- tcIfaceVectInfo (mi_module iface) type_env 
+                                       (mi_vect_info iface)
+
                -- Exports
        ; exports <- ifaceExportNames (mi_exports iface)
 
@@ -210,8 +213,9 @@ typecheckIface iface
                              , md_insts     = insts
                              , md_fam_insts = fam_insts
                              , md_rules     = rules
+                              , md_vect_info = vect_info
                              , md_exports   = exports
-                              , md_dbg_sites = noDbgSites
+                              , md_modBreaks = emptyModBreaks
                              }
     }
 \end{code}
@@ -224,11 +228,14 @@ typecheckIface iface
 %************************************************************************
 
 \begin{code}
-tcHiBootIface :: Module -> TcRn ModDetails
+tcHiBootIface :: HscSource -> Module -> TcRn ModDetails
 -- Load the hi-boot iface for the module being compiled,
 -- if it indeed exists in the transitive closure of imports
 -- Return the ModDetails, empty if no hi-boot iface
-tcHiBootIface mod
+tcHiBootIface hsc_src mod
+  | isHsBoot hsc_src           -- Already compiling a hs-boot file
+  = return emptyModDetails
+  | otherwise
   = do         { traceIf (text "loadHiBootInterface" <+> ppr mod)
 
        ; mode <- getGhcMode
@@ -376,13 +383,22 @@ tcIfaceDecl ignore_prags
 
 tcIfaceDecl ignore_prags 
            (IfaceSyn {ifName = occ_name, ifTyVars = tv_bndrs, 
-                      ifOpenSyn = isOpen, ifSynRhs = rdr_rhs_ty})
+                      ifOpenSyn = isOpen, ifSynRhs = rdr_rhs_ty,
+                      ifFamInst = mb_family})
    = bindIfaceTyVars tv_bndrs $ \ tyvars -> do
      { tc_name <- lookupIfaceTop occ_name
      ; rhs_tyki <- tcIfaceType rdr_rhs_ty
      ; let rhs = if isOpen then OpenSynTyCon rhs_tyki Nothing
                           else SynonymTyCon rhs_tyki
-     ; return (ATyCon (buildSynTyCon tc_name tyvars rhs))
+     ; famInst <- case mb_family of
+                   Nothing         -> return Nothing
+                   Just (fam, tys) -> 
+                     do { famTyCon <- tcIfaceTyCon fam
+                        ; insttys <- mapM tcIfaceType tys
+                        ; return $ Just (famTyCon, insttys)
+                        }
+     ; tycon <- buildSynTyCon tc_name tyvars rhs famInst
+     ; return $ ATyCon tycon
      }
 
 tcIfaceDecl ignore_prags
@@ -438,7 +454,6 @@ tcIfaceDataCons tycon_name tycon tc_tyvars if_cons
   = case if_cons of
        IfAbstractTyCon  -> return mkAbstractTyConRhs
        IfOpenDataTyCon  -> return mkOpenDataTyConRhs
-       IfOpenNewTyCon   -> return mkOpenNewTyConRhs
        IfDataTyCon cons -> do  { data_cons <- mappM tc_con_decl cons
                                ; return (mkDataTyConRhs data_cons) }
        IfNewTyCon con   -> do  { data_con <- tc_con_decl con
@@ -482,7 +497,7 @@ tcIfaceEqSpec spec
     do_item (occ, if_ty) = do { tv <- tcIfaceTyVar (occNameFS occ)
                               ; ty <- tcIfaceType if_ty
                               ; return (tv,ty) }
-\end{code}     
+\end{code}
 
 
 %************************************************************************
@@ -544,12 +559,13 @@ tcIfaceRule (IfaceRule {ifRuleName = name, ifActivation = act, ifRuleBndrs = bnd
                   ; return (bndrs', args', rhs') }
        ; let mb_tcs = map ifTopFreeName args
         ; lcl <- getLclEnv
-        ; let this_module = if_mod lcl
        ; returnM (Rule { ru_name = name, ru_fn = fn, ru_act = act, 
                          ru_bndrs = bndrs', ru_args = args', 
                          ru_rhs = rhs', 
                          ru_rough = mb_tcs,
-                         ru_local = nameModule fn == this_module }) }
+                         ru_local = False }) } -- An imported RULE is never for a local Id
+                                               -- or, even if it is (module loop, perhaps)
+                                               -- we'll just leave it in the non-local set
   where
        -- This function *must* mirror exactly what Rules.topFreeName does
        -- We could have stored the ru_rough field in the iface file
@@ -568,6 +584,88 @@ tcIfaceRule (IfaceRule {ifRuleName = name, ifActivation = act, ifRuleBndrs = bnd
 
 %************************************************************************
 %*                                                                     *
+               Vectorisation information
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+tcIfaceVectInfo :: Module -> TypeEnv  -> IfaceVectInfo -> IfL VectInfo
+tcIfaceVectInfo mod typeEnv (IfaceVectInfo 
+                             { ifaceVectInfoCCVar        = vars
+                             , ifaceVectInfoCCTyCon      = tycons
+                             , ifaceVectInfoCCTyConReuse = tyconsReuse
+                             })
+  = do { ccVars    <- mapM ccVarMapping vars
+       ; tyConRes1 <- mapM ccTyConMapping      tycons
+       ; tyConRes2 <- mapM ccTyConReuseMapping tycons
+       ; let (ccTyCons, ccDataCons, ccIsos) = unzip3 (tyConRes1 ++ tyConRes2)
+       ; return $ VectInfo 
+                  { vectInfoCCVar     = mkVarEnv  ccVars
+                  , vectInfoCCTyCon   = mkNameEnv ccTyCons
+                  , vectInfoCCDataCon = mkNameEnv (concat ccDataCons)
+                  , vectInfoCCIso     = mkNameEnv ccIsos
+                  }
+       }
+  where
+    ccVarMapping name 
+      = do { ccName <- lookupOrig mod (mkCloOcc (nameOccName name))
+           ; let { var   = lookupVar name
+                 ; ccVar = lookupVar ccName
+                 }
+           ; return (var, (var, ccVar))
+           }
+    ccTyConMapping name 
+      = do { ccName  <- lookupOrig mod (mkCloTyConOcc (nameOccName name))
+           ; isoName <- lookupOrig mod (mkCloIsoOcc   (nameOccName name))
+           ; let { tycon    = lookupTyCon name
+                 ; ccTycon  = lookupTyCon ccName
+                 ; isoTycon = lookupVar isoName
+                 }
+           ; ccDataCons <- mapM ccDataConMapping (tyConDataCons tycon)
+           ; return ((name, (tycon, ccTycon)),   -- (T, T_CC)
+                     ccDataCons,                 -- list of (Ci, Ci_CC)
+                     (name, (tycon, isoTycon)))  -- (T, isoT)
+           }
+    ccTyConReuseMapping name 
+      = do { isoName <- lookupOrig mod (mkCloIsoOcc   (nameOccName name))
+           ; let { tycon      = lookupTyCon name
+                 ; isoTycon   = lookupVar isoName
+                 ; ccDataCons = [ (dataConName dc, (dc, dc)) 
+                                | dc <- tyConDataCons tycon]
+                 }
+           ; return ((name, (tycon, tycon)),     -- (T, T)
+                     ccDataCons,                 -- list of (Ci, Ci)
+                     (name, (tycon, isoTycon)))  -- (T, isoT)
+           }
+    ccDataConMapping datacon
+      = do { let name = dataConName datacon
+           ; ccName <- lookupOrig mod (mkCloDataConOcc (nameOccName name))
+           ; let ccDataCon = lookupDataCon ccName
+           ; return (name, (datacon, ccDataCon))
+           }
+    --
+    lookupVar name = case lookupTypeEnv typeEnv name of
+                       Just (AnId var) -> var
+                       Just _         -> 
+                         panic "TcIface.tcIfaceVectInfo: not an id"
+                       Nothing        ->
+                         panic "TcIface.tcIfaceVectInfo: unknown name"
+    lookupTyCon name = case lookupTypeEnv typeEnv name of
+                         Just (ATyCon tc) -> tc
+                         Just _         -> 
+                           panic "TcIface.tcIfaceVectInfo: not a tycon"
+                         Nothing        ->
+                           panic "TcIface.tcIfaceVectInfo: unknown name"
+    lookupDataCon name = case lookupTypeEnv typeEnv name of
+                           Just (ADataCon dc) -> dc
+                           Just _         -> 
+                             panic "TcIface.tcIfaceVectInfo: not a datacon"
+                           Nothing        ->
+                             panic "TcIface.tcIfaceVectInfo: unknown name"
+\end{code}
+
+%************************************************************************
+%*                                                                     *
                        Types
 %*                                                                     *
 %************************************************************************
@@ -664,16 +762,17 @@ tcIfaceExpr (IfaceCase scrut case_bndr ty alts)
     returnM (Case scrut' case_bndr' ty' alts')
 
 tcIfaceExpr (IfaceLet (IfaceNonRec bndr rhs) body)
-  = tcIfaceExpr rhs            `thenM` \ rhs' ->
-    bindIfaceId bndr           $ \ bndr' ->
-    tcIfaceExpr body           `thenM` \ body' ->
-    returnM (Let (NonRec bndr' rhs') body')
+  = do { rhs' <- tcIfaceExpr rhs
+       ; id   <- tcIfaceLetBndr bndr
+       ; body' <- extendIfaceIdEnv [id] (tcIfaceExpr body)
+       ; return (Let (NonRec id rhs') body') }
 
 tcIfaceExpr (IfaceLet (IfaceRec pairs) body)
-  = bindIfaceIds bndrs         $ \ bndrs' ->
-    mappM tcIfaceExpr rhss     `thenM` \ rhss' ->
-    tcIfaceExpr body           `thenM` \ body' ->
-    returnM (Let (Rec (bndrs' `zip` rhss')) body')
+  = do { ids <- mapM tcIfaceLetBndr bndrs
+       ; extendIfaceIdEnv ids $ do
+       { rhss' <- mapM tcIfaceExpr rhss
+       ; body' <- tcIfaceExpr body
+       ; return (Let (Rec (ids `zip` rhss')) body') } }
   where
     (bndrs, rhss) = unzip pairs
 
@@ -958,8 +1057,11 @@ tcIfaceExtId name = do { thing <- tcIfaceGlobal name
 
 \begin{code}
 bindIfaceBndr :: IfaceBndr -> (CoreBndr -> IfL a) -> IfL a
-bindIfaceBndr (IfaceIdBndr bndr) thing_inside
-  = bindIfaceId bndr thing_inside
+bindIfaceBndr (IfaceIdBndr (fs, ty)) thing_inside
+  = do { name <- newIfaceName (mkVarOccFS fs)
+       ; ty' <- tcIfaceType ty
+       ; let id = mkLocalId name ty'
+       ; extendIfaceIdEnv [id] (thing_inside id) }
 bindIfaceBndr (IfaceTvBndr bndr) thing_inside
   = bindIfaceTyVar bndr thing_inside
     
@@ -971,28 +1073,26 @@ bindIfaceBndrs (b:bs) thing_inside
     thing_inside (b':bs')
 
 -----------------------
-bindIfaceId :: IfaceIdBndr -> (Id -> IfL a) -> IfL a
-bindIfaceId (occ, ty) thing_inside
-  = do { name <- newIfaceName (mkVarOccFS occ)
+tcIfaceLetBndr (IfLetBndr fs ty info)
+  = do { name <- newIfaceName (mkVarOccFS fs)
        ; ty' <- tcIfaceType ty
-       ; let { id = mkLocalId name ty' }
-       ; extendIfaceIdEnv [id] (thing_inside id) }
-    
-bindIfaceIds :: [IfaceIdBndr] -> ([Id] -> IfL a) -> IfL a
-bindIfaceIds bndrs thing_inside
-  = do         { names <- newIfaceNames (map mkVarOccFS occs)
-       ; tys' <- mappM tcIfaceType tys
-       ; let { ids = zipWithEqual "tcCoreValBndr" mkLocalId names tys' }
-       ; extendIfaceIdEnv ids (thing_inside ids) }
+       ; case info of
+               NoInfo    -> return (mkLocalId name ty')
+               HasInfo i -> return (mkLocalIdWithInfo name ty' (tc_info i)) } 
   where
-    (occs,tys) = unzip bndrs
-
+       -- Similar to tcIdInfo, but much simpler
+    tc_info [] = vanillaIdInfo
+    tc_info (HsInline p     : i) = tc_info i `setInlinePragInfo` p 
+    tc_info (HsArity a      : i) = tc_info i `setArityInfo` a 
+    tc_info (HsStrictness s : i) = tc_info i `setAllStrictnessInfo` Just s 
+    tc_info (other          : i) = pprTrace "tcIfaceLetBndr: discarding unexpected IdInfo" 
+                                           (ppr other) (tc_info i)
 
 -----------------------
-newExtCoreBndr :: IfaceIdBndr -> IfL Id
-newExtCoreBndr (var, ty)
+newExtCoreBndr :: IfaceLetBndr -> IfL Id
+newExtCoreBndr (IfLetBndr var ty _)    -- Ignoring IdInfo for now
   = do { mod <- getIfModule
-       ; name <- newGlobalBinder mod (mkVarOccFS var) noSrcLoc
+       ; name <- newGlobalBinder mod (mkVarOccFS var) noSrcSpan
        ; ty' <- tcIfaceType ty
        ; return (mkLocalId name ty') }