diff --git a/CHANGES.md b/CHANGES.md
index c502a17b0ec89beac49f792535603148a12762c1..55f28c2e58916f4d727f378169150e06c730bd48 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,5 +1,16 @@
 ## Changes in 2.28.0
- * Support qualified and unqualified names in `--ignore-link-symbol`
+ * `hi-haddock` is integrated, which means docstrings are no longer extracted
+   through typchecked module results. Instead, docstrings are taken from Haskell
+   interface (`.hi`) files.
+
+ * Support qualified and unqualified names in `--ignore-link-symbol`.
+
+ * Add `--trace-args` flag which prints arguments to standard output. This is
+   useful for examining arguments passed when Haddock is invoked through `cabal
+   haddock`, as `cabal` uses temporary response files to pass arguments to
+   Haddock.
+
+ * Avoid recompilation due to changes in optimization flags.
 
 ## Changes in 2.24.0
 
diff --git a/doc/invoking.rst b/doc/invoking.rst
index b5a4d1de1944d9870ba29f2f1e4ed129756e4997..6de7f2508aa84bda3e526c4c22d7e9d53cb4894a 100644
--- a/doc/invoking.rst
+++ b/doc/invoking.rst
@@ -179,7 +179,7 @@ The following options are available:
       * Every entity should span exactly one line. ::
 
             newtype ReaderT r (m :: * -> *) a :: * -> (* -> *) -> * -> *
-          
+
         The one exception to this rule is classes. The body of a class
         is split up with one class member per line, an opening brace on
         the line of the header, and a closing brace on a new line after
@@ -190,7 +190,7 @@ The following options are available:
                 type family Baz a;
                 type Baz a = [(a, a)];
             }
-      
+
       * Entites that are exported only indirectly (for instance data
         constructors visible via a ``ReaderT(..)`` export) have their names
         wrapped in square brackets. ::
@@ -535,6 +535,13 @@ The following options are available:
 
     Print extra information about any undocumented entities.
 
+.. option:: --trace-args
+
+    Make Haddock print the arguments it receives to standard output. This is
+    useful for examining arguments when invoking through `cabal haddock`, as
+    `cabal` uses temporary `response files
+    <https://gcc.gnu.org/wiki/Response_Files>`_ to pass arguments to Haddock.
+
 Using literate or pre-processed source
 --------------------------------------
 
diff --git a/haddock-api/src/Haddock.hs b/haddock-api/src/Haddock.hs
index 2012118198a915254a8366bac486140e552ea66d..6cb9e09f98917376c3659b79338d74d560297240 100644
--- a/haddock-api/src/Haddock.hs
+++ b/haddock-api/src/Haddock.hs
@@ -157,6 +157,12 @@ haddockWithGhc ghc args = handleTopExceptions $ do
   -- or which exits with an error or help message.
   (flags, files) <- parseHaddockOpts args
   shortcutFlags flags
+
+  -- If argument tracing is enabled, print the arguments we were given
+  when (Flag_TraceArgs `elem` flags) $ do
+    putStrLn $ "haddock received arguments:"
+    mapM_ (putStrLn . ("  " ++)) args
+
   qual <- rightOrThrowE (qualification flags)
   sinceQual <- rightOrThrowE (sinceQualification flags)
 
@@ -562,7 +568,7 @@ withGhc' libDir needHieFiles flags ghcActs = runGhc (Just libDir) $ do
     logger <- getLogger
     dynflags' <- parseGhcFlags logger =<< getSessionDynFlags
 
-    -- We disable pattern match warnings because than can be very
+    -- We disable pattern match warnings because they can be very
     -- expensive to check
     let dynflags'' = unsetPatternMatchWarnings $ updOptLevel 0 dynflags'
 
@@ -587,12 +593,14 @@ withGhc' libDir needHieFiles flags ghcActs = runGhc (Just libDir) $ do
       -- TODO: handle warnings?
 
       let extra_opts =
-            [ Opt_Haddock
-              -- Include docstrings in .hi-files.
+            [ -- Include docstrings in .hi files.
+              Opt_Haddock
 
-            -- , Opt_WriteInterface
-              -- If we can't use an old .hi-file, save the new one.
-            ] ++ if needHieFiles
+              -- Do not recompile because of changes to optimization flags
+            , Opt_IgnoreOptimChanges
+            ]
+              -- Write .hie files if we need them for hyperlinked src
+              ++ if needHieFiles
                     then [Opt_WriteHie] -- Generate .hie-files
                     else []
           dynflags' = (foldl' gopt_set dynflags extra_opts)
diff --git a/haddock-api/src/Haddock/Options.hs b/haddock-api/src/Haddock/Options.hs
index 5276ca15e3db46f4717b06eac98904a6398a276a..a912eb8c91f80b9363186c15c45e64ff21d50724 100644
--- a/haddock-api/src/Haddock/Options.hs
+++ b/haddock-api/src/Haddock/Options.hs
@@ -120,6 +120,7 @@ data Flag
   | Flag_SinceQualification String
   | Flag_IgnoreLinkSymbol String
   | Flag_ParCount (Maybe Int)
+  | Flag_TraceArgs
   deriving (Eq, Show)
 
 
@@ -237,7 +238,9 @@ options backwardsCompat =
     Option [] ["ignore-link-symbol"] (ReqArg Flag_IgnoreLinkSymbol "SYMBOL")
       "name of a symbol which does not trigger a warning in case of link issue",
     Option ['j'] [] (OptArg (\count -> Flag_ParCount (fmap read count)) "n")
-      "load modules in parallel"
+      "load modules in parallel",
+    Option []  ["trace-args"]  (NoArg Flag_TraceArgs)
+      "print the arguments provided for this invocation to stdout"
   ]