[project @ 1997-03-14 07:52:06 by simonpj]
[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 when we find an application of f to matching types, we simply replace
52 it by the matching RHS:
53 \begin{verbatim}
54         f (List Int) Bool ===>  (\d -> f' Int Bool)
55 \end{verbatim}
56 All the stuff about how many dictionaries to discard, and what types
57 to apply the specialised function to, are handled by the fact that the
58 SpecEnv contains a template for the result of the specialisation.
59
60 There is one more exciting case, which is dealt with in exactly the same
61 way.  If the specialised value is unboxed then it is lifted at its
62 definition site and unlifted at its uses.  For example:
63
64         pi :: forall a. Num a => a
65
66 might have a specialisation
67
68         [Int#] ===>  (case pi' of Lift pi# -> pi#)
69
70 where pi' :: Lift Int# is the specialised version of pi.
71
72
73 \begin{code}
74 nullSpecEnv :: SpecEnv
75 nullSpecEnv = SpecEnv nullMEnv
76
77 isNullSpecEnv :: SpecEnv -> Bool
78 isNullSpecEnv (SpecEnv env) = null (mEnvToList env)
79
80 addOneToSpecEnv :: SpecEnv -> [Type] -> CoreExpr -> MaybeErr SpecEnv ([Type], SimplifiableCoreExpr)
81 addOneToSpecEnv (SpecEnv env) tys rhs 
82   = --pprTrace "addOneToSpecEnv" (ppAbove (ppr PprDebug tys) (ppr PprDebug rhs)) $
83     case (insertMEnv matchTys env tys (occurAnalyseGlobalExpr rhs)) of
84         Succeeded menv -> Succeeded (SpecEnv menv)
85         Failed err     -> Failed err
86
87 lookupSpecEnv :: SpecEnv -> [Type] -> Maybe (SimplifiableCoreExpr, ([(TyVar,Type)], [Type]))
88 lookupSpecEnv (SpecEnv env) tys 
89   | all isTyVarTy tys = Nothing -- Short cut: no specialisation for simple tyvars
90   | otherwise         = --pprTrace "lookupSpecEnv" (ppr PprDebug tys) $
91                         lookupMEnv matchTys env tys
92 \end{code}
93
94