diff options
author | Sylvain Henry <sylvain@haskus.fr> | 2020-06-29 22:36:40 +0200 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2020-07-22 20:19:59 -0400 |
commit | f7cc431341e5b5b31758eecc8504cae8b2390c10 (patch) | |
tree | 7404d90376432d5a311a7fc6355b02085a1a5367 /compiler | |
parent | 735f9d6bac316a0c1c68a8b49bba465f07b01cdd (diff) | |
download | haskell-f7cc431341e5b5b31758eecc8504cae8b2390c10.tar.gz |
Replace HscTarget with Backend
They both have the same role and Backend name is more explicit.
Metric Decrease:
T3064
Update Haddock submodule
Diffstat (limited to 'compiler')
25 files changed, 305 insertions, 249 deletions
diff --git a/compiler/GHC.hs b/compiler/GHC.hs index d5d15143c2..f61c93ea2d 100644 --- a/compiler/GHC.hs +++ b/compiler/GHC.hs @@ -27,8 +27,8 @@ module GHC ( needsTemplateHaskellOrQQ, -- * Flags and settings - DynFlags(..), GeneralFlag(..), Severity(..), HscTarget(..), gopt, - GhcMode(..), GhcLink(..), defaultObjectTarget, + DynFlags(..), GeneralFlag(..), Severity(..), Backend(..), gopt, + GhcMode(..), GhcLink(..), parseDynamicFlags, getSessionDynFlags, setSessionDynFlags, getProgramDynFlags, setProgramDynFlags, setLogAction, @@ -302,6 +302,7 @@ import GHC.Runtime.Interpreter.Types import GHCi.RemoteTypes import GHC.Core.Ppr.TyThing ( pprFamInst ) +import GHC.Driver.Backend import GHC.Driver.Main import GHC.Driver.Make import GHC.Driver.Hooks @@ -1012,7 +1013,7 @@ desugarModule tcm = do -- -- A module must be loaded before dependent modules can be typechecked. This -- always includes generating a 'ModIface' and, depending on the --- @DynFlags@\'s 'GHC.Driver.Session.hscTarget', may also include code generation. +-- @DynFlags@\'s 'GHC.Driver.Session.backend', may also include code generation. -- -- This function will always cause recompilation and will always overwrite -- previous compilation results (potentially files on disk). diff --git a/compiler/GHC/Cmm/CLabel.hs b/compiler/GHC/Cmm/CLabel.hs index 47487c7ebe..ab1ecede5f 100644 --- a/compiler/GHC/Cmm/CLabel.hs +++ b/compiler/GHC/Cmm/CLabel.hs @@ -129,6 +129,7 @@ import GHC.Types.CostCentre import GHC.Utils.Outputable import GHC.Data.FastString import GHC.Driver.Session +import GHC.Driver.Backend import GHC.Platform import GHC.Types.Unique.Set import GHC.Utils.Misc @@ -1255,7 +1256,7 @@ pprCLabel dflags = \case where platform = targetPlatform dflags - useNCG = hscTarget dflags == HscAsm + useNCG = backend dflags == NCG maybe_underscore :: SDoc -> SDoc maybe_underscore doc = diff --git a/compiler/GHC/Cmm/Pipeline.hs b/compiler/GHC/Cmm/Pipeline.hs index e28c880d44..876de8a41e 100644 --- a/compiler/GHC/Cmm/Pipeline.hs +++ b/compiler/GHC/Cmm/Pipeline.hs @@ -24,6 +24,7 @@ import GHC.Cmm.Dataflow.Collections import GHC.Types.Unique.Supply import GHC.Driver.Session +import GHC.Driver.Backend import GHC.Utils.Error import GHC.Driver.Types import Control.Monad @@ -171,7 +172,7 @@ cpsTop hsc_env proc = -- tablesNextToCode is off. The latter is because we have no -- label to put on info tables for basic blocks that are not -- the entry point. - splitting_proc_points = hscTarget dflags /= HscAsm + splitting_proc_points = backend dflags /= NCG || not (platformTablesNextToCode platform) || -- Note [inconsistent-pic-reg] usingInconsistentPicReg diff --git a/compiler/GHC/Cmm/Switch.hs b/compiler/GHC/Cmm/Switch.hs index b8d7456b37..ee0d5a07df 100644 --- a/compiler/GHC/Cmm/Switch.hs +++ b/compiler/GHC/Cmm/Switch.hs @@ -8,14 +8,14 @@ module GHC.Cmm.Switch ( switchTargetsToList, eqSwitchTargetWith, SwitchPlan(..), - targetSupportsSwitch, + backendSupportsSwitch, createSwitchPlan, ) where import GHC.Prelude import GHC.Utils.Outputable -import GHC.Driver.Session +import GHC.Driver.Backend import GHC.Cmm.Dataflow.Label (Label) import Data.Maybe @@ -316,12 +316,12 @@ and slowed down all other cases making it not worthwhile. -} --- | Does the target support switch out of the box? Then leave this to the --- target! -targetSupportsSwitch :: HscTarget -> Bool -targetSupportsSwitch HscC = True -targetSupportsSwitch HscLlvm = True -targetSupportsSwitch _ = False +-- | Does the backend support switch out of the box? Then leave this to the +-- backend! +backendSupportsSwitch :: Backend -> Bool +backendSupportsSwitch ViaC = True +backendSupportsSwitch LLVM = True +backendSupportsSwitch _ = False -- | This function creates a SwitchPlan from a SwitchTargets value, breaking it -- down into smaller pieces suitable for code generation. diff --git a/compiler/GHC/Cmm/Switch/Implement.hs b/compiler/GHC/Cmm/Switch/Implement.hs index 3279c5ab05..a91809e585 100644 --- a/compiler/GHC/Cmm/Switch/Implement.hs +++ b/compiler/GHC/Cmm/Switch/Implement.hs @@ -35,7 +35,7 @@ import GHC.Utils.Monad (concatMapM) cmmImplementSwitchPlans :: DynFlags -> CmmGraph -> UniqSM CmmGraph cmmImplementSwitchPlans dflags g -- Switch generation done by backend (LLVM/C) - | targetSupportsSwitch (hscTarget dflags) = return g + | backendSupportsSwitch (backend dflags) = return g | otherwise = do blocks' <- concatMapM (visitSwitches (targetPlatform dflags)) (toBlockList g) return $ ofBlockList (g_entry g) blocks' diff --git a/compiler/GHC/Driver/Backend.hs b/compiler/GHC/Driver/Backend.hs index 8f227d2a2b..845a5f36c0 100644 --- a/compiler/GHC/Driver/Backend.hs +++ b/compiler/GHC/Driver/Backend.hs @@ -5,18 +5,82 @@ module GHC.Driver.Backend ( Backend (..) , platformDefaultBackend , platformNcgSupported + , backendProducesObject + , backendRetainsAllBindings ) where import GHC.Prelude import GHC.Platform --- | Backend +-- | Code generation backends. +-- +-- GHC supports several code generation backends serving different purposes +-- (producing machine code, producing ByteCode for the interpreter) and +-- supporting different platforms. +-- data Backend - = NCG -- ^ Native code generator backend - | LLVM -- ^ LLVM backend - | ViaC -- ^ Via-C backend - | Interpreter -- ^ Interpreter + = NCG -- ^ Native code generator backend. + -- + -- Compiles Cmm code into textual assembler, then relies on + -- an external assembler toolchain to produce machine code. + -- + -- Only supports a few platforms (X86, PowerPC, SPARC). + -- + -- See "GHC.CmmToAsm". + + + | LLVM -- ^ LLVM backend. + -- + -- Compiles Cmm code into LLVM textual IR, then relies on + -- LLVM toolchain to produce machine code. + -- + -- It relies on LLVM support for the calling convention used + -- by the NCG backend to produce code objects ABI compatible + -- with it (see "cc 10" or "ghccc" calling convention in + -- https://llvm.org/docs/LangRef.html#calling-conventions). + -- + -- Support a few platforms (X86, AArch64, s390x, ARM). + -- + -- See "GHC.CmmToLlvm" + + + | ViaC -- ^ Via-C backend. + -- + -- Compiles Cmm code into C code, then relies on a C compiler + -- to produce machine code. + -- + -- It produces code objects that are *not* ABI compatible + -- with those produced by NCG and LLVM backends. + -- + -- Produced code is expected to be less efficient than the + -- one produced by NCG and LLVM backends because STG + -- registers are not pinned into real registers. On the + -- other hand, it supports more target platforms (those + -- having a valid C toolchain). + -- + -- See "GHC.CmmToC" + + + | Interpreter -- ^ ByteCode interpreter. + -- + -- Produce ByteCode objects (BCO, see "GHC.ByteCode") that + -- can be interpreted. It is used by GHCi. + -- + -- Currently some extensions are not supported (unboxed + -- tuples/sums, foreign primops). + -- + -- See "GHC.CoreToByteCode" + + + | NoBackend -- ^ No code generated. + -- + -- Use this to disable code generation. It is particularly + -- useful when GHC is used as a library for other purpose + -- than generating code (e.g. to generate documentation with + -- Haddock) or when the user requested it (via -fno-code) for + -- some reason. + deriving (Eq,Ord,Show,Read) -- | Default backend to use for the given platform. @@ -41,3 +105,27 @@ platformNcgSupported platform = if ArchPPC_64 {} -> True ArchSPARC -> True _ -> False + +-- | Will this backend produce an object file on the disk? +backendProducesObject :: Backend -> Bool +backendProducesObject ViaC = True +backendProducesObject NCG = True +backendProducesObject LLVM = True +backendProducesObject Interpreter = False +backendProducesObject NoBackend = False + +-- | Does this backend retain *all* top-level bindings for a module, +-- rather than just the exported bindings, in the TypeEnv and compiled +-- code (if any)? +-- +-- Interpreter backend does this, so that GHCi can call functions inside a +-- module. +-- +-- When no backend is used we also do it, so that Haddock can get access to the +-- GlobalRdrEnv for a module after typechecking it. +backendRetainsAllBindings :: Backend -> Bool +backendRetainsAllBindings Interpreter = True +backendRetainsAllBindings NoBackend = True +backendRetainsAllBindings ViaC = False +backendRetainsAllBindings NCG = False +backendRetainsAllBindings LLVM = False diff --git a/compiler/GHC/Driver/Backpack.hs b/compiler/GHC/Driver/Backpack.hs index 8dfd865a2b..acde752f66 100644 --- a/compiler/GHC/Driver/Backpack.hs +++ b/compiler/GHC/Driver/Backpack.hs @@ -162,15 +162,15 @@ withBkpSession cid insts deps session_type do_this = do (case session_type of -- Make sure to write interfaces when we are type-checking -- indefinite packages. - TcSession | hscTarget dflags /= HscNothing + TcSession | backend dflags /= NoBackend -> flip gopt_set Opt_WriteInterface | otherwise -> id CompSession -> id ExeSession -> id) $ dflags { - hscTarget = case session_type of - TcSession -> HscNothing - _ -> hscTarget dflags, + backend = case session_type of + TcSession -> NoBackend + _ -> backend dflags, homeUnitInstantiations = insts, -- if we don't have any instantiation, don't -- fill `homeUnitInstanceOfId` as it makes no @@ -505,8 +505,7 @@ mkBackpackMsg = do showMsg msg reason = backpackProgressMsg level dflags $ showModuleIndex mod_index ++ - msg ++ showModMsg dflags (hscTarget dflags) - (recompileRequired recomp) mod_summary + msg ++ showModMsg dflags (recompileRequired recomp) mod_summary ++ reason in case recomp of MustCompile -> showMsg "Compiling " "" diff --git a/compiler/GHC/Driver/CodeOutput.hs b/compiler/GHC/Driver/CodeOutput.hs index f0bfcb76ed..5cc502a715 100644 --- a/compiler/GHC/Driver/CodeOutput.hs +++ b/compiler/GHC/Driver/CodeOutput.hs @@ -23,6 +23,7 @@ import GHC.CmmToLlvm ( llvmCodeGen ) import GHC.Types.Unique.Supply ( mkSplitUniqSupply ) import GHC.Driver.Finder ( mkStubPaths ) +import GHC.Driver.Backend import GHC.CmmToC ( writeC ) import GHC.Cmm.Lint ( cmmLint ) import GHC.Cmm ( RawCmmGroup ) @@ -94,13 +95,13 @@ codeOutput dflags this_mod filenm location foreign_stubs foreign_fps pkg_deps } ; stubs_exist <- outputForeignStubs dflags this_mod location foreign_stubs - ; a <- case hscTarget dflags of - HscAsm -> outputAsm dflags this_mod location filenm - linted_cmm_stream - HscC -> outputC dflags filenm linted_cmm_stream pkg_deps - HscLlvm -> outputLlvm dflags filenm linted_cmm_stream - HscInterpreted -> panic "codeOutput: HscInterpreted" - HscNothing -> panic "codeOutput: HscNothing" + ; a <- case backend dflags of + NCG -> outputAsm dflags this_mod location filenm + linted_cmm_stream + ViaC -> outputC dflags filenm linted_cmm_stream pkg_deps + LLVM -> outputLlvm dflags filenm linted_cmm_stream + Interpreter -> panic "codeOutput: Interpreter" + NoBackend -> panic "codeOutput: NoBackend" ; return (filenm, stubs_exist, foreign_fps, a) } diff --git a/compiler/GHC/Driver/Main.hs b/compiler/GHC/Driver/Main.hs index a743e0f1ba..b2a0f887e0 100644 --- a/compiler/GHC/Driver/Main.hs +++ b/compiler/GHC/Driver/Main.hs @@ -149,6 +149,7 @@ import GHC.Runtime.Loader ( initializePlugins ) import GHC.StgToCmm.Types (CgInfos (..), ModuleLFInfos) import GHC.Driver.Session +import GHC.Driver.Backend import GHC.Utils.Error import GHC.Utils.Outputable @@ -784,7 +785,7 @@ finish :: ModSummary finish summary tc_result mb_old_hash = do hsc_env <- getHscEnv let dflags = hsc_dflags hsc_env - target = hscTarget dflags + bcknd = backend dflags hsc_src = ms_hsc_src summary -- Desugar, if appropriate @@ -802,7 +803,7 @@ finish summary tc_result mb_old_hash = do -- interface file. case mb_desugar of -- Just cause we desugared doesn't mean we are generating code, see above. - Just desugared_guts | target /= HscNothing -> do + Just desugared_guts | bcknd /= NoBackend -> do plugins <- liftIO $ readIORef (tcg_th_coreplugins tc_result) simplified_guts <- hscSimplify' plugins desugared_guts @@ -830,11 +831,12 @@ finish summary tc_result mb_old_hash = do liftIO $ hscMaybeWriteIface dflags iface mb_old_iface_hash (ms_location summary) - return $ case (target, hsc_src) of - (HscNothing, _) -> HscNotGeneratingCode iface details - (_, HsBootFile) -> HscUpdateBoot iface details - (_, HsigFile) -> HscUpdateSig iface details - _ -> panic "finish" + return $ case bcknd of + NoBackend -> HscNotGeneratingCode iface details + _ -> case hsc_src of + HsBootFile -> HscUpdateBoot iface details + HsigFile -> HscUpdateSig iface details + _ -> panic "finish" {- Note [Writing interface files] @@ -853,10 +855,10 @@ hscMaybeWriteIface, but only once per compilation (twice with dynamic-too). hscMaybeWriteIface :: DynFlags -> ModIface -> Maybe Fingerprint -> ModLocation -> IO () hscMaybeWriteIface dflags iface old_iface location = do let force_write_interface = gopt Opt_WriteInterface dflags - write_interface = case hscTarget dflags of - HscNothing -> False - HscInterpreted -> False - _ -> True + write_interface = case backend dflags of + NoBackend -> False + Interpreter -> False + _ -> True no_change = old_iface == Just (mi_iface_hash (mi_final_exts iface)) when (write_interface || force_write_interface) $ @@ -901,8 +903,7 @@ batchMsg hsc_env mod_index recomp mod_summary = showMsg msg reason = compilationProgressMsg dflags $ (showModuleIndex mod_index ++ - msg ++ showModMsg dflags (hscTarget dflags) - (recompileRequired recomp) mod_summary) + msg ++ showModMsg dflags (recompileRequired recomp) mod_summary) ++ reason -------------------------------------------------------------- diff --git a/compiler/GHC/Driver/Make.hs b/compiler/GHC/Driver/Make.hs index 6fb5fe9c72..e59a78904d 100644 --- a/compiler/GHC/Driver/Make.hs +++ b/compiler/GHC/Driver/Make.hs @@ -40,6 +40,7 @@ import qualified GHC.Runtime.Linker as Linker import GHC.Driver.Phases import GHC.Driver.Pipeline import GHC.Driver.Session +import GHC.Driver.Backend import GHC.Utils.Error import GHC.Driver.Finder import GHC.Driver.Monad @@ -274,7 +275,7 @@ data LoadHowMuch -- -- This function implements the core of GHC's @--make@ mode. It preprocesses, -- compiles and loads the specified modules, avoiding re-compilation wherever --- possible. Depending on the target (see 'GHC.Driver.Session.hscTarget') compiling +-- possible. Depending on the backend (see 'DynFlags.backend' field) compiling -- and loading may result in files being created on disk. -- -- Calls the 'defaultWarnErrLogger' after each compiling each module, whether @@ -1516,7 +1517,7 @@ upsweep mHscMessage old_hpt stable_mods cleanup sccs = do -- Add any necessary entries to the static pointer -- table. See Note [Grand plan for static forms] in -- GHC.Iface.Tidy.StaticPtrTable. - when (hscTarget (hsc_dflags hsc_env4) == HscInterpreted) $ + when (backend (hsc_dflags hsc_env4) == Interpreter) $ liftIO $ hscAddSptEntries hsc_env4 [ spt | Just linkable <- pure $ hm_linkable mod_info @@ -1575,24 +1576,25 @@ upsweep_mod hsc_env mHscMessage old_hpt (stable_obj, stable_bco) summary mod_ind -- We're using the dflags for this module now, obtained by -- applying any options in its LANGUAGE & OPTIONS_GHC pragmas. dflags = ms_hspp_opts summary - prevailing_target = hscTarget (hsc_dflags hsc_env) - local_target = hscTarget dflags + prevailing_backend = backend (hsc_dflags hsc_env) + local_backend = backend dflags -- If OPTIONS_GHC contains -fasm or -fllvm, be careful that -- we don't do anything dodgy: these should only work to change -- from -fllvm to -fasm and vice-versa, or away from -fno-code, -- otherwise we could end up trying to link object code to byte -- code. - target = if prevailing_target /= local_target - && (not (isObjectTarget prevailing_target) - || not (isObjectTarget local_target)) - && not (prevailing_target == HscNothing) - && not (prevailing_target == HscInterpreted) - then prevailing_target - else local_target - - -- store the corrected hscTarget into the summary - summary' = summary{ ms_hspp_opts = dflags { hscTarget = target } } + bcknd = case (prevailing_backend,local_backend) of + (LLVM,NCG) -> NCG + (NCG,LLVM) -> LLVM + (NoBackend,b) + | backendProducesObject b -> b + (Interpreter,b) + | backendProducesObject b -> b + _ -> prevailing_backend + + -- store the corrected backend into the summary + summary' = summary{ ms_hspp_opts = dflags { backend = bcknd } } -- The old interface is ok if -- a) we're compiling a source file, and the old HPT @@ -1623,9 +1625,9 @@ upsweep_mod hsc_env mHscMessage old_hpt (stable_obj, stable_bco) summary mod_ind compileOne' Nothing mHscMessage hsc_env summary' mod_index nmods Nothing mb_linkable src_modified - -- With the HscNothing target we create empty linkables to avoid - -- recompilation. We have to detect these to recompile anyway if - -- the target changed since the last compile. + -- With NoBackend we create empty linkables to avoid recompilation. + -- We have to detect these to recompile anyway if the backend changed + -- since the last compile. is_fake_linkable | Just hmi <- old_hmi, Just l <- hm_linkable hmi = null (linkableUnlinked l) @@ -1658,8 +1660,8 @@ upsweep_mod hsc_env mHscMessage old_hpt (stable_obj, stable_bco) summary mod_ind -- object is stable, but we need to load the interface -- off disk to make a HMI. - | not (isObjectTarget target), is_stable_bco, - (target /= HscNothing) `implies` not is_fake_linkable -> + | not (backendProducesObject bcknd), is_stable_bco, + (bcknd /= NoBackend) `implies` not is_fake_linkable -> ASSERT(isJust old_hmi) -- must be in the old_hpt let Just hmi = old_hmi in do liftIO $ debugTraceMsg (hsc_dflags hsc_env) 5 @@ -1667,11 +1669,11 @@ upsweep_mod hsc_env mHscMessage old_hpt (stable_obj, stable_bco) summary mod_ind return hmi -- BCO is stable: nothing to do - | not (isObjectTarget target), + | not (backendProducesObject bcknd), Just hmi <- old_hmi, Just l <- hm_linkable hmi, not (isObjectLinkable l), - (target /= HscNothing) `implies` not is_fake_linkable, + (bcknd /= NoBackend) `implies` not is_fake_linkable, linkableTime l >= ms_hs_date summary -> do liftIO $ debugTraceMsg (hsc_dflags hsc_env) 5 (text "compiling non-stable BCO mod:" <+> ppr this_mod_name) @@ -1688,7 +1690,7 @@ upsweep_mod hsc_env mHscMessage old_hpt (stable_obj, stable_bco) summary mod_ind -- separately and generated a new interface, that we must -- read from the disk. -- - | isObjectTarget target, + | backendProducesObject bcknd, Just obj_date <- mb_obj_date, obj_date >= hs_date -> do case old_hmi of @@ -1728,7 +1730,7 @@ possible. When GHC is invoked with -fno-code no object files or linked output will be generated. As many errors and warnings as possible will be generated, as if -fno-code had not been passed. The session DynFlags will have -hscTarget == HscNothing. +backend == NoBackend. -fwrite-interface ~~~~~~~~~~~~~~~~ @@ -2109,15 +2111,11 @@ downsweep hsc_env old_summaries excl_mods allow_dup_roots -- for dependencies of modules that have -XTemplateHaskell, -- otherwise those modules will fail to compile. -- See Note [-fno-code mode] #8025 - map1 <- if hscTarget dflags == HscNothing - then enableCodeGenForTH - (defaultObjectTarget dflags) - map0 - else if hscTarget dflags == HscInterpreted - then enableCodeGenForUnboxedTuplesOrSums - (defaultObjectTarget dflags) - map0 - else return map0 + let default_backend = platformDefaultBackend (targetPlatform dflags) + map1 <- case backend dflags of + NoBackend -> enableCodeGenForTH default_backend map0 + Interpreter -> enableCodeGenForUnboxedTuplesOrSums default_backend map0 + _ -> return map0 if null errs then pure $ concat $ nodeMapElts map1 else pure $ map Left errs @@ -2200,7 +2198,7 @@ downsweep hsc_env old_summaries excl_mods allow_dup_roots -- the specified target, disable optimization and change the .hi -- and .o file locations to be temporary files. -- See Note [-fno-code mode] -enableCodeGenForTH :: HscTarget +enableCodeGenForTH :: Backend -> NodeMap [Either ErrorMessages ModSummary] -> IO (NodeMap [Either ErrorMessages ModSummary]) enableCodeGenForTH = @@ -2208,7 +2206,7 @@ enableCodeGenForTH = where condition = isTemplateHaskellOrQQNonBoot should_modify (ModSummary { ms_hspp_opts = dflags }) = - hscTarget dflags == HscNothing && + backend dflags == NoBackend && -- Don't enable codegen for TH on indefinite packages; we -- can't compile anything anyway! See #16219. homeUnitIsDefinite dflags @@ -2220,7 +2218,7 @@ enableCodeGenForTH = -- -- This is used in order to load code that uses unboxed tuples -- or sums into GHCi while still allowing some code to be interpreted. -enableCodeGenForUnboxedTuplesOrSums :: HscTarget +enableCodeGenForUnboxedTuplesOrSums :: Backend -> NodeMap [Either ErrorMessages ModSummary] -> IO (NodeMap [Either ErrorMessages ModSummary]) enableCodeGenForUnboxedTuplesOrSums = @@ -2233,7 +2231,7 @@ enableCodeGenForUnboxedTuplesOrSums = unboxed_tuples_or_sums d = xopt LangExt.UnboxedTuples d || xopt LangExt.UnboxedSums d should_modify (ModSummary { ms_hspp_opts = dflags }) = - hscTarget dflags == HscInterpreted + backend dflags == Interpreter -- | Helper used to implement 'enableCodeGenForTH' and -- 'enableCodeGenForUnboxedTuples'. In particular, this enables @@ -2246,10 +2244,10 @@ enableCodeGenWhen -> (ModSummary -> Bool) -> TempFileLifetime -> TempFileLifetime - -> HscTarget + -> Backend -> NodeMap [Either ErrorMessages ModSummary] -> IO (NodeMap [Either ErrorMessages ModSummary]) -enableCodeGenWhen condition should_modify staticLife dynLife target nodemap = +enableCodeGenWhen condition should_modify staticLife dynLife bcknd nodemap = traverse (traverse (traverse enable_code_gen)) nodemap where enable_code_gen ms @@ -2282,7 +2280,7 @@ enableCodeGenWhen condition should_modify staticLife dynLife target nodemap = ms { ms_location = ms_location {ml_hi_file = hi_file, ml_obj_file = o_file} - , ms_hspp_opts = updOptLevel 0 $ dflags {hscTarget = target} + , ms_hspp_opts = updOptLevel 0 $ dflags {backend = bcknd} } | otherwise = return ms @@ -2433,7 +2431,7 @@ checkSummaryTimestamp not (gopt Opt_ForceRecomp (hsc_dflags hsc_env)) = do -- update the object-file timestamp obj_timestamp <- - if isObjectTarget (hscTarget (hsc_dflags hsc_env)) + if backendProducesObject (backend (hsc_dflags hsc_env)) || obj_allowed -- bug #1205 then liftIO $ getObjTimestamp location is_boot else return Nothing @@ -2609,7 +2607,7 @@ makeNewModSummary hsc_env MakeNewModSummary{..} = do -- when the user asks to load a source file by name, we only -- use an object file if -fobject-code is on. See #1205. obj_timestamp <- liftIO $ - if isObjectTarget (hscTarget dflags) + if backendProducesObject (backend dflags) || nms_obj_allowed -- bug #1205 then getObjTimestamp nms_location nms_is_boot else return Nothing diff --git a/compiler/GHC/Driver/Pipeline.hs b/compiler/GHC/Driver/Pipeline.hs index 81a141afee..336a3bc447 100644 --- a/compiler/GHC/Driver/Pipeline.hs +++ b/compiler/GHC/Driver/Pipeline.hs @@ -53,6 +53,7 @@ import GHC.Utils.Outputable import GHC.Unit.Module import GHC.Utils.Error import GHC.Driver.Session +import GHC.Driver.Backend import GHC.Utils.Panic import GHC.Utils.Misc import GHC.Data.StringBuffer ( hGetStringBuffer, hPutStringBuffer ) @@ -183,25 +184,25 @@ compileOne' m_tc_result mHscMessage -- hscIncrementalCompile) let hsc_env' = hsc_env{ hsc_dflags = plugin_dflags } - case (status, hsc_lang) of + case (status, bcknd) of (HscUpToDate iface hmi_details, _) -> -- TODO recomp014 triggers this assert. What's going on?! -- ASSERT( isJust mb_old_linkable || isNoLink (ghcLink dflags) ) return $! HomeModInfo iface hmi_details mb_old_linkable - (HscNotGeneratingCode iface hmi_details, HscNothing) -> + (HscNotGeneratingCode iface hmi_details, NoBackend) -> let mb_linkable = if isHsBootOrSig src_flavour then Nothing -- TODO: Questionable. else Just (LM (ms_hs_date summary) this_mod []) in return $! HomeModInfo iface hmi_details mb_linkable (HscNotGeneratingCode _ _, _) -> panic "compileOne HscNotGeneratingCode" - (_, HscNothing) -> panic "compileOne HscNothing" - (HscUpdateBoot iface hmi_details, HscInterpreted) -> do + (_, NoBackend) -> panic "compileOne NoBackend" + (HscUpdateBoot iface hmi_details, Interpreter) -> do return $! HomeModInfo iface hmi_details Nothing (HscUpdateBoot iface hmi_details, _) -> do touchObjectFile dflags object_filename return $! HomeModInfo iface hmi_details Nothing - (HscUpdateSig iface hmi_details, HscInterpreted) -> do + (HscUpdateSig iface hmi_details, Interpreter) -> do let !linkable = LM (ms_hs_date summary) this_mod [] return $! HomeModInfo iface hmi_details (Just linkable) (HscUpdateSig iface hmi_details, _) -> do @@ -229,7 +230,7 @@ compileOne' m_tc_result mHscMessage hscs_mod_details = hmi_details, hscs_partial_iface = partial_iface, hscs_old_iface_hash = mb_old_iface_hash, - hscs_iface_dflags = iface_dflags }, HscInterpreted) -> do + hscs_iface_dflags = iface_dflags }, Interpreter) -> do -- In interpreted mode the regular codeGen backend is not run so we -- generate a interface without codeGen info. final_iface <- mkFullIface hsc_env'{hsc_dflags=iface_dflags} partial_iface Nothing @@ -285,7 +286,7 @@ compileOne' m_tc_result mHscMessage src_flavour = ms_hsc_src summary mod_name = ms_mod_name summary - next_phase = hscPostBackendPhase src_flavour hsc_lang + next_phase = hscPostBackendPhase src_flavour bcknd object_filename = ml_obj_file location -- #8180 - when using TemplateHaskell, switch on -dynamic-too so @@ -320,8 +321,8 @@ compileOne' m_tc_result mHscMessage -- to re-summarize all the source files. hsc_env = hsc_env0 {hsc_dflags = dflags} - -- Figure out what lang we're generating - hsc_lang = hscTarget dflags + -- Figure out which backend we're using + bcknd = backend dflags -- -fforce-recomp should also work with --make force_recomp = gopt Opt_ForceRecomp dflags @@ -329,8 +330,8 @@ compileOne' m_tc_result mHscMessage | force_recomp = SourceModified | otherwise = source_modified0 - always_do_basic_recompilation_check = case hsc_lang of - HscInterpreted -> True + always_do_basic_recompilation_check = case bcknd of + Interpreter -> True _ -> False ----------------------------------------------------------------------------- @@ -562,7 +563,7 @@ compileFile hsc_env stop_phase (src, mb_phase) = do -- If we are doing -fno-code, then act as if the output is -- 'Temporary'. This stops GHC trying to copy files to their -- final location. - | HscNothing <- hscTarget dflags = Temporary TFL_CurrentModule + | NoBackend <- backend dflags = Temporary TFL_CurrentModule | StopLn <- stop_phase, not (isNoLink ghc_link) = Persistent -- -o foo applies to linker | isJust mb_o_file = SpecificFile @@ -1144,8 +1145,7 @@ runPhase (HscOut src_flavour mod_name result) _ dflags = do setModLocation location let o_file = ml_obj_file location -- The real object file - hsc_lang = hscTarget dflags - next_phase = hscPostBackendPhase src_flavour hsc_lang + next_phase = hscPostBackendPhase src_flavour (backend dflags) case result of HscNotGeneratingCode _ _ -> @@ -1209,8 +1209,7 @@ runPhase (RealPhase CmmCpp) input_fn dflags return (RealPhase Cmm, output_fn) runPhase (RealPhase Cmm) input_fn dflags - = do let hsc_lang = hscTarget dflags - let next_phase = hscPostBackendPhase HsSrcFile hsc_lang + = do let next_phase = hscPostBackendPhase HsSrcFile (backend dflags) output_fn <- phaseOutputFilename next_phase PipeState{hsc_env} <- getPipeState liftIO $ hscCompileCmmFile hsc_env input_fn output_fn @@ -1355,7 +1354,7 @@ runPhase (RealPhase (As with_cpp)) input_fn dflags = do -- LLVM from version 3.0 onwards doesn't support the OS X system -- assembler, so we use clang as the assembler instead. (#5636) - let as_prog | hscTarget dflags == HscLlvm && + let as_prog | backend dflags == LLVM && platformOS (targetPlatform dflags) == OSDarwin = GHC.SysTools.runClang | otherwise = GHC.SysTools.runAs @@ -2060,7 +2059,7 @@ doCpp dflags raw input_fn output_fn = do ]) getBackendDefs :: DynFlags -> IO [String] -getBackendDefs dflags | hscTarget dflags == HscLlvm = do +getBackendDefs dflags | backend dflags == LLVM = do llvmVer <- figureLlvmVersion dflags return $ case fmap llvmVersionList llvmVer of Just [m] -> [ "-D__GLASGOW_HASKELL_LLVM__=" ++ format (m,0) ] @@ -2199,7 +2198,7 @@ joinObjectFiles dflags o_files output_fn = do writeInterfaceOnlyMode :: DynFlags -> Bool writeInterfaceOnlyMode dflags = gopt Opt_WriteInterface dflags && - HscNothing == hscTarget dflags + NoBackend == backend dflags -- | Figure out if a source file was modified after an output file (or if we -- anyways need to consider the source file modified since the output is gone). @@ -2214,16 +2213,16 @@ sourceModified dest_file src_timestamp = do return (t2 <= src_timestamp) -- | What phase to run after one of the backend code generators has run -hscPostBackendPhase :: HscSource -> HscTarget -> Phase +hscPostBackendPhase :: HscSource -> Backend -> Phase hscPostBackendPhase HsBootFile _ = StopLn hscPostBackendPhase HsigFile _ = StopLn -hscPostBackendPhase _ hsc_lang = - case hsc_lang of - HscC -> HCc - HscAsm -> As False - HscLlvm -> LlvmOpt - HscNothing -> StopLn - HscInterpreted -> StopLn +hscPostBackendPhase _ bcknd = + case bcknd of + ViaC -> HCc + NCG -> As False + LLVM -> LlvmOpt + NoBackend -> StopLn + Interpreter -> StopLn touchObjectFile :: DynFlags -> FilePath -> IO () touchObjectFile dflags path = do diff --git a/compiler/GHC/Driver/Session.hs b/compiler/GHC/Driver/Session.hs index 7d5c72ba74..82be1ab02e 100644 --- a/compiler/GHC/Driver/Session.hs +++ b/compiler/GHC/Driver/Session.hs @@ -47,8 +47,6 @@ module GHC.Driver.Session ( FlagSpec(..), HasDynFlags(..), ContainsDynFlags(..), RtsOptsEnabled(..), - HscTarget(..), isObjectTarget, defaultObjectTarget, - targetRetainsAllBindings, GhcMode(..), isOneShot, GhcLink(..), isNoLink, PackageFlag(..), PackageArg(..), ModRenaming(..), @@ -445,7 +443,20 @@ instance Outputable SafeHaskellMode where data DynFlags = DynFlags { ghcMode :: GhcMode, ghcLink :: GhcLink, - hscTarget :: HscTarget, + backend :: !Backend, + -- ^ The backend to use (if any). + -- + -- Whenever you change the backend, also make sure to set 'ghcLink' to + -- something sensible. + -- + -- 'NoBackend' can be used to avoid generating any output, however, note that: + -- + -- * If a program uses Template Haskell the typechecker may need to run code + -- from an imported module. To facilitate this, code generation is enabled + -- for modules imported by modules that use template haskell, using the + -- default backend for the platform. + -- See Note [-fno-code mode]. + -- formerly Settings ghcNameVersion :: {-# UNPACK #-} !GhcNameVersion, @@ -1003,45 +1014,6 @@ versionedAppDir appname platform = do versionedFilePath :: PlatformMini -> FilePath versionedFilePath platform = uniqueSubdir platform --- | The target code type of the compilation (if any). --- --- Whenever you change the target, also make sure to set 'ghcLink' to --- something sensible. --- --- 'HscNothing' can be used to avoid generating any output, however, note --- that: --- --- * If a program uses Template Haskell the typechecker may need to run code --- from an imported module. To facilitate this, code generation is enabled --- for modules imported by modules that use template haskell. --- See Note [-fno-code mode]. --- -data HscTarget - = HscC -- ^ Generate C code. - | HscAsm -- ^ Generate assembly using the native code generator. - | HscLlvm -- ^ Generate assembly using the llvm code generator. - | HscInterpreted -- ^ Generate bytecode. (Requires 'LinkInMemory') - | HscNothing -- ^ Don't generate any code. See notes above. - deriving (Eq, Show) - --- | Will this target result in an object file on the disk? -isObjectTarget :: HscTarget -> Bool -isObjectTarget HscC = True -isObjectTarget HscAsm = True -isObjectTarget HscLlvm = True -isObjectTarget _ = False - --- | Does this target retain *all* top-level bindings for a module, --- rather than just the exported bindings, in the TypeEnv and compiled --- code (if any)? In interpreted mode we do this, so that GHCi can --- call functions inside a module. In HscNothing mode we also do it, --- so that Haddock can get access to the GlobalRdrEnv for a module --- after typechecking it. -targetRetainsAllBindings :: HscTarget -> Bool -targetRetainsAllBindings HscInterpreted = True -targetRetainsAllBindings HscNothing = True -targetRetainsAllBindings _ = False - -- | The 'GhcMode' tells us whether we're doing multi-module -- compilation (controlled via the "GHC" API) or one-shot -- (single-module) compilation. This makes a difference primarily to @@ -1149,19 +1121,6 @@ instance Outputable PackageFlag where ppr (ExposePackage n arg rn) = text n <> braces (ppr arg <+> ppr rn) ppr (HidePackage str) = text "-hide-package" <+> text str --- | The 'HscTarget' value corresponding to the default way to create --- object files on the current platform. - -defaultHscTarget :: Platform -> HscTarget -defaultHscTarget platform - | platformUnregisterised platform = HscC - | NCG <- platformDefaultBackend platform = HscAsm - | otherwise = HscLlvm - -defaultObjectTarget :: DynFlags -> HscTarget -defaultObjectTarget dflags = defaultHscTarget - (targetPlatform dflags) - data DynLibLoader = Deployable | SystemDependent @@ -1272,7 +1231,7 @@ defaultDynFlags mySettings llvmConfig = DynFlags { ghcMode = CompManager, ghcLink = LinkBinary, - hscTarget = defaultHscTarget (sTargetPlatform mySettings), + backend = platformDefaultBackend (sTargetPlatform mySettings), verbosity = 0, optLevel = 0, debugLevel = 0, @@ -2492,9 +2451,9 @@ dynamic_flags_deps = [ , make_ord_flag defGhcFlag "keep-s-files" (NoArg (setGeneralFlag Opt_KeepSFiles)) , make_ord_flag defGhcFlag "keep-llvm-file" - (NoArg $ setObjTarget HscLlvm >> setGeneralFlag Opt_KeepLlvmFiles) + (NoArg $ setObjBackend LLVM >> setGeneralFlag Opt_KeepLlvmFiles) , make_ord_flag defGhcFlag "keep-llvm-files" - (NoArg $ setObjTarget HscLlvm >> setGeneralFlag Opt_KeepLlvmFiles) + (NoArg $ setObjBackend LLVM >> setGeneralFlag Opt_KeepLlvmFiles) -- This only makes sense as plural , make_ord_flag defGhcFlag "keep-tmp-files" (NoArg (setGeneralFlag Opt_KeepTmpFiles)) @@ -2667,7 +2626,7 @@ dynamic_flags_deps = [ , make_ord_flag defGhcFlag "ddump-asm-expanded" (setDumpFlag Opt_D_dump_asm_expanded) , make_ord_flag defGhcFlag "ddump-llvm" - (NoArg $ setObjTarget HscLlvm >> setDumpFlag' Opt_D_dump_llvm) + (NoArg $ setObjBackend LLVM >> setDumpFlag' Opt_D_dump_llvm) , make_ord_flag defGhcFlag "ddump-deriv" (setDumpFlag Opt_D_dump_deriv) , make_ord_flag defGhcFlag "ddump-ds" @@ -3060,24 +3019,24 @@ dynamic_flags_deps = [ ------ Compiler flags ----------------------------------------------- - , make_ord_flag defGhcFlag "fasm" (NoArg (setObjTarget HscAsm)) + , make_ord_flag defGhcFlag "fasm" (NoArg (setObjBackend NCG)) , make_ord_flag defGhcFlag "fvia-c" (NoArg (deprecate $ "The -fvia-c flag does nothing; " ++ "it will be removed in a future GHC release")) , make_ord_flag defGhcFlag "fvia-C" (NoArg (deprecate $ "The -fvia-C flag does nothing; " ++ "it will be removed in a future GHC release")) - , make_ord_flag defGhcFlag "fllvm" (NoArg (setObjTarget HscLlvm)) + , make_ord_flag defGhcFlag "fllvm" (NoArg (setObjBackend LLVM)) , make_ord_flag defFlag "fno-code" (NoArg ((upd $ \d -> - d { ghcLink=NoLink }) >> setTarget HscNothing)) + d { ghcLink=NoLink }) >> setBackend NoBackend)) , make_ord_flag defFlag "fbyte-code" (noArgM $ \dflags -> do - setTarget HscInterpreted + setBackend Interpreter pure $ gopt_set dflags Opt_ByteCode) , make_ord_flag defFlag "fobject-code" $ NoArg $ do dflags <- liftEwM getCmdLineState - setTarget $ defaultObjectTarget dflags + setBackend $ platformDefaultBackend (targetPlatform dflags) , make_dep_flag defFlag "fglasgow-exts" (NoArg enableGlasgowExts) "Use individual extensions instead" @@ -4590,24 +4549,24 @@ canonicalizeModuleIfHome dflags mod then canonicalizeHomeModule dflags (moduleName mod) else mod --- If we're linking a binary, then only targets that produce object +-- If we're linking a binary, then only backends that produce object -- code are allowed (requests for other target types are ignored). -setTarget :: HscTarget -> DynP () -setTarget l = upd $ \ dfs -> - if ghcLink dfs /= LinkBinary || isObjectTarget l - then dfs{ hscTarget = l } +setBackend :: Backend -> DynP () +setBackend l = upd $ \ dfs -> + if ghcLink dfs /= LinkBinary || backendProducesObject l + then dfs{ backend = l } else dfs -- Changes the target only if we're compiling object code. This is -- used by -fasm and -fllvm, which switch from one to the other, but -- not from bytecode to object-code. The idea is that -fasm/-fllvm -- can be safely used in an OPTIONS_GHC pragma. -setObjTarget :: HscTarget -> DynP () -setObjTarget l = updM set +setObjBackend :: Backend -> DynP () +setObjBackend l = updM set where set dflags - | isObjectTarget (hscTarget dflags) - = return $ dflags { hscTarget = l } + | backendProducesObject (backend dflags) + = return $ dflags { backend = l } | otherwise = return dflags setOptLevel :: Int -> DynFlags -> DynP DynFlags @@ -4615,7 +4574,7 @@ setOptLevel n dflags = return (updOptLevel n dflags) checkOptLevel :: Int -> DynFlags -> Either String DynFlags checkOptLevel n dflags - | hscTarget dflags == HscInterpreted && n > 0 + | backend dflags == Interpreter && n > 0 = Left "-O conflicts with --interactive; -O ignored." | otherwise = Right dflags @@ -4953,31 +4912,32 @@ makeDynFlagsConsistent dflags warn = "-dynamic-too is not supported on Windows" in loop dflags' warn - -- Via-C backend only supports unregisterised convention. Switch to a backend + -- Via-C backend only supports unregisterised ABI. Switch to a backend -- supporting it if possible. - | hscTarget dflags == HscC && + | backend dflags == ViaC && not (platformUnregisterised (targetPlatform dflags)) = case platformDefaultBackend (targetPlatform dflags) of - NCG -> let dflags' = dflags { hscTarget = HscAsm } + NCG -> let dflags' = dflags { backend = NCG } warn = "Target platform doesn't use unregisterised ABI, so using native code generator rather than compiling via C" in loop dflags' warn - LLVM -> let dflags' = dflags { hscTarget = HscLlvm } + LLVM -> let dflags' = dflags { backend = LLVM } warn = "Target platform doesn't use unregisterised ABI, so using LLVM rather than compiling via C" in loop dflags' warn - _ -> pgmError "Compiling via C is only supported with unregisterised ABI but target platform doesn't use it." - | gopt Opt_Hpc dflags && hscTarget dflags == HscInterpreted + _ -> pgmError "Compiling via C only supports unregisterised ABI but target platform doesn't use it." + + | gopt Opt_Hpc dflags && backend dflags == Interpreter = let dflags' = gopt_unset dflags Opt_Hpc warn = "Hpc can't be used with byte-code interpreter. Ignoring -fhpc." in loop dflags' warn - | hscTarget dflags `elem` [HscAsm, HscLlvm] && + | backend dflags `elem` [NCG, LLVM] && platformUnregisterised (targetPlatform dflags) - = loop (dflags { hscTarget = HscC }) + = loop (dflags { backend = ViaC }) "Target platform uses unregisterised ABI, so compiling via C" - | hscTarget dflags == HscAsm && + | backend dflags == NCG && not (platformNcgSupported $ targetPlatform dflags) - = let dflags' = dflags { hscTarget = HscLlvm } + = let dflags' = dflags { backend = LLVM } warn = "Native code generator doesn't support target platform, so using LLVM" in loop dflags' warn @@ -4995,7 +4955,7 @@ makeDynFlagsConsistent dflags | LinkInMemory <- ghcLink dflags , not (gopt Opt_ExternalInterpreter dflags) , hostIsProfiled - , isObjectTarget (hscTarget dflags) + , backendProducesObject (backend dflags) , WayProf `Set.notMember` ways dflags = loop dflags{ways = Set.insert WayProf (ways dflags)} "Enabling -prof, because -fobject-code is enabled and GHCi is profiled" diff --git a/compiler/GHC/Driver/Types.hs b/compiler/GHC/Driver/Types.hs index 5671079723..4029ab1c2c 100644 --- a/compiler/GHC/Driver/Types.hs +++ b/compiler/GHC/Driver/Types.hs @@ -192,6 +192,7 @@ import GHC.Core.DataCon import GHC.Core.PatSyn import GHC.Builtin.Names ( gHC_PRIM, ioTyConName, printName, mkInteractiveModule ) import GHC.Builtin.Types +import GHC.Driver.Backend import GHC.Driver.CmdLine import GHC.Driver.Session import GHC.Runtime.Linker.Types ( DynLinker, Linkable(..), Unlinked(..), SptEntry(..) ) @@ -2997,8 +2998,8 @@ instance Outputable ModSummary where char '}' ] -showModMsg :: DynFlags -> HscTarget -> Bool -> ModSummary -> String -showModMsg dflags target recomp mod_summary = showSDoc dflags $ +showModMsg :: DynFlags -> Bool -> ModSummary -> String +showModMsg dflags recomp mod_summary = showSDoc dflags $ if gopt Opt_HideSourcePaths dflags then text mod_str else hsep $ @@ -3017,10 +3018,10 @@ showModMsg dflags target recomp mod_summary = showSDoc dflags $ mod = moduleName (ms_mod mod_summary) mod_str = showPpr dflags mod ++ hscSourceString (ms_hsc_src mod_summary) dyn_file = op $ msDynObjFilePath mod_summary dflags - obj_file = case target of - HscInterpreted | recomp -> "interpreted" - HscNothing -> "nothing" - _ -> (op $ msObjFilePath mod_summary) + obj_file = case backend dflags of + Interpreter | recomp -> "interpreted" + NoBackend -> "nothing" + _ -> (op $ msObjFilePath mod_summary) {- ************************************************************************ @@ -3171,7 +3172,7 @@ isObjectLinkable l = not (null unlinked) && all isObject unlinked where unlinked = linkableUnlinked l -- A linkable with no Unlinked's is treated as a BCO. We can -- generate a linkable with no Unlinked's as a result of - -- compiling a module in HscNothing mode, and this choice + -- compiling a module in NoBackend mode, and this choice -- happens to work well with checkStability in module GHC. linkableObjs :: Linkable -> [FilePath] diff --git a/compiler/GHC/HsToCore.hs b/compiler/GHC/HsToCore.hs index af67088e51..13f5ca5dd4 100644 --- a/compiler/GHC/HsToCore.hs +++ b/compiler/GHC/HsToCore.hs @@ -23,6 +23,7 @@ import GHC.Prelude import GHC.HsToCore.Usage import GHC.Driver.Session import GHC.Driver.Types +import GHC.Driver.Backend import GHC.Hs import GHC.Tc.Types import GHC.Tc.Utils.Monad ( finalSafeMode, fixSafeInstances ) @@ -123,7 +124,7 @@ deSugar hsc_env (const ()) $ do { -- Desugar the program ; let export_set = availsToNameSet exports - target = hscTarget dflags + bcknd = backend dflags hpcInfo = emptyHpcInfo other_hpc_info ; (binds_cvr, ds_hpc_info, modBreaks) @@ -153,7 +154,7 @@ deSugar hsc_env do { -- Add export flags to bindings keep_alive <- readIORef keep_var ; let (rules_for_locals, rules_for_imps) = partition isLocalRule all_rules - final_prs = addExportFlagsAndRules target export_set keep_alive + final_prs = addExportFlagsAndRules bcknd export_set keep_alive rules_for_locals (fromOL all_prs) final_pgm = combineEvBinds ds_ev_binds final_prs @@ -288,9 +289,9 @@ deSugarExpr hsc_env tc_expr = do { -} addExportFlagsAndRules - :: HscTarget -> NameSet -> NameSet -> [CoreRule] + :: Backend -> NameSet -> NameSet -> [CoreRule] -> [(Id, t)] -> [(Id, t)] -addExportFlagsAndRules target exports keep_alive rules prs +addExportFlagsAndRules bcknd exports keep_alive rules prs = mapFst add_one prs where add_one bndr = add_rules name (add_export name bndr) @@ -326,7 +327,7 @@ addExportFlagsAndRules target exports keep_alive rules prs -- isExternalName separates the user-defined top-level names from those -- introduced by the type checker. is_exported :: Name -> Bool - is_exported | targetRetainsAllBindings target = isExternalName + is_exported | backendRetainsAllBindings bcknd = isExternalName | otherwise = (`elemNameSet` exports) {- diff --git a/compiler/GHC/HsToCore/Coverage.hs b/compiler/GHC/HsToCore/Coverage.hs index edd67e5b17..b52b4ac209 100644 --- a/compiler/GHC/HsToCore/Coverage.hs +++ b/compiler/GHC/HsToCore/Coverage.hs @@ -24,6 +24,7 @@ import GHC.Hs import GHC.Unit import GHC.Utils.Outputable as Outputable import GHC.Driver.Session +import GHC.Driver.Backend import GHC.Core.ConLike import Control.Monad import GHC.Types.SrcLoc @@ -1050,7 +1051,7 @@ coveragePasses dflags = -- | Should we produce 'Breakpoint' ticks? breakpointsEnabled :: DynFlags -> Bool -breakpointsEnabled dflags = hscTarget dflags == HscInterpreted +breakpointsEnabled dflags = backend dflags == Interpreter -- | Tickishs that only make sense when their source code location -- refers to the current file. This might not always be true due to diff --git a/compiler/GHC/Iface/Load.hs b/compiler/GHC/Iface/Load.hs index de4ef89283..3d8a1f47ef 100644 --- a/compiler/GHC/Iface/Load.hs +++ b/compiler/GHC/Iface/Load.hs @@ -41,6 +41,7 @@ import {-# SOURCE #-} GHC.IfaceToCore , tcIfaceAnnotations, tcIfaceCompleteSigs ) import GHC.Driver.Session +import GHC.Driver.Backend import GHC.Iface.Syntax import GHC.Iface.Env import GHC.Driver.Types @@ -592,12 +593,12 @@ dontLeakTheHPT thing_inside = do -- instantiation of a signature might reside in the HPT, so -- this case breaks the assumption that EPS interfaces only -- refer to other EPS interfaces. We can detect when we're in - -- typechecking-only mode by using hscTarget==HscNothing, and + -- typechecking-only mode by using backend==NoBackend, and -- in that case we don't empty the HPT. (admittedly this is -- a bit of a hack, better suggestions welcome). A number of -- tests in testsuite/tests/backpack break without this -- tweak. - !hpt | hscTarget hsc_dflags == HscNothing = hsc_HPT + !hpt | backend hsc_dflags == NoBackend = hsc_HPT | otherwise = emptyHomePackageTable in HscEnv { hsc_targets = panic "cleanTopEnv: hsc_targets" diff --git a/compiler/GHC/Iface/Make.hs b/compiler/GHC/Iface/Make.hs index b43fe30bb3..bb383f6a57 100644 --- a/compiler/GHC/Iface/Make.hs +++ b/compiler/GHC/Iface/Make.hs @@ -46,6 +46,7 @@ import GHC.Core.FamInstEnv import GHC.Tc.Utils.Monad import GHC.Hs import GHC.Driver.Types +import GHC.Driver.Backend import GHC.Driver.Session import GHC.Types.Var.Env import GHC.Types.Var @@ -144,7 +145,7 @@ updateDecl decls (Just CgInfos{ cgNonCafs = NonCaffySet non_cafs, cgLFInfos = lf -- | Make an interface from the results of typechecking only. Useful -- for non-optimising compilation, or where we aren't generating any --- object code at all ('HscNothing'). +-- object code at all ('NoBackend'). mkIfaceTc :: HscEnv -> SafeHaskellMode -- The safe haskell mode -> ModDetails -- gotten from mkBootModDetails, probably @@ -301,8 +302,8 @@ mkIface_ hsc_env -- scope available. (#5534) maybeGlobalRdrEnv :: GlobalRdrEnv -> Maybe GlobalRdrEnv maybeGlobalRdrEnv rdr_env - | targetRetainsAllBindings (hscTarget dflags) = Just rdr_env - | otherwise = Nothing + | backendRetainsAllBindings (backend dflags) = Just rdr_env + | otherwise = Nothing ifFamInstTcName = ifFamInstFam diff --git a/compiler/GHC/Iface/Recomp.hs b/compiler/GHC/Iface/Recomp.hs index 58d9dd05af..4d680f4aca 100644 --- a/compiler/GHC/Iface/Recomp.hs +++ b/compiler/GHC/Iface/Recomp.hs @@ -23,6 +23,7 @@ import GHC.Types.Annotations import GHC.Core import GHC.Tc.Utils.Monad import GHC.Hs +import GHC.Driver.Backend import GHC.Driver.Types import GHC.Driver.Finder import GHC.Driver.Session @@ -169,7 +170,7 @@ check_old_iface hsc_env mod_summary src_modified maybe_iface -- If the source has changed and we're in interactive mode, -- avoid reading an interface; just return the one we might -- have been supplied with. - True | not (isObjectTarget $ hscTarget dflags) -> + True | not (backendProducesObject $ backend dflags) -> return (MustCompile, maybe_iface) -- Try and read the old interface for the current module diff --git a/compiler/GHC/Iface/Tidy.hs b/compiler/GHC/Iface/Tidy.hs index 5121c11681..3c3fb4b488 100644 --- a/compiler/GHC/Iface/Tidy.hs +++ b/compiler/GHC/Iface/Tidy.hs @@ -18,6 +18,7 @@ import GHC.Prelude import GHC.Tc.Types import GHC.Driver.Session +import GHC.Driver.Backend import GHC.Core import GHC.Core.Unfold import GHC.Core.FVs @@ -383,10 +384,10 @@ tidyProgram hsc_env (ModGuts { mg_module = mod sptCreateStaticBinds hsc_env mod tidy_binds ; let { spt_init_code = sptModuleInitCode mod spt_entries ; add_spt_init_code = - case hscTarget dflags of + case backend dflags of -- If we are compiling for the interpreter we will insert -- any necessary SPT entries dynamically - HscInterpreted -> id + Interpreter -> id -- otherwise add a C stub to do so _ -> (`appendStubC` spt_init_code) diff --git a/compiler/GHC/Runtime/Eval.hs b/compiler/GHC/Runtime/Eval.hs index e88dfc3277..6871073eea 100644 --- a/compiler/GHC/Runtime/Eval.hs +++ b/compiler/GHC/Runtime/Eval.hs @@ -1256,7 +1256,7 @@ showModule mod_summary = withSession $ \hsc_env -> do interpreted <- moduleIsBootOrNotObjectLinkable mod_summary let dflags = hsc_dflags hsc_env - return (showModMsg dflags (hscTarget dflags) interpreted mod_summary) + return (showModMsg dflags interpreted mod_summary) moduleIsBootOrNotObjectLinkable :: GhcMonad m => ModSummary -> m Bool moduleIsBootOrNotObjectLinkable mod_summary = withSession $ \hsc_env -> diff --git a/compiler/GHC/Runtime/Linker/Types.hs b/compiler/GHC/Runtime/Linker/Types.hs index 429a658042..7899feae9e 100644 --- a/compiler/GHC/Runtime/Linker/Types.hs +++ b/compiler/GHC/Runtime/Linker/Types.hs @@ -71,7 +71,7 @@ data Linkable = LM { -- -- INVARIANT: A valid linkable always has at least one 'Unlinked' item. -- If this list is empty, the Linkable represents a fake linkable, which - -- is generated in HscNothing mode to avoid recompiling modules. + -- is generated with no backend is used to avoid recompiling modules. -- -- ToDo: Do items get removed from this list when they get linked? } diff --git a/compiler/GHC/StgToCmm.hs b/compiler/GHC/StgToCmm.hs index 04ce004df4..40a43b3e06 100644 --- a/compiler/GHC/StgToCmm.hs +++ b/compiler/GHC/StgToCmm.hs @@ -37,6 +37,7 @@ import GHC.Driver.Session import GHC.Utils.Error import GHC.Driver.Types +import GHC.Driver.Backend import GHC.Types.CostCentre import GHC.Types.Id import GHC.Types.Id.Info @@ -165,7 +166,7 @@ cgTopBinding dflags (StgTopStringLit id str) = do -- emit either a CmmString literal or dump the string in a file and emit a -- CmmFileEmbed literal. -- See Note [Embedding large binary blobs] in GHC.CmmToAsm.Ppr - let isNCG = hscTarget dflags == HscAsm + let isNCG = backend dflags == NCG isSmall = fromIntegral (BS.length str) <= binBlobThreshold dflags asString = binBlobThreshold dflags == 0 || isSmall diff --git a/compiler/GHC/StgToCmm/Prim.hs b/compiler/GHC/StgToCmm/Prim.hs index afbcc34836..c3a14f9b1c 100644 --- a/compiler/GHC/StgToCmm/Prim.hs +++ b/compiler/GHC/StgToCmm/Prim.hs @@ -37,6 +37,7 @@ import GHC.StgToCmm.Heap import GHC.StgToCmm.Prof ( costCentreFrom ) import GHC.Driver.Session +import GHC.Driver.Backend import GHC.Platform import GHC.Types.Basic import GHC.Cmm.BlockId @@ -1594,12 +1595,8 @@ emitPrimOp dflags primop = case primop of [_, CmmLit (CmmInt n _) ] -> isJust (exactLog2 n) _ -> False - ncg = case hscTarget dflags of - HscAsm -> True - _ -> False - llvm = case hscTarget dflags of - HscLlvm -> True - _ -> False + ncg = backend dflags == NCG + llvm = backend dflags == LLVM x86ish = case platformArch platform of ArchX86 -> True ArchX86_64 -> True @@ -2169,7 +2166,7 @@ vecElemProjectCast _ _ _ = Nothing checkVecCompatibility :: DynFlags -> PrimOpVecCat -> Length -> Width -> FCode () checkVecCompatibility dflags vcat l w = do - when (hscTarget dflags /= HscLlvm) $ do + when (backend dflags /= LLVM) $ do sorry $ unlines ["SIMD vector instructions require the LLVM back-end." ,"Please use -fllvm."] check vecWidth vcat l w diff --git a/compiler/GHC/Tc/Gen/Foreign.hs b/compiler/GHC/Tc/Gen/Foreign.hs index df699b9b78..902829fb68 100644 --- a/compiler/GHC/Tc/Gen/Foreign.hs +++ b/compiler/GHC/Tc/Gen/Foreign.hs @@ -57,6 +57,7 @@ import GHC.Core.TyCon import GHC.Tc.Utils.TcType import GHC.Builtin.Names import GHC.Driver.Session +import GHC.Driver.Backend import GHC.Utils.Outputable as Outputable import GHC.Platform import GHC.Types.SrcLoc @@ -474,31 +475,31 @@ checkSafe, noCheckSafe :: Bool checkSafe = True noCheckSafe = False --- Checking a supported backend is in use - -checkCOrAsmOrLlvm :: HscTarget -> Validity -checkCOrAsmOrLlvm HscC = IsValid -checkCOrAsmOrLlvm HscAsm = IsValid -checkCOrAsmOrLlvm HscLlvm = IsValid +-- | Checking a supported backend is in use +checkCOrAsmOrLlvm :: Backend -> Validity +checkCOrAsmOrLlvm ViaC = IsValid +checkCOrAsmOrLlvm NCG = IsValid +checkCOrAsmOrLlvm LLVM = IsValid checkCOrAsmOrLlvm _ = NotValid (text "requires unregisterised, llvm (-fllvm) or native code generation (-fasm)") -checkCOrAsmOrLlvmOrInterp :: HscTarget -> Validity -checkCOrAsmOrLlvmOrInterp HscC = IsValid -checkCOrAsmOrLlvmOrInterp HscAsm = IsValid -checkCOrAsmOrLlvmOrInterp HscLlvm = IsValid -checkCOrAsmOrLlvmOrInterp HscInterpreted = IsValid +-- | Checking a supported backend is in use +checkCOrAsmOrLlvmOrInterp :: Backend -> Validity +checkCOrAsmOrLlvmOrInterp ViaC = IsValid +checkCOrAsmOrLlvmOrInterp NCG = IsValid +checkCOrAsmOrLlvmOrInterp LLVM = IsValid +checkCOrAsmOrLlvmOrInterp Interpreter = IsValid checkCOrAsmOrLlvmOrInterp _ = NotValid (text "requires interpreted, unregisterised, llvm or native code generation") -checkCg :: (HscTarget -> Validity) -> TcM () +checkCg :: (Backend -> Validity) -> TcM () checkCg check = do dflags <- getDynFlags - let target = hscTarget dflags - case target of - HscNothing -> return () + let bcknd = backend dflags + case bcknd of + NoBackend -> return () _ -> - case check target of + case check bcknd of IsValid -> return () NotValid err -> addErrTc (text "Illegal foreign declaration:" <+> err) diff --git a/compiler/GHC/Tc/Gen/Sig.hs b/compiler/GHC/Tc/Gen/Sig.hs index aee53733f4..7d253f079d 100644 --- a/compiler/GHC/Tc/Gen/Sig.hs +++ b/compiler/GHC/Tc/Gen/Sig.hs @@ -43,6 +43,7 @@ import GHC.Core.Type ( mkTyVarBinders ) import GHC.Core.Multiplicity import GHC.Driver.Session +import GHC.Driver.Backend import GHC.Types.Var ( TyVar, Specificity(..), tyVarKind, binderVars ) import GHC.Types.Id ( Id, idName, idType, idInlinePragma, setInlinePragma, mkLocalId ) import GHC.Builtin.Names( mkUnboundName ) @@ -817,10 +818,10 @@ tcImpPrags prags -- we don't want complaints about lack of INLINABLE pragmas not_specialising dflags | not (gopt Opt_Specialise dflags) = True - | otherwise = case hscTarget dflags of - HscNothing -> True - HscInterpreted -> True - _other -> False + | otherwise = case backend dflags of + NoBackend -> True + Interpreter -> True + _other -> False tcImpSpec :: (Name, Sig GhcRn) -> TcM [TcSpecPrag] tcImpSpec (name, prag) |