Commit 5800ebfe authored by Ömer Sinan Ağacan's avatar Ömer Sinan Ağacan Committed by Marge Bot

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

    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:
parent beffa147
Pipeline #16807 failed with stages
in 481 minutes and 9 seconds
......@@ -1197,7 +1197,7 @@ runPhase (HscOut src_flavour mod_name result) _ dflags = do
final_iface <- liftIO (mkFullIface hsc_env'{hsc_dflags=iface_dflags} partial_iface (Just caf_infos))
let final_mod_details = {-# SCC updateModDetailsCafInfos #-}
updateModDetailsCafInfos caf_infos mod_details
updateModDetailsCafInfos iface_dflags caf_infos mod_details
setIface final_iface final_mod_details
-- See Note [Writing interface files]
......@@ -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)
:: 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) $ -}
ModDetails{ md_types = type_env -- for unfoldings
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment