[project @ 1997-05-26 02:33:57 by sof]
[ghc-hetmet.git] / ghc / compiler / specialise / SpecUtils.lhs
index 8a01992..e2eec02 100644 (file)
@@ -1,5 +1,5 @@
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1993-1995
+% (c) The GRASP/AQUA Project, Glasgow University, 1993-1996
 %
 \section[Specialise]{Stamping out overloading, and (optionally) polymorphism}
 
@@ -8,9 +8,8 @@
 
 module SpecUtils (
        specialiseCallTys,
-       ConstraintVector(..),
+       SYN_IE(ConstraintVector),
        getIdOverloading,
-       mkConstraintVector,
        isUnboxedSpecialisation,
 
        specialiseConstrTys,
@@ -21,42 +20,66 @@ module SpecUtils (
        pprSpecErrs
     ) where
 
-import Type
-import Bag             ( Bag, isEmptyBag, bagToList )
-import FiniteMap       ( FiniteMap, emptyFM, addListToFM_C,
-                         plusFM_C, keysFM, lookupWithDefaultFM
+IMP_Ubiq(){-uitous-}
+
+import CmdLineOpts     ( opt_SpecialiseOverloaded, opt_SpecialiseUnboxed,
+                         opt_SpecialiseAll
+                       )
+import Bag             ( isEmptyBag, bagToList, Bag )
+import Class           ( GenClass{-instance NamedThing-}, SYN_IE(Class),
+                         GenClassOp {- instance NamedThing -} )
+import FiniteMap       ( emptyFM, addListToFM_C, plusFM_C, keysFM,
+                         lookupWithDefaultFM
                        )
-import Id              ( mkSameSpecCon, idType,
-                         isDictFunId, isConstMethodId_maybe,
+import Id              ( idType, isDictFunId, isConstMethodId_maybe,
                          isDefaultMethodId_maybe,
-                         getInstIdModule, Id )
-import Maybes
-import Outputable
-import Pretty
-import Util
+                         GenId {-instance NamedThing -}, SYN_IE(Id)
+                       )
+import Maybes          ( maybeToBool, catMaybes, firstJust )
+import Name            ( OccName, pprOccName, modAndOcc, NamedThing(..) )
+import PprStyle                ( PprStyle(..) )
+import PprType         ( pprGenType, pprParendGenType, pprMaybeTy,
+                         TyCon{-ditto-}, GenType{-ditto-}, GenTyVar, GenClassOp
+                       )
+import Pretty          -- plenty of it
+import TyCon           ( tyConTyVars, TyCon{-instance NamedThing-} )
+import Type            ( splitSigmaTy, mkTyVarTy, mkForAllTys,
+                         getTyVar_maybe, isUnboxedType, SYN_IE(Type)
+                       )
+import TyVar           ( GenTyVar{-instance Eq-}, SYN_IE(TyVar) )
+import Unique          ( Unique{-instance Eq-} )
+import Util            ( equivClasses, zipWithEqual, cmpPString,
+                         assertPanic, panic{-ToDo:rm-}
+                       )
+
+#if __GLASGOW_HASKELL__ >= 202
+import Outputable       ( Outputable(..) )
+#endif
+
+cmpType = panic "SpecUtils.cmpType (ToDo: get rid of)"
+mkSameSpecCon = panic "SpecUtils.mkSameSpecCon (ToDo)"
+getInstIdModule = panic "SpecUtils.getInstIdModule (ToDo)"
+specialiseTy :: Type -> [Maybe Type] -> Int -> Type
+specialiseTy = panic "SpecUtils.specialiseTy (ToDo)"
 \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
-                 -> [Type]             -- Type args
-                 -> [Maybe Type]       -- Nothings replace non-specialised type args
-
-specialiseCallTys True _ _ cvec tys
-  = map Just tys
-specialiseCallTys False spec_unboxed spec_overloading cvec tys
-  = zipWithEqual spec_ty_other cvec tys
+specialiseCallTys :: ConstraintVector  -- Tells which type args are overloaded
+                 -> [Type]             -- Type args
+                 -> [Maybe Type]       -- Nothings replace non-specialised type args
+
+specialiseCallTys cvec tys
+  | opt_SpecialiseAll = map Just tys
+  | otherwise        = zipWithEqual "specialiseCallTys" spec_ty_other cvec tys
   where
-    spec_ty_other c ty | (spec_unboxed && isUnboxedDataType ty)
-                        || (spec_overloading && c)
-                        = Just ty
-                      | otherwise
-                        = Nothing
+    spec_ty_other c ty | (opt_SpecialiseUnboxed && isUnboxedType ty) ||
+                        (opt_SpecialiseOverloaded && c)
+                      = Just ty
+                      | otherwise = Nothing
+
 \end{code}
 
 @getIdOverloading@ grabs the type of an Id, and returns a
@@ -85,29 +108,20 @@ gained by specialising wrt them.
 
 \begin{code}
 getIdOverloading :: Id
-                -> ([TyVarTemplate], [(Class,TyVarTemplate)])
+                -> ([TyVar], [(Class,TyVar)])
 getIdOverloading id
   = (tyvars, tyvar_part_of theta)
   where
     (tyvars, theta, _) = splitSigmaTy (idType id)
 
-    tyvar_part_of []                 = []
-    tyvar_part_of ((clas,ty) : theta) = case getTyVarTemplateMaybe ty of
-                                           Nothing    -> []
-                                           Just tyvar -> (clas, tyvar) : tyvar_part_of theta
+    tyvar_part_of []            = []
+    tyvar_part_of ((c,ty):theta) = case (getTyVar_maybe ty) of
+                                    Nothing -> []
+                                    Just tv -> (c, tv) : 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}
@@ -115,7 +129,7 @@ isUnboxedSpecialisation :: [Maybe Type] -> Bool
 isUnboxedSpecialisation tys
   = any is_unboxed tys
   where
-    is_unboxed (Just ty) = isUnboxedDataType ty
+    is_unboxed (Just ty) = isUnboxedType ty
     is_unboxed Nothing   = False
 \end{code}
 
@@ -129,7 +143,7 @@ specialiseConstrTys :: [Type]
 specialiseConstrTys tys
   = map maybe_unboxed_ty tys
   where
-    maybe_unboxed_ty ty = case isUnboxedDataType ty of
+    maybe_unboxed_ty ty = case isUnboxedType ty of
                            True  -> Just ty
                            False -> Nothing
 \end{code}
@@ -150,19 +164,19 @@ with a list of specialising types. An error message is returned if not.
 \begin{code}
 argTysMatchSpecTys_error :: [Maybe Type]
                         -> [Type]
-                        -> Maybe Pretty
+                        -> Maybe Doc
 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 [pprParendType PprDebug ty | ty <- arg_tys]])
+    else Just (sep [ptext SLIT("Spec and Arg Types Inconsistent:"),
+                     ptext SLIT("spectys="), sep [pprMaybeTy PprDebug ty | ty <- spec_tys],
+                     ptext SLIT("argtys="), sep [pprParendGenType PprDebug ty | ty <- arg_tys]])
   where
     match (Nothing:spec_tys) (arg:arg_tys)
-      = not (isUnboxedDataType arg) &&
+      = not (isUnboxedType arg) &&
        match spec_tys arg_tys
     match (Just spec:spec_tys) (arg:arg_tys)
-      = case (cmpUniType True{-properly-} spec arg) of
+      = case (cmpType True{-properly-} spec arg) of
          EQ_   -> match spec_tys arg_tys
          other -> False
     match [] [] = True
@@ -177,16 +191,16 @@ pprSpecErrs :: FAST_STRING                        -- module name
            -> (Bag (Id,[Maybe Type]))  -- errors
            -> (Bag (Id,[Maybe Type]))  -- warnings
            -> (Bag (TyCon,[Maybe Type]))       -- errors
-           -> Pretty
+           -> Doc
 
 pprSpecErrs this_mod spec_errs spec_warn spec_tyerrs
   | not any_errs && not any_warn
-  = ppNil
+  = empty
 
   | otherwise
-  = ppAboves [
-       ppStr "SPECIALISATION MESSAGES:",
-       ppAboves (map pp_module_specs use_modules)
+  = vcat [
+       ptext SLIT("SPECIALISATION MESSAGES:"),
+       vcat (map pp_module_specs use_modules)
        ]
   where
     any_errs = not (isEmptyBag spec_errs && isEmptyBag spec_tyerrs)
@@ -208,27 +222,26 @@ pprSpecErrs this_mod spec_errs spec_warn spec_tyerrs
       where
        (mod_name, id_name) = get_id_name id
 
+
     get_id_name id
+
+{- Don't understand this -- and looks TURGID.  SLPJ 4 Nov 96 
       | 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
+           use_mod = get_mod
        in (use_mod, _NIL_)
 
       | otherwise
-      = getOrigName id
+-}
+      = modAndOcc 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)
+       (mod_name, ty_name) = modAndOcc ty
 
     module_names    = concat [keysFM idspecs_fm, keysFM tyspecs_fm]
     mods            = map head (equivClasses _CMP_STRING_ module_names)
@@ -239,106 +252,94 @@ pprSpecErrs this_mod spec_errs spec_warn spec_tyerrs
                            EQ_   -> ([_NIL_], tail mods)
                            other -> ([], mods)
 
-    (prels, others) = partition from_prelude known
-    use_modules     = unks ++ prels ++ others
+    use_modules     = unks ++ known
 
-    pp_module_specs :: FAST_STRING -> Pretty
+    pp_module_specs :: FAST_STRING -> Doc
     pp_module_specs mod
       | mod == _NIL_
       = ASSERT (null mod_tyspecs)
-       ppAboves (map (pp_idspec ty_sty (ppStr "UNKNOWN:")) mod_idspecs)
+       vcat (map (pp_idspec ty_sty (ptext SLIT("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)
+      = vcat [
+           vcat (map (pp_tyspec ty_sty (pp_module mod)) mod_tyspecs),
+           vcat (map (pp_idspec ty_sty (pp_module mod)) mod_idspecs)
            ]
 
       | otherwise
-      = ppNil
+      = empty
 
       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 "SpecUtils:PprInterface:sw_chkr")
+       ty_sty = PprInterface
 
 pp_module mod
-  = ppBesides [ppPStr mod, ppStr ":"]
+  = hcat [ptext mod, char ':']
 
-pp_tyspec :: PprStyle -> Pretty -> (FAST_STRING, TyCon, [Maybe Type]) -> Pretty
+pp_tyspec :: PprStyle -> Doc -> (OccName, TyCon, [Maybe Type]) -> Doc
 
 pp_tyspec sty pp_mod (_, tycon, tys)
-  = ppCat [pp_mod,
-          ppStr "{-# SPECIALIZE", ppStr "data",
-          pprNonOp PprForUser tycon, ppCat (map (pprParendType sty) spec_tys),
-          ppStr "#-}", ppStr "{- Essential -}"
+  = hsep [pp_mod,
+          text "{-# SPECIALIZE data",
+          ppr PprForUser tycon, hsep (map (pprParendGenType sty) spec_tys),
+          text "-} {- Essential -}"
           ]
   where
-    tvs = getTyConTyVarTemplates tycon
+    tvs = tyConTyVars tycon
     (spec_args, tv_maybes) = unzip (map choose_ty (tvs `zip` tys))
-    spec_tys = map (mkForallTy (catMaybes tv_maybes)) spec_args
+    spec_tys = map (mkForAllTys (catMaybes tv_maybes)) spec_args
 
-    choose_ty (tv, Nothing) = (mkTyVarTemplateTy tv, Just tv)
+    choose_ty (tv, Nothing) = (mkTyVarTy tv, Just tv)
     choose_ty (tv, Just ty) = (ty, Nothing)
 
-pp_idspec :: PprStyle -> Pretty -> (FAST_STRING, Id, [Maybe Type], Bool) -> Pretty
+pp_idspec :: PprStyle -> Doc -> (OccName, Id, [Maybe Type], Bool) -> Doc
 
 pp_idspec sty pp_mod (_, id, tys, is_err)
   | isDictFunId id
-  = ppCat [pp_mod,
-          ppStr "{-# SPECIALIZE",
-          ppStr "instance",
-          pprType sty spec_ty,
-          ppStr "#-}", pp_essential ]
+  = hsep [pp_mod,
+          text "{-# SPECIALIZE instance",
+          pprGenType sty spec_ty,
+          text "#-}", 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 "::",
-          pprType sty spec_ty,
-          ppStr "#-} {- IN instance",
-          ppPStr cls_str, pprParendType sty clsty,
-          ppStr "-}", pp_essential ]
+    hsep [pp_mod,
+          text "{-# SPECIALIZE",
+          ppr sty clsop, text "::",
+          pprGenType sty spec_ty,
+          text "#-} {- IN instance",
+          pprOccName sty (getOccName cls), pprParendGenType sty clsty,
+          text "-}", 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 "::",
-          pprType sty spec_ty,
-          ppStr "-}", pp_essential ]
+    hsep [pp_mod,
+          text "{- instance",
+          pprOccName sty (getOccName cls),
+          ptext SLIT("EXPLICIT METHOD REQUIRED"),
+          ppr sty clsop, text "::",
+          pprGenType sty spec_ty,
+          text "-}", pp_essential ]
 
   | otherwise
-  = ppCat [pp_mod,
-          ppStr "{-# SPECIALIZE",
-          pprNonOp PprForUser id, ppStr "::",
-          pprType sty spec_ty,
-          ppStr "#-}", pp_essential ]
+  = hsep [pp_mod,
+          text "{-# SPECIALIZE",
+          ppr PprForUser id, ptext SLIT("::"),
+          pprGenType sty spec_ty,
+          text "#-}", pp_essential ]
   where
     spec_ty = specialiseTy (idType id) tys 100   -- HACK to drop all dicts!!!
-    pp_essential = if is_err then ppStr "{- Essential -}" else ppNil
+    pp_essential = if is_err then text "{- Essential -}" else empty
 
     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}