Fix vectorisation of classes
authorManuel M T Chakravarty <chak@cse.unsw.edu.au>
Sun, 15 Jan 2012 11:10:28 +0000 (22:10 +1100)
committerManuel M T Chakravarty <chak@cse.unsw.edu.au>
Sun, 15 Jan 2012 21:19:30 +0000 (08:19 +1100)
- Make sure that we have no implicit names in ifaces
- Any vectorisation info makes a module an orphan module
- Allow 'Show' in vectorised code without vectorising it for the moment

.gitignore
compiler/iface/MkIface.lhs
compiler/iface/TcIface.lhs
compiler/main/HscTypes.lhs
compiler/main/TidyPgm.lhs
compiler/rename/RnSource.lhs
compiler/vectorise/Vectorise/Monad.hs
compiler/vectorise/Vectorise/Type/Classify.hs
compiler/vectorise/Vectorise/Type/Env.hs

index 4897988..e65a4c2 100644 (file)
@@ -240,3 +240,5 @@ _darcs/
 
 
 /extra-gcc-opts
+
+.tm_properties
index 86a5124..6e29165 100644 (file)
@@ -622,7 +622,7 @@ addFingerprints hsc_env mb_old_fingerprint iface0 new_decls
                 mi_orphan      = not (   null orph_rules
                                       && null orph_insts
                                       && null orph_fis
-                                      && null (ifaceVectInfoVar (mi_vect_info iface0))),
+                                      && isNoIfaceVectInfo (mi_vect_info iface0))),
                 mi_finsts      = not . null $ mi_fam_insts iface0,
                 mi_decls       = sorted_decls,
                 mi_hash_fn     = lookupOccEnv local_env }
index 5894607..6946752 100644 (file)
@@ -745,9 +745,9 @@ tcIfaceVectInfo mod typeEnv (IfaceVectInfo
        ; tyConRes1   <- mapM (vectTyConVectMapping varsSet)  tycons
        ; tyConRes2   <- mapM (vectTyConReuseMapping varsSet) tyconsReuse
        ; vScalarVars <- mapM vectVar                         scalarVars
-       ; let (vTyCons, vDataCons) = unzip (tyConRes1 ++ tyConRes2)
+       ; let (vTyCons, vDataCons, vScSels) = unzip3 (tyConRes1 ++ tyConRes2)
        ; return $ VectInfo 
-                  { vectInfoVar          = mkVarEnv  vVars
+                  { vectInfoVar          = mkVarEnv  vVars `extendVarEnvList` concat vScSels
                   , vectInfoTyCon        = mkNameEnv vTyCons
                   , vectInfoDataCon      = mkNameEnv (concat vDataCons)
                   , vectInfoScalarVars   = mkVarSet  vScalarVars
@@ -765,6 +765,19 @@ tcIfaceVectInfo mod typeEnv (IfaceVectInfo
                        tcIfaceExtId vName
            ; return (var, (var, vVar))
            }
+      -- where
+      --   lookupLocalOrExternalId name
+      --     = do { let mb_id = lookupTypeEnv typeEnv name
+      --          ; case mb_id of
+      --                -- id is local
+      --              Just (AnId id) -> return id
+      --                -- name is not an Id => internal inconsistency
+      --              Just _         -> notAnIdErr
+      --                -- Id is external
+      --              Nothing        -> tcIfaceExtId name
+      --          }
+      -- 
+      --   notAnIdErr = pprPanic "TcIface.tcIfaceVectInfo: not an id" (ppr name)
 
     vectVar name 
       = forkM (ptext (sLit "vect scalar var")  <+> ppr name)  $
@@ -779,13 +792,17 @@ tcIfaceVectInfo mod typeEnv (IfaceVectInfo
       = vectTyConMapping vars name name
 
     vectTyConMapping vars name vName
-      = do { tycon  <- lookupLocalOrExternal name
-           ; vTycon <- lookupLocalOrExternal vName
+      = do { tycon  <- lookupLocalOrExternalTyCon name
+           ; vTycon <- forkM (ptext (sLit "vTycon of") <+> ppr vName) $ 
+                         lookupLocalOrExternalTyCon vName
 
-               -- map the data constructors of the original type constructor to those of the
+               -- Map the data constructors of the original type constructor to those of the
                -- vectorised type constructor /unless/ the type constructor was vectorised
                -- abstractly; if it was vectorised abstractly, the workers of its data constructors
-               -- do not appear in the set of vectorised variables
+               -- do not appear in the set of vectorised variables.
+               --
+               -- NB: This is lazy!  We don't pull at the type constructors before we actually use
+               --     the data constructor mapping.
            ; let isAbstract | isClassTyCon tycon = False
                             | datacon:_ <- tyConDataCons tycon 
                                                  = not $ dataConWrapId datacon `elemVarSet` vars
@@ -796,14 +813,25 @@ tcIfaceVectInfo mod typeEnv (IfaceVectInfo
                                                                         (tyConDataCons vTycon)
                                            ]
 
+                   -- Map the (implicit) superclass and methods selectors as they don't occur in
+                   -- the var map.
+                 vScSels    | Just cls  <- tyConClass_maybe tycon
+                            , Just vCls <- tyConClass_maybe vTycon 
+                            = [ (sel, (sel, vSel))
+                              | (sel, vSel) <- zip (classAllSelIds cls) (classAllSelIds vCls)
+                              ]
+                            | otherwise
+                            = []
+
            ; return ( (name, (tycon, vTycon))          -- (T, T_v)
                     , vDataCons                        -- list of (Ci, Ci_v)
+                    , vScSels                          -- list of (seli, seli_v)
                     )
            }
       where
           -- we need a fully defined version of the type constructor to be able to extract
           -- its data constructors etc.
-        lookupLocalOrExternal name
+        lookupLocalOrExternalTyCon name
           = do { let mb_tycon = lookupTypeEnv typeEnv name
                ; case mb_tycon of
                      -- tycon is local
index db81bc4..3224acf 100644 (file)
@@ -92,7 +92,7 @@ module HscTypes (
 
         -- * Vectorisation information
         VectInfo(..), IfaceVectInfo(..), noVectInfo, plusVectInfo,
-        noIfaceVectInfo,
+        noIfaceVectInfo, isNoIfaceVectInfo,
 
         -- * Safe Haskell information
         hscGetSafeInf, hscSetSafeInf,
@@ -696,8 +696,8 @@ data ModIface
         mi_insts       :: [IfaceClsInst],     -- ^ Sorted class instance
         mi_fam_insts   :: [IfaceFamInst],  -- ^ Sorted family instances
         mi_rules       :: [IfaceRule],     -- ^ Sorted rules
-        mi_orphan_hash :: !Fingerprint,    -- ^ Hash for orphan rules and class
-                                           -- and family instances combined
+        mi_orphan_hash :: !Fingerprint,    -- ^ Hash for orphan rules, class and family
+                                           -- instances, and vectorise pragmas combined
 
         mi_vect_info :: !IfaceVectInfo,    -- ^ Vectorisation information
 
@@ -1566,6 +1566,8 @@ lookupFixity env n = case lookupNameEnv env n of
 --
 -- * A transformation rule in a module other than the one defining
 --   the function in the head of the rule
+--
+-- * A vectorisation pragma
 type WhetherHasOrphans   = Bool
 
 -- | Does this module define family instances?
@@ -2009,6 +2011,10 @@ concatVectInfo = foldr plusVectInfo noVectInfo
 noIfaceVectInfo :: IfaceVectInfo
 noIfaceVectInfo = IfaceVectInfo [] [] [] [] []
 
+isNoIfaceVectInfo :: IfaceVectInfo -> Bool
+isNoIfaceVectInfo (IfaceVectInfo l1 l2 l3 l4 l5)
+  = null l1 && null l2 && null l3 && null l4 && null l5
+
 instance Outputable VectInfo where
   ppr info = vcat
              [ ptext (sLit "variables     :") <+> ppr (vectInfoVar          info)
index 5e2a937..3107b79 100644 (file)
@@ -513,6 +513,7 @@ tidyVectInfo (_, var_env) info@(VectInfo { vectInfoVar          = vars
                                tidy_var_v = lookup_var var_v
                          , isExportedId tidy_var
                          , isExportedId tidy_var_v
+                         , not $ isImplicitId var
                          ]
 
     tidy_scalarVars = mkVarSet [ lookup_var var 
index 197f2b2..c676a9b 100644 (file)
@@ -682,7 +682,7 @@ rnHsVectDecl (HsVectClassOut _)
   = panic "RnSource.rnHsVectDecl: Unexpected 'HsVectClassOut'"
 rnHsVectDecl (HsVectInstIn instTy)
   = do { instTy' <- rnLHsInstType (text "In a VECTORISE pragma") instTy
-       ; return (HsVectInstIn instTy', emptyFVs)
+       ; return (HsVectInstIn instTy', extractHsTyNames instTy')
        }
 rnHsVectDecl (HsVectInstOut _)
   = panic "RnSource.rnHsVectDecl: Unexpected 'HsVectInstOut'"
index a6bf6d9..426682c 100644 (file)
@@ -54,12 +54,12 @@ initV :: HscEnv
       -> VM a
       -> IO (Maybe (VectInfo, a))
 initV hsc_env guts info thing_inside
-  = do {
-         let type_env = typeEnvFromEntities ids (mg_tcs guts) (mg_fam_insts guts)
+  = do { dumpIfVtTrace "Incoming VectInfo" (ppr info)
+
+       ; let type_env = typeEnvFromEntities ids (mg_tcs guts) (mg_fam_insts guts)
        ; (_, Just res) <- initDs hsc_env (mg_module guts)
                                          (mg_rdr_env guts) type_env go
 
-       ; dumpIfVtTrace "Incoming VectInfo" (ppr info)
        ; case res of
            Nothing
              -> dumpIfVtTrace "Vectorisation FAILED!" empty
index 7122cb7..ead7f14 100644 (file)
@@ -23,6 +23,7 @@ import DataCon
 import TyCon
 import TypeRep
 import Type
+import PrelNames
 import Digraph
 
 
@@ -54,14 +55,21 @@ classifyTyCons convStatus tcs = classify [] [] [] convStatus (tyConGroups tcs)
       where
         refs = ds `delListFromUniqSet` tcs
 
-        can_convert  = isNullUFM (refs `minusUFM` cs) && all convertable tcs
+        can_convert  = (isNullUFM (refs `minusUFM` cs) && all convertable tcs)
+                       || isShowClass tcs
         must_convert = foldUFM (||) False (intersectUFM_C const cs refs)
+                       && (not . isShowClass $ tcs)
 
         -- We currently admit Haskell 2011-style data and newtype declarations as well as type
         -- constructors representing classes.
         convertable tc 
           = (isDataTyCon tc || isNewTyCon tc) && all isVanillaDataCon (tyConDataCons tc)
             || isClassTyCon tc
+            
+        -- !!!FIXME: currently we allow 'Show' in vectorised code without actually providing a
+        --   vectorised definition (to be able to vectorise 'Num')
+        isShowClass [tc] = tyConName tc == showClassName
+        isShowClass _    = False
 
 -- Used to group type constructors into mutually dependent groups.
 --
index a6f77bb..0051d07 100644 (file)
@@ -147,14 +147,6 @@ vectTypeEnv :: [TyCon]                  -- Type constructors defined in this mod
 vectTypeEnv tycons vectTypeDecls vectClassDecls
   = do { traceVt "** vectTypeEnv" $ ppr tycons
 
-         -- Build a map containing all vectorised type constructor.  If they are scalar, they are
-         -- mapped to 'False' (vectorised type constructor == original type constructor).
-       ; allScalarTyConNames <- globalScalarTyCons  -- covers both current and imported modules
-       ; vectTyCons          <- globalVectTyCons
-       ; let vectTyConBase    = mapNameEnv (const True) vectTyCons   -- by default fully vectorised
-             vectTyConFlavour = foldNameSet (\n env -> extendNameEnv env n False) vectTyConBase
-                                            allScalarTyConNames
-
        ; let   -- {-# VECTORISE SCALAR type T -#} (imported and local tycons)
              localAbstractTyCons    = [tycon | VectType True tycon Nothing <- vectTypeDecls]
 
@@ -172,6 +164,23 @@ vectTypeEnv tycons vectTypeDecls vectClassDecls
                                         localAbstractTyCons ++ map fst3 vectTyConsWithRHS
              notVectSpecialTyCon tc = not $ (tyConName tc) `elemNameSet` vectSpecialTyConNames
 
+         -- Build a map containing all vectorised type constructor.  If they are scalar, they are
+         -- mapped to 'False' (vectorised type constructor == original type constructor).
+       ; allScalarTyConNames <- globalScalarTyCons  -- covers both current and imported modules
+       ; vectTyCons          <- globalVectTyCons
+       ; let vectTyConBase    = mapNameEnv (const True) vectTyCons    -- by default fully vectorised
+             vectTyConFlavour = vectTyConBase 
+                                `plusNameEnv` 
+                                mkNameEnv [ (tyConName tycon, True) 
+                                          | (tycon, _, _) <- vectTyConsWithRHS]
+                                `plusNameEnv`
+                                mkNameEnv [ (tcName, False)           -- original representation
+                                          | tcName <- nameSetToList allScalarTyConNames]
+                                `plusNameEnv`
+                                mkNameEnv [ (tyConName tycon, False)  -- original representation
+                                          | tycon <- localAbstractTyCons]
+                                            
+
            -- Split the list of 'TyCons' into the ones (1) that we must vectorise and those (2)
            -- that we could, but don't need to vectorise.  Type constructors that are not data
            -- type constructors or use non-Haskell98 features are being dropped.  They may not
@@ -219,6 +228,12 @@ vectTypeEnv tycons vectTypeDecls vectClassDecls
            -- Vectorise all the data type declarations that we can and must vectorise (enter the
            -- type and data constructors into the vectorisation map on-the-fly.)
        ; new_tcs <- vectTyConDecls conv_tcs
+       
+       ; let dumpTc tc vTc = traceVt "---" (ppr tc <+> text "::" <+> ppr (dataConSig tc) $$
+                                            ppr vTc <+> text "::" <+> ppr (dataConSig vTc))
+             dataConSig tc | Just dc <- tyConSingleDataCon_maybe tc = dataConRepType dc
+                           | otherwise                              = panic "dataConSig"
+       ; zipWithM_ dumpTc (filter isClassTyCon conv_tcs) (filter isClassTyCon new_tcs)
 
            -- We don't need new representation types for dictionary constructors. The constructors
            -- are always fully applied, and we don't need to lift them to arrays as a dictionary