summaryrefslogtreecommitdiff
path: root/compiler/iface
diff options
context:
space:
mode:
authorBartosz Nitka <niteria@gmail.com>2018-02-22 06:44:59 -0800
committerBartosz Nitka <niteria@gmail.com>2018-03-02 04:41:58 -0800
commitb8f03bbe16af7a09b494a33fbbe523ecd82f1a50 (patch)
tree0455b9ccf3682e510fc957c92f45341df2c43b96 /compiler/iface
parent2756117bd26c2cb70d3f51954a88b7d7bdf3d3f2 (diff)
downloadhaskell-b8f03bbe16af7a09b494a33fbbe523ecd82f1a50.tar.gz
Cache the fingerprint of sOpt_P
Before this change we would compute a hash of all the command line -optP flags once per file. With a lot of files and many -optP flags, that's a lot of repeated work. I added a new Note that explains the approach and rationale. Test Plan: new test Reviewers: simonmar, simonpj, bgamari Reviewed By: simonpj Subscribers: rwbarton, thomie, carter GHC Trac Issues: #14697 Differential Revision: https://phabricator.haskell.org/D4445
Diffstat (limited to 'compiler/iface')
-rw-r--r--compiler/iface/FlagChecker.hs37
1 files changed, 36 insertions, 1 deletions
diff --git a/compiler/iface/FlagChecker.hs b/compiler/iface/FlagChecker.hs
index 1fc597bdfe..2ef369a5e9 100644
--- a/compiler/iface/FlagChecker.hs
+++ b/compiler/iface/FlagChecker.hs
@@ -47,8 +47,10 @@ fingerprintDynFlags dflags@DynFlags{..} this_mod nameio =
-- -I, -D and -U flags affect CPP
cpp = ( map normalise $ flattenIncludes includePaths
- , opt_P dflags ++ picPOpts dflags)
-- normalise: eliminate spurious differences due to "./foo" vs "foo"
+ , picPOpts dflags
+ , opt_P_signature dflags)
+ -- See Note [Repeated -optP hashing]
-- Note [path flags and recompilation]
paths = [ hcSuf ]
@@ -144,3 +146,36 @@ 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.
-}
+
+{- Note [Repeated -optP hashing]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We invoke fingerprintDynFlags for each compiled module to include
+the hash of relevant DynFlags in the resulting interface file.
+-optP (preprocessor) flags are part of that hash.
+-optP flags can come from multiple places:
+
+ 1. -optP flags directly passed on command line.
+ 2. -optP flags implied by other flags. Eg. -DPROFILING implied by -prof.
+ 3. -optP flags added with {-# OPTIONS -optP-D__F__ #-} in a file.
+
+When compiling many modules at once with many -optP command line arguments
+the work of hashing -optP flags would be repeated. This can get expensive
+and as noted on #14697 it can take 7% of time and 14% of allocations on
+a real codebase.
+
+The obvious solution is to cache the hash of -optP flags per GHC invocation.
+However, one has to be careful there, as the flags that were added in 3. way
+have to be accounted for.
+
+The current strategy is as follows:
+
+ 1. Lazily compute the hash of sOpt_p in sOpt_P_fingerprint whenever sOpt_p
+ is modified. This serves dual purpose. It ensures correctness for when
+ we add per file -optP flags and lets us save work for when we don't.
+ 2. When computing the fingerprint in fingerprintDynFlags use the cached
+ value *and* fingerprint the additional implied (see 2. above) -optP flags.
+ This is relatively cheap and saves the headache of fingerprinting all
+ the -optP flags and tracking all the places that could invalidate the
+ cache.
+-}