Allow users to ignore optimization changes
[ghc.git] / compiler / iface / FlagChecker.hs
1 {-# LANGUAGE RecordWildCards #-}
2
3 -- | This module manages storing the various GHC option flags in a modules
4 -- interface file as part of the recompilation checking infrastructure.
5 module FlagChecker (
6 fingerprintDynFlags
7 , fingerprintOptFlags
8 , fingerprintHpcFlags
9 ) where
10
11 import GhcPrelude
12
13 import Binary
14 import BinIface ()
15 import DynFlags
16 import HscTypes
17 import Module
18 import Name
19 import Fingerprint
20 import BinFingerprint
21 -- import Outputable
22
23 import qualified EnumSet
24 import System.FilePath (normalise)
25
26 -- | Produce a fingerprint of a @DynFlags@ value. We only base
27 -- the finger print on important fields in @DynFlags@ so that
28 -- the recompilation checker can use this fingerprint.
29 --
30 -- NB: The 'Module' parameter is the 'Module' recorded by the
31 -- *interface* file, not the actual 'Module' according to our
32 -- 'DynFlags'.
33 fingerprintDynFlags :: DynFlags -> Module
34 -> (BinHandle -> Name -> IO ())
35 -> IO Fingerprint
36
37 fingerprintDynFlags dflags@DynFlags{..} this_mod nameio =
38 let mainis = if mainModIs == this_mod then Just mainFunIs else Nothing
39 -- see #5878
40 -- pkgopts = (thisPackage dflags, sort $ packageFlags dflags)
41 safeHs = setSafeMode safeHaskell
42 -- oflags = sort $ filter filterOFlags $ flags dflags
43
44 -- *all* the extension flags and the language
45 lang = (fmap fromEnum language,
46 map fromEnum $ EnumSet.toList extensionFlags)
47
48 -- -I, -D and -U flags affect CPP
49 cpp = (map normalise includePaths, opt_P dflags ++ picPOpts dflags)
50 -- normalise: eliminate spurious differences due to "./foo" vs "foo"
51
52 -- Note [path flags and recompilation]
53 paths = [ hcSuf ]
54
55 -- -fprof-auto etc.
56 prof = if gopt Opt_SccProfilingOn dflags then fromEnum profAuto else 0
57
58 flags = (mainis, safeHs, lang, cpp, paths, prof)
59
60 in -- pprTrace "flags" (ppr flags) $
61 computeFingerprint nameio flags
62
63 -- Fingerprint the optimisation info. We keep this separate from the rest of
64 -- the flags because GHCi users (especially) may wish to ignore changes in
65 -- optimisation level or optimisation flags so as to use as many pre-existing
66 -- object files as they can.
67 -- See Note [Ignoring some flag changes]
68 fingerprintOptFlags :: DynFlags
69 -> (BinHandle -> Name -> IO ())
70 -> IO Fingerprint
71 fingerprintOptFlags DynFlags{..} nameio =
72 let
73 -- See https://ghc.haskell.org/trac/ghc/ticket/10923
74 -- We used to fingerprint the optimisation level, but as Joachim
75 -- Breitner pointed out in comment 9 on that ticket, it's better
76 -- to ignore that and just look at the individual optimisation flags.
77 opt_flags = map fromEnum $ filter (`EnumSet.member` optimisationFlags)
78 (EnumSet.toList generalFlags)
79
80 in computeFingerprint nameio opt_flags
81
82 -- Fingerprint the HPC info. We keep this separate from the rest of
83 -- the flags because GHCi users (especially) may wish to use an object
84 -- file compiled for HPC when not actually using HPC.
85 -- See Note [Ignoring some flag changes]
86 fingerprintHpcFlags :: DynFlags
87 -> (BinHandle -> Name -> IO ())
88 -> IO Fingerprint
89 fingerprintHpcFlags dflags@DynFlags{..} nameio =
90 let
91 -- -fhpc, see https://ghc.haskell.org/trac/ghc/ticket/11798
92 -- hpcDir is output-only, so we should recompile if it changes
93 hpc = if gopt Opt_Hpc dflags then Just hpcDir else Nothing
94
95 in computeFingerprint nameio hpc
96
97
98 {- Note [path flags and recompilation]
99
100 There are several flags that we deliberately omit from the
101 recompilation check; here we explain why.
102
103 -osuf, -odir, -hisuf, -hidir
104 If GHC decides that it does not need to recompile, then
105 it must have found an up-to-date .hi file and .o file.
106 There is no point recording these flags - the user must
107 have passed the correct ones. Indeed, the user may
108 have compiled the source file in one-shot mode using
109 -o to specify the .o file, and then loaded it in GHCi
110 using -odir.
111
112 -stubdir
113 We omit this one because it is automatically set by -outputdir, and
114 we don't want changes in -outputdir to automatically trigger
115 recompilation. This could be wrong, but only in very rare cases.
116
117 -i (importPaths)
118 For the same reason as -osuf etc. above: if GHC decides not to
119 recompile, then it must have already checked all the .hi files on
120 which the current module depends, so it must have found them
121 successfully. It is occasionally useful to be able to cd to a
122 different directory and use -i flags to enable GHC to find the .hi
123 files; we don't want this to force recompilation.
124
125 The only path-related flag left is -hcsuf.
126 -}
127
128 {- Note [Ignoring some flag changes]
129 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
130
131 Normally, --make tries to reuse only compilation products that are
132 the same as those that would have been produced compiling from
133 scratch. Sometimes, however, users would like to be more aggressive
134 about recompilation avoidance. This is particularly likely when
135 developing using GHCi (see #13604). Currently, we allow users to
136 ignore optimisation changes using -fignore-optim-changes, and to
137 ignore HPC option changes using -fignore-hpc-changes. If there's a
138 demand for it, we could also allow changes to -fprof-auto-* flags
139 (although we can't allow -prof flags to differ). The key thing about
140 these options is that we can still successfully link a library or
141 executable when some of its components differ in these ways.
142
143 The way we accomplish this is to leave the optimization and HPC
144 options out of the flag hash, hashing them separately.
145 -}