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