[project @ 1996-03-19 08:58:34 by partain]
[ghc-hetmet.git] / ghc / compiler / specialise / SpecTyFuns.lhs
diff --git a/ghc/compiler/specialise/SpecTyFuns.lhs b/ghc/compiler/specialise/SpecTyFuns.lhs
deleted file mode 100644 (file)
index a013194..0000000
+++ /dev/null
@@ -1,346 +0,0 @@
-%
-% (c) The GRASP/AQUA Project, Glasgow University, 1993-1995
-%
-\section[Specialise]{Stamping out overloading, and (optionally) polymorphism}
-
-\begin{code}
-#include "HsVersions.h"
-
-module SpecTyFuns (
-       specialiseCallTys,
-       ConstraintVector(..),
-       getIdOverloading,
-       mkConstraintVector,
-       isUnboxedSpecialisation,
-
-       specialiseConstrTys,
-       mkSpecialisedCon,
-
-       argTysMatchSpecTys_error,
-
-       pprSpecErrs,
-
-       Maybe(..), Pretty(..), UniType
-    ) where
-
-import AbsUniType
-import Bag             ( Bag, isEmptyBag, bagToList )
-import FiniteMap       ( FiniteMap, emptyFM, addListToFM_C,
-                         plusFM_C, keysFM, lookupWithDefaultFM
-                       )
-import Id              ( mkSameSpecCon, getIdUniType,
-                         isDictFunId, isConstMethodId_maybe,
-                         isDefaultMethodId_maybe,
-                         getInstIdModule, Id )
-import Maybes  
-import Outputable
-import Pretty
-import Util
-\end{code}
-
-@specialiseCallTys@ works out which type args don't need to be specialised on,
-based on flags, the overloading constraint vector, and the types.
-
-\begin{code}
-specialiseCallTys :: Bool              -- Specialise on all type args
-                 -> Bool               -- Specialise on unboxed type args
-                 -> Bool               -- Specialise on overloaded type args
-                 -> ConstraintVector   -- Tells which type args are overloaded
-                 -> [UniType]          -- Type args
-                 -> [Maybe UniType]    -- Nothings replace non-specialised type args
-
-specialiseCallTys True _ _ cvec tys
-  = map Just tys
-specialiseCallTys False spec_unboxed spec_overloading cvec tys
-  = zipWith spec_ty_other cvec tys
-  where
-    spec_ty_other c ty | (spec_unboxed && isUnboxedDataType ty)
-                        || (spec_overloading && c)
-                        = Just ty
-                      | otherwise
-                         = Nothing
-\end{code}
-
-@getIdOverloading@ grabs the type of an Id, and returns a 
-list of its polymorphic variables, and the initial segment of
-its ThetaType, in which the classes constrain only type variables.
-For example, if the Id's type is
-
-       forall a,b,c. Eq a -> Ord [a] -> tau
-
-we'll return
-
-       ([a,b,c], [(Eq,a)])
-
-This seems curious at first.  For a start, the type above looks odd,
-because we usually only have dictionary args whose types are of
-the form (C a) where a is a type variable.  But this doesn't hold for
-the functions arising from instance decls, which sometimes get 
-arguements with types of form (C (T a)) for some type constructor T.
-
-Should we specialise wrt this compound-type dictionary?  This is
-a heuristic judgement, as indeed is the fact that we specialise wrt
-only dictionaries.  We choose *not* to specialise wrt compound dictionaries
-because at the moment the only place they show up is in instance decls,
-where they are simply plugged into a returned dictionary.  So nothing is
-gained by specialising wrt them.
-
-\begin{code}
-getIdOverloading :: Id
-                -> ([TyVarTemplate], [(Class,TyVarTemplate)])
-getIdOverloading id
-  = (tyvars, tyvar_part_of theta)
-  where
-    (tyvars, theta, _) = splitType (getIdUniType id)
-
-    tyvar_part_of []                 = []
-    tyvar_part_of ((clas,ty) : theta) = case getTyVarTemplateMaybe ty of
-                                           Nothing    -> []
-                                           Just tyvar -> (clas, tyvar) : tyvar_part_of theta
-\end{code}
-
-\begin{code}
-type ConstraintVector = [Bool] -- True for constrained tyvar, false otherwise
-
-mkConstraintVector :: Id 
-                  -> ConstraintVector
-
-mkConstraintVector id
-  = [tyvar `elem` constrained_tyvars | tyvar <- tyvars]
-  where
-    (tyvars, class_tyvar_pairs) = getIdOverloading id
-    constrained_tyvars   = map snd class_tyvar_pairs   -- May contain dups
-\end{code}
-
-\begin{code}
-isUnboxedSpecialisation :: [Maybe UniType] -> Bool
-isUnboxedSpecialisation tys
-  = any is_unboxed tys
-  where
-    is_unboxed (Just ty) = isUnboxedDataType ty
-    is_unboxed Nothing   = False
-\end{code}
-
-@specialiseConstrTys@ works out which type args don't need to be
-specialised on. We only speciailise on unboxed types.
-
-\begin{code}
-specialiseConstrTys :: [UniType]
-                   -> [Maybe UniType]
-
-specialiseConstrTys tys
-  = map maybe_unboxed_ty tys
-  where
-    maybe_unboxed_ty ty = case isUnboxedDataType ty of
-                           True  -> Just ty
-                           False -> Nothing
-\end{code}
-
-\begin{code}
-mkSpecialisedCon :: Id -> [UniType] -> Id
-mkSpecialisedCon con tys
-  = if spec_reqd
-    then mkSameSpecCon spec_tys con
-    else con
-  where
-    spec_tys  = specialiseConstrTys tys
-    spec_reqd = maybeToBool (firstJust spec_tys)
-\end{code}
-
-@argTysMatchSpecTys@ checks if a list of argument types is consistent
-with a list of specialising types. An error message is returned if not.
-\begin{code}
-argTysMatchSpecTys_error :: [Maybe UniType]
-                        -> [UniType] 
-                        -> Maybe Pretty
-argTysMatchSpecTys_error spec_tys arg_tys
-  = if match spec_tys arg_tys
-    then Nothing
-    else Just (ppSep [ppStr "Spec and Arg Types Inconsistent:",
-                     ppStr "spectys=", ppSep [pprMaybeTy PprDebug ty | ty <- spec_tys],
-                     ppStr "argtys=", ppSep [pprParendUniType PprDebug ty | ty <- arg_tys]])
-  where
-    match (Nothing:spec_tys) (arg:arg_tys)
-      = not (isUnboxedDataType arg) &&
-        match spec_tys arg_tys
-    match (Just spec:spec_tys) (arg:arg_tys)
-      = case (cmpUniType True{-properly-} spec arg) of
-          EQ_   -> match spec_tys arg_tys
-          other -> False
-    match [] [] = True
-    match _  _  = False
-\end{code}
-
-@pprSpecErrs@ prints error and warning information
-about imported specialisations which do not exist.
-
-\begin{code}
-pprSpecErrs :: FAST_STRING                     -- module name
-           -> (Bag (Id,[Maybe UniType]))       -- errors
-           -> (Bag (Id,[Maybe UniType]))       -- warnings
-           -> (Bag (TyCon,[Maybe UniType]))    -- errors
-           -> Pretty
-
-pprSpecErrs this_mod spec_errs spec_warn spec_tyerrs
-  | not any_errs && not any_warn
-  = ppNil
-
-  | otherwise
-  = ppAboves [
-       ppStr "SPECIALISATION MESSAGES:",
-       ppAboves (map pp_module_specs use_modules)
-        ]
-  where
-    any_errs = not (isEmptyBag spec_errs && isEmptyBag spec_tyerrs)
-    any_warn = not (isEmptyBag spec_warn)
-
-    mk_module_fm get_mod_data errs_bag
-      = addListToFM_C (++) emptyFM errs_list
-      where
-        errs_list = map get_mod_data (bagToList errs_bag)
-
-    tyspecs_fm = mk_module_fm get_ty_data spec_tyerrs
-
-    iderrs_fm  = mk_module_fm (get_id_data True) spec_errs
-    idwarn_fm  = mk_module_fm (get_id_data False) spec_warn
-    idspecs_fm = plusFM_C (++) idwarn_fm iderrs_fm
-
-    get_id_data is_err (id, tys)
-      = (mod_name, [(id_name, id, tys, is_err)])
-      where
-       (mod_name, id_name) = get_id_name id
-
-    get_id_name id
-      | maybeToBool (isDefaultMethodId_maybe id)
-      = (this_mod, _NIL_)
-
-      | isDictFunId id || maybeToBool (isConstMethodId_maybe id)
-      = let get_mod = getInstIdModule id
-           use_mod = if from_prelude get_mod
-                     then SLIT("Prelude")
-                     else get_mod
-       in (use_mod, _NIL_)
-
-      | otherwise
-      = getOrigName id
-
-    get_ty_data (ty, tys)
-      = (mod_name, [(ty_name, ty, tys)])
-      where
-       (mod_name,ty_name) = getOrigName ty
-
-    from_prelude mod
-      = SLIT("Prelude") == (_SUBSTR_ mod 0 6)
-    module_names    = concat [keysFM idspecs_fm, keysFM tyspecs_fm]
-    mods            = map head (equivClasses _CMP_STRING_ module_names)
-
-    (unks, known)   = if null mods
-                     then ([], [])
-                     else case _CMP_STRING_ (head mods) _NIL_ of
-                           EQ_   -> ([_NIL_], tail mods)
-                           other -> ([], mods)
-                                  
-    (prels, others) = partition from_prelude known
-    use_modules     = unks ++ prels ++ others
-
-    pp_module_specs :: FAST_STRING -> Pretty
-    pp_module_specs mod
-      | mod == _NIL_
-      = ASSERT (null mod_tyspecs)
-       ppAboves (map (pp_idspec ty_sty (ppStr "UNKNOWN:")) mod_idspecs)
-
-      | have_specs
-      = ppAboves [
-           ppAboves (map (pp_tyspec ty_sty (pp_module mod)) mod_tyspecs),
-           ppAboves (map (pp_idspec ty_sty (pp_module mod)) mod_idspecs)
-           ]
-
-      | otherwise
-      = ppNil
-
-      where
-        mod_tyspecs = lookupWithDefaultFM tyspecs_fm [] mod
-        mod_idspecs = lookupWithDefaultFM idspecs_fm [] mod
-       have_specs  = not (null mod_tyspecs && null mod_idspecs)
-       ty_sty = PprInterface (error "SpecTyFuns:PprInterface:sw_chkr")
-
-pp_module mod
-  = ppBesides [ppPStr mod, ppStr ":"]
-
-pp_tyspec :: PprStyle -> Pretty -> (FAST_STRING, TyCon, [Maybe UniType]) -> Pretty
-
-pp_tyspec sty pp_mod (_, tycon, tys)
-  = ppCat [pp_mod,
-          ppStr "{-# SPECIALIZE", ppStr "data",
-          pprNonOp PprForUser tycon, ppCat (map (pprParendUniType sty) spec_tys),
-          ppStr "#-}", ppStr "{- Essential -}"
-           ]
-  where
-    tvs = getTyConTyVarTemplates tycon
-    (spec_args, tv_maybes) = unzip (map choose_ty (tvs `zip` tys))
-    spec_tys = map (mkForallTy (catMaybes tv_maybes)) spec_args
-
-    choose_ty (tv, Nothing) = (mkTyVarTemplateTy tv, Just tv)
-    choose_ty (tv, Just ty) = (ty, Nothing)
-
-pp_idspec :: PprStyle -> Pretty -> (FAST_STRING, Id, [Maybe UniType], Bool) -> Pretty
-
-pp_idspec sty pp_mod (_, id, tys, is_err)
-  | isDictFunId id
-  = ppCat [pp_mod,
-          ppStr "{-# SPECIALIZE",
-          ppStr "instance",
-          pprUniType sty spec_ty,
-          ppStr "#-}", pp_essential ]
-
-  | is_const_method_id
-  = let
-       Just (cls, clsty, clsop) = const_method_maybe
-       (_, cls_str) = getOrigName cls
-       clsop_str    = getClassOpString clsop
-    in
-    ppCat [pp_mod,
-          ppStr "{-# SPECIALIZE",
-          pp_clsop clsop_str, ppStr "::",
-          pprUniType sty spec_ty,
-          ppStr "#-} {- IN instance",
-          ppPStr cls_str, pprParendUniType sty clsty,
-          ppStr "-}", pp_essential ]
-
-  | is_default_method_id
-  = let
-       Just (cls, clsop, _) = default_method_maybe
-       (_, cls_str) = getOrigName cls
-       clsop_str    = getClassOpString clsop
-    in
-    ppCat [pp_mod,
-          ppStr "{- instance",
-          ppPStr cls_str,
-          ppStr "EXPLICIT METHOD REQUIRED",
-          pp_clsop clsop_str, ppStr "::",
-          pprUniType sty spec_ty,
-          ppStr "-}", pp_essential ]
-
-  | otherwise
-  = ppCat [pp_mod,
-          ppStr "{-# SPECIALIZE",
-          pprNonOp PprForUser id, ppStr "::",
-          pprUniType sty spec_ty,
-          ppStr "#-}", pp_essential ]
-  where
-    spec_ty = specialiseTy (getIdUniType id) tys 100   -- HACK to drop all dicts!!!
-    pp_essential = if is_err then ppStr "{- Essential -}" else ppNil
-
-    const_method_maybe = isConstMethodId_maybe id
-    is_const_method_id = maybeToBool const_method_maybe
-
-    default_method_maybe = isDefaultMethodId_maybe id
-    is_default_method_id = maybeToBool default_method_maybe
-
-    pp_clsop str | isAvarop str
-                = ppBesides [ppLparen, ppPStr str, ppRparen]
-                | otherwise
-                = ppPStr str
-
-\end{code}