Allow users to ignore optimization changes
authorDavid Feuer <david.feuer@gmail.com>
Mon, 11 Dec 2017 18:03:52 +0000 (13:03 -0500)
committerBen Gamari <ben@smart-cactus.org>
Mon, 11 Dec 2017 18:03:53 +0000 (13:03 -0500)
* Add a new flag, `-fignore-optim-changes`, allowing them to avoid
  recompilation if the only changes are to the `-O` level or to
  flags controlling optimizations.

* When `-fignore-optim-changes` is *off*, recompile when optimization
  flags (e.g., `-fno-full-laziness`) change. Previously, we ignored
  these unconditionally when deciding whether to recompile a module.

Reviewers: austin, bgamari, simonmar

Reviewed By: simonmar

Subscribers: duog, carter, simonmar, rwbarton, thomie

GHC Trac Issues: #13604

Differential Revision: https://phabricator.haskell.org/D4123

19 files changed:
compiler/iface/FlagChecker.hs
compiler/iface/LoadIface.hs
compiler/iface/MkIface.hs
compiler/main/DynFlags.hs
compiler/main/HscTypes.hs
docs/users_guide/8.4.1-notes.rst
docs/users_guide/separate_compilation.rst
ghc/Main.hs
testsuite/tests/driver/Makefile
testsuite/tests/driver/T13604.hs [new file with mode: 0644]
testsuite/tests/driver/T13604.stdout [new file with mode: 0644]
testsuite/tests/driver/T13604a.hs [new file with mode: 0644]
testsuite/tests/driver/T13604a.stdout [new file with mode: 0644]
testsuite/tests/driver/T13914/T13914.stdout
testsuite/tests/driver/all.T
testsuite/tests/ghci/scripts/T9293.stdout
testsuite/tests/ghci/scripts/ghci024.stdout
testsuite/tests/ghci/scripts/ghci057.stdout
testsuite/tests/hpc/T11798.stdout

index eb99c74..f81b265 100644 (file)
@@ -4,6 +4,8 @@
 -- interface file as part of the recompilation checking infrastructure.
 module FlagChecker (
         fingerprintDynFlags
+      , fingerprintOptFlags
+      , fingerprintHpcFlags
     ) where
 
 import GhcPrelude
@@ -53,25 +55,45 @@ fingerprintDynFlags dflags@DynFlags{..} this_mod nameio =
         -- -fprof-auto etc.
         prof = if gopt Opt_SccProfilingOn dflags then fromEnum profAuto else 0
 
-        -- -O, see https://ghc.haskell.org/trac/ghc/ticket/10923
-        opt = if hscTarget == HscInterpreted ||
-                 hscTarget == HscNothing
-                 then 0
-                 else optLevel
+        flags = (mainis, safeHs, lang, cpp, paths, prof)
 
+    in -- pprTrace "flags" (ppr flags) $
+       computeFingerprint nameio flags
+
+-- Fingerprint the optimisation info. We keep this separate from the rest of
+-- the flags because GHCi users (especially) may wish to ignore changes in
+-- optimisation level or optimisation flags so as to use as many pre-existing
+-- object files as they can.
+-- See Note [Ignoring some flag changes]
+fingerprintOptFlags :: DynFlags
+                      -> (BinHandle -> Name -> IO ())
+                      -> IO Fingerprint
+fingerprintOptFlags DynFlags{..} nameio =
+      let
+        -- See https://ghc.haskell.org/trac/ghc/ticket/10923
+        -- We used to fingerprint the optimisation level, but as Joachim
+        -- Breitner pointed out in comment 9 on that ticket, it's better
+        -- to ignore that and just look at the individual optimisation flags.
+        opt_flags = map fromEnum $ filter (`EnumSet.member` optimisationFlags)
+                                          (EnumSet.toList generalFlags)
+
+      in computeFingerprint nameio opt_flags
+
+-- Fingerprint the HPC info. We keep this separate from the rest of
+-- the flags because GHCi users (especially) may wish to use an object
+-- file compiled for HPC when not actually using HPC.
+-- See Note [Ignoring some flag changes]
+fingerprintHpcFlags :: DynFlags
+                      -> (BinHandle -> Name -> IO ())
+                      -> IO Fingerprint
+fingerprintHpcFlags dflags@DynFlags{..} nameio =
+      let
         -- -fhpc, see https://ghc.haskell.org/trac/ghc/ticket/11798
         -- hpcDir is output-only, so we should recompile if it changes
         hpc = if gopt Opt_Hpc dflags then Just hpcDir else Nothing
 
-        -- -fignore-asserts, which affects how `Control.Exception.assert` works
-        ignore_asserts = gopt Opt_IgnoreAsserts dflags
-
-        -- Nesting just to avoid ever more Binary tuple instances
-        flags = (mainis, safeHs, lang, cpp, paths,
-                 (prof, opt, hpc, ignore_asserts))
+      in computeFingerprint nameio hpc
 
-    in -- pprTrace "flags" (ppr flags) $
-       computeFingerprint nameio flags
 
 {- Note [path flags and recompilation]
 
@@ -102,3 +124,22 @@ recompilation check; here we explain why.
 
 The only path-related flag left is -hcsuf.
 -}
+
+{- Note [Ignoring some flag changes]
+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Normally, --make tries to reuse only compilation products that are
+the same as those that would have been produced compiling from
+scratch. Sometimes, however, users would like to be more aggressive
+about recompilation avoidance. This is particularly likely when
+developing using GHCi (see #13604). Currently, we allow users to
+ignore optimisation changes using -fignore-optim-changes, and to
+ignore HPC option changes using -fignore-hpc-changes. If there's a
+demand for it, we could also allow changes to -fprof-auto-* flags
+(although we can't allow -prof flags to differ). The key thing about
+these options is that we can still successfully link a library or
+executable when some of its components differ in these ways.
+
+The way we accomplish this is to leave the optimization and HPC
+options out of the flag hash, hashing them separately.
+-}
index b91d984..b9a7759 100644 (file)
@@ -1020,6 +1020,8 @@ pprModIface iface
         , nest 2 (text "export-list hash:" <+> ppr (mi_exp_hash iface))
         , nest 2 (text "orphan hash:" <+> ppr (mi_orphan_hash iface))
         , nest 2 (text "flag hash:" <+> ppr (mi_flag_hash iface))
+        , nest 2 (text "opt_hash:" <+> ppr (mi_opt_hash iface))
+        , nest 2 (text "hpc_hash:" <+> ppr (mi_hpc_hash iface))
         , nest 2 (text "sig of:" <+> ppr (mi_sig_of iface))
         , nest 2 (text "used TH splices:" <+> ppr (mi_used_th iface))
         , nest 2 (text "where")
index a12cff2..6d696d9 100644 (file)
@@ -4,6 +4,7 @@
 -}
 
 {-# LANGUAGE CPP, NondecreasingIndentation #-}
+{-# LANGUAGE MultiWayIf #-}
 
 -- | Module for constructing @ModIface@ values (interface files),
 -- writing them to disk and comparing two versions to see if
@@ -279,6 +280,8 @@ mkIface_ hsc_env maybe_old_fingerprint
               mi_iface_hash  = fingerprint0,
               mi_mod_hash    = fingerprint0,
               mi_flag_hash   = fingerprint0,
+              mi_opt_hash    = fingerprint0,
+              mi_hpc_hash    = fingerprint0,
               mi_exp_hash    = fingerprint0,
               mi_used_th     = used_th,
               mi_orphan_hash = fingerprint0,
@@ -660,6 +663,10 @@ addFingerprints hsc_env mb_old_fingerprint iface0 new_decls
    -- the abi hash and one that should
    flag_hash <- fingerprintDynFlags dflags this_mod putNameLiterally
 
+   opt_hash <- fingerprintOptFlags dflags putNameLiterally
+
+   hpc_hash <- fingerprintHpcFlags dflags putNameLiterally
+
    -- the ABI hash depends on:
    --   - decls
    --   - export list
@@ -695,6 +702,8 @@ addFingerprints hsc_env mb_old_fingerprint iface0 new_decls
                 mi_exp_hash    = export_hash,
                 mi_orphan_hash = orphan_hash,
                 mi_flag_hash   = flag_hash,
+                mi_opt_hash    = opt_hash,
+                mi_hpc_hash    = hpc_hash,
                 mi_orphan      = not (   all ifRuleAuto orph_rules
                                            -- See Note [Orphans and auto-generated rules]
                                       && null orph_insts
@@ -1200,6 +1209,10 @@ checkVersions hsc_env mod_summary iface
             then return (RecompBecause "-this-unit-id changed", Nothing) else do {
        ; recomp <- checkFlagHash hsc_env iface
        ; if recompileRequired recomp then return (recomp, Nothing) else do {
+       ; recomp <- checkOptimHash hsc_env iface
+       ; if recompileRequired recomp then return (recomp, Nothing) else do {
+       ; recomp <- checkHpcHash hsc_env iface
+       ; if recompileRequired recomp then return (recomp, Nothing) else do {
        ; recomp <- checkMergedSignatures mod_summary iface
        ; if recompileRequired recomp then return (recomp, Nothing) else do {
        ; recomp <- checkHsig mod_summary iface
@@ -1223,7 +1236,7 @@ checkVersions hsc_env mod_summary iface
        ; updateEps_ $ \eps  -> eps { eps_is_boot = mod_deps }
        ; recomp <- checkList [checkModUsage this_pkg u | u <- mi_usages iface]
        ; return (recomp, Just iface)
-    }}}}}}
+    }}}}}}}}
   where
     this_pkg = thisPackage (hsc_dflags hsc_env)
     -- This is a bit of a hack really
@@ -1255,6 +1268,36 @@ checkFlagHash hsc_env iface = do
                      (text "  Module flags have changed")
                      old_hash new_hash
 
+-- | Check the optimisation flags haven't changed
+checkOptimHash :: HscEnv -> ModIface -> IfG RecompileRequired
+checkOptimHash hsc_env iface = do
+    let old_hash = mi_opt_hash iface
+    new_hash <- liftIO $ fingerprintOptFlags (hsc_dflags hsc_env)
+                                               putNameLiterally
+    if | old_hash == new_hash
+       -> up_to_date (text "Optimisation flags unchanged")
+       | gopt Opt_IgnoreOptimChanges (hsc_dflags hsc_env)
+       -> up_to_date (text "Optimisation flags changed; ignoring")
+       | otherwise
+       -> out_of_date_hash "Optimisation flags changed"
+                     (text "  Optimisation flags have changed")
+                     old_hash new_hash
+
+-- | Check the HPC flags haven't changed
+checkHpcHash :: HscEnv -> ModIface -> IfG RecompileRequired
+checkHpcHash hsc_env iface = do
+    let old_hash = mi_hpc_hash iface
+    new_hash <- liftIO $ fingerprintHpcFlags (hsc_dflags hsc_env)
+                                               putNameLiterally
+    if | old_hash == new_hash
+       -> up_to_date (text "HPC flags unchanged")
+       | gopt Opt_IgnoreHpcChanges (hsc_dflags hsc_env)
+       -> up_to_date (text "HPC flags changed; ignoring")
+       | otherwise
+       -> out_of_date_hash "HPC flags changed"
+                     (text "  HPC flags have changed")
+                     old_hash new_hash
+
 -- Check that the set of signatures we are merging in match.
 -- If the -unit-id flags change, this can change too.
 checkMergedSignatures :: ModSummary -> ModIface -> IfG RecompileRequired
index 74c0a22..4b95bfa 100644 (file)
@@ -60,6 +60,7 @@ module DynFlags (
         makeDynFlagsConsistent,
         shouldUseColor,
         positionIndependent,
+        optimisationFlags,
 
         Way(..), mkBuildTag, wayRTSOnly, addWay', updateWays,
         wayGeneralFlags, wayUnsetGeneralFlags,
@@ -400,6 +401,7 @@ data DumpFlag
    | Opt_D_no_debug_output
    deriving (Eq, Show, Enum)
 
+
 -- | Enumerates the simple on-or-off dynamic flags
 data GeneralFlag
 -- See Note [Updating flag description in the User's Guide]
@@ -478,6 +480,10 @@ data GeneralFlag
    | Opt_AlignmentSanitisation
    | Opt_CatchBottoms
 
+   -- PreInlining is on by default. The option is there just to see how
+   -- bad things get if you turn it off!
+   | Opt_SimplPreInlining
+
    -- Interface files
    | Opt_IgnoreInterfacePragmas
    | Opt_OmitInterfacePragmas
@@ -491,6 +497,8 @@ data GeneralFlag
    -- misc opts
    | Opt_Pp
    | Opt_ForceRecomp
+   | Opt_IgnoreOptimChanges
+   | Opt_IgnoreHpcChanges
    | Opt_ExcessPrecision
    | Opt_EagerBlackHoling
    | Opt_NoHsMain
@@ -535,10 +543,6 @@ data GeneralFlag
    | Opt_VersionMacros
    | Opt_WholeArchiveHsLibs
 
-   -- PreInlining is on by default. The option is there just to see how
-   -- bad things get if you turn it off!
-   | Opt_SimplPreInlining
-
    -- output style opts
    | Opt_ErrorSpans -- Include full span info in error messages,
                     -- instead of just the start position.
@@ -593,6 +597,65 @@ data GeneralFlag
    | Opt_G_NoOptCoercion
    deriving (Eq, Show, Enum)
 
+-- Check whether a flag should be considered an "optimisation flag"
+-- for purposes of recompilation avoidance (see
+-- Note [Ignoring some flag changes] in FlagChecker). Being listed here is
+-- not a guarantee that the flag has no other effect. We could, and
+-- perhaps should, separate out the flags that have some minor impact on
+-- program semantics and/or error behavior (e.g., assertions), but
+-- then we'd need to go to extra trouble (and an additional flag)
+-- to allow users to ignore the optimisation level even though that
+-- means ignoring some change.
+optimisationFlags :: EnumSet GeneralFlag
+optimisationFlags = EnumSet.fromList
+   [ Opt_CallArity
+   , Opt_Strictness
+   , Opt_LateDmdAnal
+   , Opt_KillAbsence
+   , Opt_KillOneShot
+   , Opt_FullLaziness
+   , Opt_FloatIn
+   , Opt_Specialise
+   , Opt_SpecialiseAggressively
+   , Opt_CrossModuleSpecialise
+   , Opt_StaticArgumentTransformation
+   , Opt_CSE
+   , Opt_StgCSE
+   , Opt_LiberateCase
+   , Opt_SpecConstr
+   , Opt_SpecConstrKeen
+   , Opt_DoLambdaEtaExpansion
+   , Opt_IgnoreAsserts
+   , Opt_DoEtaReduction
+   , Opt_CaseMerge
+   , Opt_CaseFolding
+   , Opt_UnboxStrictFields
+   , Opt_UnboxSmallStrictFields
+   , Opt_DictsCheap
+   , Opt_EnableRewriteRules
+   , Opt_Vectorise
+   , Opt_VectorisationAvoidance
+   , Opt_RegsGraph
+   , Opt_RegsIterative
+   , Opt_PedanticBottoms
+   , Opt_LlvmTBAA
+   , Opt_LlvmPassVectorsInRegisters
+   , Opt_LlvmFillUndefWithGarbage
+   , Opt_IrrefutableTuples
+   , Opt_CmmSink
+   , Opt_CmmElimCommonBlocks
+   , Opt_OmitYields
+   , Opt_FunToThunk
+   , Opt_DictsStrict
+   , Opt_DmdTxDictSel
+   , Opt_Loopification
+   , Opt_CprAnal
+   , Opt_WorkerWrapper
+   , Opt_SolveConstantDicts
+   , Opt_CatchBottoms
+   , Opt_IgnoreAsserts
+   ]
+
 -- | Used when outputting warnings: if a reason is given, it is
 -- displayed. If a warning isn't controlled by a flag, this is made
 -- explicit at the point of use.
@@ -3754,6 +3817,8 @@ fFlagsDeps = [
   flagSpec "flat-cache"                       Opt_FlatCache,
   flagSpec "float-in"                         Opt_FloatIn,
   flagSpec "force-recomp"                     Opt_ForceRecomp,
+  flagSpec "ignore-optim-changes"             Opt_IgnoreOptimChanges,
+  flagSpec "ignore-hpc-changes"               Opt_IgnoreHpcChanges,
   flagSpec "full-laziness"                    Opt_FullLaziness,
   flagSpec "fun-to-thunk"                     Opt_FunToThunk,
   flagSpec "gen-manifest"                     Opt_GenManifest,
index b7baa57..fa0eed2 100644 (file)
@@ -857,7 +857,10 @@ data ModIface
         mi_iface_hash :: !Fingerprint,        -- ^ Hash of the whole interface
         mi_mod_hash   :: !Fingerprint,        -- ^ Hash of the ABI only
         mi_flag_hash  :: !Fingerprint,        -- ^ Hash of the important flags
-                                              -- used when compiling this module
+                                              -- used when compiling the module,
+                                              -- excluding optimisation flags
+        mi_opt_hash   :: !Fingerprint,        -- ^ Hash of optimisation flags
+        mi_hpc_hash   :: !Fingerprint,        -- ^ Hash of hpc flags
 
         mi_orphan     :: !WhetherHasOrphans,  -- ^ Whether this module has orphans
         mi_finsts     :: !WhetherHasFamInst,
@@ -1018,6 +1021,8 @@ instance Binary ModIface where
                  mi_iface_hash= iface_hash,
                  mi_mod_hash  = mod_hash,
                  mi_flag_hash = flag_hash,
+                 mi_opt_hash  = opt_hash,
+                 mi_hpc_hash  = hpc_hash,
                  mi_orphan    = orphan,
                  mi_finsts    = hasFamInsts,
                  mi_deps      = deps,
@@ -1044,6 +1049,8 @@ instance Binary ModIface where
         put_ bh iface_hash
         put_ bh mod_hash
         put_ bh flag_hash
+        put_ bh opt_hash
+        put_ bh hpc_hash
         put_ bh orphan
         put_ bh hasFamInsts
         lazyPut bh deps
@@ -1072,6 +1079,8 @@ instance Binary ModIface where
         iface_hash  <- get bh
         mod_hash    <- get bh
         flag_hash   <- get bh
+        opt_hash    <- get bh
+        hpc_hash    <- get bh
         orphan      <- get bh
         hasFamInsts <- get bh
         deps        <- lazyGet bh
@@ -1099,6 +1108,8 @@ instance Binary ModIface where
                  mi_iface_hash  = iface_hash,
                  mi_mod_hash    = mod_hash,
                  mi_flag_hash   = flag_hash,
+                 mi_opt_hash    = opt_hash,
+                 mi_hpc_hash    = hpc_hash,
                  mi_orphan      = orphan,
                  mi_finsts      = hasFamInsts,
                  mi_deps        = deps,
@@ -1136,6 +1147,8 @@ emptyModIface mod
                mi_iface_hash  = fingerprint0,
                mi_mod_hash    = fingerprint0,
                mi_flag_hash   = fingerprint0,
+               mi_opt_hash    = fingerprint0,
+               mi_hpc_hash    = fingerprint0,
                mi_orphan      = False,
                mi_finsts      = False,
                mi_hsc_src     = HsSrcFile,
index 7d6cfdd..246a278 100644 (file)
@@ -256,6 +256,12 @@ Compiler
 - Lots of other bugs. See `Trac <https://ghc.haskell.org/trac/ghc/query?status=closed&milestone=8.4.1&col=id&col=summary&col=status&col=type&col=priority&col=milestone&col=component&order=priority>`_
   for a complete list.
 
+- New flags :ghc-flag:`-fignore-optim-changes` and
+  :ghc-flag:`-fignore-hpc-changes` allow GHC to reuse previously compiled
+  modules even if they were compiled with different optimisation or HPC
+  flags. These options are enabled by default by :ghc-flag:`--interactive`.
+  See :ghc-ticket:`13604`
+
 Runtime system
 ~~~~~~~~~~~~~~
 
index 10ae28c..2375f63 100644 (file)
@@ -542,6 +542,23 @@ The recompilation checker
     existing ``.o`` file in place, if it can be determined that the
     module does not need to be recompiled.
 
+.. ghc-flag:: -fignore-optim-changes
+    :shortdesc: Do not recompile modules just to match changes to
+    optimisation flags. This is especially useful for avoiding
+    recompilation when using GHCi, and is enabled by default for
+    GHCi.
+    :type: dynamic
+    :reverse: -fno-ignore-optim-changes
+    :category: recompilation
+
+.. ghc-flag:: -fignore-hpc-changes
+    :shortdesc: Do not recompile modules just to match changes to
+    HPC flags. This is especially useful for avoiding recompilation
+    when using GHCi, and is enabled by default for GHCi.
+    :type: dynamic
+    :reverse: -fno-ignore-hpc-changes
+    :category: recompilation
+
 In the olden days, GHC compared the newly-generated ``.hi`` file with
 the previous version; if they were identical, it left the old one alone
 and didn't change its modification date. In consequence, importers of a
index 74b017a..b720dea 100644 (file)
@@ -179,10 +179,16 @@ main' postLoadMode dflags0 args flagWarnings = do
       -- can be overriden from the command-line
       -- XXX: this should really be in the interactive DynFlags, but
       -- we don't set that until later in interactiveUI
-      dflags2  | DoInteractive <- postLoadMode = imp_qual_enabled
-               | DoEval _      <- postLoadMode = imp_qual_enabled
+      -- We also set -fignore-optim-changes and -fignore-hpc-changes,
+      -- which are program-level options. Again, this doesn't really
+      -- feel like the right place to handle this, but we don't have
+      -- a great story for the moment.
+      dflags2  | DoInteractive <- postLoadMode = def_ghci_flags
+               | DoEval _      <- postLoadMode = def_ghci_flags
                | otherwise                     = dflags1
-        where imp_qual_enabled = dflags1 `gopt_set` Opt_ImplicitImportQualified
+        where def_ghci_flags = dflags1 `gopt_set` Opt_ImplicitImportQualified
+                                       `gopt_set` Opt_IgnoreOptimChanges
+                                       `gopt_set` Opt_IgnoreHpcChanges
 
         -- The rest of the arguments are "dynamic"
         -- Leftover ones are presumably files
index ffb924a..727cc44 100644 (file)
@@ -637,6 +637,20 @@ T10923:
        # should NOT output "compilation is NOT required"
        "$(TEST_HC)" $(TEST_HC_OPTS) -v1 -O -c T10923.hs
 
+.PHONY: T13604
+T13604:
+       $(RM) -rf T13604.o T13604.hi
+       "$(TEST_HC)" $(TEST_HC_OPTS) -v1 -O0 -c T13604.hs
+       # SHOULD output "compilation is NOT required"
+       "$(TEST_HC)" $(TEST_HC_OPTS) -v1 -O -c -fignore-optim-changes T13604.hs
+
+.PHONY: T13604a
+T13604a:
+       $(RM) -rf T13604a.o T13604a.hi
+       "$(TEST_HC)" $(TEST_HC_OPTS) -v1 -O0 -c -fhpc T13604a.hs
+       # SHOULD output "compilation is NOT required"
+       "$(TEST_HC)" $(TEST_HC_OPTS) -v1 -O0 -c -fignore-hpc-changes T13604a.hs
+
 .PHONY: T12955
 T12955:
        ! "$(TEST_HC)" $(TEST_HC_OPTS) --make T12955
diff --git a/testsuite/tests/driver/T13604.hs b/testsuite/tests/driver/T13604.hs
new file mode 100644 (file)
index 0000000..d98fb58
--- /dev/null
@@ -0,0 +1 @@
+module T13604 where
diff --git a/testsuite/tests/driver/T13604.stdout b/testsuite/tests/driver/T13604.stdout
new file mode 100644 (file)
index 0000000..ae02c1f
--- /dev/null
@@ -0,0 +1 @@
+compilation IS NOT required
diff --git a/testsuite/tests/driver/T13604a.hs b/testsuite/tests/driver/T13604a.hs
new file mode 100644 (file)
index 0000000..ea79324
--- /dev/null
@@ -0,0 +1 @@
+module T13604a where
diff --git a/testsuite/tests/driver/T13604a.stdout b/testsuite/tests/driver/T13604a.stdout
new file mode 100644 (file)
index 0000000..ae02c1f
--- /dev/null
@@ -0,0 +1 @@
+compilation IS NOT required
index 04d14aa..d443ed4 100644 (file)
@@ -5,11 +5,11 @@ main: Assertion failed
 CallStack (from HasCallStack):
   assert, called at main.hs:3:8 in main:Main
 With -fignore-asserts
-[1 of 1] Compiling Main             ( main.hs, main.o ) [flags changed]
+[1 of 1] Compiling Main             ( main.hs, main.o ) [Optimisation flags changed]
 Linking main ...
 OK
 Without -fignore-asserts
-[1 of 1] Compiling Main             ( main.hs, main.o ) [flags changed]
+[1 of 1] Compiling Main             ( main.hs, main.o ) [Optimisation flags changed]
 Linking main ...
 main: Assertion failed
 CallStack (from HasCallStack):
index 19dcc0a..a63513a 100644 (file)
@@ -271,3 +271,5 @@ test('T12955', normal, run_command, ['$MAKE -s --no-print-directory T12955'])
 test('T12971', ignore_stdout, run_command, ['$MAKE -s --no-print-directory T12971'])
 test('json', normal, compile_fail, ['-ddump-json'])
 test('json2', normal, compile, ['-ddump-types -ddump-json'])
+test('T13604', [], run_command, ['$MAKE -s --no-print-directory T13604'])
+test('T13604a', [], run_command, ['$MAKE -s --no-print-directory T13604a'])
index b2de541..c5be11a 100644 (file)
@@ -6,6 +6,8 @@ with the following modifiers:
 GHCi-specific dynamic flag settings:
 other dynamic, non-language, flag settings:
   -fno-diagnostics-show-caret
+  -fignore-optim-changes
+  -fignore-hpc-changes
   -fno-ghci-history
   -fimplicit-import-qualified
   -fshow-warning-groups
@@ -22,6 +24,8 @@ with the following modifiers:
 GHCi-specific dynamic flag settings:
 other dynamic, non-language, flag settings:
   -fno-diagnostics-show-caret
+  -fignore-optim-changes
+  -fignore-hpc-changes
   -fno-ghci-history
   -fimplicit-import-qualified
   -fshow-warning-groups
@@ -37,6 +41,8 @@ with the following modifiers:
 GHCi-specific dynamic flag settings:
 other dynamic, non-language, flag settings:
   -fno-diagnostics-show-caret
+  -fignore-optim-changes
+  -fignore-hpc-changes
   -fno-ghci-history
   -fimplicit-import-qualified
   -fshow-warning-groups
@@ -54,6 +60,8 @@ with the following modifiers:
 GHCi-specific dynamic flag settings:
 other dynamic, non-language, flag settings:
   -fno-diagnostics-show-caret
+  -fignore-optim-changes
+  -fignore-hpc-changes
   -fno-ghci-history
   -fimplicit-import-qualified
   -fshow-warning-groups
index 978b6f9..1247616 100644 (file)
@@ -7,6 +7,8 @@ with the following modifiers:
 GHCi-specific dynamic flag settings:
 other dynamic, non-language, flag settings:
   -fno-diagnostics-show-caret
+  -fignore-optim-changes
+  -fignore-hpc-changes
   -fno-ghci-history
   -fimplicit-import-qualified
   -fshow-warning-groups
index b2de541..c5be11a 100644 (file)
@@ -6,6 +6,8 @@ with the following modifiers:
 GHCi-specific dynamic flag settings:
 other dynamic, non-language, flag settings:
   -fno-diagnostics-show-caret
+  -fignore-optim-changes
+  -fignore-hpc-changes
   -fno-ghci-history
   -fimplicit-import-qualified
   -fshow-warning-groups
@@ -22,6 +24,8 @@ with the following modifiers:
 GHCi-specific dynamic flag settings:
 other dynamic, non-language, flag settings:
   -fno-diagnostics-show-caret
+  -fignore-optim-changes
+  -fignore-hpc-changes
   -fno-ghci-history
   -fimplicit-import-qualified
   -fshow-warning-groups
@@ -37,6 +41,8 @@ with the following modifiers:
 GHCi-specific dynamic flag settings:
 other dynamic, non-language, flag settings:
   -fno-diagnostics-show-caret
+  -fignore-optim-changes
+  -fignore-hpc-changes
   -fno-ghci-history
   -fimplicit-import-qualified
   -fshow-warning-groups
@@ -54,6 +60,8 @@ with the following modifiers:
 GHCi-specific dynamic flag settings:
 other dynamic, non-language, flag settings:
   -fno-diagnostics-show-caret
+  -fignore-optim-changes
+  -fignore-hpc-changes
   -fno-ghci-history
   -fimplicit-import-qualified
   -fshow-warning-groups
index 024b0dc..90142dd 100644 (file)
@@ -1,2 +1,2 @@
 [1 of 1] Compiling T11798           ( T11798.hs, T11798.o )
-[1 of 1] Compiling T11798           ( T11798.hs, T11798.o ) [flags changed]
+[1 of 1] Compiling T11798           ( T11798.hs, T11798.o ) [HPC flags changed]