44f6fd2ecbf21b86adb46f9c474885bd941dd194
[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 TyVar --ToDo:rm
24 \end{code}
25
26
27 A @SpecEnv@ holds details of an @Id@'s specialisations.  It should be
28 a newtype (ToDo), but for 1.2 compatibility we make it a data type.
29 It can't be a synonym because there's an IdInfo instance of it
30 that doesn't work if it's (MatchEnv a b).
31 Furthermore, making it a data type makes it easier to break the IdInfo loop.
32
33 \begin{code}
34 data SpecEnv = SpecEnv (MatchEnv [Type] SimplifiableCoreExpr)
35 \end{code}
36
37 For example, if \tr{f}'s @SpecEnv@ contains the mapping:
38 \begin{verbatim}
39         [List a, b]  ===>  (\d -> f' a b)
40 \end{verbatim}
41 then when we find an application of f to matching types, we simply replace
42 it by the matching RHS:
43 \begin{verbatim}
44         f (List Int) Bool ===>  (\d -> f' Int Bool)
45 \end{verbatim}
46 All the stuff about how many dictionaries to discard, and what types
47 to apply the specialised function to, are handled by the fact that the
48 SpecEnv contains a template for the result of the specialisation.
49
50 There is one more exciting case, which is dealt with in exactly the same
51 way.  If the specialised value is unboxed then it is lifted at its
52 definition site and unlifted at its uses.  For example:
53
54         pi :: forall a. Num a => a
55
56 might have a specialisation
57
58         [Int#] ===>  (case pi' of Lift pi# -> pi#)
59
60 where pi' :: Lift Int# is the specialised version of pi.
61
62
63 \begin{code}
64 nullSpecEnv :: SpecEnv
65 nullSpecEnv = SpecEnv nullMEnv
66
67 isNullSpecEnv :: SpecEnv -> Bool
68 isNullSpecEnv (SpecEnv env) = null (mEnvToList env)
69
70 addOneToSpecEnv :: SpecEnv -> [Type] -> CoreExpr -> MaybeErr SpecEnv ([Type], SimplifiableCoreExpr)
71 addOneToSpecEnv (SpecEnv env) tys rhs 
72   = --pprTrace "addOneToSpecEnv" (($$) (ppr PprDebug tys) (ppr PprDebug rhs)) $
73     case (insertMEnv matchTys env tys (occurAnalyseGlobalExpr rhs)) of
74         Succeeded menv -> Succeeded (SpecEnv menv)
75         Failed err     -> Failed err
76
77 lookupSpecEnv :: SpecEnv -> [Type] -> Maybe (SimplifiableCoreExpr, ([(TyVar,Type)], [Type]))
78 lookupSpecEnv (SpecEnv env) tys 
79   | all isTyVarTy tys = Nothing -- Short cut: no specialisation for simple tyvars
80   | otherwise         = --pprTrace "lookupSpecEnv" (ppr PprDebug tys) $
81                         lookupMEnv matchTys env tys
82 \end{code}
83
84