[project @ 1999-05-26 14:12:07 by simonmar]
[ghc-hetmet.git] / ghc / compiler / basicTypes / Id.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 %
4 \section[Id]{@Ids@: Value and constructor identifiers}
5
6 \begin{code}
7 module Id (
8         Id, DictId,
9
10         -- Simple construction
11         mkId, mkVanillaId, mkSysLocal, mkUserLocal,
12         mkTemplateLocals, mkWildId, mkTemplateLocal,
13
14         -- Taking an Id apart
15         idName, idType, idUnique, idInfo,
16         idPrimRep, isId,
17         recordSelectorFieldLabel,
18
19         -- Modifying an Id
20         setIdName, setIdUnique, setIdType, setIdNoDiscard, 
21         setIdInfo, modifyIdInfo, maybeModifyIdInfo,
22
23         -- Predicates
24         omitIfaceSigForId,
25         externallyVisibleId,
26         idFreeTyVars, 
27
28         -- Inline pragma stuff
29         getInlinePragma, setInlinePragma, modifyInlinePragma, 
30         idMustBeINLINEd, idMustNotBeINLINEd,
31
32         isSpecPragmaId, isRecordSelector,
33         isPrimitiveId_maybe, isDataConId_maybe,
34         isConstantId, isBottomingId, idAppIsBottom,
35         isExportedId, isUserExportedId,
36
37         -- One shot lambda stuff
38         isOneShotLambda, setOneShotLambda,
39
40         -- IdInfo stuff
41         setIdUnfolding,
42         setIdArity,
43         setIdDemandInfo,
44         setIdStrictness,
45         setIdWorkerInfo,
46         setIdSpecialisation,
47         setIdUpdateInfo,
48         setIdCafInfo,
49         setIdCprInfo,
50
51         getIdArity,
52         getIdDemandInfo,
53         getIdStrictness,
54         getIdWorkerInfo,
55         getIdUnfolding,
56         getIdSpecialisation,
57         getIdUpdateInfo,
58         getIdCafInfo,
59         getIdCprInfo
60
61     ) where
62
63 #include "HsVersions.h"
64
65 import {-# SOURCE #-} CoreUnfold ( Unfolding )
66 import {-# SOURCE #-} CoreSyn    ( CoreRules )
67
68 import Var              ( Id, DictId,
69                           isId, mkIdVar,
70                           idName, idType, idUnique, idInfo,
71                           setIdName, setVarType, setIdUnique, 
72                           setIdInfo, modifyIdInfo, maybeModifyIdInfo,
73                           externallyVisibleId
74                         )
75 import VarSet
76 import Type             ( Type, tyVarsOfType, typePrimRep, addFreeTyVars )
77 import IdInfo
78 import Demand           ( Demand, isStrict, wwLazy )
79 import Name             ( Name, OccName,
80                           mkSysLocalName, mkLocalName,
81                           isWiredInName, isUserExportedName
82                         ) 
83 import Const            ( Con(..) )
84 import PrimRep          ( PrimRep )
85 import PrimOp           ( PrimOp )
86 import FieldLabel       ( FieldLabel(..) )
87 import SrcLoc           ( SrcLoc )
88 import Unique           ( Unique, mkBuiltinUnique, getBuiltinUniques )
89 import Outputable
90
91 infixl  1 `setIdUnfolding`,
92           `setIdArity`,
93           `setIdDemandInfo`,
94           `setIdStrictness`,
95           `setIdWorkerInfo`,
96           `setIdSpecialisation`,
97           `setIdUpdateInfo`,
98           `setInlinePragma`,
99           `getIdCafInfo`,
100           `getIdCprInfo`
101
102         -- infixl so you can say (id `set` a `set` b)
103 \end{code}
104
105
106
107 %************************************************************************
108 %*                                                                      *
109 \subsection{Simple Id construction}
110 %*                                                                      *
111 %************************************************************************
112
113 Absolutely all Ids are made by mkId.  It 
114         a) Pins free-tyvar-info onto the Id's type, 
115            where it can easily be found.
116         b) Ensures that exported Ids are 
117
118 \begin{code}
119 mkId :: Name -> Type -> IdInfo -> Id
120 mkId name ty info = mkIdVar name (addFreeTyVars ty) info'
121                   where
122                     info' | isUserExportedName name = setNoDiscardInfo info
123                           | otherwise               = info
124 \end{code}
125
126 \begin{code}
127 mkVanillaId :: Name -> Type -> Id
128 mkVanillaId name ty = mkId name ty vanillaIdInfo
129
130 -- SysLocal: for an Id being created by the compiler out of thin air...
131 -- UserLocal: an Id with a name the user might recognize...
132 mkUserLocal :: OccName     -> Unique -> Type -> SrcLoc -> Id
133 mkSysLocal  :: FAST_STRING -> Unique -> Type -> Id
134
135 mkSysLocal  fs uniq ty      = mkVanillaId (mkSysLocalName uniq fs)      ty
136 mkUserLocal occ uniq ty loc = mkVanillaId (mkLocalName    uniq occ loc) ty
137 \end{code}
138
139 Make some local @Ids@ for a template @CoreExpr@.  These have bogus
140 @Uniques@, but that's OK because the templates are supposed to be
141 instantiated before use.
142
143 \begin{code}
144 -- "Wild Id" typically used when you need a binder that you don't expect to use
145 mkWildId :: Type -> Id
146 mkWildId ty = mkSysLocal SLIT("wild") (mkBuiltinUnique 1) ty
147
148 -- "Template locals" typically used in unfoldings
149 mkTemplateLocals :: [Type] -> [Id]
150 mkTemplateLocals tys = zipWith (mkSysLocal SLIT("tpl"))
151                                (getBuiltinUniques (length tys))
152                                tys
153
154 mkTemplateLocal :: Int -> Type -> Id
155 mkTemplateLocal i ty = mkSysLocal SLIT("tpl") (mkBuiltinUnique i) ty
156 \end{code}
157
158
159 %************************************************************************
160 %*                                                                      *
161 \subsection[Id-general-funs]{General @Id@-related functions}
162 %*                                                                      *
163 %************************************************************************
164
165 \begin{code}
166 idFreeTyVars :: Id -> TyVarSet
167 idFreeTyVars id = tyVarsOfType (idType id)
168
169 setIdType :: Id -> Type -> Id
170         -- Add free tyvar info to the type
171 setIdType id ty = setVarType id (addFreeTyVars ty)
172
173 idPrimRep :: Id -> PrimRep
174 idPrimRep id = typePrimRep (idType id)
175 \end{code}
176
177
178 %************************************************************************
179 %*                                                                      *
180 \subsection{Special Ids}
181 %*                                                                      *
182 %************************************************************************
183
184 \begin{code}
185 idFlavour :: Id -> IdFlavour
186 idFlavour id = flavourInfo (idInfo id)
187
188 setIdNoDiscard :: Id -> Id
189 setIdNoDiscard id       -- Make an Id into a NoDiscardId, unless it is already
190   = modifyIdInfo setNoDiscardInfo id
191
192 recordSelectorFieldLabel :: Id -> FieldLabel
193 recordSelectorFieldLabel id = case idFlavour id of
194                                 RecordSelId lbl -> lbl
195
196 isRecordSelector id = case idFlavour id of
197                         RecordSelId lbl -> True
198                         other           -> False
199
200 isPrimitiveId_maybe id = case idFlavour id of
201                             ConstantId (PrimOp op) -> Just op
202                             other                  -> Nothing
203
204 isDataConId_maybe id = case idFlavour id of
205                           ConstantId (DataCon con) -> Just con
206                           other                    -> Nothing
207
208 isConstantId id = case idFlavour id of
209                     ConstantId _ -> True
210                     other        -> False
211
212 isSpecPragmaId id = case idFlavour id of
213                         SpecPragmaId -> True
214                         other        -> False
215
216 -- Don't drop a binding for an exported Id,
217 -- if it otherwise looks dead.  
218 isExportedId :: Id -> Bool
219 isExportedId id = case idFlavour id of
220                         VanillaId -> False
221                         other     -> True       -- All the others are no-discard
222
223 -- Say if an Id was exported by the user
224 -- Implies isExportedId (see mkId above)
225 isUserExportedId :: Id -> Bool
226 isUserExportedId id = isUserExportedName (idName id)
227 \end{code}
228
229
230 omitIfaceSigForId tells whether an Id's info is implied by other declarations,
231 so we don't need to put its signature in an interface file, even if it's mentioned
232 in some other interface unfolding.
233
234 \begin{code}
235 omitIfaceSigForId :: Id -> Bool
236 omitIfaceSigForId id
237   | isWiredInName (idName id)
238   = True
239
240   | otherwise
241   = case idFlavour id of
242         RecordSelId _  -> True  -- Includes dictionary selectors
243         ConstantId _   -> True
244                 -- ConstantIds are implied by their type or class decl;
245                 -- remember that all type and class decls appear in the interface file.
246                 -- The dfun id must *not* be omitted, because it carries version info for
247                 -- the instance decl
248
249         other          -> False -- Don't omit!
250 \end{code}
251
252
253
254 %************************************************************************
255 %*                                                                      *
256 \subsection{IdInfo stuff}
257 %*                                                                      *
258 %************************************************************************
259
260 \begin{code}
261         ---------------------------------
262         -- ARITY
263 getIdArity :: Id -> ArityInfo
264 getIdArity id = arityInfo (idInfo id)
265
266 setIdArity :: Id -> ArityInfo -> Id
267 setIdArity id arity = modifyIdInfo (`setArityInfo` arity) id
268
269         ---------------------------------
270         -- STRICTNESS
271 getIdStrictness :: Id -> StrictnessInfo
272 getIdStrictness id = strictnessInfo (idInfo id)
273
274 setIdStrictness :: Id -> StrictnessInfo -> Id
275 setIdStrictness id strict_info = modifyIdInfo (`setStrictnessInfo` strict_info) id
276
277 -- isBottomingId returns true if an application to n args would diverge
278 isBottomingId :: Id -> Bool
279 isBottomingId id = isBottomingStrictness (strictnessInfo (idInfo id))
280
281 idAppIsBottom :: Id -> Int -> Bool
282 idAppIsBottom id n = appIsBottom (strictnessInfo (idInfo id)) n
283
284         ---------------------------------
285         -- WORKER ID
286 getIdWorkerInfo :: Id -> WorkerInfo
287 getIdWorkerInfo id = workerInfo (idInfo id)
288
289 setIdWorkerInfo :: Id -> WorkerInfo -> Id
290 setIdWorkerInfo id work_info = modifyIdInfo (`setWorkerInfo` work_info) id
291
292         ---------------------------------
293         -- UNFOLDING
294 getIdUnfolding :: Id -> Unfolding
295 getIdUnfolding id = unfoldingInfo (idInfo id)
296
297 setIdUnfolding :: Id -> Unfolding -> Id
298 setIdUnfolding id unfolding = modifyIdInfo (`setUnfoldingInfo` unfolding) id
299
300         ---------------------------------
301         -- DEMAND
302 getIdDemandInfo :: Id -> Demand
303 getIdDemandInfo id = demandInfo (idInfo id)
304
305 setIdDemandInfo :: Id -> Demand -> Id
306 setIdDemandInfo id demand_info = modifyIdInfo (`setDemandInfo` demand_info) id
307
308         ---------------------------------
309         -- UPDATE INFO
310 getIdUpdateInfo :: Id -> UpdateInfo
311 getIdUpdateInfo id = updateInfo (idInfo id)
312
313 setIdUpdateInfo :: Id -> UpdateInfo -> Id
314 setIdUpdateInfo id upd_info = modifyIdInfo (`setUpdateInfo` upd_info) id
315
316         ---------------------------------
317         -- SPECIALISATION
318 getIdSpecialisation :: Id -> CoreRules
319 getIdSpecialisation id = specInfo (idInfo id)
320
321 setIdSpecialisation :: Id -> CoreRules -> Id
322 setIdSpecialisation id spec_info = modifyIdInfo (`setSpecInfo` spec_info) id
323
324         ---------------------------------
325         -- CAF INFO
326 getIdCafInfo :: Id -> CafInfo
327 getIdCafInfo id = cafInfo (idInfo id)
328
329 setIdCafInfo :: Id -> CafInfo -> Id
330 setIdCafInfo id caf_info = modifyIdInfo (`setCafInfo` caf_info) id
331
332         ---------------------------------
333         -- CPR INFO
334 getIdCprInfo :: Id -> CprInfo
335 getIdCprInfo id = cprInfo (idInfo id)
336
337 setIdCprInfo :: Id -> CprInfo -> Id
338 setIdCprInfo id cpr_info = modifyIdInfo (`setCprInfo` cpr_info) id
339 \end{code}
340
341
342         ---------------------------------
343         -- INLINING
344 The inline pragma tells us to be very keen to inline this Id, but it's still
345 OK not to if optimisation is switched off.
346
347 \begin{code}
348 getInlinePragma :: Id -> InlinePragInfo
349 getInlinePragma id = inlinePragInfo (idInfo id)
350
351 setInlinePragma :: Id -> InlinePragInfo -> Id
352 setInlinePragma id prag = modifyIdInfo (`setInlinePragInfo` prag) id
353
354 modifyInlinePragma :: Id -> (InlinePragInfo -> InlinePragInfo) -> Id
355 modifyInlinePragma id fn = modifyIdInfo (\info -> info `setInlinePragInfo` (fn (inlinePragInfo info))) id
356
357 idMustNotBeINLINEd id = case getInlinePragma id of
358                           IMustNotBeINLINEd -> True
359                           IAmALoopBreaker   -> True
360                           other             -> False
361
362 idMustBeINLINEd id =  case getInlinePragma id of
363                         IMustBeINLINEd -> True
364                         other          -> False
365 \end{code}
366
367
368         ---------------------------------
369         -- ONE-SHOT LAMBDAS
370 \begin{code}
371 isOneShotLambda :: Id -> Bool
372 isOneShotLambda id = case lbvarInfo (idInfo id) of
373                         IsOneShotLambda -> True
374                         NoLBVarInfo     -> False
375
376 setOneShotLambda :: Id -> Id
377 setOneShotLambda id = modifyIdInfo (`setLBVarInfo` IsOneShotLambda) id
378 \end{code}