From db791f3ce801f99b944908c5c1e36f1f8a027d8f Mon Sep 17 00:00:00 2001 From: simonpj Date: Fri, 8 Dec 2000 09:44:51 +0000 Subject: [PATCH] [project @ 2000-12-08 09:44:51 by simonpj] Complete Simons arity/caf changes --- ghc/compiler/coreSyn/CoreTidy.lhs | 37 ++++++++++++++++++---- ghc/compiler/main/HscMain.lhs | 3 +- ghc/compiler/main/MkIface.lhs | 62 +++---------------------------------- 3 files changed, 36 insertions(+), 66 deletions(-) diff --git a/ghc/compiler/coreSyn/CoreTidy.lhs b/ghc/compiler/coreSyn/CoreTidy.lhs index 18bba01..95a9959 100644 --- a/ghc/compiler/coreSyn/CoreTidy.lhs +++ b/ghc/compiler/coreSyn/CoreTidy.lhs @@ -368,7 +368,7 @@ tidyIdInfo us tidy_env is_external unfold_info arity_info caf_info id `setStrictnessInfo` strictnessInfo core_idinfo `setInlinePragInfo` inlinePragInfo core_idinfo `setUnfoldingInfo` unfold_info - `setWorkerInfo` tidyWorker tidy_env (workerInfo core_idinfo) + `setWorkerInfo` tidyWorker tidy_env arity_info (workerInfo core_idinfo) `setSpecInfo` rules' `setArityInfo` ArityExactly arity_info `setCafInfo` caf_info @@ -388,6 +388,7 @@ tidyIdInfo us tidy_env is_external unfold_info arity_info caf_info id flavour -> pprTrace "tidyIdInfo" (ppr id <+> ppFlavourInfo flavour) flavour + -- This is where we set names to local/global based on whether they really are -- externally visible (see comment at the top of this module). If the name -- was previously local, we have to give it a unique occurrence name if @@ -418,6 +419,35 @@ tidyTopName mod orig_env occ_env external name local = not global internal = not external +------------ Worker -------------- +-- We only treat a function as having a worker if +-- the exported arity (which is now the number of visible lambdas) +-- is the same as the arity at the moment of the w/w split +-- If so, we can safely omit the unfolding inside the wrapper, and +-- instead re-generate it from the type/arity/strictness info +-- But if the arity has changed, we just take the simple path and +-- put the unfolding into the interface file, forgetting the fact +-- that it's a wrapper. +-- +-- How can this happen? Sometimes we get +-- f = coerce t (\x y -> $wf x y) +-- at the moment of w/w split; but the eta reducer turns it into +-- f = coerce t $wf +-- which is perfectly fine except that the exposed arity so far as +-- the code generator is concerned (zero) differs from the arity +-- when we did the split (2). +-- +-- All this arises because we use 'arity' to mean "exactly how many +-- top level lambdas are there" in interface files; but during the +-- compilation of this module it means "how many things can I apply +-- this to". +tidyWorker tidy_env real_arity (HasWorker work_id wrap_arity) + | real_arity == wrap_arity + = HasWorker (tidyVarOcc tidy_env work_id) wrap_arity +tidyWorker tidy_env real_arity other + = NoWorker + +------------ Rules -------------- tidyIdRules :: TidyEnv -> [IdCoreRule] -> UniqSM [IdCoreRule] tidyIdRules env [] = returnUs [] tidyIdRules env ((fn,rule) : rules) @@ -425,11 +455,6 @@ tidyIdRules env ((fn,rule) : rules) tidyIdRules env rules `thenUs` \ rules -> returnUs ((tidyVarOcc env fn, rule) : rules) -tidyWorker tidy_env (HasWorker work_id wrap_arity) - = HasWorker (tidyVarOcc tidy_env work_id) wrap_arity -tidyWorker tidy_env NoWorker - = NoWorker - tidyRules :: TidyEnv -> CoreRules -> UniqSM CoreRules tidyRules env (Rules rules fvs) = mapUs (tidyRule env) rules `thenUs` \ rules -> diff --git a/ghc/compiler/main/HscMain.lhs b/ghc/compiler/main/HscMain.lhs index cf9bbe6..49139b7 100644 --- a/ghc/compiler/main/HscMain.lhs +++ b/ghc/compiler/main/HscMain.lhs @@ -225,8 +225,7 @@ hscRecomp ghci_mode dflags location maybe_checked_iface hst hit pcs_ch ------------------- -- BUILD THE NEW ModDetails AND ModIface ------------------- - ; let new_details = mkModDetails env_tc tidy_binds - (bindersOfBinds tidy_binds) orphan_rules + ; let new_details = mkModDetails env_tc tidy_binds orphan_rules ; final_iface <- mkFinalIface ghci_mode dflags location maybe_checked_iface new_iface new_details diff --git a/ghc/compiler/main/MkIface.lhs b/ghc/compiler/main/MkIface.lhs index 693316f..e43429c 100644 --- a/ghc/compiler/main/MkIface.lhs +++ b/ghc/compiler/main/MkIface.lhs @@ -68,11 +68,10 @@ import IO ( IOMode(..), openFile, hClose ) \begin{code} mkModDetails :: TypeEnv -- From typechecker -> [CoreBind] -- Final bindings - -> [Id] -- Top-level Ids from the code generator; -- they have authoritative arity info -> [IdCoreRule] -- Tidy orphan rules -> ModDetails -mkModDetails type_env tidy_binds stg_ids orphan_rules +mkModDetails type_env tidy_binds orphan_rules = ModDetails { md_types = new_type_env, md_rules = rule_dcls, md_insts = filter isDictFunId final_ids } @@ -99,10 +98,9 @@ mkModDetails type_env tidy_binds stg_ids orphan_rules keep_it (AnId id) = hasNoBinding id keep_it other = True - stg_id_set = mkVarSet stg_ids - final_ids = [addStgInfo stg_id_set id | bind <- tidy_binds - , id <- bindersOf bind - , isGlobalName (idName id)] + final_ids = [id | bind <- tidy_binds + , id <- bindersOf bind + , isGlobalName (idName id)] -- The complete rules are gotten by combining -- a) the orphan rules @@ -125,58 +123,6 @@ mkModDetailsFromIface type_env rules -- All the rules from an interface are of the IfaceRuleOut form \end{code} - -We have to add on the arity and CAF info computed by the code generator -This is also the moment at which we may forget that this function has -a worker: see the comments below - -\begin{code} -addStgInfo :: IdSet -- Ids used at code-gen time; they have better pragma info! - -> Id -> Id -addStgInfo stg_ids id - = id `setIdInfo` final_idinfo - where - idinfo = idInfo id - idinfo' = idinfo `setArityInfo` stg_arity - `setCafInfo` cafInfo stg_idinfo - final_idinfo | worker_ok = idinfo' - | otherwise = idinfo' `setWorkerInfo` NoWorker - - stg_idinfo = case lookupVarSet stg_ids id of - Just id' -> idInfo id' - Nothing -> pprTrace "ifaceBinds not found:" (ppr id) $ - idInfo id - - stg_arity = arityInfo stg_idinfo - - ------------ Worker -------------- - -- We only treat a function as having a worker if - -- the exported arity (which is now the number of visible lambdas) - -- is the same as the arity at the moment of the w/w split - -- If so, we can safely omit the unfolding inside the wrapper, and - -- instead re-generate it from the type/arity/strictness info - -- But if the arity has changed, we just take the simple path and - -- put the unfolding into the interface file, forgetting the fact - -- that it's a wrapper. - -- - -- How can this happen? Sometimes we get - -- f = coerce t (\x y -> $wf x y) - -- at the moment of w/w split; but the eta reducer turns it into - -- f = coerce t $wf - -- which is perfectly fine except that the exposed arity so far as - -- the code generator is concerned (zero) differs from the arity - -- when we did the split (2). - -- - -- All this arises because we use 'arity' to mean "exactly how many - -- top level lambdas are there" in interface files; but during the - -- compilation of this module it means "how many things can I apply - -- this to". - worker_ok = case workerInfo idinfo of - NoWorker -> True - HasWorker work_id wrap_arity -> wrap_arity == arityLowerBound stg_arity -\end{code} - - \begin{code} getRules :: [IdCoreRule] -- Orphan rules -> [CoreBind] -- Bindings, with rules in the top-level Ids -- 1.7.10.4