2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 \section[Id]{@Ids@: Value and constructor identifiers}
10 -- Simple construction
11 mkId, mkVanillaId, mkSysLocal, mkUserLocal,
12 mkTemplateLocals, mkWildId, mkTemplateLocal,
15 idName, idType, idUnique, idInfo,
17 recordSelectorFieldLabel,
20 setIdName, setIdUnique, setIdType, setIdNoDiscard,
21 setIdInfo, modifyIdInfo, maybeModifyIdInfo,
28 -- Inline pragma stuff
29 getInlinePragma, setInlinePragma, modifyInlinePragma,
30 idMustBeINLINEd, idMustNotBeINLINEd,
32 isSpecPragmaId, isRecordSelector,
33 isPrimitiveId_maybe, isDataConId_maybe,
34 isConstantId, isBottomingId, idAppIsBottom,
35 isExportedId, isUserExportedId,
37 -- One shot lambda stuff
38 isOneShotLambda, setOneShotLambda,
63 #include "HsVersions.h"
65 import {-# SOURCE #-} CoreUnfold ( Unfolding )
66 import {-# SOURCE #-} CoreSyn ( CoreRules )
68 import Var ( Id, DictId,
70 idName, idType, idUnique, idInfo,
71 setIdName, setVarType, setIdUnique,
72 setIdInfo, modifyIdInfo, maybeModifyIdInfo,
76 import Type ( Type, tyVarsOfType, typePrimRep, addFreeTyVars )
78 import Demand ( Demand, isStrict, wwLazy )
79 import Name ( Name, OccName,
80 mkSysLocalName, mkLocalName,
81 isWiredInName, isUserExportedName
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 )
91 infixl 1 `setIdUnfolding`,
96 `setIdSpecialisation`,
102 -- infixl so you can say (id `set` a `set` b)
107 %************************************************************************
109 \subsection{Simple Id construction}
111 %************************************************************************
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
119 mkId :: Name -> Type -> IdInfo -> Id
120 mkId name ty info = mkIdVar name (addFreeTyVars ty) info'
122 info' | isUserExportedName name = setNoDiscardInfo info
127 mkVanillaId :: Name -> Type -> Id
128 mkVanillaId name ty = mkId name ty vanillaIdInfo
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
135 mkSysLocal fs uniq ty = mkVanillaId (mkSysLocalName uniq fs) ty
136 mkUserLocal occ uniq ty loc = mkVanillaId (mkLocalName uniq occ loc) ty
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.
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
148 -- "Template locals" typically used in unfoldings
149 mkTemplateLocals :: [Type] -> [Id]
150 mkTemplateLocals tys = zipWith (mkSysLocal SLIT("tpl"))
151 (getBuiltinUniques (length tys))
154 mkTemplateLocal :: Int -> Type -> Id
155 mkTemplateLocal i ty = mkSysLocal SLIT("tpl") (mkBuiltinUnique i) ty
159 %************************************************************************
161 \subsection[Id-general-funs]{General @Id@-related functions}
163 %************************************************************************
166 idFreeTyVars :: Id -> TyVarSet
167 idFreeTyVars id = tyVarsOfType (idType id)
169 setIdType :: Id -> Type -> Id
170 -- Add free tyvar info to the type
171 setIdType id ty = setVarType id (addFreeTyVars ty)
173 idPrimRep :: Id -> PrimRep
174 idPrimRep id = typePrimRep (idType id)
178 %************************************************************************
180 \subsection{Special Ids}
182 %************************************************************************
185 idFlavour :: Id -> IdFlavour
186 idFlavour id = flavourInfo (idInfo id)
188 setIdNoDiscard :: Id -> Id
189 setIdNoDiscard id -- Make an Id into a NoDiscardId, unless it is already
190 = modifyIdInfo setNoDiscardInfo id
192 recordSelectorFieldLabel :: Id -> FieldLabel
193 recordSelectorFieldLabel id = case idFlavour id of
194 RecordSelId lbl -> lbl
196 isRecordSelector id = case idFlavour id of
197 RecordSelId lbl -> True
200 isPrimitiveId_maybe id = case idFlavour id of
201 ConstantId (PrimOp op) -> Just op
204 isDataConId_maybe id = case idFlavour id of
205 ConstantId (DataCon con) -> Just con
208 isConstantId id = case idFlavour id of
212 isSpecPragmaId id = case idFlavour id of
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
221 other -> True -- All the others are no-discard
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)
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.
235 omitIfaceSigForId :: Id -> Bool
237 | isWiredInName (idName id)
241 = case idFlavour id of
242 RecordSelId _ -> True -- Includes dictionary selectors
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
249 other -> False -- Don't omit!
254 %************************************************************************
256 \subsection{IdInfo stuff}
258 %************************************************************************
261 ---------------------------------
263 getIdArity :: Id -> ArityInfo
264 getIdArity id = arityInfo (idInfo id)
266 setIdArity :: Id -> ArityInfo -> Id
267 setIdArity id arity = modifyIdInfo (`setArityInfo` arity) id
269 ---------------------------------
271 getIdStrictness :: Id -> StrictnessInfo
272 getIdStrictness id = strictnessInfo (idInfo id)
274 setIdStrictness :: Id -> StrictnessInfo -> Id
275 setIdStrictness id strict_info = modifyIdInfo (`setStrictnessInfo` strict_info) id
277 -- isBottomingId returns true if an application to n args would diverge
278 isBottomingId :: Id -> Bool
279 isBottomingId id = isBottomingStrictness (strictnessInfo (idInfo id))
281 idAppIsBottom :: Id -> Int -> Bool
282 idAppIsBottom id n = appIsBottom (strictnessInfo (idInfo id)) n
284 ---------------------------------
286 getIdWorkerInfo :: Id -> WorkerInfo
287 getIdWorkerInfo id = workerInfo (idInfo id)
289 setIdWorkerInfo :: Id -> WorkerInfo -> Id
290 setIdWorkerInfo id work_info = modifyIdInfo (`setWorkerInfo` work_info) id
292 ---------------------------------
294 getIdUnfolding :: Id -> Unfolding
295 getIdUnfolding id = unfoldingInfo (idInfo id)
297 setIdUnfolding :: Id -> Unfolding -> Id
298 setIdUnfolding id unfolding = modifyIdInfo (`setUnfoldingInfo` unfolding) id
300 ---------------------------------
302 getIdDemandInfo :: Id -> Demand
303 getIdDemandInfo id = demandInfo (idInfo id)
305 setIdDemandInfo :: Id -> Demand -> Id
306 setIdDemandInfo id demand_info = modifyIdInfo (`setDemandInfo` demand_info) id
308 ---------------------------------
310 getIdUpdateInfo :: Id -> UpdateInfo
311 getIdUpdateInfo id = updateInfo (idInfo id)
313 setIdUpdateInfo :: Id -> UpdateInfo -> Id
314 setIdUpdateInfo id upd_info = modifyIdInfo (`setUpdateInfo` upd_info) id
316 ---------------------------------
318 getIdSpecialisation :: Id -> CoreRules
319 getIdSpecialisation id = specInfo (idInfo id)
321 setIdSpecialisation :: Id -> CoreRules -> Id
322 setIdSpecialisation id spec_info = modifyIdInfo (`setSpecInfo` spec_info) id
324 ---------------------------------
326 getIdCafInfo :: Id -> CafInfo
327 getIdCafInfo id = cafInfo (idInfo id)
329 setIdCafInfo :: Id -> CafInfo -> Id
330 setIdCafInfo id caf_info = modifyIdInfo (`setCafInfo` caf_info) id
332 ---------------------------------
334 getIdCprInfo :: Id -> CprInfo
335 getIdCprInfo id = cprInfo (idInfo id)
337 setIdCprInfo :: Id -> CprInfo -> Id
338 setIdCprInfo id cpr_info = modifyIdInfo (`setCprInfo` cpr_info) id
342 ---------------------------------
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.
348 getInlinePragma :: Id -> InlinePragInfo
349 getInlinePragma id = inlinePragInfo (idInfo id)
351 setInlinePragma :: Id -> InlinePragInfo -> Id
352 setInlinePragma id prag = modifyIdInfo (`setInlinePragInfo` prag) id
354 modifyInlinePragma :: Id -> (InlinePragInfo -> InlinePragInfo) -> Id
355 modifyInlinePragma id fn = modifyIdInfo (\info -> info `setInlinePragInfo` (fn (inlinePragInfo info))) id
357 idMustNotBeINLINEd id = case getInlinePragma id of
358 IMustNotBeINLINEd -> True
359 IAmALoopBreaker -> True
362 idMustBeINLINEd id = case getInlinePragma id of
363 IMustBeINLINEd -> True
368 ---------------------------------
371 isOneShotLambda :: Id -> Bool
372 isOneShotLambda id = case lbvarInfo (idInfo id) of
373 IsOneShotLambda -> True
376 setOneShotLambda :: Id -> Id
377 setOneShotLambda id = modifyIdInfo (`setLBVarInfo` IsOneShotLambda) id