Id.lhs 9.94 KB
Newer Older
1 2
%
% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 4 5 6
%
\section[Id]{@Ids@: Value and constructor identifiers}

\begin{code}
7
module Id (
8
	Id, DictId,
9

10
	-- Simple construction
11 12
	mkId, mkVanillaId, mkSysLocal, mkUserLocal,
	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 21
	setIdName, setIdUnique, setIdType, setIdNoDiscard, 
	setIdInfo, modifyIdInfo, maybeModifyIdInfo,
22 23

	-- Predicates
24
	omitIfaceSigForId,
25
	externallyVisibleId,
26 27 28 29
	idFreeTyVars, 

	-- Inline pragma stuff
	getInlinePragma, setInlinePragma, modifyInlinePragma, 
30
	idMustBeINLINEd, idMustNotBeINLINEd,
31

32
	isSpecPragmaId,	isRecordSelector,
33
	isPrimitiveId_maybe, isDataConId_maybe,
34 35
	isConstantId, isBottomingId, idAppIsBottom,
	isExportedId, isUserExportedId,
36 37 38 39 40 41

	-- IdInfo stuff
	setIdUnfolding,
	setIdArity,
	setIdDemandInfo,
	setIdStrictness,
42
	setIdWorkerInfo,
43 44 45
	setIdSpecialisation,
	setIdUpdateInfo,
	setIdCafInfo,
46
	setIdCprInfo,
47

48 49 50
	getIdArity,
	getIdDemandInfo,
	getIdStrictness,
51
	getIdWorkerInfo,
52
	getIdUnfolding,
53
	getIdSpecialisation,
54
	getIdUpdateInfo,
55 56
	getIdCafInfo,
	getIdCprInfo
57

58
    ) where
59

60
#include "HsVersions.h"
sof's avatar
sof committed
61

sof's avatar
sof committed
62
import {-# SOURCE #-} CoreUnfold ( Unfolding )
63
import {-# SOURCE #-} CoreSyn    ( CoreRules )
sof's avatar
sof committed
64

65 66 67 68 69
import Var		( Id, DictId,
			  isId, mkIdVar,
			  idName, idType, idUnique, idInfo,
			  setIdName, setVarType, setIdUnique, 
			  setIdInfo, modifyIdInfo, maybeModifyIdInfo,
70 71 72
			  externallyVisibleId
			)
import VarSet
73
import Type		( Type, tyVarsOfType, typePrimRep, addFreeTyVars )
74
import IdInfo
75
import Demand		( Demand, isStrict, wwLazy )
sof's avatar
sof committed
76
import Name	 	( Name, OccName,
77
			  mkSysLocalName, mkLocalName,
78
			  isWiredInName, isUserExportedName
sof's avatar
sof committed
79
			) 
80 81
import Const		( Con(..) )
import PrimRep		( PrimRep )
82
import PrimOp		( PrimOp )
83
import FieldLabel	( FieldLabel(..) )
84
import SrcLoc		( SrcLoc )
85
import Unique		( Unique, mkBuiltinUnique, getBuiltinUniques )
86
import Outputable
87

88 89 90 91
infixl 	1 `setIdUnfolding`,
	  `setIdArity`,
	  `setIdDemandInfo`,
	  `setIdStrictness`,
92
	  `setIdWorkerInfo`,
93 94
	  `setIdSpecialisation`,
	  `setIdUpdateInfo`,
95 96 97 98
	  `setInlinePragma`,
	  `getIdCafInfo`,
	  `getIdCprInfo`

99
	-- infixl so you can say (id `set` a `set` b)
100 101 102
\end{code}


103

104 105
%************************************************************************
%*									*
106
\subsection{Simple Id construction}
107 108 109
%*									*
%************************************************************************

110 111 112 113
Absolutely all Ids are made by mkId.  It 
	a) Pins free-tyvar-info onto the Id's type, 
	   where it can easily be found.
	b) Ensures that exported Ids are 
114

115 116 117 118 119 120 121
\begin{code}
mkId :: Name -> Type -> IdInfo -> Id
mkId name ty info = mkIdVar name (addFreeTyVars ty) info'
		  where
		    info' | isUserExportedName name = setNoDiscardInfo info
			  | otherwise		    = info
\end{code}
122

123 124 125
\begin{code}
mkVanillaId :: Name -> Type -> Id
mkVanillaId name ty = mkId name ty vanillaIdInfo
126 127 128

-- SysLocal: for an Id being created by the compiler out of thin air...
-- UserLocal: an Id with a name the user might recognize...
129
mkUserLocal :: OccName     -> Unique -> Type -> SrcLoc -> Id
130
mkSysLocal  :: FAST_STRING -> Unique -> Type -> Id
131

132 133
mkSysLocal  fs uniq ty      = mkVanillaId (mkSysLocalName uniq fs)      ty
mkUserLocal occ uniq ty loc = mkVanillaId (mkLocalName    uniq occ loc) ty
134
\end{code}
135 136 137 138 139 140

Make some local @Ids@ for a template @CoreExpr@.  These have bogus
@Uniques@, but that's OK because the templates are supposed to be
instantiated before use.

\begin{code}
141 142
-- "Wild Id" typically used when you need a binder that you don't expect to use
mkWildId :: Type -> Id
143
mkWildId ty = mkSysLocal SLIT("wild") (mkBuiltinUnique 1) ty
144 145

-- "Template locals" typically used in unfoldings
146
mkTemplateLocals :: [Type] -> [Id]
147
mkTemplateLocals tys = zipWith (mkSysLocal SLIT("tpl"))
148 149
			       (getBuiltinUniques (length tys))
			       tys
150 151 152

mkTemplateLocal :: Int -> Type -> Id
mkTemplateLocal i ty = mkSysLocal SLIT("tpl") (mkBuiltinUnique i) ty
153 154 155
\end{code}


156 157 158 159 160 161 162
%************************************************************************
%*									*
\subsection[Id-general-funs]{General @Id@-related functions}
%*									*
%************************************************************************

\begin{code}
163
idFreeTyVars :: Id -> TyVarSet
164
idFreeTyVars id = tyVarsOfType (idType id)
165

166
setIdType :: Id -> Type -> Id
167 168
	-- Add free tyvar info to the type
setIdType id ty = setVarType id (addFreeTyVars ty)
sof's avatar
sof committed
169

170 171
idPrimRep :: Id -> PrimRep
idPrimRep id = typePrimRep (idType id)
172 173 174 175 176
\end{code}


%************************************************************************
%*									*
177
\subsection{Special Ids}
178 179 180
%*									*
%************************************************************************

sof's avatar
sof committed
181
\begin{code}
182 183 184 185 186 187 188
idFlavour :: Id -> IdFlavour
idFlavour id = flavourInfo (idInfo id)

setIdNoDiscard :: Id -> Id
setIdNoDiscard id	-- Make an Id into a NoDiscardId, unless it is already
  = modifyIdInfo setNoDiscardInfo id

189
recordSelectorFieldLabel :: Id -> FieldLabel
190
recordSelectorFieldLabel id = case idFlavour id of
191
				RecordSelId lbl -> lbl
sof's avatar
sof committed
192

193
isRecordSelector id = case idFlavour id of
194 195
			RecordSelId lbl -> True
			other	  	-> False
sof's avatar
sof committed
196

197
isPrimitiveId_maybe id = case idFlavour id of
198 199
			    ConstantId (PrimOp op) -> Just op
			    other		   -> Nothing
sof's avatar
sof committed
200

201
isDataConId_maybe id = case idFlavour id of
202 203
			  ConstantId (DataCon con) -> Just con
			  other		           -> Nothing
sof's avatar
sof committed
204

205
isConstantId id = case idFlavour id of
206 207
		    ConstantId _ -> True
		    other	 -> False
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223

isSpecPragmaId id = case idFlavour id of
			SpecPragmaId -> True
			other	     -> False

-- Don't drop a binding for an exported Id,
-- if it otherwise looks dead.  
isExportedId :: Id -> Bool
isExportedId id = case idFlavour id of
			VanillaId -> False
			other	  -> True	-- All the others are no-discard

-- Say if an Id was exported by the user
-- Implies isExportedId (see mkId above)
isUserExportedId :: Id -> Bool
isUserExportedId id = isUserExportedName (idName id)
224 225
\end{code}

226

227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
omitIfaceSigForId tells whether an Id's info is implied by other declarations,
so we don't need to put its signature in an interface file, even if it's mentioned
in some other interface unfolding.

\begin{code}
omitIfaceSigForId :: Id -> Bool
omitIfaceSigForId id
  | isWiredInName (idName id)
  = True

  | otherwise
  = case idFlavour id of
	RecordSelId _  -> True	-- Includes dictionary selectors
        ConstantId _   -> True
		-- ConstantIds are implied by their type or class decl;
		-- remember that all type and class decls appear in the interface file.
		-- The dfun id must *not* be omitted, because it carries version info for
		-- the instance decl

	other	       -> False	-- Don't omit!
\end{code}



251 252
%************************************************************************
%*									*
253
\subsection{IdInfo stuff}
254 255 256
%*									*
%************************************************************************

257
\begin{code}
258 259
	---------------------------------
	-- ARITY
260
getIdArity :: Id -> ArityInfo
261
getIdArity id = arityInfo (idInfo id)
262

263
setIdArity :: Id -> ArityInfo -> Id
264
setIdArity id arity = modifyIdInfo (`setArityInfo` arity) id
265

266 267
	---------------------------------
	-- STRICTNESS
268
getIdStrictness :: Id -> StrictnessInfo
269
getIdStrictness id = strictnessInfo (idInfo id)
270

271
setIdStrictness :: Id -> StrictnessInfo -> Id
272
setIdStrictness id strict_info = modifyIdInfo (`setStrictnessInfo` strict_info) id
273

274 275 276 277 278 279
-- isBottomingId returns true if an application to n args would diverge
isBottomingId :: Id -> Bool
isBottomingId id = isBottomingStrictness (strictnessInfo (idInfo id))

idAppIsBottom :: Id -> Int -> Bool
idAppIsBottom id n = appIsBottom (strictnessInfo (idInfo id)) n
280

281 282 283 284 285 286
	---------------------------------
	-- WORKER ID
getIdWorkerInfo :: Id -> WorkerInfo
getIdWorkerInfo id = workerInfo (idInfo id)

setIdWorkerInfo :: Id -> WorkerInfo -> Id
287
setIdWorkerInfo id work_info = modifyIdInfo (`setWorkerInfo` work_info) id
288

289 290
	---------------------------------
	-- UNFOLDING
291
getIdUnfolding :: Id -> Unfolding
292
getIdUnfolding id = unfoldingInfo (idInfo id)
293

294
setIdUnfolding :: Id -> Unfolding -> Id
295
setIdUnfolding id unfolding = modifyIdInfo (`setUnfoldingInfo` unfolding) id
sof's avatar
sof committed
296

297 298
	---------------------------------
	-- DEMAND
299
getIdDemandInfo :: Id -> Demand
300
getIdDemandInfo id = demandInfo (idInfo id)
301

302
setIdDemandInfo :: Id -> Demand -> Id
303
setIdDemandInfo id demand_info = modifyIdInfo (`setDemandInfo` demand_info) id
304

305 306
	---------------------------------
	-- UPDATE INFO
307
getIdUpdateInfo :: Id -> UpdateInfo
308
getIdUpdateInfo id = updateInfo (idInfo id)
309

310
setIdUpdateInfo :: Id -> UpdateInfo -> Id
311
setIdUpdateInfo id upd_info = modifyIdInfo (`setUpdateInfo` upd_info) id
312

313 314
	---------------------------------
	-- SPECIALISATION
315
getIdSpecialisation :: Id -> CoreRules
316
getIdSpecialisation id = specInfo (idInfo id)
317

318 319
setIdSpecialisation :: Id -> CoreRules -> Id
setIdSpecialisation id spec_info = modifyIdInfo (`setSpecInfo` spec_info) id
320

321 322
	---------------------------------
	-- CAF INFO
323
getIdCafInfo :: Id -> CafInfo
324
getIdCafInfo id = cafInfo (idInfo id)
325

326
setIdCafInfo :: Id -> CafInfo -> Id
327
setIdCafInfo id caf_info = modifyIdInfo (`setCafInfo` caf_info) id
328 329 330 331 332 333 334

	---------------------------------
	-- CPR INFO
getIdCprInfo :: Id -> CprInfo
getIdCprInfo id = cprInfo (idInfo id)

setIdCprInfo :: Id -> CprInfo -> Id
335
setIdCprInfo id cpr_info = modifyIdInfo (`setCprInfo` cpr_info) id
336 337
\end{code}

sof's avatar
sof committed
338

339 340 341 342
	---------------------------------
	-- INLINING
The inline pragma tells us to be very keen to inline this Id, but it's still
OK not to if optimisation is switched off.
343 344

\begin{code}
345
getInlinePragma :: Id -> InlinePragInfo
346
getInlinePragma id = inlinePragInfo (idInfo id)
347

348
setInlinePragma :: Id -> InlinePragInfo -> Id
349
setInlinePragma id prag = modifyIdInfo (`setInlinePragInfo` prag) id
350

351
modifyInlinePragma :: Id -> (InlinePragInfo -> InlinePragInfo) -> Id
352
modifyInlinePragma id fn = modifyIdInfo (\info -> info `setInlinePragInfo` (fn (inlinePragInfo info))) id
353

354 355 356 357
idMustNotBeINLINEd id = case getInlinePragma id of
			  IMustNotBeINLINEd -> True
			  IAmALoopBreaker   -> True
			  other		    -> False
358

359 360 361
idMustBeINLINEd id =  case getInlinePragma id of
			IMustBeINLINEd -> True
			other	       -> False
362
\end{code}