X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2FbasicTypes%2FId.lhs;h=fd65fe40090abb82fa97e2b96b070e57fed08662;hp=fbf6b4a25644ba63f9fc95c7a86680152d4631c1;hb=16b9e80dc14db24509f051f294b5b51943285090;hpb=af7c22d99d3067c4769fc6f2ef21aecbb1268f50 diff --git a/compiler/basicTypes/Id.lhs b/compiler/basicTypes/Id.lhs index fbf6b4a..fd65fe4 100644 --- a/compiler/basicTypes/Id.lhs +++ b/compiler/basicTypes/Id.lhs @@ -30,7 +30,7 @@ module Id ( mkLocalId, mkLocalIdWithInfo, mkExportedLocalId, mkSysLocal, mkSysLocalM, mkUserLocal, mkUserLocalM, mkTemplateLocals, mkTemplateLocalsNum, mkTemplateLocal, - mkWorkerId, + mkWorkerId, mkWiredInIdName, -- ** Taking an Id apart idName, idType, idUnique, idInfo, idDetails, @@ -49,7 +49,7 @@ module Id ( isImplicitId, isDeadBinder, isDictId, isStrictId, isExportedId, isLocalId, isGlobalId, isRecordSelector, isNaughtyRecordSelector, - isClassOpId_maybe, isDFunId, + isClassOpId_maybe, isDFunId, dfunNSilent, isPrimOpId, isPrimOpId_maybe, isFCallId, isFCallId_maybe, isDataConWorkId, isDataConWorkId_maybe, isDataConId_maybe, idDataCon, @@ -76,6 +76,7 @@ module Id ( idOccInfo, -- ** Writing 'IdInfo' fields + setIdUnfoldingLazily, setIdUnfolding, setIdArity, setIdDemandInfo, @@ -119,7 +120,8 @@ import Util( count ) import StaticFlags -- infixl so you can say (id `set` a `set` b) -infixl 1 `setIdUnfolding`, +infixl 1 `setIdUnfoldingLazily`, + `setIdUnfolding`, `setIdArity`, `setIdOccInfo`, `setIdDemandInfo`, @@ -170,7 +172,7 @@ localiseId :: Id -> Id -- Make an with the same unique and type as the -- incoming Id, but with an *Internal* Name and *LocalId* flavour localiseId id - | isLocalId id && isInternalName name + | ASSERT( isId id ) isLocalId id && isInternalName name = id | otherwise = mkLocalIdWithInfo (localiseName name) (idType id) (idInfo id) @@ -258,6 +260,9 @@ mkUserLocal occ uniq ty loc = mkLocalId (mkInternalName uniq occ loc) ty mkUserLocalM :: MonadUnique m => OccName -> Type -> SrcSpan -> m Id mkUserLocalM occ ty loc = getUniqueM >>= (\uniq -> return (mkUserLocal occ uniq ty loc)) +mkWiredInIdName :: Module -> FastString -> Unique -> Id -> Name +mkWiredInIdName mod fs uniq id + = mkWiredInName mod (mkOccNameFS varName fs) uniq (AnId id) UserSyntax \end{code} Make some local @Ids@ for a template @CoreExpr@. These have bogus @@ -327,8 +332,13 @@ isPrimOpId id = case Var.idDetails id of _ -> False isDFunId id = case Var.idDetails id of - DFunId _ -> True - _ -> False + DFunId {} -> True + _ -> False + +dfunNSilent :: Id -> Int +dfunNSilent id = case Var.idDetails id of + DFunId ns _ -> ns + _ -> pprTrace "dfunSilent: not a dfun:" (ppr id) 0 isPrimOpId_maybe id = case Var.idDetails id of PrimOpId op -> Just op @@ -493,6 +503,9 @@ realIdUnfolding :: Id -> Unfolding -- Expose the unfolding if there is one, including for loop breakers realIdUnfolding id = unfoldingInfo (idInfo id) +setIdUnfoldingLazily :: Id -> Unfolding -> Id +setIdUnfoldingLazily id unfolding = modifyIdInfo (`setUnfoldingInfoLazily` unfolding) id + setIdUnfolding :: Id -> Unfolding -> Id setIdUnfolding id unfolding = modifyIdInfo (`setUnfoldingInfo` unfolding) id @@ -651,29 +664,44 @@ zapFragileIdInfo = zapInfo zapFragileInfo Note [transferPolyIdInfo] ~~~~~~~~~~~~~~~~~~~~~~~~~ -Suppose we have +This transfer is used in two places: + FloatOut (long-distance let-floating) + SimplUtils.abstractFloats (short-distance let-floating) + +Consider the short-distance let-floating: f = /\a. let g = rhs in ... -where g has interesting strictness information. Then if we float thus +Then if we float thus g' = /\a. rhs - f = /\a. ...[g' a/g] + f = /\a. ...[g' a/g].... we *do not* want to lose g's * strictness information * arity * inline pragma (though that is bit more debatable) + * occurrence info + +Mostly this is just an optimisation, but it's *vital* to +transfer the occurrence info. Consider + + NonRec { f = /\a. let Rec { g* = ..g.. } in ... } -It's simple to retain strictness and arity, but not so simple to retain +where the '*' means 'LoopBreaker'. Then if we float we must get + + Rec { g'* = /\a. ...(g' a)... } + NonRec { f = /\a. ...[g' a/g]....} + +where g' is also marked as LoopBreaker. If not, terrible things +can happen if we re-simplify the binding (and the Simplifier does +sometimes simplify a term twice); see Trac #4345. + +It's not so simple to retain * worker info * rules so we simply discard those. Sooner or later this may bite us. -This transfer is used in two places: - FloatOut (long-distance let-floating) - SimplUtils.abstractFloats (short-distance let-floating) - If we abstract wrt one or more *value* binders, we must modify the arity and strictness info before transferring it. E.g. f = \x. e @@ -696,6 +724,7 @@ transferPolyIdInfo old_id abstract_wrt new_id old_info = idInfo old_id old_arity = arityInfo old_info old_inline_prag = inlinePragInfo old_info + old_occ_info = occInfo old_info new_arity = old_arity + arity_increase old_strictness = strictnessInfo old_info new_strictness = fmap (increaseStrictSigArity arity_increase) old_strictness @@ -703,4 +732,5 @@ transferPolyIdInfo old_id abstract_wrt new_id transfer new_info = new_info `setStrictnessInfo` new_strictness `setArityInfo` new_arity `setInlinePragInfo` old_inline_prag + `setOccInfo` old_occ_info \end{code}