X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Fvectorise%2FVectType.hs;h=46c32676d62dfde4a358e73a06975c064e71d65c;hb=c1681a73fa4ca4cf8758264ae387ac09a9e900d8;hp=155f42097983c9c9c49cacb8965739df0c135da8;hpb=df62b50deaadeab84a89b20b277dd4707f90c724;p=ghc-hetmet.git diff --git a/compiler/vectorise/VectType.hs b/compiler/vectorise/VectType.hs index 155f420..46c3267 100644 --- a/compiler/vectorise/VectType.hs +++ b/compiler/vectorise/VectType.hs @@ -1,4 +1,4 @@ -module VectType ( vectTyCon, vectType ) +module VectType ( vectTyCon, vectType, vectTypeEnv ) where #include "HsVersions.h" @@ -6,13 +6,27 @@ where import VectMonad import VectUtils +import HscTypes ( TypeEnv, extendTypeEnvList, typeEnvTyCons ) +import DataCon import TyCon import Type import TypeRep +import OccName +import MkId +import BasicTypes ( StrictnessMark(..), boolToRecFlag ) +import NameEnv + +import Unique +import UniqFM +import UniqSet +import Digraph ( SCC(..), stronglyConnComp ) import Outputable -import Control.Monad ( liftM2 ) +import Control.Monad ( liftM2, zipWithM_ ) + +-- ---------------------------------------------------------------------------- +-- Types vectTyCon :: TyCon -> VM TyCon vectTyCon tc @@ -44,3 +58,170 @@ vectType ty@(ForAllTy _ _) vectType ty = pprPanic "vectType:" (ppr ty) +-- ---------------------------------------------------------------------------- +-- Type definitions + +type TyConGroup = ([TyCon], UniqSet TyCon) + +vectTypeEnv :: TypeEnv -> VM TypeEnv +vectTypeEnv env + = do + cs <- readGEnv $ mk_map . global_tycons + let (conv_tcs, keep_tcs) = classifyTyCons cs groups + keep_dcs = concatMap tyConDataCons keep_tcs + zipWithM_ defTyCon keep_tcs keep_tcs + zipWithM_ defDataCon keep_dcs keep_dcs + new_tcs <- vectTyConDecls conv_tcs + return $ extendTypeEnvList env + (map ATyCon new_tcs ++ [ADataCon dc | tc <- new_tcs + , dc <- tyConDataCons tc]) + where + tycons = typeEnvTyCons env + groups = tyConGroups tycons + + mk_map env = listToUFM_Directly [(u, getUnique n /= u) | (u,n) <- nameEnvUniqueElts env] + + keep_tc tc = let dcs = tyConDataCons tc + in + defTyCon tc tc >> zipWithM_ defDataCon dcs dcs + + +vectTyConDecls :: [TyCon] -> VM [TyCon] +vectTyConDecls tcs = fixV $ \tcs' -> + do + mapM_ (uncurry defTyCon) (lazy_zip tcs tcs') + mapM vectTyConDecl tcs + where + lazy_zip [] _ = [] + lazy_zip (x:xs) ~(y:ys) = (x,y) : lazy_zip xs ys + +vectTyConDecl :: TyCon -> VM TyCon +vectTyConDecl tc + = do + name' <- cloneName mkVectTyConOcc name + rhs' <- vectAlgTyConRhs (algTyConRhs tc) + + return $ mkAlgTyCon name' + kind + tyvars + [] -- no stupid theta + rhs' + [] -- no selector ids + NoParentTyCon -- FIXME + rec_flag -- FIXME: is this ok? + False -- FIXME: no generics + False -- not GADT syntax + where + name = tyConName tc + kind = tyConKind tc + tyvars = tyConTyVars tc + rec_flag = boolToRecFlag (isRecursiveTyCon tc) + +vectAlgTyConRhs :: AlgTyConRhs -> VM AlgTyConRhs +vectAlgTyConRhs (DataTyCon { data_cons = data_cons + , is_enum = is_enum + }) + = do + data_cons' <- mapM vectDataCon data_cons + zipWithM_ defDataCon data_cons data_cons' + return $ DataTyCon { data_cons = data_cons' + , is_enum = is_enum + } + +vectDataCon :: DataCon -> VM DataCon +vectDataCon dc + | not . null $ dataConExTyVars dc = pprPanic "vectDataCon: existentials" (ppr dc) + | not . null $ dataConEqSpec dc = pprPanic "vectDataCon: eq spec" (ppr dc) + | otherwise + = do + name' <- cloneName mkVectDataConOcc name + tycon' <- vectTyCon tycon + arg_tys <- mapM vectType rep_arg_tys + wrk_name <- cloneName mkDataConWorkerOcc name' + + let ids = mkDataConIds (panic "vectDataCon: wrapped id") + wrk_name + data_con + data_con = mkDataCon name' + False -- not infix + (map (const NotMarkedStrict) arg_tys) + [] -- no labelled fields + univ_tvs + [] -- no existential tvs for now + [] -- no eq spec for now + [] -- no theta + arg_tys + tycon' + [] -- no stupid theta + ids + return data_con + where + name = dataConName dc + univ_tvs = dataConUnivTyVars dc + rep_arg_tys = dataConOrigArgTys dc + tycon = dataConTyCon dc + +-- | Split the given tycons into two sets depending on whether they have to be +-- converted (first list) or not (second list). The first argument contains +-- information about the conversion status of external tycons: +-- +-- * tycons which have converted versions are mapped to True +-- * tycons which are not changed by vectorisation are mapped to False +-- * tycons which can't be converted are not elements of the map +-- +classifyTyCons :: UniqFM Bool -> [TyConGroup] -> ([TyCon], [TyCon]) +classifyTyCons = classify [] [] + where + classify conv keep cs [] = (conv, keep) + classify conv keep cs ((tcs, ds) : rs) + | can_convert && must_convert + = classify (tcs ++ conv) keep (cs `addListToUFM` [(tc,True) | tc <- tcs]) rs + | can_convert + = classify conv (tcs ++ keep) (cs `addListToUFM` [(tc,False) | tc <- tcs]) rs + | otherwise + = classify conv keep cs rs + where + refs = ds `delListFromUniqSet` tcs + + can_convert = isNullUFM (refs `minusUFM` cs) && all convertable tcs + must_convert = foldUFM (||) False (intersectUFM_C const cs refs) + + convertable tc = isDataTyCon tc && all isVanillaDataCon (tyConDataCons tc) + +-- | Compute mutually recursive groups of tycons in topological order +-- +tyConGroups :: [TyCon] -> [TyConGroup] +tyConGroups tcs = map mk_grp (stronglyConnComp edges) + where + edges = [((tc, ds), tc, uniqSetToList ds) | tc <- tcs + , let ds = tyConsOfTyCon tc] + + mk_grp (AcyclicSCC (tc, ds)) = ([tc], ds) + mk_grp (CyclicSCC els) = (tcs, unionManyUniqSets dss) + where + (tcs, dss) = unzip els + +tyConsOfTyCon :: TyCon -> UniqSet TyCon +tyConsOfTyCon + = tyConsOfTypes . concatMap dataConRepArgTys . tyConDataCons + +tyConsOfType :: Type -> UniqSet TyCon +tyConsOfType ty + | Just ty' <- coreView ty = tyConsOfType ty' +tyConsOfType (TyVarTy v) = emptyUniqSet +tyConsOfType (TyConApp tc tys) = extend (tyConsOfTypes tys) + where + extend | isUnLiftedTyCon tc + || isTupleTyCon tc = id + + | otherwise = (`addOneToUniqSet` tc) + +tyConsOfType (AppTy a b) = tyConsOfType a `unionUniqSets` tyConsOfType b +tyConsOfType (FunTy a b) = (tyConsOfType a `unionUniqSets` tyConsOfType b) + `addOneToUniqSet` funTyCon +tyConsOfType (ForAllTy _ ty) = tyConsOfType ty +tyConsOfType other = pprPanic "ClosureConv.tyConsOfType" $ ppr other + +tyConsOfTypes :: [Type] -> UniqSet TyCon +tyConsOfTypes = unionManyUniqSets . map tyConsOfType +