X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Fvectorise%2FVectType.hs;h=29b68435dee817c2d97c60b3bc637b3459cbe853;hb=ae7dacf4c3b014fa0ec6f94ac5b2e0a19b1b2f45;hp=fb0b9dc25ace34b86dfd377c1aa1c785fc08a879;hpb=f8bfbc444dc77d9d8c5f19ff33e198da43c7a8f0;p=ghc-hetmet.git diff --git a/compiler/vectorise/VectType.hs b/compiler/vectorise/VectType.hs index fb0b9dc..29b6843 100644 --- a/compiler/vectorise/VectType.hs +++ b/compiler/vectorise/VectType.hs @@ -6,13 +6,21 @@ where import VectMonad import VectUtils +import DataCon import TyCon import Type import TypeRep +import OccName +import MkId +import BasicTypes ( StrictnessMark(..), boolToRecFlag ) + +import UniqFM +import UniqSet +import Digraph ( SCC(..), stronglyConnComp ) import Outputable -import Control.Monad ( liftM2 ) +import Control.Monad ( liftM2, zipWithM_ ) -- ---------------------------------------------------------------------------- -- Types @@ -47,3 +55,141 @@ vectType ty@(ForAllTy _ _) vectType ty = pprPanic "vectType:" (ppr ty) +-- ---------------------------------------------------------------------------- +-- Type definitions + +type TyConGroup = ([TyCon], UniqSet TyCon) + +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) = tyConsOfTypes tys `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 +