From: Roman Leshchinskiy Date: Tue, 17 Jul 2007 05:03:37 +0000 (+0000) Subject: Classification of tycons for vectorisation X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=commitdiff_plain;h=aba1fff3e9c8f4f3c7d65f48354447b02b06bf1f Classification of tycons for vectorisation --- diff --git a/compiler/vectorise/VectType.hs b/compiler/vectorise/VectType.hs index fb0b9dc..c7c2468 100644 --- a/compiler/vectorise/VectType.hs +++ b/compiler/vectorise/VectType.hs @@ -6,10 +6,15 @@ where import VectMonad import VectUtils +import DataCon import TyCon import Type import TypeRep +import UniqFM +import UniqSet +import Digraph ( SCC(..), stronglyConnComp ) + import Outputable import Control.Monad ( liftM2 ) @@ -47,3 +52,66 @@ vectType ty@(ForAllTy _ _) vectType ty = pprPanic "vectType:" (ppr ty) +-- ---------------------------------------------------------------------------- +-- Type definitions + +type TyConGroup = ([TyCon], UniqSet TyCon) + +-- | 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 +