X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Fiface%2FMkIface.lhs;h=4de3a6fdc2134465f44b1e1de9fa6e32870ea732;hb=2900ac71b7f36fbf2f4a89b4dd85583f694bc31c;hp=c55f54f772fd3f0aedb35507e69623f50d637c7d;hpb=d95ce839533391e7118257537044f01cbb1d6694;p=ghc-hetmet.git diff --git a/compiler/iface/MkIface.lhs b/compiler/iface/MkIface.lhs index c55f54f..4de3a6f 100644 --- a/compiler/iface/MkIface.lhs +++ b/compiler/iface/MkIface.lhs @@ -51,7 +51,6 @@ Basic idea: #include "HsVersions.h" import IfaceSyn -import IfaceType import LoadIface import Id import IdInfo @@ -77,7 +76,6 @@ import Name import RdrName import NameEnv import NameSet -import OccName import Module import BinIface import ErrUtils @@ -95,7 +93,6 @@ import ListSetOps import Binary import Fingerprint import Bag -import Panic import Control.Monad import Data.List @@ -188,26 +185,15 @@ mkDependencies -- on M.hi-boot, and hence that we should do the hi-boot consistency -- check.) - -- Modules don't compare lexicographically usually, - -- but we want them to do so here. - le_mod :: Module -> Module -> Bool - le_mod m1 m2 = moduleNameFS (moduleName m1) - <= moduleNameFS (moduleName m2) - - le_dep_mod :: (ModuleName, IsBootInterface) - -> (ModuleName, IsBootInterface) -> Bool - le_dep_mod (m1,_) (m2,_) = moduleNameFS m1 <= moduleNameFS m2 - - pkgs | th_used = insertList thPackageId (imp_dep_pkgs imports) | otherwise = imp_dep_pkgs imports - return Deps { dep_mods = sortLe le_dep_mod dep_mods, - dep_pkgs = sortLe (<=) pkgs, - dep_orphs = sortLe le_mod (imp_orphs imports), - dep_finsts = sortLe le_mod (imp_finsts imports) } + return Deps { dep_mods = sortBy (stableModuleNameCmp `on` fst) dep_mods, + dep_pkgs = sortBy stablePackageIdCmp pkgs, + dep_orphs = sortBy stableModuleCmp (imp_orphs imports), + dep_finsts = sortBy stableModuleCmp (imp_finsts imports) } -- sort to get into canonical order - + -- NB. remember to use lexicographic ordering mkIface_ :: HscEnv -> Maybe Fingerprint -> Module -> IsBootInterface -> NameSet -> Dependencies -> GlobalRdrEnv @@ -631,7 +617,8 @@ freeNamesDeclABI (_mod, decl, extras) = data IfaceDeclExtras = IfaceIdExtras Fixity [IfaceRule] | IfaceDataExtras Fixity [IfaceInstABI] [(Fixity,[IfaceRule])] - | IfaceClassExtras [IfaceInstABI] [(Fixity,[IfaceRule])] + | IfaceClassExtras Fixity [IfaceInstABI] [(Fixity,[IfaceRule])] + | IfaceSynExtras Fixity | IfaceOtherDeclExtras freeNamesDeclExtras :: IfaceDeclExtras -> NameSet @@ -639,8 +626,10 @@ freeNamesDeclExtras (IfaceIdExtras _ rules) = unionManyNameSets (map freeNamesIfRule rules) freeNamesDeclExtras (IfaceDataExtras _ _insts subs) = unionManyNameSets (map freeNamesSub subs) -freeNamesDeclExtras (IfaceClassExtras _insts subs) +freeNamesDeclExtras (IfaceClassExtras _ _insts subs) = unionManyNameSets (map freeNamesSub subs) +freeNamesDeclExtras (IfaceSynExtras _) + = emptyNameSet freeNamesDeclExtras IfaceOtherDeclExtras = emptyNameSet @@ -653,10 +642,12 @@ instance Binary IfaceDeclExtras where putByte bh 1; put_ bh fix; put_ bh rules put_ bh (IfaceDataExtras fix insts cons) = do putByte bh 2; put_ bh fix; put_ bh insts; put_ bh cons - put_ bh (IfaceClassExtras insts methods) = do - putByte bh 3; put_ bh insts; put_ bh methods + put_ bh (IfaceClassExtras fix insts methods) = do + putByte bh 3; put_ bh fix; put_ bh insts; put_ bh methods + put_ bh (IfaceSynExtras fix) = do + putByte bh 4; put_ bh fix put_ bh IfaceOtherDeclExtras = do - putByte bh 4 + putByte bh 5 declExtras :: (OccName -> Fixity) -> OccEnv [IfaceRule] @@ -673,9 +664,10 @@ declExtras fix_fn rule_env inst_env decl (map IfaceInstABI $ lookupOccEnvL inst_env n) (map (id_extras . ifConOcc) (visibleIfConDecls cons)) IfaceClass{ifSigs=sigs} -> - IfaceClassExtras + IfaceClassExtras (fix_fn n) (map IfaceInstABI $ lookupOccEnvL inst_env n) [id_extras op | IfaceClassOp op _ _ <- sigs] + IfaceSyn{} -> IfaceSynExtras (fix_fn n) _other -> IfaceOtherDeclExtras where n = ifName decl @@ -920,11 +912,15 @@ mkIfaceAnnotation (Annotation { ann_target = target, ann_value = serialized }) = \begin{code} mkIfaceExports :: [AvailInfo] -> [(Module, [GenAvailInfo OccName])] - -- Group by module and sort by occurrence - -- This keeps the list in canonical order + -- Group by module and sort by occurrence mkIfaceExports exports = [ (mod, eltsFM avails) - | (mod, avails) <- fmToList groupFM + | (mod, avails) <- sortBy (stableModuleCmp `on` fst) + (moduleEnvToList groupFM) + -- NB. the fmToList is in a random order, + -- because Ord Module is not a predictable + -- ordering. Hence we perform a final sort + -- using the stable Module ordering. ] where -- Group by the module where the exported entities are defined @@ -1271,9 +1267,10 @@ tyThingToIfaceDecl :: TyThing -> IfaceDecl -- Reason: Iface stuff uses OccNames, and the conversion here does -- not do tidying on the way tyThingToIfaceDecl (AnId id) - = IfaceId { ifName = getOccName id, - ifType = toIfaceType (idType id), - ifIdInfo = info } + = IfaceId { ifName = getOccName id, + ifType = toIfaceType (idType id), + ifIdDetails = toIfaceIdDetails (idDetails id), + ifIdInfo = info } where info = case toIfaceIdInfo (idInfo id) of [] -> NoInfo @@ -1351,6 +1348,7 @@ tyThingToIfaceDecl (ATyCon tycon) ifaceConDecl data_con = IfCon { ifConOcc = getOccName (dataConName data_con), ifConInfix = dataConIsInfix data_con, + ifConWrapper = isJust (dataConWrapId_maybe data_con), ifConUnivTvs = toIfaceTvBndrs (dataConUnivTyVars data_con), ifConExTvs = toIfaceTvBndrs (dataConExTyVars data_con), ifConEqSpec = to_eq_spec (dataConEqSpec data_con), @@ -1397,7 +1395,7 @@ instanceToIfaceInst (Instance { is_dfun = dfun_id, is_flag = oflag, (tvs, fds) = classTvsFds cls arg_names = [filterNameSet is_local (tyClsNamesOfType ty) | ty <- tys] orph | is_local cls_name = Just (nameOccName cls_name) - | all isJust mb_ns = ASSERT( not (null mb_ns) ) head mb_ns + | all isJust mb_ns = head mb_ns | otherwise = Nothing mb_ns :: [Maybe OccName] -- One for each fundep; a locally-defined name @@ -1438,14 +1436,22 @@ toIfaceLetBndr id = IfLetBndr (occNameFS (getOccName id)) -- See Note [IdInfo on nested let-bindings] in IfaceSyn id_info = idInfo id inline_prag = inlinePragInfo id_info - prag_info | isAlwaysActive inline_prag = NoInfo - | otherwise = HasInfo [HsInline inline_prag] + prag_info | isDefaultInlinePragma inline_prag = NoInfo + | otherwise = HasInfo [HsInline inline_prag] -------------------------- +toIfaceIdDetails :: IdDetails -> IfaceIdDetails +toIfaceIdDetails VanillaId = IfVanillaId +toIfaceIdDetails DFunId = IfVanillaId +toIfaceIdDetails (RecSelId { sel_naughty = n + , sel_tycon = tc }) = IfRecSelId (toIfaceTyCon tc) n +toIfaceIdDetails other = pprTrace "toIfaceIdDetails" (ppr other) + IfVanillaId -- Unexpected + toIfaceIdInfo :: IdInfo -> [IfaceInfoItem] toIfaceIdInfo id_info = catMaybes [arity_hsinfo, caf_hsinfo, strict_hsinfo, - inline_hsinfo, unfold_hsinfo] + inline_hsinfo, wrkr_hsinfo, unfold_hsinfo] where ------------ Arity -------------- arity_info = arityInfo id_info @@ -1464,29 +1470,35 @@ toIfaceIdInfo id_info Just sig | not (isTopSig sig) -> Just (HsStrictness sig) _other -> Nothing + ------------ Worker -------------- + work_info = workerInfo id_info + has_worker = workerExists work_info + wrkr_hsinfo = case work_info of + HasWorker work_id wrap_arity -> + Just (HsWorker ((idName work_id)) wrap_arity) + NoWorker -> Nothing + ------------ Unfolding -------------- - unfold_hsinfo = fmap HsUnfold $ toIfUnfolding (unfoldingInfo id_info) + -- The unfolding is redundant if there is a worker + unfold_info = unfoldingInfo id_info + rhs = unfoldingTemplate unfold_info + no_unfolding = neverUnfold unfold_info + -- The CoreTidy phase retains unfolding info iff + -- we want to expose the unfolding, taking into account + -- unconditional NOINLINE, etc. See TidyPgm.addExternal + unfold_hsinfo | no_unfolding = Nothing + | has_worker = Nothing -- Unfolding is implicit + | otherwise = Just (HsUnfold (toIfaceExpr rhs)) ------------ Inline prag -------------- inline_prag = inlinePragInfo id_info - inline_hsinfo | isAlwaysActive inline_prag = Nothing - | isNothing unfold_hsinfo = Nothing + inline_hsinfo | isDefaultInlinePragma inline_prag = Nothing + | no_unfolding && not has_worker + && isFunLike (inlinePragmaRuleMatchInfo inline_prag) + = Nothing -- If the iface file give no unfolding info, we -- don't need to say when inlining is OK! - | otherwise = Just (HsInline inline_prag) - --------------------------- -toIfUnfolding :: Unfolding -> Maybe IfaceUnfolding -toIfUnfolding (CoreUnfolding { uf_tmpl = rhs, uf_guidance = guidance }) - = case guidance of - UnfoldNever -> Nothing - _ -> Just (IfCoreUnfold (toIfaceExpr rhs)) -toIfUnfolding (InlineRule { uf_worker = Just wkr, uf_arity = arity }) - = Just (IfWrapper arity (idName wkr)) -toIfUnfolding (InlineRule { uf_worker = Nothing, uf_tmpl = rhs, uf_arity = arity }) - = Just (IfInlineRule arity (toIfaceExpr rhs)) -toIfUnfolding _ - = Nothing + | otherwise = Just (HsInline inline_prag) -------------------------- coreRuleToIfaceRule :: Module -> CoreRule -> IfaceRule @@ -1543,6 +1555,7 @@ toIfaceExpr (Note n e) = IfaceNote (toIfaceNote n) (toIfaceExpr e) --------------------- toIfaceNote :: Note -> IfaceNote toIfaceNote (SCC cc) = IfaceSCC cc +toIfaceNote InlineMe = IfaceInlineMe toIfaceNote (CoreNote s) = IfaceCoreNote s ---------------------