summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorSylvain Henry <sylvain@haskus.fr>2020-06-29 22:36:40 +0200
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-07-22 20:19:59 -0400
commitf7cc431341e5b5b31758eecc8504cae8b2390c10 (patch)
tree7404d90376432d5a311a7fc6355b02085a1a5367 /compiler
parent735f9d6bac316a0c1c68a8b49bba465f07b01cdd (diff)
downloadhaskell-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')
-rw-r--r--compiler/GHC.hs7
-rw-r--r--compiler/GHC/Cmm/CLabel.hs3
-rw-r--r--compiler/GHC/Cmm/Pipeline.hs3
-rw-r--r--compiler/GHC/Cmm/Switch.hs16
-rw-r--r--compiler/GHC/Cmm/Switch/Implement.hs2
-rw-r--r--compiler/GHC/Driver/Backend.hs98
-rw-r--r--compiler/GHC/Driver/Backpack.hs11
-rw-r--r--compiler/GHC/Driver/CodeOutput.hs15
-rw-r--r--compiler/GHC/Driver/Main.hs27
-rw-r--r--compiler/GHC/Driver/Make.hs80
-rw-r--r--compiler/GHC/Driver/Pipeline.hs53
-rw-r--r--compiler/GHC/Driver/Session.hs130
-rw-r--r--compiler/GHC/Driver/Types.hs15
-rw-r--r--compiler/GHC/HsToCore.hs11
-rw-r--r--compiler/GHC/HsToCore/Coverage.hs3
-rw-r--r--compiler/GHC/Iface/Load.hs5
-rw-r--r--compiler/GHC/Iface/Make.hs7
-rw-r--r--compiler/GHC/Iface/Recomp.hs3
-rw-r--r--compiler/GHC/Iface/Tidy.hs5
-rw-r--r--compiler/GHC/Runtime/Eval.hs2
-rw-r--r--compiler/GHC/Runtime/Linker/Types.hs2
-rw-r--r--compiler/GHC/StgToCmm.hs3
-rw-r--r--compiler/GHC/StgToCmm/Prim.hs11
-rw-r--r--compiler/GHC/Tc/Gen/Foreign.hs33
-rw-r--r--compiler/GHC/Tc/Gen/Sig.hs9
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)