Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ Major changes:

Behavior changes:

* From GHC 9.4.1, the strategy for the automatic insertion of cost-centres for
profiling recommended by the GHC User's Guide is `-fprof-late`. Stack's
`build --profile` command now adopts that recommendation (rather than
`-fprof-auto`, still applicable to earlier GHC versions). Existing profiling
builds will be rebuilt.

Other enhancements:

* Consider Cabal 3.18 to be a tested library and remove warnings.
Expand Down
24 changes: 14 additions & 10 deletions doc/commands/build_command.md
Original file line number Diff line number Diff line change
Expand Up @@ -979,20 +979,24 @@ expressions, and generate a profiling report in tests or benchmarks.

GHC provides various strategies for the automatic insertion of cost-centres into
the compiled program. The flag enables the strategy recommended in the GHC
User's Guide (GHC flag `-fprof-auto`) and gives every Constant Applicative Form
(CAF, a top-level thunk) its own cost-centre stack) (GHC flag `-fprof-cafs`).
User's Guide and gives every Constant Applicative Form (CAF, a top-level thunk)
its own cost-centre stack) (GHC flag `-fprof-cafs`).

!!! note
The recommended strategy:

From GHC 9.4.1, the stategy recommended in the GHC User's Guide has been
`-fprof-late`. Stack has not yet been updated to reflect that.
* **for GHC 9.4.1 and later**, is enabled by GHC flag `-fprof-late`. This
strategy annotates, after GHC's optimizer has run and unfoldings have been
created, all top-level bindings (only) with `SCC` (Set Cost Centre). If a
function is inlined into a use site its costs will be counted against the
caller’s cost-centre; and

The recommended strategy annotates, before GHC's optimizer has run, all bindings (top-level or nested, whether exported or not), other than those marked
`INLINE`, with `SCC` (Set Cost Centre).
* **otherwise**, is enabled by GHC flag `-fprof-auto`. This strategy annotates,
before GHC's optimizer has run, all bindings (top-level or nested, whether
exported or not), other than those marked `INLINE`, with `SCC`.

The GHC flags set by the flag can be reversed with GHC flags `-fno-prof-auto` or
`-fno-prof-cafs` and other GHC flags applied. See the
[`--ghc-options`](#-ghc-options-option) option.
The GHC flags set by the flag can be reversed with GHC flags `-fno-prof-late` or
`-fno-prof-auto` (as applicable) or `-fno-prof-cafs` and other GHC flags
applied. See the [`--ghc-options`](#-ghc-options-option) option.

The flag affects the location of the local project installation directory. See
the [`stack path --local-install-root`](path_command.md) command.
Expand Down
16 changes: 12 additions & 4 deletions src/Stack/Build/Source.hs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ loadSourceMap targets boptsCli sma = do
bconfig <- view buildConfigL
let errsPackages = mapMaybe checkPackage packagesWithCliFlags
compiler = sma.compiler
ghcVersion = getGhcVersion compiler
buildOpts = bconfig.config.build
infoTableProfSupported = ghcVersion >= mkVersion [9, 2, 1]
infoTableProfUnsupportedWarning =
Expand Down Expand Up @@ -146,6 +145,7 @@ loadSourceMap targets boptsCli sma = do
, globalPkgs
}
where
ghcVersion = getGhcVersion sma.compiler
cliFlags = boptsCli.flags
targetsAndSmaDeps = targets.deps <> sma.deps
packagesWithCliFlags = mapMaybe maybeProjectWithCliFlags $ Map.toList cliFlags
Expand Down Expand Up @@ -212,6 +212,7 @@ loadSourceMap targets boptsCli sma = do
ghcOptions = generalGhcOptions
bconfig
boptsCli
ghcVersion
isTarget
isProjectPackage
isInfoTableProf
Expand Down Expand Up @@ -276,7 +277,7 @@ hashSourceMapData boptsCli sm = do
isInfoTableProf =
ghcVersion >= mkVersion [9, 2, 1] && bc.config.build.infoTableProf
bootGhcOpts =
map display (generalGhcOptions bc boptsCli False False isInfoTableProf)
map display (generalGhcOptions bc boptsCli ghcVersion False False isInfoTableProf)
hashedContent =
toLazyByteString $ compilerPath
<> compilerInfo
Expand Down Expand Up @@ -337,11 +338,12 @@ generalCabalConfigOpts bconfig boptsCli name isTarget isLocal = concat
generalGhcOptions ::
BuildConfig
-> BuildOptsCLI
-> Version
-> Bool
-> Bool
-> Bool
-> [Text]
generalGhcOptions bconfig boptsCli isTarget isLocal isInfoTableProf = concat
generalGhcOptions bconfig boptsCli ghcVersion isTarget isLocal isInfoTableProf = concat
[ Map.findWithDefault [] AGOEverything config.ghcOptionsByCat
, if isLocal
then Map.findWithDefault [] AGOLocals config.ghcOptionsByCat
Expand All @@ -351,7 +353,7 @@ generalGhcOptions bconfig boptsCli isTarget isLocal isInfoTableProf = concat
else []
, concat [["-fhpc"] | isLocal && bopts.testOpts.coverage]
, if bopts.libProfile || bopts.exeProfile
then ["-fprof-auto", "-fprof-cafs"]
then [recommendedProfStrategy, "-fprof-cafs"]
else []
, [ "-g" | not $ bopts.libStrip || bopts.exeStrip ]
, if isInfoTableProf
Expand All @@ -364,6 +366,12 @@ generalGhcOptions bconfig boptsCli isTarget isLocal isInfoTableProf = concat
where
bopts = config.build
config = view configL bconfig
-- The strategy for the automatic insertion of cost centres for profiling, as
-- recommended by the GHC User's Guide:
recommendedProfStrategy :: Text
recommendedProfStrategy
| ghcVersion >= mkVersion [9, 4, 1] = "-fprof-late"
| otherwise = "-fprof-auto"
includeExtraOptions =
case config.applyGhcOptions of
AGOTargets -> isTarget
Expand Down
6 changes: 6 additions & 0 deletions src/Stack/ConfigureOpts.hs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,12 @@ configureOptsNonPathRelated econfig bco deps isLocal package = concat
| bopts.libProfile || bopts.exeProfile
]
, ["--enable-profiling" | bopts.exeProfile && isLocal]
-- The default --profiling-detail is exported-functions (equivalent to GHC's
-- -fprof-auto-exported) and toplevel-functions (equivalent to GHC's
-- -fprof-auto-top). Neither adds anything to GHC's -fprof-auto and neither
-- are required for GHC's -fprof-late. So, we turn it off, which applies to
-- both executables and libraries:
, ["--profiling-detail=none"]
, ["--enable-split-objs" | bopts.splitObjs]
, [ "--disable-library-stripping"
| not $ bopts.libStrip || bopts.exeStrip
Expand Down
Loading