[project @ 1996-07-19 18:36:04 by partain]
[ghc-hetmet.git] / ghc / compiler / specialise / SpecEnv.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1993-1996
3 %
4 \section[SpecEnv]{Specialisation info about an @Id@}
5
6 \begin{code}
7 #include "HsVersions.h"
8
9 module SpecEnv (
10         SYN_IE(SpecEnv), MatchEnv,
11         nullSpecEnv, isNullSpecEnv,
12         addOneToSpecEnv, lookupSpecEnv
13     ) where
14
15 IMP_Ubiq()
16
17 import MatchEnv
18 import Type             ( matchTys, isTyVarTy )
19 import Usage            ( SYN_IE(UVar) )
20 import OccurAnal        ( occurAnalyseGlobalExpr )
21 import CoreSyn          ( SYN_IE(CoreExpr), SYN_IE(SimplifiableCoreExpr) )
22 import Maybes           ( MaybeErr(..) )
23 --import PprStyle--ToDo:rm
24 --import Util(pprTrace)--ToDo:rm
25 --import Outputable--ToDo:rm
26 --import PprType--ToDo:rm
27 --import Pretty--ToDo:rm
28 --import PprCore--ToDo:rm
29 --import Id--ToDo:rm
30 --import TyVar--ToDo:rm
31 --import Unique--ToDo:rm
32 --import IdInfo--ToDo:rm
33 --import PprEnv--ToDo:rm
34 \end{code}
35
36
37 A @SpecEnv@ holds details of an @Id@'s specialisations.  It should be
38 a newtype (ToDo), but for 1.2 compatibility we make it a data type.
39 It can't be a synonym because there's an IdInfo instance of it
40 that doesn't work if it's (MatchEnv a b).
41 Furthermore, making it a data type makes it easier to break the IdInfo loop.
42
43 \begin{code}
44 data SpecEnv = SpecEnv (MatchEnv [Type] SimplifiableCoreExpr)
45 \end{code}
46
47 For example, if \tr{f}'s @SpecEnv@ contains the mapping:
48 \begin{verbatim}
49         [List a, b]  ===>  (\d -> f' a b)
50 \end{verbatim}
51 then
52 \begin{verbatim}
53         f (List Int) Bool d  ===>  f' Int Bool
54 \end{verbatim}
55 All the stuff about how many dictionaries to discard, and what types
56 to apply the specialised function to, are handled by the fact that the
57 SpecEnv contains a template for the result of the specialisation.
58
59 There is one more exciting case, which is dealt with in exactly the same
60 way.  If the specialised value is unboxed then it is lifted at its
61 definition site and unlifted at its uses.  For example:
62
63         pi :: forall a. Num a => a
64
65 might have a specialisation
66
67         [Int#] ===>  (case pi' of Lift pi# -> pi#)
68
69 where pi' :: Lift Int# is the specialised version of pi.
70
71
72 \begin{code}
73 nullSpecEnv :: SpecEnv
74 nullSpecEnv = SpecEnv nullMEnv
75
76 isNullSpecEnv :: SpecEnv -> Bool
77 isNullSpecEnv (SpecEnv env) = null (mEnvToList env)
78
79 addOneToSpecEnv :: SpecEnv -> [Type] -> CoreExpr -> MaybeErr SpecEnv ([Type], SimplifiableCoreExpr)
80 addOneToSpecEnv (SpecEnv env) tys rhs 
81   = --pprTrace "addOneToSpecEnv" (ppAbove (ppr PprDebug tys) (ppr PprDebug rhs)) $
82     case (insertMEnv matchTys env tys (occurAnalyseGlobalExpr rhs)) of
83         Succeeded menv -> Succeeded (SpecEnv menv)
84         Failed err     -> Failed err
85
86 lookupSpecEnv :: SpecEnv -> [Type] -> Maybe (SimplifiableCoreExpr, ([(TyVar,Type)], [Type]))
87 lookupSpecEnv (SpecEnv env) tys 
88   | all isTyVarTy tys = Nothing -- Short cut: no specialisation for simple tyvars
89   | otherwise         = --pprTrace "lookupSpecEnv" (ppr PprDebug tys) $
90                         lookupMEnv matchTys env tys
91 \end{code}