Simon Jakobi pushed to branch wip/sjakobi/T25450-print-cpu at Glasgow Haskell Compiler / GHC
Commits:
-
d177606f
by Simon Jakobi at 2026-06-01T22:51:53+02:00
14 changed files:
- + changelog.d/print-enabled-cpu-features
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Session.hs
- docs/users_guide/using.rst
- ghc/GHC/Driver/Session/Lint.hs
- ghc/GHC/Driver/Session/Mode.hs
- ghc/Main.hs
- testsuite/tests/driver/all.T
- + testsuite/tests/driver/print_enabled_cpu_features.stdout
- + testsuite/tests/driver/print_enabled_cpu_features_avx2.stdout
- + testsuite/tests/driver/print_enabled_cpu_features_avx512.stdout
- + testsuite/tests/driver/print_enabled_cpu_features_bmi2.stdout
- + testsuite/tests/driver/print_enabled_cpu_features_fma.stdout
- + testsuite/tests/driver/print_enabled_cpu_features_unknown_flag.stderr
Changes:
| 1 | +section: compiler
|
|
| 2 | +synopsis: Add --print-enabled-cpu-features flag
|
|
| 3 | +issues: #25450
|
|
| 4 | +mrs: !16117
|
|
| 5 | + |
|
| 6 | +description:
|
|
| 7 | + GHC now supports a new mode flag ``--print-enabled-cpu-features``, which
|
|
| 8 | + prints a JSON object describing the CPU features currently enabled for code
|
|
| 9 | + generation, together with a set of ``-m...`` flags that reproduce the
|
|
| 10 | + effective feature set for the current target.
|
|
| 11 | + Dynamic options such as ``-mavx2`` and ``-mbmi2`` are respected. ::
|
|
| 12 | + |
|
| 13 | + $ ghc -mavx2 --print-enabled-cpu-features
|
|
| 14 | + {"tag":"enabled-cpu-features","version":1,"target":"x86_64-linux-gnu",
|
|
| 15 | + "features":["SSE","SSE2","SSE3","SSSE3","SSE4.1","SSE4.2","AVX","AVX2"],
|
|
| 16 | + "as_m_flags":["-mavx2"]} |
| ... | ... | @@ -1615,6 +1615,7 @@ initPromotionTickContext dflags = |
| 1615 | 1615 | |
| 1616 | 1616 | -- -----------------------------------------------------------------------------
|
| 1617 | 1617 | -- SSE, AVX, FMA
|
| 1618 | +-- See Note [Keeping enabledCpuFeatures in sync] in GHC.Driver.Session
|
|
| 1618 | 1619 | |
| 1619 | 1620 | isSse3Enabled :: DynFlags -> Bool
|
| 1620 | 1621 | isSse3Enabled dflags = sseAvxVersion dflags >= Just SSE3 || isAvxEnabled dflags
|
| ... | ... | @@ -1705,11 +1706,14 @@ We handle this as follows: |
| 1705 | 1706 | |
| 1706 | 1707 | -- -----------------------------------------------------------------------------
|
| 1707 | 1708 | -- LA664
|
| 1709 | +-- See Note [Keeping enabledCpuFeatures in sync] in GHC.Driver.Session
|
|
| 1710 | + |
|
| 1708 | 1711 | isLa664Enabled :: DynFlags -> Bool
|
| 1709 | 1712 | isLa664Enabled dflags = la664 dflags
|
| 1710 | 1713 | |
| 1711 | 1714 | -- -----------------------------------------------------------------------------
|
| 1712 | 1715 | -- BMI2
|
| 1716 | +-- See Note [Keeping enabledCpuFeatures in sync] in GHC.Driver.Session
|
|
| 1713 | 1717 | |
| 1714 | 1718 | isBmiEnabled :: DynFlags -> Bool
|
| 1715 | 1719 | isBmiEnabled dflags = case platformArch (targetPlatform dflags) of
|
| ... | ... | @@ -196,6 +196,8 @@ module GHC.Driver.Session ( |
| 196 | 196 | |
| 197 | 197 | -- * Compiler configuration suitable for display to the user
|
| 198 | 198 | compilerInfo,
|
| 199 | + showEnabledCpuFeatures,
|
|
| 200 | + enabledCpuFeatures,
|
|
| 199 | 201 | |
| 200 | 202 | targetHasRTSWays,
|
| 201 | 203 | |
| ... | ... | @@ -277,6 +279,7 @@ import GHC.Utils.TmpFs |
| 277 | 279 | import GHC.Utils.Fingerprint
|
| 278 | 280 | import GHC.Utils.Outputable
|
| 279 | 281 | import GHC.Utils.Error (emptyDiagOpts, logInfo)
|
| 282 | +import GHC.Utils.Json
|
|
| 280 | 283 | import GHC.Settings
|
| 281 | 284 | import GHC.CmmToAsm.CFG.Weight
|
| 282 | 285 | import GHC.Core.Opt.CallerCC
|
| ... | ... | @@ -3677,6 +3680,132 @@ compilerInfo dflags |
| 3677 | 3680 | queryCmdMaybe p f = expandDirectories (query (maybe "" (prgPath . p) . f))
|
| 3678 | 3681 | queryFlagsMaybe p f = query (maybe "" (unwords . map escapeArg . prgFlags . p) . f)
|
| 3679 | 3682 | |
| 3683 | +showEnabledCpuFeatures :: DynFlags -> String
|
|
| 3684 | +showEnabledCpuFeatures dflags = showSDocUnsafe $ renderJSON $ JSObject
|
|
| 3685 | + [ ("tag", JSString "enabled-cpu-features")
|
|
| 3686 | + -- Schema version of this JSON object; bump it whenever the shape or
|
|
| 3687 | + -- meaning of the fields changes, so consumers can detect incompatibility.
|
|
| 3688 | + , ("version", JSInt 1)
|
|
| 3689 | + , ("target", JSString (platformMisc_targetPlatformString (platformMisc dflags)))
|
|
| 3690 | + , ("features", JSArray (map JSString features))
|
|
| 3691 | + -- A set of `-m...` flags that, passed to GHC for this target, reproduce
|
|
| 3692 | + -- the effective feature set above. Note this need not be the flags the
|
|
| 3693 | + -- user actually passed: implied features are folded in, and a feature
|
|
| 3694 | + -- enabled by default may be reproduced by the empty set.
|
|
| 3695 | + , ("as_m_flags", JSArray (map JSString asMFlags))
|
|
| 3696 | + ]
|
|
| 3697 | + where
|
|
| 3698 | + (features, asMFlags) = enabledCpuFeatures dflags
|
|
| 3699 | + |
|
| 3700 | +{- Note [Keeping enabledCpuFeatures in sync]
|
|
| 3701 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 3702 | +`enabledCpuFeatures` must be updated whenever a new CPU feature flag is added
|
|
| 3703 | +to GHC. The three places to touch are, all in GHC.Driver.DynFlags:
|
|
| 3704 | + |
|
| 3705 | + 1. The flag registration (e.g. `make_ord_flag defGhcFlag "mnewfeat" ...`)
|
|
| 3706 | + 2. The corresponding `is*Enabled` predicate
|
|
| 3707 | + 3. The `enabledCpuFeatures` function below — add the feature to `features`
|
|
| 3708 | + and, if it has a GHC `-m...` flag, to `as_m_flags` via the appropriate
|
|
| 3709 | + architecture branch.
|
|
| 3710 | + |
|
| 3711 | +See Note [Implications between X86 CPU feature flags] in GHC.Driver.DynFlags
|
|
| 3712 | +for the implication structure that `x86FeaturesAndFlags` and `x86AsMFlags`
|
|
| 3713 | +must respect.
|
|
| 3714 | +-}
|
|
| 3715 | + |
|
| 3716 | +enabledCpuFeatures :: DynFlags -> ([String], [String])
|
|
| 3717 | +enabledCpuFeatures dflags = case platformArch (targetPlatform dflags) of
|
|
| 3718 | + ArchX86_64 -> x86FeaturesAndFlags dflags
|
|
| 3719 | + ArchX86 -> x86FeaturesAndFlags dflags
|
|
| 3720 | + ArchLoongArch64 ->
|
|
| 3721 | + ( fmaFeature ++ [ "LA664" | isLa664Enabled dflags ]
|
|
| 3722 | + , fmaFlag ++ [ "-mla664" | isLa664Enabled dflags ]
|
|
| 3723 | + )
|
|
| 3724 | + _ -> (fmaFeature, fmaFlag)
|
|
| 3725 | + where
|
|
| 3726 | + -- `-mfma` is a cross-platform flag. On x86 it is folded into the
|
|
| 3727 | + -- SSE/AVX hierarchy (handled in x86FeaturesAndFlags); on every other
|
|
| 3728 | + -- architecture FMA stands on its own and gates FMA codegen via
|
|
| 3729 | + -- isFmaEnabled in stgToCmmAllowFMAInstr. `fma dflags` is the source of
|
|
| 3730 | + -- truth (it defaults to True on AArch64).
|
|
| 3731 | + fmaFeature = [ "FMA" | fma dflags ]
|
|
| 3732 | + fmaFlag = [ "-mfma" | fma dflags ]
|
|
| 3733 | + |
|
| 3734 | +x86FeaturesAndFlags :: DynFlags -> ([String], [String])
|
|
| 3735 | +x86FeaturesAndFlags dflags =
|
|
| 3736 | + -- SSE/SSE2 are determined by the target platform rather than a dynamic
|
|
| 3737 | + -- flag, hence those predicates take Platform while the others take DynFlags.
|
|
| 3738 | + ( [ "SSE" | isSseEnabled platform ]
|
|
| 3739 | + ++ [ "SSE2" | isSse2Enabled platform ]
|
|
| 3740 | + ++ [ "SSE3" | isSse3Enabled dflags ]
|
|
| 3741 | + ++ [ "SSSE3" | isSsse3Enabled dflags ]
|
|
| 3742 | + ++ [ "SSE4.1" | isSse4_1Enabled dflags ]
|
|
| 3743 | + ++ [ "SSE4.2" | isSse4_2Enabled dflags ]
|
|
| 3744 | + ++ [ "AVX" | isAvxEnabled dflags ]
|
|
| 3745 | + ++ [ "AVX2" | isAvx2Enabled dflags ]
|
|
| 3746 | + ++ [ "AVX512F" | isAvx512fEnabled dflags ]
|
|
| 3747 | + ++ [ "AVX512BW" | isAvx512bwEnabled dflags ]
|
|
| 3748 | + ++ [ "AVX512CD" | isAvx512cdEnabled dflags ]
|
|
| 3749 | + ++ [ "AVX512DQ" | isAvx512dqEnabled dflags ]
|
|
| 3750 | + ++ [ "AVX512ER" | isAvx512erEnabled dflags ]
|
|
| 3751 | + ++ [ "AVX512PF" | isAvx512pfEnabled dflags ]
|
|
| 3752 | + ++ [ "AVX512VL" | isAvx512vlEnabled dflags ]
|
|
| 3753 | + ++ [ "BMI1" | isBmiEnabled dflags ]
|
|
| 3754 | + ++ [ "BMI2" | isBmi2Enabled dflags ]
|
|
| 3755 | + ++ [ "FMA" | isFmaEnabled dflags ]
|
|
| 3756 | + ++ [ "GFNI" | isGfniEnabled dflags ]
|
|
| 3757 | + , x86AsMFlags dflags
|
|
| 3758 | + )
|
|
| 3759 | + where
|
|
| 3760 | + platform = targetPlatform dflags
|
|
| 3761 | + |
|
| 3762 | +x86AsMFlags :: DynFlags -> [String]
|
|
| 3763 | +x86AsMFlags dflags =
|
|
| 3764 | + avx512Flags
|
|
| 3765 | + ++ vectorFlags
|
|
| 3766 | + ++ bmiFlags
|
|
| 3767 | + ++ fmaFlags
|
|
| 3768 | + ++ gfniFlags
|
|
| 3769 | + where
|
|
| 3770 | + avx512Extensions =
|
|
| 3771 | + [ ("-mavx512bw", avx512bw dflags)
|
|
| 3772 | + , ("-mavx512cd", avx512cd dflags)
|
|
| 3773 | + , ("-mavx512dq", avx512dq dflags)
|
|
| 3774 | + , ("-mavx512er", avx512er dflags)
|
|
| 3775 | + , ("-mavx512pf", avx512pf dflags)
|
|
| 3776 | + , ("-mavx512vl", avx512vl dflags)
|
|
| 3777 | + ]
|
|
| 3778 | + |
|
| 3779 | + hasAvx512Extension = any snd avx512Extensions
|
|
| 3780 | + hasAvx512 = avx512f dflags || hasAvx512Extension
|
|
| 3781 | + |
|
| 3782 | + avx512Flags =
|
|
| 3783 | + [ "-mavx512f" | avx512f dflags && not hasAvx512Extension ]
|
|
| 3784 | + ++ [ flag | (flag, True) <- avx512Extensions ]
|
|
| 3785 | + |
|
| 3786 | + vectorFlags
|
|
| 3787 | + | hasAvx512 = []
|
|
| 3788 | + | otherwise =
|
|
| 3789 | + case sseAvxVersion dflags of
|
|
| 3790 | + Just AVX2 -> ["-mavx2"]
|
|
| 3791 | + Just AVX1 -> ["-mavx"]
|
|
| 3792 | + Just SSE42 -> ["-msse4.2"]
|
|
| 3793 | + Just SSE4 -> ["-msse4"]
|
|
| 3794 | + Just SSSE3 -> ["-mssse3"]
|
|
| 3795 | + Just SSE3 -> ["-msse3"]
|
|
| 3796 | + _ -> []
|
|
| 3797 | + |
|
| 3798 | + bmiFlags = case bmiVersion dflags of
|
|
| 3799 | + Just BMI2 -> ["-mbmi2"]
|
|
| 3800 | + Just BMI1 -> ["-mbmi"]
|
|
| 3801 | + Nothing -> []
|
|
| 3802 | + |
|
| 3803 | + fmaFlags
|
|
| 3804 | + | fma dflags && not hasAvx512 = ["-mfma"]
|
|
| 3805 | + | otherwise = []
|
|
| 3806 | + |
|
| 3807 | + gfniFlags = [ "-mgfni" | gfni dflags ]
|
|
| 3808 | + |
|
| 3680 | 3809 | -- | Query if the target RTS has the given 'Ways'. It's computed from
|
| 3681 | 3810 | -- the @"RTS ways"@ field in the settings file.
|
| 3682 | 3811 | targetHasRTSWays :: DynFlags -> Ways -> Bool
|
| ... | ... | @@ -488,6 +488,16 @@ The available mode flags are: |
| 488 | 488 | List the flags passed to the C compiler for the linking step
|
| 489 | 489 | during GHC build.
|
| 490 | 490 | |
| 491 | +.. ghc-flag:: --print-enabled-cpu-features
|
|
| 492 | + :shortdesc: display the effective enabled CPU features for code generation
|
|
| 493 | + :type: mode
|
|
| 494 | + :category: modes
|
|
| 495 | + |
|
| 496 | + Print a JSON object describing the CPU features currently enabled for code
|
|
| 497 | + generation, together with a set of ``-m...`` flags that reproduce the
|
|
| 498 | + effective feature set for the current target.
|
|
| 499 | + Dynamic options such as ``-mavx2`` and ``-mbmi2`` are respected.
|
|
| 500 | + |
|
| 491 | 501 | .. ghc-flag:: --print-debug-on
|
| 492 | 502 | :shortdesc: print whether GHC was built with ``-DDEBUG``
|
| 493 | 503 | :type: mode
|
| 1 | 1 | {-# LANGUAGE CPP #-}
|
| 2 | 2 | {-# LANGUAGE NondecreasingIndentation #-}
|
| 3 | -module GHC.Driver.Session.Lint (checkOptions) where
|
|
| 3 | +module GHC.Driver.Session.Lint (checkOptions, unknownFlagsErr) where
|
|
| 4 | 4 | |
| 5 | 5 | import GHC.Driver.Backend
|
| 6 | 6 | import GHC.Driver.Phases
|
| ... | ... | @@ -77,6 +77,7 @@ isShowGhciUsageMode _ = False |
| 77 | 77 | |
| 78 | 78 | data PostLoadMode
|
| 79 | 79 | = ShowInterface FilePath -- ghc --show-iface
|
| 80 | + | PrintEnabledCpuFeatures -- ghc --print-enabled-cpu-features
|
|
| 80 | 81 | | DoMkDependHS -- ghc -M
|
| 81 | 82 | | StopBefore StopPhase -- ghc -E | -C | -S
|
| 82 | 83 | -- StopBefore StopLn is the default
|
| ... | ... | @@ -90,12 +91,13 @@ data PostLoadMode |
| 90 | 91 | | DoFrontend ModuleName -- ghc --frontend Plugin.Module
|
| 91 | 92 | |
| 92 | 93 | doMkDependHSMode, doMakeMode, doInteractiveMode, doRunMode,
|
| 93 | - doAbiHashMode, showUnitsMode :: Mode
|
|
| 94 | + doAbiHashMode, printEnabledCpuFeaturesMode, showUnitsMode :: Mode
|
|
| 94 | 95 | doMkDependHSMode = mkPostLoadMode DoMkDependHS
|
| 95 | 96 | doMakeMode = mkPostLoadMode DoMake
|
| 96 | 97 | doInteractiveMode = mkPostLoadMode DoInteractive
|
| 97 | 98 | doRunMode = mkPostLoadMode DoRun
|
| 98 | 99 | doAbiHashMode = mkPostLoadMode DoAbiHash
|
| 100 | +printEnabledCpuFeaturesMode = mkPostLoadMode PrintEnabledCpuFeatures
|
|
| 99 | 101 | showUnitsMode = mkPostLoadMode ShowPackages
|
| 100 | 102 | |
| 101 | 103 | showInterfaceMode :: FilePath -> Mode
|
| ... | ... | @@ -203,6 +205,8 @@ mode_flags = |
| 203 | 205 | , defFlag "-show-options" (PassFlag (setMode showOptionsMode))
|
| 204 | 206 | , defFlag "-supported-languages" (PassFlag (setMode showSupportedExtensionsMode))
|
| 205 | 207 | , defFlag "-supported-extensions" (PassFlag (setMode showSupportedExtensionsMode))
|
| 208 | + , defFlag "-print-enabled-cpu-features"
|
|
| 209 | + (PassFlag (setMode printEnabledCpuFeaturesMode))
|
|
| 206 | 210 | , defFlag "-show-packages" (PassFlag (setMode showUnitsMode))
|
| 207 | 211 | ] ++
|
| 208 | 212 | [ defFlag k' (PassFlag (setMode (printSetting k)))
|
| ... | ... | @@ -229,55 +229,64 @@ main' postLoadMode units dflags0 args flagWarnings = do |
| 229 | 229 | liftIO $ exitWith (ExitFailure 1)) $ do
|
| 230 | 230 | liftIO $ printOrThrowDiagnostics logger4 (initPrintConfig dflags4) diag_opts flagWarnings'
|
| 231 | 231 | |
| 232 | - liftIO $ showBanner postLoadMode dflags4
|
|
| 233 | - |
|
| 234 | - let (dflags5, srcs, objs) = parseTargetFiles dflags4 (map unLoc fileish_args)
|
|
| 235 | - |
|
| 236 | - -- we've finished manipulating the DynFlags, update the session
|
|
| 237 | - _ <- GHC.setSessionDynFlags dflags5
|
|
| 238 | - dflags6 <- GHC.getSessionDynFlags
|
|
| 239 | - |
|
| 240 | - -- Must do this before loading plugins
|
|
| 241 | - liftIO $ initUniqSupply (initialUnique dflags6) (uniqueIncrement dflags6)
|
|
| 242 | - |
|
| 243 | - -- Initialise plugins here because the plugin author might already expect this
|
|
| 244 | - -- subsequent call to `getLogger` to be affected by a plugin.
|
|
| 245 | - initializeSessionPlugins
|
|
| 246 | - hsc_env <- getSession
|
|
| 247 | - logger <- getLogger
|
|
| 248 | - |
|
| 249 | - |
|
| 250 | - ---------------- Display configuration -----------
|
|
| 251 | - case verbosity dflags6 of
|
|
| 252 | - v | v == 4 -> liftIO $ dumpUnitsSimple hsc_env
|
|
| 253 | - | v >= 5 -> liftIO $ dumpUnits hsc_env
|
|
| 254 | - | otherwise -> return ()
|
|
| 255 | - |
|
| 256 | - ---------------- Final sanity checking -----------
|
|
| 257 | - liftIO $ checkOptions postLoadMode dflags6 srcs objs units
|
|
| 258 | - |
|
| 259 | - ---------------- Do the business -----------
|
|
| 260 | - handleSourceError (\e -> do
|
|
| 261 | - GHC.printException e
|
|
| 262 | - liftIO $ exitWith (ExitFailure 1)) $ do
|
|
| 263 | - case postLoadMode of
|
|
| 264 | - ShowInterface f -> liftIO $ showIface logger
|
|
| 265 | - (hsc_dflags hsc_env)
|
|
| 266 | - (hsc_units hsc_env)
|
|
| 267 | - (hsc_NC hsc_env)
|
|
| 268 | - f
|
|
| 269 | - DoMake -> doMake units srcs
|
|
| 270 | - DoMkDependHS -> doMkDependHS (map fst srcs)
|
|
| 271 | - StopBefore p -> liftIO (oneShot hsc_env p srcs)
|
|
| 272 | - DoInteractive -> ghciUI units srcs Nothing
|
|
| 273 | - DoEval exprs -> ghciUI units srcs $ Just $ reverse exprs
|
|
| 274 | - DoRun -> doRun units srcs args
|
|
| 275 | - DoAbiHash -> abiHash (map fst srcs)
|
|
| 276 | - ShowPackages -> liftIO $ showUnits hsc_env
|
|
| 277 | - DoFrontend f -> doFrontend f srcs
|
|
| 278 | - DoBackpack -> doBackpack (map fst srcs)
|
|
| 279 | - |
|
| 280 | - liftIO $ dumpFinalStats logger
|
|
| 232 | + case postLoadMode of
|
|
| 233 | + PrintEnabledCpuFeatures -> liftIO $ do
|
|
| 234 | + -- This mode bypasses parseTargetFiles/checkOptions, so reject any
|
|
| 235 | + -- leftover flag-like arguments (e.g. a mistyped -mavx22) ourselves;
|
|
| 236 | + -- otherwise the typo would be silently ignored.
|
|
| 237 | + let unknown_opts = [ f | f@('-':_) <- map unLoc fileish_args ]
|
|
| 238 | + when (not (null unknown_opts)) (unknownFlagsErr unknown_opts)
|
|
| 239 | + putStrLn (showEnabledCpuFeatures dflags4)
|
|
| 240 | + _ -> do
|
|
| 241 | + liftIO $ showBanner postLoadMode dflags4
|
|
| 242 | + |
|
| 243 | + let (dflags5, srcs, objs) = parseTargetFiles dflags4 (map unLoc fileish_args)
|
|
| 244 | + |
|
| 245 | + -- we've finished manipulating the DynFlags, update the session
|
|
| 246 | + _ <- GHC.setSessionDynFlags dflags5
|
|
| 247 | + dflags6 <- GHC.getSessionDynFlags
|
|
| 248 | + |
|
| 249 | + -- Must do this before loading plugins
|
|
| 250 | + liftIO $ initUniqSupply (initialUnique dflags6) (uniqueIncrement dflags6)
|
|
| 251 | + |
|
| 252 | + -- Initialise plugins here because the plugin author might already expect this
|
|
| 253 | + -- subsequent call to `getLogger` to be affected by a plugin.
|
|
| 254 | + initializeSessionPlugins
|
|
| 255 | + hsc_env <- getSession
|
|
| 256 | + logger <- getLogger
|
|
| 257 | + |
|
| 258 | + |
|
| 259 | + ---------------- Display configuration -----------
|
|
| 260 | + case verbosity dflags6 of
|
|
| 261 | + v | v == 4 -> liftIO $ dumpUnitsSimple hsc_env
|
|
| 262 | + | v >= 5 -> liftIO $ dumpUnits hsc_env
|
|
| 263 | + | otherwise -> return ()
|
|
| 264 | + |
|
| 265 | + ---------------- Final sanity checking -----------
|
|
| 266 | + liftIO $ checkOptions postLoadMode dflags6 srcs objs units
|
|
| 267 | + |
|
| 268 | + ---------------- Do the business -----------
|
|
| 269 | + handleSourceError (\e -> do
|
|
| 270 | + GHC.printException e
|
|
| 271 | + liftIO $ exitWith (ExitFailure 1)) $ do
|
|
| 272 | + case postLoadMode of
|
|
| 273 | + ShowInterface f -> liftIO $ showIface logger
|
|
| 274 | + (hsc_dflags hsc_env)
|
|
| 275 | + (hsc_units hsc_env)
|
|
| 276 | + (hsc_NC hsc_env)
|
|
| 277 | + f
|
|
| 278 | + DoMake -> doMake units srcs
|
|
| 279 | + DoMkDependHS -> doMkDependHS (map fst srcs)
|
|
| 280 | + StopBefore p -> liftIO (oneShot hsc_env p srcs)
|
|
| 281 | + DoInteractive -> ghciUI units srcs Nothing
|
|
| 282 | + DoEval exprs -> ghciUI units srcs $ Just $ reverse exprs
|
|
| 283 | + DoRun -> doRun units srcs args
|
|
| 284 | + DoAbiHash -> abiHash (map fst srcs)
|
|
| 285 | + ShowPackages -> liftIO $ showUnits hsc_env
|
|
| 286 | + DoFrontend f -> doFrontend f srcs
|
|
| 287 | + DoBackpack -> doBackpack (map fst srcs)
|
|
| 288 | + |
|
| 289 | + liftIO $ dumpFinalStats logger
|
|
| 281 | 290 | |
| 282 | 291 | doRun :: [String] -> [(FilePath, Maybe Phase)] -> [Located String] -> Ghc ()
|
| 283 | 292 | doRun units srcs args = do
|
| ... | ... | @@ -515,4 +524,3 @@ abiHash strs = do |
| 515 | 524 | f <- fingerprintBinMem bh
|
| 516 | 525 | |
| 517 | 526 | putStrLn (showPpr dflags f) |
| 518 | - |
| 1 | +def normalise_enabled_cpu_target(msg):
|
|
| 2 | + return re.sub(r'"target":"[^"]+"', '"target":"TARGET"', msg)
|
|
| 3 | + |
|
| 4 | +def normalise_unknown_flag(msg):
|
|
| 5 | + # Keep only the stable 'unrecognised flag' line; the program-name prefix,
|
|
| 6 | + # the suggestion list, and the usage trailer vary across configurations.
|
|
| 7 | + m = re.search(r'unrecognised flag: \S+', msg)
|
|
| 8 | + return m.group(0) + '\n' if m else msg
|
|
| 9 | + |
|
| 1 | 10 | test('driver011', [extra_files(['A011.hs'])], makefile_test, ['test011'])
|
| 2 | 11 | |
| 3 | 12 | test('driver012', [extra_files(['A012.hs'])], makefile_test, ['test012'])
|
| ... | ... | @@ -221,6 +230,41 @@ test('T9938B', [], makefile_test, []) |
| 221 | 230 | test('T9963', exit_code(1), run_command,
|
| 222 | 231 | ['{compiler} --interactive -ignore-dot-ghci --print-libdir'])
|
| 223 | 232 | |
| 233 | +test('print_enabled_cpu_features',
|
|
| 234 | + [unless(arch('x86_64') or arch('i386'), skip),
|
|
| 235 | + normalise_fun(normalise_enabled_cpu_target)],
|
|
| 236 | + run_command,
|
|
| 237 | + ['{compiler} --print-enabled-cpu-features'])
|
|
| 238 | + |
|
| 239 | +test('print_enabled_cpu_features_avx2',
|
|
| 240 | + [unless(arch('x86_64') or arch('i386'), skip),
|
|
| 241 | + normalise_fun(normalise_enabled_cpu_target)],
|
|
| 242 | + run_command,
|
|
| 243 | + ['{compiler} -mavx2 --print-enabled-cpu-features'])
|
|
| 244 | + |
|
| 245 | +test('print_enabled_cpu_features_bmi2',
|
|
| 246 | + [unless(arch('x86_64') or arch('i386'), skip),
|
|
| 247 | + normalise_fun(normalise_enabled_cpu_target)],
|
|
| 248 | + run_command,
|
|
| 249 | + ['{compiler} -mbmi2 --print-enabled-cpu-features'])
|
|
| 250 | + |
|
| 251 | +test('print_enabled_cpu_features_fma',
|
|
| 252 | + [unless(arch('x86_64') or arch('i386'), skip),
|
|
| 253 | + normalise_fun(normalise_enabled_cpu_target)],
|
|
| 254 | + run_command,
|
|
| 255 | + ['{compiler} -mfma --print-enabled-cpu-features'])
|
|
| 256 | + |
|
| 257 | +test('print_enabled_cpu_features_avx512',
|
|
| 258 | + [unless(arch('x86_64'), skip),
|
|
| 259 | + normalise_fun(normalise_enabled_cpu_target)],
|
|
| 260 | + run_command,
|
|
| 261 | + ['{compiler} -mavx512dq -mavx512vl --print-enabled-cpu-features'])
|
|
| 262 | + |
|
| 263 | +test('print_enabled_cpu_features_unknown_flag',
|
|
| 264 | + [normalise_fun(normalise_unknown_flag), exit_code(1)],
|
|
| 265 | + run_command,
|
|
| 266 | + ['{compiler} -mavx22 --print-enabled-cpu-features'])
|
|
| 267 | + |
|
| 224 | 268 | test('T10219', normal, run_command,
|
| 225 | 269 | # `-x hspp` in make mode should work.
|
| 226 | 270 | # Note: need to specify `-x hspp` before the filename.
|
| 1 | +{"tag":"enabled-cpu-features","version":1,"target":"TARGET","features":["SSE","SSE2"],"as_m_flags":[]} |
| 1 | +{"tag":"enabled-cpu-features","version":1,"target":"TARGET","features":["SSE","SSE2","SSE3","SSSE3","SSE4.1","SSE4.2","AVX","AVX2"],"as_m_flags":["-mavx2"]} |
| 1 | +{"tag":"enabled-cpu-features","version":1,"target":"TARGET","features":["SSE","SSE2","SSE3","SSSE3","SSE4.1","SSE4.2","AVX","AVX2","AVX512F","AVX512DQ","AVX512VL","FMA"],"as_m_flags":["-mavx512dq","-mavx512vl"]} |
| 1 | +{"tag":"enabled-cpu-features","version":1,"target":"TARGET","features":["SSE","SSE2","BMI1","BMI2"],"as_m_flags":["-mbmi2"]} |
| 1 | +{"tag":"enabled-cpu-features","version":1,"target":"TARGET","features":["SSE","SSE2","SSE3","SSSE3","SSE4.1","SSE4.2","AVX","FMA"],"as_m_flags":["-mfma"]} |
| 1 | +ghc: unrecognised flag: -mavx22
|
|
| 2 | +did you mean one of:
|
|
| 3 | + -mavx2
|
|
| 4 | + -mavx
|
|
| 5 | + |
|
| 6 | +Usage: For basic information, try the `--help' option. |