diff options
author | Ömer Sinan Ağacan <omeragacan@gmail.com> | 2020-03-09 18:16:32 +0300 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2020-03-17 07:38:08 -0400 |
commit | 5800ebfeb2fe3e3ed985cdf08a66defea73db71d (patch) | |
tree | d00a9a842d351b61b7ad4998c583d71cef6a153c /compiler/main | |
parent | beffa14771ebd6ba24b20337f29045364621c5fa (diff) | |
download | haskell-5800ebfeb2fe3e3ed985cdf08a66defea73db71d.tar.gz |
Don't update ModDetails with CafInfos when opts are disabled
This is consistent with the interface file behavior where we omit
HsNoCafRefs annotations with -fomit-interface-pragmas (implied by -O0).
ModDetails and ModIface are just different representations of the same
thing, so they really need to be in sync. This patch does the right
thing and does not need too much explanation, but here's an example of a
problem not doing this causes in !2842:
-- MyInteger.hs
module MyInteger
( MyInteger (MyInteger)
, ToMyInteger (toMyInteger)
) where
newtype MyInteger = MyInteger Integer
class ToMyInteger a where
toMyInteger :: a -> MyInteger
instance ToMyInteger Integer where
toMyInteger = MyInteger {- . succ -}
-- Main.hs
module Main
( main
) where
import MyInteger (MyInteger (MyInteger), toMyInteger)
main :: IO ()
main = do
let (MyInteger i) = (id . toMyInteger) (41 :: Integer)
print i
If I build this with -O0, without this fix, we generate a ModDetails with
accurate LFInfo for toMyInteger (MyInteger.$fToMyIntegerInteger) which says that
it's a LFReEntrant with arity 1. This means in the use site (Main) we tag the
value:
R3 = MyInteger.$fToMyIntegerInteger_closure + 1;
R2 = GHC.Base.id_closure;
R1 = GHC.Base.._closure;
Sp = Sp - 16;
call stg_ap_ppp_fast(R4, R3, R2, R1) args: 24, res: 0, upd: 24;
Now we change the definition by uncommenting the `succ` part and it becomes a thunk:
MyInteger.$fToMyIntegerInteger [InlPrag=INLINE (sat-args=0)]
:: MyInteger.ToMyInteger GHC.Integer.Type.Integer
[GblId[DFunId(nt)]] =
{} \u [] $ctoMyInteger_rEA;
and its LFInfo is now LFThunk. This change in LFInfo makes a difference in the
use site: we can no longer tag it.
But becuase the interface fingerprint does not change (because ModIface does not
change) we don't rebuild Main and tag the thunk.
(1.2% increase in allocations when building T12545 on armv7 because we
generate more code without CafInfos)
Metric Increase:
T12545
Diffstat (limited to 'compiler/main')
-rw-r--r-- | compiler/main/UpdateCafInfos.hs | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/compiler/main/UpdateCafInfos.hs b/compiler/main/UpdateCafInfos.hs index a1287e88c6..dd4881ec6e 100644 --- a/compiler/main/UpdateCafInfos.hs +++ b/compiler/main/UpdateCafInfos.hs @@ -7,6 +7,7 @@ module UpdateCafInfos import GhcPrelude import GHC.Core +import GHC.Driver.Session import GHC.Driver.Types import Id import IdInfo @@ -21,10 +22,16 @@ import Outputable -- | Update CafInfos of all occurences (in rules, unfoldings, class instances) updateModDetailsCafInfos - :: NameSet -- ^ Non-CAFFY names in the module. Names not in this set are CAFFY. + :: DynFlags + -> NameSet -- ^ Non-CAFFY names in the module. Names not in this set are CAFFY. -> ModDetails -- ^ ModDetails to update -> ModDetails -updateModDetailsCafInfos non_cafs mod_details = + +updateModDetailsCafInfos dflags _ mod_details + | gopt Opt_OmitInterfacePragmas dflags + = mod_details + +updateModDetailsCafInfos _ non_cafs mod_details = {- pprTrace "updateModDetailsCafInfos" (text "non_cafs:" <+> ppr non_cafs) $ -} let ModDetails{ md_types = type_env -- for unfoldings |