    {-# LANGUAGE CPP #-}
    {-# LANGUAGE MultiWayIf #-}
    {-# LANGUAGE DerivingVia #-}
    {-# LANGUAGE NamedFieldPuns #-}
    {-# LANGUAGE MultiParamTypeClasses #-}
    {-# LANGUAGE GADTs #-}
    {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
    #include <ghcplatform.h>

    {- Functions for providing the default interpretation of the 'TPhase' actions
    -}
    module GHC.Driver.Pipeline.Execute where

    import GHC.Prelude
    import Control.Monad
    import Control.Monad.IO.Class
    import Control.Monad.Catch
    import GHC.Driver.Hooks
    import Control.Monad.Trans.Reader
    import GHC.Driver.Pipeline.Monad
    import GHC.Driver.Pipeline.Phases
    import GHC.Driver.Env hiding (Hsc)
    import GHC.Unit.Module.Location
    import GHC.Driver.Phases
    import GHC.Unit.Types
    import GHC.Types.SourceFile
    import GHC.Unit.Module.Status
    import GHC.Unit.Module.ModIface
    import GHC.Driver.Backend
    import GHC.Driver.Session
    import GHC.Unit.Module.ModSummary
    import qualified GHC.LanguageExtensions as LangExt
    import GHC.Types.SrcLoc
    import GHC.Driver.Main
    import GHC.Tc.Types
    import GHC.Types.Error
    import GHC.Driver.Errors.Types
    import GHC.Fingerprint
    import GHC.Utils.Logger
    import GHC.Utils.TmpFs
    import GHC.Platform
    import Data.List (intercalate, isInfixOf)
    import GHC.Unit.Env
    import GHC.Utils.Error
    import Data.Maybe
    import GHC.CmmToLlvm.Mangler
    import GHC.SysTools
    import GHC.SysTools.Cpp
    import System.Directory
    import System.FilePath
    import GHC.Utils.Misc
    import GHC.Utils.Outputable
    import GHC.Unit.Info
    import GHC.Unit.State
    import GHC.Unit.Home
    import GHC.Data.Maybe
    import GHC.Iface.Make
    import GHC.Driver.Config.Parser
    import GHC.Parser.Header
    import GHC.Data.StringBuffer
    import GHC.Types.SourceError
    import GHC.Unit.Finder
    import Data.IORef
    import GHC.Types.Name.Env
    import GHC.Platform.Ways
    import GHC.Driver.LlvmConfigCache (readLlvmConfigCache)
    import GHC.CmmToLlvm.Config (LlvmTarget (..), LlvmConfig (..))
    import {-# SOURCE #-} GHC.Driver.Pipeline (compileForeign, compileEmptyStub)
    import GHC.Settings
    import System.IO
    import GHC.Linker.ExtraObj
    import GHC.Linker.Dynamic
    import GHC.Utils.Panic
    import GHC.Utils.Touch
    import GHC.Unit.Module.Env
    import GHC.Driver.Env.KnotVars
    import GHC.Driver.Config.Finder
    import GHC.Rename.Names
    import GHC.StgToJS.Linker.Linker (embedJsFile)

    import Language.Haskell.Syntax.Module.Name
    import GHC.Unit.Home.ModInfo
    import GHC.Runtime.Loader (initializePlugins)

    newtype HookedUse a = HookedUse { forall a. HookedUse a -> (Hooks, PhaseHook) -> IO a
    runHookedUse :: (Hooks, PhaseHook) -> IO a }
      deriving ((forall a b. (a -> b) -> HookedUse a -> HookedUse b)
    -> (forall a b. a -> HookedUse b -> HookedUse a)
    -> Functor HookedUse
    forall a b. a -> HookedUse b -> HookedUse a
    forall a b. (a -> b) -> HookedUse a -> HookedUse b
    forall (f :: * -> *).
    (forall a b. (a -> b) -> f a -> f b)
    -> (forall a b. a -> f b -> f a) -> Functor f
    $cfmap :: forall a b. (a -> b) -> HookedUse a -> HookedUse b
    fmap :: forall a b. (a -> b) -> HookedUse a -> HookedUse b
    $c<$ :: forall a b. a -> HookedUse b -> HookedUse a
    <$ :: forall a b. a -> HookedUse b -> HookedUse a
    Functor, Functor HookedUse
    Functor HookedUse =>
    (forall a. a -> HookedUse a)
    -> (forall a b. HookedUse (a -> b) -> HookedUse a -> HookedUse b)
    -> (forall a b c.
        (a -> b -> c) -> HookedUse a -> HookedUse b -> HookedUse c)
    -> (forall a b. HookedUse a -> HookedUse b -> HookedUse b)
    -> (forall a b. HookedUse a -> HookedUse b -> HookedUse a)
    -> Applicative HookedUse
    forall a. a -> HookedUse a
    forall a b. HookedUse a -> HookedUse b -> HookedUse a
    forall a b. HookedUse a -> HookedUse b -> HookedUse b
    forall a b. HookedUse (a -> b) -> HookedUse a -> HookedUse b
    forall a b c.
    (a -> b -> c) -> HookedUse a -> HookedUse b -> HookedUse c
    forall (f :: * -> *).
    Functor f =>
    (forall a. a -> f a)
    -> (forall a b. f (a -> b) -> f a -> f b)
    -> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
    -> (forall a b. f a -> f b -> f b)
    -> (forall a b. f a -> f b -> f a)
    -> Applicative f
    $cpure :: forall a. a -> HookedUse a
    pure :: forall a. a -> HookedUse a
    $c<*> :: forall a b. HookedUse (a -> b) -> HookedUse a -> HookedUse b
    <*> :: forall a b. HookedUse (a -> b) -> HookedUse a -> HookedUse b
    $cliftA2 :: forall a b c.
    (a -> b -> c) -> HookedUse a -> HookedUse b -> HookedUse c
    liftA2 :: forall a b c.
    (a -> b -> c) -> HookedUse a -> HookedUse b -> HookedUse c
    $c*> :: forall a b. HookedUse a -> HookedUse b -> HookedUse b
    *> :: forall a b. HookedUse a -> HookedUse b -> HookedUse b
    $c<* :: forall a b. HookedUse a -> HookedUse b -> HookedUse a
    <* :: forall a b. HookedUse a -> HookedUse b -> HookedUse a
    Applicative, Applicative HookedUse
    Applicative HookedUse =>
    (forall a b. HookedUse a -> (a -> HookedUse b) -> HookedUse b)
    -> (forall a b. HookedUse a -> HookedUse b -> HookedUse b)
    -> (forall a. a -> HookedUse a)
    -> Monad HookedUse
    forall a. a -> HookedUse a
    forall a b. HookedUse a -> HookedUse b -> HookedUse b
    forall a b. HookedUse a -> (a -> HookedUse b) -> HookedUse b
    forall (m :: * -> *).
    Applicative m =>
    (forall a b. m a -> (a -> m b) -> m b)
    -> (forall a b. m a -> m b -> m b)
    -> (forall a. a -> m a)
    -> Monad m
    $c>>= :: forall a b. HookedUse a -> (a -> HookedUse b) -> HookedUse b
    >>= :: forall a b. HookedUse a -> (a -> HookedUse b) -> HookedUse b
    $c>> :: forall a b. HookedUse a -> HookedUse b -> HookedUse b
    >> :: forall a b. HookedUse a -> HookedUse b -> HookedUse b
    $creturn :: forall a. a -> HookedUse a
    return :: forall a. a -> HookedUse a
    Monad, Monad HookedUse
    Monad HookedUse =>
    (forall a. IO a -> HookedUse a) -> MonadIO HookedUse
    forall a. IO a -> HookedUse a
    forall (m :: * -> *).
    Monad m =>
    (forall a. IO a -> m a) -> MonadIO m
    $cliftIO :: forall a. IO a -> HookedUse a
    liftIO :: forall a. IO a -> HookedUse a
    MonadIO, Monad HookedUse
    Monad HookedUse =>
    (forall e a. (HasCallStack, Exception e) => e -> HookedUse a)
    -> MonadThrow HookedUse
    forall e a. (HasCallStack, Exception e) => e -> HookedUse a
    forall (m :: * -> *).
    Monad m =>
    (forall e a. (HasCallStack, Exception e) => e -> m a)
    -> MonadThrow m
    $cthrowM :: forall e a. (HasCallStack, Exception e) => e -> HookedUse a
    throwM :: forall e a. (HasCallStack, Exception e) => e -> HookedUse a
    MonadThrow, MonadThrow HookedUse
    MonadThrow HookedUse =>
    (forall e a.
     (HasCallStack, Exception e) =>
     HookedUse a -> (e -> HookedUse a) -> HookedUse a)
    -> MonadCatch HookedUse
    forall e a.
    (HasCallStack, Exception e) =>
    HookedUse a -> (e -> HookedUse a) -> HookedUse a
    forall (m :: * -> *).
    MonadThrow m =>
    (forall e a.
     (HasCallStack, Exception e) =>
     m a -> (e -> m a) -> m a)
    -> MonadCatch m
    $ccatch :: forall e a.
    (HasCallStack, Exception e) =>
    HookedUse a -> (e -> HookedUse a) -> HookedUse a
    catch :: forall e a.
    (HasCallStack, Exception e) =>
    HookedUse a -> (e -> HookedUse a) -> HookedUse a
    MonadCatch) via (ReaderT (Hooks, PhaseHook) IO)

    instance MonadUse TPhase HookedUse where
      use :: forall a. TPhase a -> HookedUse a
    use TPhase a
    fa = ((Hooks, PhaseHook) -> IO a) -> HookedUse a
    forall a. ((Hooks, PhaseHook) -> IO a) -> HookedUse a
    HookedUse (((Hooks, PhaseHook) -> IO a) -> HookedUse a)
    -> ((Hooks, PhaseHook) -> IO a) -> HookedUse a
    forall a b. (a -> b) -> a -> b
    $ \(Hooks
    hooks, (PhaseHook forall a. TPhase a -> IO a
    k)) ->
        case Hooks -> Maybe PhaseHook
    runPhaseHook Hooks
    hooks of
          Maybe PhaseHook
    Nothing -> TPhase a -> IO a
    forall a. TPhase a -> IO a
    k TPhase a
    fa
          Just (PhaseHook forall a. TPhase a -> IO a
    h) -> TPhase a -> IO a
    forall a. TPhase a -> IO a
    h TPhase a
    fa

    -- | The default mechanism to run a pipeline, see Note [The Pipeline Monad]
    runPipeline :: Hooks -> HookedUse a -> IO a
    runPipeline :: forall a. Hooks -> HookedUse a -> IO a
    runPipeline Hooks
    hooks HookedUse a
    pipeline = HookedUse a -> (Hooks, PhaseHook) -> IO a
    forall a. HookedUse a -> (Hooks, PhaseHook) -> IO a
    runHookedUse HookedUse a
    pipeline (Hooks
    hooks, (forall a. TPhase a -> IO a) -> PhaseHook
    PhaseHook TPhase a -> IO a
    forall a. TPhase a -> IO a
    runPhase)

    -- | Default interpretation of each phase, in terms of IO.
    runPhase :: TPhase out -> IO out
    runPhase :: forall a. TPhase a -> IO a
    runPhase (T_Unlit PipeEnv
    pipe_env HscEnv
    hsc_env String
    inp_path) = do
      out_path <- Phase -> PipeEnv -> HscEnv -> Maybe ModLocation -> IO String
    phaseOutputFilenameNew (HscSource -> Phase
    Cpp HscSource
    HsSrcFile) PipeEnv
    pipe_env HscEnv
    hsc_env Maybe ModLocation
    forall a. Maybe a
    Nothing
      runUnlitPhase hsc_env inp_path out_path
    runPhase (T_FileArgs HscEnv
    hsc_env String
    inp_path) = HscEnv
    -> String
    -> IO (DynFlags, Messages PsMessage, Messages DriverMessage)
    getFileArgs HscEnv
    hsc_env String
    inp_path
    runPhase (T_Cpp PipeEnv
    pipe_env HscEnv
    hsc_env String
    inp_path) = do
      out_path <- Phase -> PipeEnv -> HscEnv -> Maybe ModLocation -> IO String
    phaseOutputFilenameNew (HscSource -> Phase
    HsPp HscSource
    HsSrcFile) PipeEnv
    pipe_env HscEnv
    hsc_env Maybe ModLocation
    forall a. Maybe a
    Nothing
      runCppPhase hsc_env inp_path out_path
    runPhase (T_HsPp PipeEnv
    pipe_env HscEnv
    hsc_env String
    origin_path String
    inp_path) = do
      out_path <- Phase -> PipeEnv -> HscEnv -> Maybe ModLocation -> IO String
    phaseOutputFilenameNew (HscSource -> Phase
    Hsc HscSource
    HsSrcFile) PipeEnv
    pipe_env HscEnv
    hsc_env Maybe ModLocation
    forall a. Maybe a
    Nothing
      runHsPpPhase hsc_env origin_path inp_path out_path
    runPhase (T_HscRecomp PipeEnv
    pipe_env HscEnv
    hsc_env String
    fp HscSource
    hsc_src) = do
      PipeEnv
    -> HscEnv
    -> String
    -> HscSource
    -> IO (HscEnv, ModSummary, HscRecompStatus)
    runHscPhase PipeEnv
    pipe_env HscEnv
    hsc_env String
    fp HscSource
    hsc_src
    runPhase (T_Hsc HscEnv
    hsc_env ModSummary
    mod_sum) = HscEnv -> ModSummary -> IO (FrontendResult, Messages GhcMessage)
    runHscTcPhase HscEnv
    hsc_env ModSummary
    mod_sum
    runPhase (T_HscPostTc HscEnv
    hsc_env ModSummary
    ms FrontendResult
    fer Messages GhcMessage
    m Maybe Fingerprint
    mfi) =
      HscEnv
    -> ModSummary
    -> FrontendResult
    -> Messages GhcMessage
    -> Maybe Fingerprint
    -> IO HscBackendAction
    runHscPostTcPhase HscEnv
    hsc_env ModSummary
    ms FrontendResult
    fer Messages GhcMessage
    m Maybe Fingerprint
    mfi
    runPhase (T_HscBackend PipeEnv
    pipe_env HscEnv
    hsc_env ModuleName
    mod_name HscSource
    hsc_src ModLocation
    location HscBackendAction
    x) = do
      PipeEnv
    -> HscEnv
    -> ModuleName
    -> HscSource
    -> ModLocation
    -> HscBackendAction
    -> IO ([String], ModIface, HomeModLinkable, String)
    runHscBackendPhase PipeEnv
    pipe_env HscEnv
    hsc_env ModuleName
    mod_name HscSource
    hsc_src ModLocation
    location HscBackendAction
    x
    runPhase (T_CmmCpp PipeEnv
    pipe_env HscEnv
    hsc_env String
    input_fn) = do
      output_fn <- Phase -> PipeEnv -> HscEnv -> Maybe ModLocation -> IO String
    phaseOutputFilenameNew Phase
    Cmm PipeEnv
    pipe_env HscEnv
    hsc_env Maybe ModLocation
    forall a. Maybe a
    Nothing
      doCpp (hsc_logger hsc_env)
            (hsc_tmpfs hsc_env)
            (hsc_dflags hsc_env)
            (hsc_unit_env hsc_env)
            (CppOpts
              { useHsCpp       = False
              , cppLinePragmas = True
              })
            input_fn output_fn
      return output_fn
    runPhase (T_Js PipeEnv
    pipe_env HscEnv
    hsc_env Maybe ModLocation
    location String
    js_src) =
      PipeEnv -> HscEnv -> Maybe ModLocation -> String -> IO String
    runJsPhase PipeEnv
    pipe_env HscEnv
    hsc_env Maybe ModLocation
    location String
    js_src
    runPhase (T_ForeignJs PipeEnv
    pipe_env HscEnv
    hsc_env Maybe ModLocation
    location String
    js_src) =
      PipeEnv -> HscEnv -> Maybe ModLocation -> String -> IO String
    runForeignJsPhase PipeEnv
    pipe_env HscEnv
    hsc_env Maybe ModLocation
    location String
    js_src
    runPhase (T_Cmm PipeEnv
    pipe_env HscEnv
    hsc_env String
    input_fn) = do
      let dflags :: DynFlags
    dflags = HscEnv -> DynFlags
    hsc_dflags HscEnv
    hsc_env
      let next_phase :: Phase
    next_phase = HscSource -> Backend -> Phase
    hscPostBackendPhase HscSource
    HsSrcFile (DynFlags -> Backend
    backend DynFlags
    dflags)
      output_fn <- Phase -> PipeEnv -> HscEnv -> Maybe ModLocation -> IO String
    phaseOutputFilenameNew Phase
    next_phase PipeEnv
    pipe_env HscEnv
    hsc_env Maybe ModLocation
    forall a. Maybe a
    Nothing
      mstub <- hscCompileCmmFile hsc_env (src_filename pipe_env) input_fn output_fn
      stub_o <- mapM (compileStub hsc_env) mstub
      let foreign_os = Maybe String -> [String]
    forall a. Maybe a -> [a]
    maybeToList Maybe String
    stub_o
      return (foreign_os, output_fn)

    runPhase (T_Cc Phase
    phase PipeEnv
    pipe_env HscEnv
    hsc_env Maybe ModLocation
    location String
    input_fn) = Phase
    -> PipeEnv -> HscEnv -> Maybe ModLocation -> String -> IO String
    runCcPhase Phase
    phase PipeEnv
    pipe_env HscEnv
    hsc_env Maybe ModLocation
    location String
    input_fn
    runPhase (T_As Bool
    cpp PipeEnv
    pipe_env HscEnv
    hsc_env Maybe ModLocation
    location String
    input_fn) = do
      Bool
    -> PipeEnv -> HscEnv -> Maybe ModLocation -> String -> IO String
    runAsPhase Bool
    cpp PipeEnv
    pipe_env HscEnv
    hsc_env Maybe ModLocation
    location String
    input_fn
    runPhase (T_LlvmOpt PipeEnv
    pipe_env HscEnv
    hsc_env String
    input_fn) =
      PipeEnv -> HscEnv -> String -> IO String
    runLlvmOptPhase PipeEnv
    pipe_env HscEnv
    hsc_env String
    input_fn
    runPhase (T_LlvmLlc PipeEnv
    pipe_env HscEnv
    hsc_env String
    input_fn) =
      PipeEnv -> HscEnv -> String -> IO String
    runLlvmLlcPhase PipeEnv
    pipe_env HscEnv
    hsc_env String
    input_fn
    runPhase (T_LlvmAs Bool
    cpp PipeEnv
    pipe_env HscEnv
    hsc_env Maybe ModLocation
    location String
    input_fn) = do
      Bool
    -> PipeEnv -> HscEnv -> Maybe ModLocation -> String -> IO String
    runLlvmAsPhase Bool
    cpp PipeEnv
    pipe_env HscEnv
    hsc_env Maybe ModLocation
    location String
    input_fn
    runPhase (T_LlvmMangle PipeEnv
    pipe_env HscEnv
    hsc_env String
    input_fn) =
      PipeEnv -> HscEnv -> String -> IO String
    runLlvmManglePhase PipeEnv
    pipe_env HscEnv
    hsc_env String
    input_fn
    runPhase (T_MergeForeign PipeEnv
    pipe_env HscEnv
    hsc_env String
    input_fn [String]
    fos) =
      PipeEnv -> HscEnv -> String -> [String] -> IO String
    runMergeForeign PipeEnv
    pipe_env HscEnv
    hsc_env String
    input_fn [String]
    fos

    runLlvmManglePhase :: PipeEnv -> HscEnv -> FilePath -> IO [Char]
    runLlvmManglePhase :: PipeEnv -> HscEnv -> String -> IO String
    runLlvmManglePhase PipeEnv
    pipe_env HscEnv
    hsc_env String
    input_fn = do
          let next_phase :: Phase
    next_phase = Bool -> Phase
    As Bool
    False
          output_fn <- Phase -> PipeEnv -> HscEnv -> Maybe ModLocation -> IO String
    phaseOutputFilenameNew Phase
    next_phase PipeEnv
    pipe_env HscEnv
    hsc_env Maybe ModLocation
    forall a. Maybe a
    Nothing
          let dflags = HscEnv -> DynFlags
    hsc_dflags HscEnv
    hsc_env
          llvmFixupAsm (targetPlatform dflags) input_fn output_fn
          return output_fn

    runMergeForeign :: PipeEnv -> HscEnv -> FilePath -> [FilePath] -> IO FilePath
    runMergeForeign :: PipeEnv -> HscEnv -> String -> [String] -> IO String
    runMergeForeign PipeEnv
    _pipe_env HscEnv
    hsc_env String
    input_fn [String]
    foreign_os = do
         if [String] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [String]
    foreign_os
           then String -> IO String
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return String
    input_fn
           else do
             -- Work around a binutil < 2.31 bug where you can't merge objects if the output file
             -- is one of the inputs
             new_o <- Logger
    -> TmpFs -> TempDir -> TempFileLifetime -> String -> IO String
    newTempName (HscEnv -> Logger
    hsc_logger HscEnv
    hsc_env)
                                  (HscEnv -> TmpFs
    hsc_tmpfs HscEnv
    hsc_env)
                                  (DynFlags -> TempDir
    tmpDir (HscEnv -> DynFlags
    hsc_dflags HscEnv
    hsc_env))
                                  TempFileLifetime
    TFL_CurrentModule String
    "o"
             copyFile input_fn new_o
             joinObjectFiles hsc_env (new_o : foreign_os) input_fn
             return input_fn

    runLlvmLlcPhase :: PipeEnv -> HscEnv -> FilePath -> IO FilePath
    runLlvmLlcPhase :: PipeEnv -> HscEnv -> String -> IO String
    runLlvmLlcPhase PipeEnv
    pipe_env HscEnv
    hsc_env String
    input_fn = do
        -- Note [Clamping of llc optimizations]
        -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        -- See #13724
        --
        -- we clamp the llc optimization between [1,2]. This is because passing -O0
        -- to llc 3.9 or llc 4.0, the naive register allocator can fail with
        --
        --   Error while trying to spill R1 from class GPR: Cannot scavenge register
        --   without an emergency spill slot!
        --
        -- Observed at least with target 'arm-unknown-linux-gnueabihf'.
        --
        --
        -- With LLVM4, llc -O3 crashes when ghc-stage1 tries to compile
        --   rts/HeapStackCheck.cmm
        --
        -- llc -O3 '-mtriple=arm-unknown-linux-gnueabihf' -enable-tbaa /var/folders/fv/xqjrpfj516n5xq_m_ljpsjx00000gn/T/ghc33674_0/ghc_6.bc -o /var/folders/fv/xqjrpfj516n5xq_m_ljpsjx00000gn/T/ghc33674_0/ghc_7.lm_s
        -- 0  llc                      0x0000000102ae63e8 llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 40
        -- 1  llc                      0x0000000102ae69a6 SignalHandler(int) + 358
        -- 2  libsystem_platform.dylib 0x00007fffc23f4b3a _sigtramp + 26
        -- 3  libsystem_c.dylib        0x00007fffc226498b __vfprintf + 17876
        -- 4  llc                      0x00000001029d5123 llvm::SelectionDAGISel::LowerArguments(llvm::Function const&) + 5699
        -- 5  llc                      0x0000000102a21a35 llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) + 3381
        -- 6  llc                      0x0000000102a202b1 llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) + 1457
        -- 7  llc                      0x0000000101bdc474 (anonymous namespace)::ARMDAGToDAGISel::runOnMachineFunction(llvm::MachineFunction&) + 20
        -- 8  llc                      0x00000001025573a6 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) + 134
        -- 9  llc                      0x000000010274fb12 llvm::FPPassManager::runOnFunction(llvm::Function&) + 498
        -- 10 llc                      0x000000010274fd23 llvm::FPPassManager::runOnModule(llvm::Module&) + 67
        -- 11 llc                      0x00000001027501b8 llvm::legacy::PassManagerImpl::run(llvm::Module&) + 920
        -- 12 llc                      0x000000010195f075 compileModule(char**, llvm::LLVMContext&) + 12133
        -- 13 llc                      0x000000010195bf0b main + 491
        -- 14 libdyld.dylib            0x00007fffc21e5235 start + 1
        -- Stack dump:
        -- 0.  Program arguments: llc -O3 -mtriple=arm-unknown-linux-gnueabihf -enable-tbaa /var/folders/fv/xqjrpfj516n5xq_m_ljpsjx00000gn/T/ghc33674_0/ghc_6.bc -o /var/folders/fv/xqjrpfj516n5xq_m_ljpsjx00000gn/T/ghc33674_0/ghc_7.lm_s
        -- 1.  Running pass 'Function Pass Manager' on module '/var/folders/fv/xqjrpfj516n5xq_m_ljpsjx00000gn/T/ghc33674_0/ghc_6.bc'.
        -- 2.  Running pass 'ARM Instruction Selection' on function '@"stg_gc_f1$def"'
        --
        -- Observed at least with -mtriple=arm-unknown-linux-gnueabihf -enable-tbaa
        --
        llvm_config <- LlvmConfigCache -> IO LlvmConfig
    readLlvmConfigCache (HscEnv -> LlvmConfigCache
    hsc_llvm_config HscEnv
    hsc_env)
        let dflags = HscEnv -> DynFlags
    hsc_dflags HscEnv
    hsc_env
            logger = HscEnv -> Logger
    hsc_logger HscEnv
    hsc_env
            llvmOpts = case DynFlags -> Int
    llvmOptLevel DynFlags
    dflags of
              Int
    0 -> String
    "-O1" -- required to get the non-naive reg allocator. Passing -regalloc=greedy is not sufficient.
              Int
    1 -> String
    "-O1"
              Int
    _ -> String
    "-O2"

            defaultOptions = (String -> Option) -> [String] -> [Option]
    forall a b. (a -> b) -> [a] -> [b]
    map String -> Option
    GHC.SysTools.Option ([String] -> [Option])
    -> (([String], [String]) -> [String])
    -> ([String], [String])
    -> [Option]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (String -> [String]) -> [String] -> [String]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap String -> [String]
    words ([String] -> [String])
    -> (([String], [String]) -> [String])
    -> ([String], [String])
    -> [String]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ([String], [String]) -> [String]
    forall a b. (a, b) -> b
    snd
                             (([String], [String]) -> [Option])
    -> ([String], [String]) -> [Option]
    forall a b. (a -> b) -> a -> b
    $ [(String, String)] -> ([String], [String])
    forall a b. [(a, b)] -> ([a], [b])
    unzip (LlvmConfig -> DynFlags -> [(String, String)]
    llvmOptions LlvmConfig
    llvm_config DynFlags
    dflags)
            optFlag = if [String] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null (DynFlags -> (DynFlags -> [String]) -> [String]
    forall a. DynFlags -> (DynFlags -> [a]) -> [a]
    getOpts DynFlags
    dflags DynFlags -> [String]
    opt_lc)
                      then (String -> Option) -> [String] -> [Option]
    forall a b. (a -> b) -> [a] -> [b]
    map String -> Option
    GHC.SysTools.Option ([String] -> [Option]) -> [String] -> [Option]
    forall a b. (a -> b) -> a -> b
    $ String -> [String]
    words String
    llvmOpts
                      else []

        next_phase <- if -- hidden debugging flag '-dno-llvm-mangler' to skip mangling
                         | gopt Opt_NoLlvmMangler dflags -> return (As False)
                         | otherwise -> return LlvmMangle

        output_fn <- phaseOutputFilenameNew next_phase pipe_env hsc_env Nothing

        GHC.SysTools.runLlvmLlc logger dflags
                    (  optFlag
                    ++ defaultOptions
                    ++ [ GHC.SysTools.FileOption "" input_fn
                       , GHC.SysTools.Option "-o"
                       , GHC.SysTools.FileOption "" output_fn
                       ]
                    )

        return output_fn

    runLlvmOptPhase :: PipeEnv -> HscEnv -> FilePath -> IO FilePath
    runLlvmOptPhase :: PipeEnv -> HscEnv -> String -> IO String
    runLlvmOptPhase PipeEnv
    pipe_env HscEnv
    hsc_env String
    input_fn = do
        let dflags :: DynFlags
    dflags = HscEnv -> DynFlags
    hsc_dflags HscEnv
    hsc_env
            logger :: Logger
    logger = HscEnv -> Logger
    hsc_logger HscEnv
    hsc_env
        llvm_config <- LlvmConfigCache -> IO LlvmConfig
    readLlvmConfigCache (HscEnv -> LlvmConfigCache
    hsc_llvm_config HscEnv
    hsc_env)
        let -- we always (unless -optlo specified) run Opt since we rely on it to
            -- fix up some pretty big deficiencies in the code we generate
            optIdx = Int -> Int -> Int
    forall a. Ord a => a -> a -> a
    max Int
    0 (Int -> Int) -> Int -> Int
    forall a b. (a -> b) -> a -> b
    $ Int -> Int -> Int
    forall a. Ord a => a -> a -> a
    min Int
    2 (Int -> Int) -> Int -> Int
    forall a b. (a -> b) -> a -> b
    $ DynFlags -> Int
    llvmOptLevel DynFlags
    dflags  -- ensure we're in [0,2]
            llvmOpts = case Int -> [(Int, String)] -> Maybe String
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup Int
    optIdx ([(Int, String)] -> Maybe String)
    -> [(Int, String)] -> Maybe String
    forall a b. (a -> b) -> a -> b
    $ LlvmConfig -> [(Int, String)]
    llvmPasses LlvmConfig
    llvm_config of
                        Just String
    passes -> String
    passes
                        Maybe String
    Nothing -> String -> String
    forall a. HasCallStack => String -> a
    panic (String
    "runPhase LlvmOpt: llvm-passes file "
                                          String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    "is missing passes for level "
                                          String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show Int
    optIdx)
            defaultOptions = (String -> Option) -> [String] -> [Option]
    forall a b. (a -> b) -> [a] -> [b]
    map String -> Option
    GHC.SysTools.Option ([String] -> [Option])
    -> (([String], [String]) -> [String])
    -> ([String], [String])
    -> [Option]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [[String]] -> [String]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat ([[String]] -> [String])
    -> (([String], [String]) -> [[String]])
    -> ([String], [String])
    -> [String]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (String -> [String]) -> [String] -> [[String]]
    forall a b. (a -> b) -> [a] -> [b]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap String -> [String]
    words ([String] -> [[String]])
    -> (([String], [String]) -> [String])
    -> ([String], [String])
    -> [[String]]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ([String], [String]) -> [String]
    forall a b. (a, b) -> a
    fst
                             (([String], [String]) -> [Option])
    -> ([String], [String]) -> [Option]
    forall a b. (a -> b) -> a -> b
    $ [(String, String)] -> ([String], [String])
    forall a b. [(a, b)] -> ([a], [b])
    unzip (LlvmConfig -> DynFlags -> [(String, String)]
    llvmOptions LlvmConfig
    llvm_config DynFlags
    dflags)

            -- don't specify anything if user has specified commands. We do this
            -- for opt but not llc since opt is very specifically for optimisation
            -- passes only, so if the user is passing us extra options we assume
            -- they know what they are doing and don't get in the way.
            optFlag = if [String] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null (DynFlags -> (DynFlags -> [String]) -> [String]
    forall a. DynFlags -> (DynFlags -> [a]) -> [a]
    getOpts DynFlags
    dflags DynFlags -> [String]
    opt_lo)
                      then (String -> Option) -> [String] -> [Option]
    forall a b. (a -> b) -> [a] -> [b]
    map String -> Option
    GHC.SysTools.Option ([String] -> [Option]) -> [String] -> [Option]
    forall a b. (a -> b) -> a -> b
    $ String -> [String]
    words String
    llvmOpts
                      else []

        output_fn <- phaseOutputFilenameNew LlvmLlc pipe_env hsc_env Nothing

        GHC.SysTools.runLlvmOpt logger dflags
                   (   optFlag
                    ++ defaultOptions ++
                    [ GHC.SysTools.FileOption "" input_fn
                    , GHC.SysTools.Option "-o"
                    , GHC.SysTools.FileOption "" output_fn]
                    )

        return output_fn

    -- Run either 'clang' or 'gcc' phases
    runGenericAsPhase :: (Logger -> DynFlags -> [Option] -> IO ()) -> [Option] -> Bool -> PipeEnv -> HscEnv -> Maybe ModLocation -> FilePath -> IO FilePath
    runGenericAsPhase :: (Logger -> DynFlags -> [Option] -> IO ())
    -> [Option]
    -> Bool
    -> PipeEnv
    -> HscEnv
    -> Maybe ModLocation
    -> String
    -> IO String
    runGenericAsPhase Logger -> DynFlags -> [Option] -> IO ()
    run_as [Option]
    extra_opts Bool
    with_cpp PipeEnv
    pipe_env HscEnv
    hsc_env Maybe ModLocation
    location String
    input_fn = do
            let dflags :: DynFlags
    dflags     = HscEnv -> DynFlags
    hsc_dflags   HscEnv
    hsc_env
            let logger :: Logger
    logger     = HscEnv -> Logger
    hsc_logger   HscEnv
    hsc_env

            let cmdline_include_paths :: IncludeSpecs
    cmdline_include_paths = DynFlags -> IncludeSpecs
    includePaths DynFlags
    dflags
            let pic_c_flags :: [String]
    pic_c_flags = DynFlags -> [String]
    picCCOpts DynFlags
    dflags

            output_fn <- Phase -> PipeEnv -> HscEnv -> Maybe ModLocation -> IO String
    phaseOutputFilenameNew Phase
    StopLn PipeEnv
    pipe_env HscEnv
    hsc_env Maybe ModLocation
    location

            -- we create directories for the object file, because it
            -- might be a hierarchical module.
            createDirectoryIfMissing True (takeDirectory output_fn)

            let global_includes = [ String -> Option
    GHC.SysTools.Option (String
    "-I" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    p)
                                  | String
    p <- IncludeSpecs -> [String]
    includePathsGlobal IncludeSpecs
    cmdline_include_paths ]
            let local_includes = [ String -> Option
    GHC.SysTools.Option (String
    "-iquote" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    p)
                                 | String
    p <- IncludeSpecs -> [String]
    includePathsQuote IncludeSpecs
    cmdline_include_paths [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++
                                    IncludeSpecs -> [String]
    includePathsQuoteImplicit IncludeSpecs
    cmdline_include_paths]
            let runAssembler String
    inputFilename String
    outputFilename
                  = String -> (String -> IO ()) -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    String -> (String -> m a) -> m a
    withAtomicRename String
    outputFilename ((String -> IO ()) -> IO ()) -> (String -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \String
    temp_outputFilename ->
                        Logger -> DynFlags -> [Option] -> IO ()
    run_as
                           Logger
    logger DynFlags
    dflags
                           ([Option]
    local_includes [Option] -> [Option] -> [Option]
    forall a. [a] -> [a] -> [a]
    ++ [Option]
    global_includes
                           -- See Note [-fPIC for assembler]
                           [Option] -> [Option] -> [Option]
    forall a. [a] -> [a] -> [a]
    ++ (String -> Option) -> [String] -> [Option]
    forall a b. (a -> b) -> [a] -> [b]
    map String -> Option
    GHC.SysTools.Option [String]
    pic_c_flags
                           -- See Note [Produce big objects on Windows]
                           [Option] -> [Option] -> [Option]
    forall a. [a] -> [a] -> [a]
    ++ [ String -> Option
    GHC.SysTools.Option String
    "-Wa,-mbig-obj"
                              | Platform -> OS
    platformOS (DynFlags -> Platform
    targetPlatform DynFlags
    dflags) OS -> OS -> Bool
    forall a. Eq a => a -> a -> Bool
    == OS
    OSMinGW32
                              , Bool -> Bool
    not (Bool -> Bool) -> Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $ Platform -> Bool
    target32Bit (DynFlags -> Platform
    targetPlatform DynFlags
    dflags)
                              ]

                           -- See Note [-Wa,--no-type-check on wasm32]
                           [Option] -> [Option] -> [Option]
    forall a. [a] -> [a] -> [a]
    ++ [ String -> Option
    GHC.SysTools.Option String
    "-Wa,--no-type-check"
                              | Platform -> Arch
    platformArch (DynFlags -> Platform
    targetPlatform DynFlags
    dflags) Arch -> Arch -> Bool
    forall a. Eq a => a -> a -> Bool
    == Arch
    ArchWasm32]

                           [Option] -> [Option] -> [Option]
    forall a. [a] -> [a] -> [a]
    ++ [ String -> Option
    GHC.SysTools.Option String
    "-x"
                              , if Bool
    with_cpp
                                  then String -> Option
    GHC.SysTools.Option String
    "assembler-with-cpp"
                                  else String -> Option
    GHC.SysTools.Option String
    "assembler"
                              , String -> Option
    GHC.SysTools.Option String
    "-c"
                              , String -> String -> Option
    GHC.SysTools.FileOption String
    "" String
    inputFilename
                              , String -> Option
    GHC.SysTools.Option String
    "-o"
                              , String -> String -> Option
    GHC.SysTools.FileOption String
    "" String
    temp_outputFilename
                              ] [Option] -> [Option] -> [Option]
    forall a. [a] -> [a] -> [a]
    ++ [Option]
    extra_opts)

            debugTraceMsg logger 4 (text "Running the assembler")
            runAssembler input_fn output_fn

            return output_fn

    -- Invoke `clang` to assemble a .S file produced by LLvm toolchain
    runLlvmAsPhase :: Bool -> PipeEnv -> HscEnv -> Maybe ModLocation -> FilePath -> IO FilePath
    runLlvmAsPhase :: Bool
    -> PipeEnv -> HscEnv -> Maybe ModLocation -> String -> IO String
    runLlvmAsPhase =
      (Logger -> DynFlags -> [Option] -> IO ())
    -> [Option]
    -> Bool
    -> PipeEnv
    -> HscEnv
    -> Maybe ModLocation
    -> String
    -> IO String
    runGenericAsPhase Logger -> DynFlags -> [Option] -> IO ()
    runLlvmAs [ String -> Option
    GHC.SysTools.Option String
    "-Wno-unused-command-line-argument" ]

    -- Invoke 'gcc' to assemble a .S file
    runAsPhase :: Bool -> PipeEnv -> HscEnv -> Maybe ModLocation -> FilePath -> IO FilePath
    runAsPhase :: Bool
    -> PipeEnv -> HscEnv -> Maybe ModLocation -> String -> IO String
    runAsPhase =
      (Logger -> DynFlags -> [Option] -> IO ())
    -> [Option]
    -> Bool
    -> PipeEnv
    -> HscEnv
    -> Maybe ModLocation
    -> String
    -> IO String
    runGenericAsPhase Logger -> DynFlags -> [Option] -> IO ()
    runAs []

    -- Note [JS Backend .o file procedure]
    -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    --
    -- The JS backend breaks some of the assumptions on file generation order
    -- because it directly produces .o files. This violation breaks some of the
    -- assumptions on file timestamps, particularly in the postHsc phase. The
    -- postHsc phase for the JS backend is performed in 'runJsPhase'. Consider
    -- what the NCG does:
    --
    -- With other NCG backends we have the following order:
    -- 1. The backend produces a .s file
    -- 2. Then we write the interface file, .hi
    -- 3. Then we generate a .o file in a postHsc phase (calling the asm phase etc.)
    --
    -- For the JS Backend this order is different
    -- 1. The JS Backend _directly_ produces .o files
    -- 2. Then we write the interface file. Notice that this breaks the ordering
    -- of .hi > .o (step 2 and step 3 in the NCG above).
    --
    -- This violation results in timestamp checks which pass on the NCG but fail
    -- in the JS backend. In particular, checks that compare 'ms_obj_date', and
    -- 'ms_iface_date' in 'GHC.Unit.Module.ModSummary'.
    --
    -- Thus to fix this ordering we touch the object files we generated earlier
    -- to ensure these timestamps abide by the proper ordering.

    -- | Run the JS Backend postHsc phase.
    runJsPhase :: PipeEnv -> HscEnv -> Maybe ModLocation -> FilePath -> IO FilePath
    runJsPhase :: PipeEnv -> HscEnv -> Maybe ModLocation -> String -> IO String
    runJsPhase PipeEnv
    _pipe_env HscEnv
    _hsc_env Maybe ModLocation
    _location String
    input_fn = do
      -- The object file is already generated. We only touch it to ensure the
      -- timestamp is refreshed, see Note [JS Backend .o file procedure].
      String -> IO ()
    touchObjectFile String
    input_fn
      String -> IO String
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return String
    input_fn

    -- | Deal with foreign JS files (embed them into .o files)
    runForeignJsPhase :: PipeEnv -> HscEnv -> Maybe ModLocation -> FilePath -> IO FilePath
    runForeignJsPhase :: PipeEnv -> HscEnv -> Maybe ModLocation -> String -> IO String
    runForeignJsPhase PipeEnv
    pipe_env HscEnv
    hsc_env Maybe ModLocation
    _location String
    input_fn = do
      let dflags :: DynFlags
    dflags     = HscEnv -> DynFlags
    hsc_dflags   HscEnv
    hsc_env
      let logger :: Logger
    logger     = HscEnv -> Logger
    hsc_logger   HscEnv
    hsc_env
      let tmpfs :: TmpFs
    tmpfs      = HscEnv -> TmpFs
    hsc_tmpfs    HscEnv
    hsc_env
      let unit_env :: UnitEnv
    unit_env   = HscEnv -> UnitEnv
    hsc_unit_env HscEnv
    hsc_env

      output_fn <- Phase -> PipeEnv -> HscEnv -> Maybe ModLocation -> IO String
    phaseOutputFilenameNew Phase
    StopLn PipeEnv
    pipe_env HscEnv
    hsc_env Maybe ModLocation
    forall a. Maybe a
    Nothing
      embedJsFile logger dflags tmpfs unit_env input_fn output_fn
      return output_fn

    runCcPhase :: Phase -> PipeEnv -> HscEnv -> Maybe ModLocation -> FilePath -> IO FilePath
    runCcPhase :: Phase
    -> PipeEnv -> HscEnv -> Maybe ModLocation -> String -> IO String
    runCcPhase Phase
    cc_phase PipeEnv
    pipe_env HscEnv
    hsc_env Maybe ModLocation
    location String
    input_fn = do
      let dflags :: DynFlags
    dflags    = HscEnv -> DynFlags
    hsc_dflags HscEnv
    hsc_env
      let logger :: Logger
    logger    = HscEnv -> Logger
    hsc_logger HscEnv
    hsc_env
      let unit_env :: UnitEnv
    unit_env  = HscEnv -> UnitEnv
    hsc_unit_env HscEnv
    hsc_env
      let home_unit :: HomeUnit
    home_unit = HscEnv -> HomeUnit
    hsc_home_unit HscEnv
    hsc_env
      let tmpfs :: TmpFs
    tmpfs     = HscEnv -> TmpFs
    hsc_tmpfs HscEnv
    hsc_env
      let platform :: Platform
    platform  = UnitEnv -> Platform
    ue_platform UnitEnv
    unit_env
      let hcc :: Bool
    hcc       = Phase
    cc_phase Phase -> Phase -> Bool
    `eqPhase` Phase
    HCc

      let cmdline_include_paths :: IncludeSpecs
    cmdline_include_paths =  DynFlags -> IncludeSpecs -> IncludeSpecs
    offsetIncludePaths DynFlags
    dflags (DynFlags -> IncludeSpecs
    includePaths DynFlags
    dflags)

      -- HC files have the dependent packages stamped into them
      pkgs <- if Bool
    hcc then String -> IO [UnitId]
    getHCFilePackages String
    input_fn else [UnitId] -> IO [UnitId]
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return []

      -- add package include paths even if we're just compiling .c
      -- files; this is the Value Add(TM) that using ghc instead of
      -- gcc gives you :)
      ps <- mayThrowUnitErr (preloadUnitsInfo' unit_env pkgs)
      let pkg_include_dirs     = [UnitInfo] -> [String]
    collectIncludeDirs [UnitInfo]
    ps
      let include_paths_global = (String -> [String] -> [String])
    -> [String] -> [String] -> [String]
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr (\ String
    x [String]
    xs -> (String
    "-I" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    x) String -> [String] -> [String]
    forall a. a -> [a] -> [a]
    : [String]
    xs) []
            (IncludeSpecs -> [String]
    includePathsGlobal IncludeSpecs
    cmdline_include_paths [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String]
    pkg_include_dirs)
      let include_paths_quote = (String -> [String] -> [String])
    -> [String] -> [String] -> [String]
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr (\ String
    x [String]
    xs -> (String
    "-iquote" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    x) String -> [String] -> [String]
    forall a. a -> [a] -> [a]
    : [String]
    xs) []
            (IncludeSpecs -> [String]
    includePathsQuote IncludeSpecs
    cmdline_include_paths [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++
             IncludeSpecs -> [String]
    includePathsQuoteImplicit IncludeSpecs
    cmdline_include_paths)
      let include_paths = [String]
    include_paths_quote [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String]
    include_paths_global

      let gcc_extra_viac_flags = DynFlags -> [String]
    extraGccViaCFlags DynFlags
    dflags
      let pic_c_flags = DynFlags -> [String]
    picCCOpts DynFlags
    dflags

      let verbFlags = DynFlags -> [String]
    getVerbFlags DynFlags
    dflags

      -- cc-options are not passed when compiling .hc files.  Our
      -- hc code doesn't not #include any header files anyway, so these
      -- options aren't necessary.
      let pkg_extra_cc_opts
              | Bool
    hcc       = []
              | Bool
    otherwise = [UnitInfo] -> [String]
    collectExtraCcOpts [UnitInfo]
    ps

      let framework_paths
              | Platform -> Bool
    platformUsesFrameworks Platform
    platform
              = let pkgFrameworkPaths :: [String]
    pkgFrameworkPaths     = [UnitInfo] -> [String]
    collectFrameworksDirs [UnitInfo]
    ps
                    cmdlineFrameworkPaths :: [String]
    cmdlineFrameworkPaths = DynFlags -> [String]
    frameworkPaths DynFlags
    dflags
                in (String -> String) -> [String] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map (String
    "-F"String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++) ([String]
    cmdlineFrameworkPaths [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String]
    pkgFrameworkPaths)
              | Bool
    otherwise
              = []

      let cc_opt | DynFlags -> Int
    llvmOptLevel DynFlags
    dflags Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    2 = [ String
    "-O2" ]
                 | DynFlags -> Int
    llvmOptLevel DynFlags
    dflags Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    1 = [ String
    "-O" ]
                 | Bool
    otherwise            = []

      output_fn <- phaseOutputFilenameNew StopLn pipe_env hsc_env location

      -- we create directories for the object file, because it
      -- might be a hierarchical module.
      createDirectoryIfMissing True (takeDirectory output_fn)

      let
        more_hcc_opts =
              -- on x86 the floating point regs have greater precision
              -- than a double, which leads to unpredictable results.
              -- By default, we turn this off with -ffloat-store unless
              -- the user specified -fexcess-precision.
              (if Platform -> Arch
    platformArch Platform
    platform Arch -> Arch -> Bool
    forall a. Eq a => a -> a -> Bool
    == Arch
    ArchX86 Bool -> Bool -> Bool
    &&
                  Bool -> Bool
    not (GeneralFlag -> DynFlags -> Bool
    gopt GeneralFlag
    Opt_ExcessPrecision DynFlags
    dflags)
                      then [ String
    "-ffloat-store" ]
                      else []) [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++

              -- gcc's -fstrict-aliasing allows two accesses to memory
              -- to be considered non-aliasing if they have different types.
              -- This interacts badly with the C code we generate, which is
              -- very weakly typed, being derived from C--.
              [String
    "-fno-strict-aliasing"]

      ghcVersionH <- getGhcVersionPathName dflags unit_env

      withAtomicRename output_fn $ \String
    temp_outputFilename ->
        Maybe ForeignSrcLang
    -> Logger -> TmpFs -> DynFlags -> [Option] -> IO ()
    GHC.SysTools.runCc (Phase -> Maybe ForeignSrcLang
    phaseForeignLanguage Phase
    cc_phase) Logger
    logger TmpFs
    tmpfs DynFlags
    dflags (
                      [ String -> Option
    GHC.SysTools.Option String
    "-c"
                      , String -> String -> Option
    GHC.SysTools.FileOption String
    "" String
    input_fn
                      , String -> Option
    GHC.SysTools.Option String
    "-o"
                      , String -> String -> Option
    GHC.SysTools.FileOption String
    "" String
    temp_outputFilename
                      ]
                     [Option] -> [Option] -> [Option]
    forall a. [a] -> [a] -> [a]
    ++ (String -> Option) -> [String] -> [Option]
    forall a b. (a -> b) -> [a] -> [b]
    map String -> Option
    GHC.SysTools.Option (
                        [String]
    pic_c_flags

                     -- See Note [Produce big objects on Windows]
                     [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [ String
    "-Wa,-mbig-obj"
                        | Platform -> OS
    platformOS (DynFlags -> Platform
    targetPlatform DynFlags
    dflags) OS -> OS -> Bool
    forall a. Eq a => a -> a -> Bool
    == OS
    OSMinGW32
                        , Bool -> Bool
    not (Bool -> Bool) -> Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $ Platform -> Bool
    target32Bit (DynFlags -> Platform
    targetPlatform DynFlags
    dflags)
                        ]

              -- Stub files generated for foreign exports references the runIO_closure
              -- and runNonIO_closure symbols, which are defined in the base package.
              -- These symbols are imported into the stub.c file via RtsAPI.h, and the
              -- way we do the import depends on whether we're currently compiling
              -- the base package or not.
                     [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ (if Platform -> OS
    platformOS Platform
    platform OS -> OS -> Bool
    forall a. Eq a => a -> a -> Bool
    == OS
    OSMinGW32 Bool -> Bool -> Bool
    &&
                            HomeUnit -> UnitId -> Bool
    forall u. GenHomeUnit u -> UnitId -> Bool
    isHomeUnitId HomeUnit
    home_unit UnitId
    baseUnitId
                              then [ String
    "-DCOMPILING_BASE_PACKAGE" ]
                              else [])

                     -- GCC 4.6+ doesn't like -Wimplicit when compiling C++.
                     [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ (if (Phase
    cc_phase Phase -> Phase -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Phase
    Ccxx Bool -> Bool -> Bool
    && Phase
    cc_phase Phase -> Phase -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Phase
    Cobjcxx)
                           then [String
    "-Wimplicit"]
                           else [])

                     [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ (if Bool
    hcc
                           then [String]
    gcc_extra_viac_flags [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String]
    more_hcc_opts
                           else [])
                     [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String]
    verbFlags
                     [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String]
    cc_opt
                     [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [ String
    "-include", String
    ghcVersionH ]
                     [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String]
    framework_paths
                     [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String]
    include_paths
                     [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String]
    pkg_extra_cc_opts
                     ))

      return output_fn

    -- This is where all object files get written from, for hs-boot and hsig files as well.
    runHscBackendPhase :: PipeEnv
                       -> HscEnv
                       -> ModuleName
                       -> HscSource
                       -> ModLocation
                       -> HscBackendAction
                       -> IO ([FilePath], ModIface, HomeModLinkable, FilePath)
    runHscBackendPhase :: PipeEnv
    -> HscEnv
    -> ModuleName
    -> HscSource
    -> ModLocation
    -> HscBackendAction
    -> IO ([String], ModIface, HomeModLinkable, String)
    runHscBackendPhase PipeEnv
    pipe_env HscEnv
    hsc_env ModuleName
    mod_name HscSource
    src_flavour ModLocation
    location HscBackendAction
    result = do
      let dflags :: DynFlags
    dflags = HscEnv -> DynFlags
    hsc_dflags HscEnv
    hsc_env
          logger :: Logger
    logger = HscEnv -> Logger
    hsc_logger HscEnv
    hsc_env
          o_file :: String
    o_file = if DynFlags -> Bool
    dynamicNow DynFlags
    dflags then ModLocation -> String
    ml_dyn_obj_file ModLocation
    location else ModLocation -> String
    ml_obj_file ModLocation
    location -- The real object file
          next_phase :: Phase
    next_phase = HscSource -> Backend -> Phase
    hscPostBackendPhase HscSource
    src_flavour (DynFlags -> Backend
    backend DynFlags
    dflags)
      case HscBackendAction
    result of
          HscUpdate ModIface
    iface ->
              if | Bool -> Bool
    not (Backend -> Bool
    backendGeneratesCode (DynFlags -> Backend
    backend DynFlags
    dflags))  ->
                    String -> IO ([String], ModIface, HomeModLinkable, String)
    forall a. HasCallStack => String -> a
    panic String
    "HscUpdate not relevant for NoBackend"
                 | Bool -> Bool
    not (Backend -> Bool
    backendGeneratesCodeForHsBoot (DynFlags -> Backend
    backend DynFlags
    dflags)) -> do
                    -- In Interpreter way, there is just no linkable for hs-boot files
                    -- and we don't want to write an empty `o-boot` file when we're not
                    -- supposed to be writing any .o files (#22669)
                    ([String], ModIface, HomeModLinkable, String)
    -> IO ([String], ModIface, HomeModLinkable, String)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([], ModIface
    iface, HomeModLinkable
    emptyHomeModInfoLinkable, String
    o_file)
                 | Bool
    otherwise -> do
                     case HscSource
    src_flavour of
                       HscSource
    HsigFile -> do
                         -- We need to create a REAL but empty .o file
                         -- because we are going to attempt to put it in a library
                         let input_fn :: String
    input_fn = String -> Maybe String -> String
    forall a. HasCallStack => String -> Maybe a -> a
    expectJust String
    "runPhase" (ModLocation -> Maybe String
    ml_hs_file ModLocation
    location)
                             basename :: String
    basename = String -> String
    dropExtension String
    input_fn
                         DynFlags -> HscEnv -> String -> ModLocation -> ModuleName -> IO ()
    compileEmptyStub DynFlags
    dflags HscEnv
    hsc_env String
    basename ModLocation
    location ModuleName
    mod_name

                       -- In the case of hs-boot files, generate a dummy .o-boot
                       -- stamp file for the benefit of Make
                       HscSource
    HsBootFile -> String -> IO ()
    touchObjectFile String
    o_file
                       HscSource
    HsSrcFile -> String -> IO ()
    forall a. HasCallStack => String -> a
    panic String
    "HscUpdate not relevant for HscSrcFile"

                     -- MP: I wonder if there are any lurking bugs here because we
                     -- return Linkable == emptyHomeModInfoLinkable, despite the fact that there is a
                     -- linkable (.o-boot) which we check for in `Iface/Recomp.hs` and
                     -- then will carry around the linkable if we're doing
                     -- recompilation.
                     ([String], ModIface, HomeModLinkable, String)
    -> IO ([String], ModIface, HomeModLinkable, String)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([], ModIface
    iface, HomeModLinkable
    emptyHomeModInfoLinkable, String
    o_file)
          HscRecomp { hscs_guts :: HscBackendAction -> CgGuts
    hscs_guts = CgGuts
    cgguts,
                      hscs_mod_location :: HscBackendAction -> ModLocation
    hscs_mod_location = ModLocation
    mod_location,
                      hscs_partial_iface :: HscBackendAction -> PartialModIface
    hscs_partial_iface = PartialModIface
    partial_iface,
                      hscs_old_iface_hash :: HscBackendAction -> Maybe Fingerprint
    hscs_old_iface_hash = Maybe Fingerprint
    mb_old_iface_hash
                    }
            -> if Bool -> Bool
    not (Backend -> Bool
    backendGeneratesCode (DynFlags -> Backend
    backend DynFlags
    dflags)) then
                 String -> IO ([String], ModIface, HomeModLinkable, String)
    forall a. HasCallStack => String -> a
    panic String
    "HscRecomp not relevant for NoBackend"
               else if Backend -> Bool
    backendWritesFiles (DynFlags -> Backend
    backend DynFlags
    dflags) then
                 do
                  output_fn <- Phase -> PipeEnv -> HscEnv -> Maybe ModLocation -> IO String
    phaseOutputFilenameNew Phase
    next_phase PipeEnv
    pipe_env HscEnv
    hsc_env (ModLocation -> Maybe ModLocation
    forall a. a -> Maybe a
    Just ModLocation
    location)
                  (outputFilename, mStub, foreign_files, stg_infos, cg_infos) <-

                    hscGenHardCode hsc_env cgguts mod_location output_fn
                  final_iface <- mkFullIface hsc_env partial_iface stg_infos cg_infos

                  -- See Note [Writing interface files]
                  hscMaybeWriteIface logger dflags False final_iface mb_old_iface_hash mod_location
                  mlinkable <-
                    if backendGeneratesCode (backend dflags) && gopt Opt_ByteCodeAndObjectCode dflags
                      then do
                        bc <- generateFreshByteCode hsc_env mod_name (mkCgInteractiveGuts cgguts) mod_location
                        return $ emptyHomeModInfoLinkable { homeMod_bytecode = Just bc }

                      else return emptyHomeModInfoLinkable

                  stub_o <- mapM (compileStub hsc_env) mStub
                  foreign_os <-
                    mapM (uncurry (compileForeign hsc_env)) foreign_files
                  let fos = ([String] -> (String -> [String]) -> Maybe String -> [String]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] String -> [String]
    forall a. a -> [a]
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe String
    stub_o [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String]
    foreign_os)

                  -- This is awkward, no linkable is produced here because we still
                  -- have some way to do before the object file is produced
                  -- In future we can split up the driver logic more so that this function
                  -- is in TPipeline and in this branch we can invoke the rest of the backend phase.
                  return (fos, final_iface, mlinkable, outputFilename)

               else
                  -- In interpreted mode the regular codeGen backend is not run so we
                  -- generate a interface without codeGen info.
                do
                  final_iface <- HscEnv
    -> PartialModIface
    -> Maybe StgCgInfos
    -> Maybe CmmCgInfos
    -> IO ModIface
    mkFullIface HscEnv
    hsc_env PartialModIface
    partial_iface Maybe StgCgInfos
    forall a. Maybe a
    Nothing Maybe CmmCgInfos
    forall a. Maybe a
    Nothing
                  hscMaybeWriteIface logger dflags True final_iface mb_old_iface_hash location
                  bc <- generateFreshByteCode hsc_env mod_name (mkCgInteractiveGuts cgguts) mod_location
                  return ([], final_iface, emptyHomeModInfoLinkable { homeMod_bytecode = Just bc } , panic "interpreter")

    runUnlitPhase :: HscEnv -> FilePath -> FilePath -> IO FilePath
    runUnlitPhase :: HscEnv -> String -> String -> IO String
    runUnlitPhase HscEnv
    hsc_env String
    input_fn String
    output_fn = do
        let
           -- escape the characters \, ", and ', but don't try to escape
           -- Unicode or anything else (so we don't use Util.charToC
           -- here).  If we get this wrong, then in
           -- GHC.HsToCore.Ticks.isGoodTickSrcSpan where we check that the filename in
           -- a SrcLoc is the same as the source filename, the two will
           -- look bogusly different. See test:
           -- testsuite/tests/hpc/function/subdir/tough2.hs
           escape :: String -> String
    escape (Char
    '\\':String
    cs) = Char
    '\\'Char -> String -> String
    forall a. a -> [a] -> [a]
    :Char
    '\\'Char -> String -> String
    forall a. a -> [a] -> [a]
    : String -> String
    escape String
    cs
           escape (Char
    '\"':String
    cs) = Char
    '\\'Char -> String -> String
    forall a. a -> [a] -> [a]
    :Char
    '\"'Char -> String -> String
    forall a. a -> [a] -> [a]
    : String -> String
    escape String
    cs
           escape (Char
    '\'':String
    cs) = Char
    '\\'Char -> String -> String
    forall a. a -> [a] -> [a]
    :Char
    '\''Char -> String -> String
    forall a. a -> [a] -> [a]
    : String -> String
    escape String
    cs
           escape (Char
    c:String
    cs)    = Char
    c Char -> String -> String
    forall a. a -> [a] -> [a]
    : String -> String
    escape String
    cs
           escape []        = []

        let flags :: [Option]
    flags = [ -- The -h option passes the file name for unlit to
                      -- put in a #line directive
                      String -> Option
    GHC.SysTools.Option     String
    "-h"
                      -- See Note [Don't normalise input filenames].
                    , String -> Option
    GHC.SysTools.Option (String -> Option) -> String -> Option
    forall a b. (a -> b) -> a -> b
    $ String -> String
    escape String
    input_fn
                    , String -> String -> Option
    GHC.SysTools.FileOption String
    "" String
    input_fn
                    , String -> String -> Option
    GHC.SysTools.FileOption String
    "" String
    output_fn
                    ]

        let dflags :: DynFlags
    dflags = HscEnv -> DynFlags
    hsc_dflags HscEnv
    hsc_env
            logger :: Logger
    logger = HscEnv -> Logger
    hsc_logger HscEnv
    hsc_env
        Logger -> DynFlags -> [Option] -> IO ()
    GHC.SysTools.runUnlit Logger
    logger DynFlags
    dflags [Option]
    flags

        String -> IO String
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return String
    output_fn

    getFileArgs :: HscEnv -> FilePath -> IO ((DynFlags, Messages PsMessage, Messages DriverMessage))
    getFileArgs :: HscEnv
    -> String
    -> IO (DynFlags, Messages PsMessage, Messages DriverMessage)
    getFileArgs HscEnv
    hsc_env String
    input_fn = do
      let dflags0 :: DynFlags
    dflags0 = HscEnv -> DynFlags
    hsc_dflags HscEnv
    hsc_env
          parser_opts :: ParserOpts
    parser_opts = DynFlags -> ParserOpts
    initParserOpts DynFlags
    dflags0
      (warns0, src_opts) <- ParserOpts -> String -> IO (Messages PsMessage, [Located String])
    getOptionsFromFile ParserOpts
    parser_opts String
    input_fn
      (dflags1, unhandled_flags, warns)
        <- parseDynamicFilePragma dflags0 src_opts
      checkProcessArgsResult unhandled_flags
      return (dflags1, warns0, warns)

    runCppPhase :: HscEnv -> FilePath -> FilePath -> IO FilePath
    runCppPhase :: HscEnv -> String -> String -> IO String
    runCppPhase HscEnv
    hsc_env String
    input_fn String
    output_fn = do
      Logger
    -> TmpFs
    -> DynFlags
    -> UnitEnv
    -> CppOpts
    -> String
    -> String
    -> IO ()
    doCpp (HscEnv -> Logger
    hsc_logger HscEnv
    hsc_env)
               (HscEnv -> TmpFs
    hsc_tmpfs HscEnv
    hsc_env)
               (HscEnv -> DynFlags
    hsc_dflags HscEnv
    hsc_env)
               (HscEnv -> UnitEnv
    hsc_unit_env HscEnv
    hsc_env)
               (CppOpts
                  { useHsCpp :: Bool
    useHsCpp       = Bool
    True
                  , cppLinePragmas :: Bool
    cppLinePragmas = Bool
    True
                  })
               String
    input_fn String
    output_fn
      String -> IO String
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return String
    output_fn

    runHscPhase :: PipeEnv
      -> HscEnv
      -> FilePath
      -> HscSource
      -> IO (HscEnv, ModSummary, HscRecompStatus)
    runHscPhase :: PipeEnv
    -> HscEnv
    -> String
    -> HscSource
    -> IO (HscEnv, ModSummary, HscRecompStatus)
    runHscPhase PipeEnv
    pipe_env HscEnv
    hsc_env0 String
    input_fn HscSource
    src_flavour = do
      let dflags0 :: DynFlags
    dflags0 = HscEnv -> DynFlags
    hsc_dflags HscEnv
    hsc_env0
          PipeEnv{ src_basename :: PipeEnv -> String
    src_basename=String
    basename,
                   src_suffix :: PipeEnv -> String
    src_suffix=String
    suff } = PipeEnv
    pipe_env

      -- we add the current directory (i.e. the directory in which
      -- the .hs files resides) to the include path, since this is
      -- what gcc does, and it's probably what you want.
      let current_dir :: String
    current_dir = String -> String
    takeDirectory String
    basename
          new_includes :: IncludeSpecs
    new_includes = IncludeSpecs -> [String] -> IncludeSpecs
    addImplicitQuoteInclude IncludeSpecs
    paths [String
    current_dir]
          paths :: IncludeSpecs
    paths = DynFlags -> IncludeSpecs
    includePaths DynFlags
    dflags0
          dflags :: DynFlags
    dflags = DynFlags
    dflags0 { includePaths = new_includes }
          hsc_env1 :: HscEnv
    hsc_env1 = HasDebugCallStack => DynFlags -> HscEnv -> HscEnv
    DynFlags -> HscEnv -> HscEnv
    hscSetFlags DynFlags
    dflags HscEnv
    hsc_env0

      -- Initialise plugins as the flags passed into runHscPhase might have local plugins just
      -- specific to this module.
      hsc_env <- HscEnv -> IO HscEnv
    initializePlugins HscEnv
    hsc_env1

      -- gather the imports and module name
      (hspp_buf,mod_name,imps,src_imps, ghc_prim_imp) <- do
        buf <- hGetStringBuffer input_fn
        let imp_prelude = Extension -> DynFlags -> Bool
    xopt Extension
    LangExt.ImplicitPrelude DynFlags
    dflags
            popts = DynFlags -> ParserOpts
    initParserOpts DynFlags
    dflags
            rn_pkg_qual = UnitEnv -> ModuleName -> RawPkgQual -> PkgQual
    renameRawPkgQual (HscEnv -> UnitEnv
    hsc_unit_env HscEnv
    hsc_env)
            rn_imps = ((RawPkgQual, GenLocated SrcSpan ModuleName)
     -> (PkgQual, GenLocated SrcSpan ModuleName))
    -> [(RawPkgQual, GenLocated SrcSpan ModuleName)]
    -> [(PkgQual, GenLocated SrcSpan ModuleName)]
    forall a b. (a -> b) -> [a] -> [b]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(RawPkgQual
    rpk, lmn :: GenLocated SrcSpan ModuleName
    lmn@(L SrcSpan
    _ ModuleName
    mn)) -> (ModuleName -> RawPkgQual -> PkgQual
    rn_pkg_qual ModuleName
    mn RawPkgQual
    rpk, GenLocated SrcSpan ModuleName
    lmn))
        eimps <- getImports popts imp_prelude buf input_fn (basename <.> suff)
        case eimps of
            Left Messages PsMessage
    errs -> Messages GhcMessage
    -> IO
         (Maybe StringBuffer, ModuleName,
          [(PkgQual, GenLocated SrcSpan ModuleName)],
          [(PkgQual, GenLocated SrcSpan ModuleName)], Bool)
    forall (io :: * -> *) a. MonadIO io => Messages GhcMessage -> io a
    throwErrors (PsMessage -> GhcMessage
    GhcPsMessage (PsMessage -> GhcMessage)
    -> Messages PsMessage -> Messages GhcMessage
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Messages PsMessage
    errs)
            Right ([(RawPkgQual, GenLocated SrcSpan ModuleName)]
    src_imps,[(RawPkgQual, GenLocated SrcSpan ModuleName)]
    imps, Bool
    ghc_prim_imp, L SrcSpan
    _ ModuleName
    mod_name) -> (Maybe StringBuffer, ModuleName,
     [(PkgQual, GenLocated SrcSpan ModuleName)],
     [(PkgQual, GenLocated SrcSpan ModuleName)], Bool)
    -> IO
         (Maybe StringBuffer, ModuleName,
          [(PkgQual, GenLocated SrcSpan ModuleName)],
          [(PkgQual, GenLocated SrcSpan ModuleName)], Bool)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return
                  (StringBuffer -> Maybe StringBuffer
    forall a. a -> Maybe a
    Just StringBuffer
    buf, ModuleName
    mod_name, [(RawPkgQual, GenLocated SrcSpan ModuleName)]
    -> [(PkgQual, GenLocated SrcSpan ModuleName)]
    rn_imps [(RawPkgQual, GenLocated SrcSpan ModuleName)]
    imps, [(RawPkgQual, GenLocated SrcSpan ModuleName)]
    -> [(PkgQual, GenLocated SrcSpan ModuleName)]
    rn_imps [(RawPkgQual, GenLocated SrcSpan ModuleName)]
    src_imps, Bool
    ghc_prim_imp)

      -- Take -o into account if present
      -- Very like -ohi, but we must *only* do this if we aren't linking
      -- (If we're linking then the -o applies to the linked thing, not to
      -- the object file for one module.)
      -- Note the nasty duplication with the same computation in compileFile above
      location <- mkOneShotModLocation pipe_env dflags src_flavour mod_name
      let o_file = ModLocation -> String
    ml_obj_file ModLocation
    location -- The real object file
          hi_file = ModLocation -> String
    ml_hi_file ModLocation
    location
          hie_file = ModLocation -> String
    ml_hie_file ModLocation
    location
          dyn_o_file = ModLocation -> String
    ml_dyn_obj_file ModLocation
    location

      src_hash <- getFileHash (basename <.> suff)
      hi_date <- modificationTimeIfExists hi_file
      hie_date <- modificationTimeIfExists hie_file
      o_mod <- modificationTimeIfExists o_file
      dyn_o_mod <- modificationTimeIfExists dyn_o_file

      -- Tell the finder cache about this module
      mod <- do
        let home_unit = HscEnv -> HomeUnit
    hsc_home_unit HscEnv
    hsc_env
        let fc        = HscEnv -> FinderCache
    hsc_FC HscEnv
    hsc_env
        addHomeModuleToFinder fc home_unit mod_name location

      -- Make the ModSummary to hand to hscMain
      let
        mod_summary = ModSummary {  ms_mod :: Module
    ms_mod       = Module
    mod,
                                    ms_hsc_src :: HscSource
    ms_hsc_src   = HscSource
    src_flavour,
                                    ms_hspp_file :: String
    ms_hspp_file = String
    input_fn,
                                    ms_hspp_opts :: DynFlags
    ms_hspp_opts = DynFlags
    dflags,
                                    ms_hspp_buf :: Maybe StringBuffer
    ms_hspp_buf  = Maybe StringBuffer
    hspp_buf,
                                    ms_location :: ModLocation
    ms_location  = ModLocation
    location,
                                    ms_hs_hash :: Fingerprint
    ms_hs_hash   = Fingerprint
    src_hash,
                                    ms_obj_date :: Maybe UTCTime
    ms_obj_date  = Maybe UTCTime
    o_mod,
                                    ms_dyn_obj_date :: Maybe UTCTime
    ms_dyn_obj_date = Maybe UTCTime
    dyn_o_mod,
                                    ms_parsed_mod :: Maybe HsParsedModule
    ms_parsed_mod   = Maybe HsParsedModule
    forall a. Maybe a
    Nothing,
                                    ms_iface_date :: Maybe UTCTime
    ms_iface_date   = Maybe UTCTime
    hi_date,
                                    ms_hie_date :: Maybe UTCTime
    ms_hie_date     = Maybe UTCTime
    hie_date,
                                    ms_ghc_prim_import :: Bool
    ms_ghc_prim_import = Bool
    ghc_prim_imp,
                                    ms_textual_imps :: [(PkgQual, GenLocated SrcSpan ModuleName)]
    ms_textual_imps = [(PkgQual, GenLocated SrcSpan ModuleName)]
    imps,
                                    ms_srcimps :: [(PkgQual, GenLocated SrcSpan ModuleName)]
    ms_srcimps      = [(PkgQual, GenLocated SrcSpan ModuleName)]
    src_imps }

      -- run the compiler!
      let msg :: Messager
          msg HscEnv
    hsc_env (Int, Int)
    _ RecompileRequired
    what ModuleGraphNode
    _ = Logger -> RecompileRequired -> IO ()
    oneShotMsg (HscEnv -> Logger
    hsc_logger HscEnv
    hsc_env) RecompileRequired
    what

      -- Need to set the knot-tying mutable variable for interface
      -- files. See GHC.Tc.Utils.TcGblEnv.tcg_type_env_var.
      -- See also Note [hsc_type_env_var hack]
      type_env_var <- newIORef emptyNameEnv
      let hsc_env' = HscEnv
    hsc_env { hsc_type_env_vars = knotVarsFromModuleEnv (mkModuleEnv [(mod, type_env_var)]) }

      status <- hscRecompStatus (Just msg) hsc_env' mod_summary
                            Nothing emptyHomeModInfoLinkable (1, 1)

      return (hsc_env', mod_summary, status)

    -- | Calculate the ModLocation from the provided DynFlags. This function is only used
    -- in one-shot mode and therefore takes into account the effect of -o/-ohi flags
    -- (which do nothing in --make mode)
    mkOneShotModLocation :: PipeEnv -> DynFlags -> HscSource -> ModuleName -> IO ModLocation
    mkOneShotModLocation :: PipeEnv -> DynFlags -> HscSource -> ModuleName -> IO ModLocation
    mkOneShotModLocation PipeEnv
    pipe_env DynFlags
    dflags HscSource
    src_flavour ModuleName
    mod_name = do
        let PipeEnv{ src_basename :: PipeEnv -> String
    src_basename=String
    basename,
                 src_suffix :: PipeEnv -> String
    src_suffix=String
    suff } = PipeEnv
    pipe_env
        let location1 :: ModLocation
    location1 = FinderOpts -> ModuleName -> String -> String -> ModLocation
    mkHomeModLocation2 FinderOpts
    fopts ModuleName
    mod_name String
    basename String
    suff

        -- Boot-ify it if necessary
        let location2 :: ModLocation
    location2
              | HscSource
    HsBootFile <- HscSource
    src_flavour = ModLocation -> ModLocation
    addBootSuffixLocnOut ModLocation
    location1
              | Bool
    otherwise                 = ModLocation
    location1

        -- Take -ohi into account if present
        -- This can't be done in mkHomeModuleLocation because
        -- it only applies to the module being compiles
        let ohi :: Maybe String
    ohi = DynFlags -> Maybe String
    outputHi DynFlags
    dflags
            location3 :: ModLocation
    location3 | Just String
    fn <- Maybe String
    ohi = ModLocation
    location2{ ml_hi_file = fn }
                      | Bool
    otherwise      = ModLocation
    location2

        let dynohi :: Maybe String
    dynohi = DynFlags -> Maybe String
    dynOutputHi DynFlags
    dflags
            location4 :: ModLocation
    location4 | Just String
    fn <- Maybe String
    dynohi = ModLocation
    location3{ ml_dyn_hi_file = fn }
                      | Bool
    otherwise         = ModLocation
    location3

        -- Take -o into account if present
        -- Very like -ohi, but we must *only* do this if we aren't linking
        -- (If we're linking then the -o applies to the linked thing, not to
        -- the object file for one module.)
        -- Note the nasty duplication with the same computation in compileFile
        -- above
        let expl_o_file :: Maybe String
    expl_o_file = DynFlags -> Maybe String
    outputFile_ DynFlags
    dflags
            expl_dyn_o_file :: Maybe String
    expl_dyn_o_file  = DynFlags -> Maybe String
    dynOutputFile_ DynFlags
    dflags
            location5 :: ModLocation
    location5 | Just String
    ofile <- Maybe String
    expl_o_file
                      , let dyn_ofile :: String
    dyn_ofile = String -> Maybe String -> String
    forall a. a -> Maybe a -> a
    fromMaybe (String
    ofile String -> String -> String
    -<.> DynFlags -> String
    dynObjectSuf_ DynFlags
    dflags) Maybe String
    expl_dyn_o_file
                      , GhcLink -> Bool
    isNoLink (DynFlags -> GhcLink
    ghcLink DynFlags
    dflags)
                      = ModLocation
    location4 { ml_obj_file = ofile
                                  , ml_dyn_obj_file = dyn_ofile }
                      | Just String
    dyn_ofile <- Maybe String
    expl_dyn_o_file
                      = ModLocation
    location4 { ml_dyn_obj_file = dyn_ofile }
                      | Bool
    otherwise = ModLocation
    location4
        ModLocation -> IO ModLocation
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ModLocation
    location5
        where
          fopts :: FinderOpts
    fopts = DynFlags -> FinderOpts
    initFinderOpts DynFlags
    dflags

    runHscTcPhase :: HscEnv -> ModSummary -> IO (FrontendResult, Messages GhcMessage)
    runHscTcPhase :: HscEnv -> ModSummary -> IO (FrontendResult, Messages GhcMessage)
    runHscTcPhase = HscEnv -> ModSummary -> IO (FrontendResult, Messages GhcMessage)
    hscTypecheckAndGetWarnings

    runHscPostTcPhase ::
        HscEnv
      -> ModSummary
      -> FrontendResult
      -> Messages GhcMessage
      -> Maybe Fingerprint
      -> IO HscBackendAction
    runHscPostTcPhase :: HscEnv
    -> ModSummary
    -> FrontendResult
    -> Messages GhcMessage
    -> Maybe Fingerprint
    -> IO HscBackendAction
    runHscPostTcPhase HscEnv
    hsc_env ModSummary
    mod_summary FrontendResult
    tc_result Messages GhcMessage
    tc_warnings Maybe Fingerprint
    mb_old_hash = do
            HscEnv -> Hsc HscBackendAction -> IO HscBackendAction
    forall a. HscEnv -> Hsc a -> IO a
    runHsc HscEnv
    hsc_env (Hsc HscBackendAction -> IO HscBackendAction)
    -> Hsc HscBackendAction -> IO HscBackendAction
    forall a b. (a -> b) -> a -> b
    $ do
                ModSummary
    -> FrontendResult
    -> Messages GhcMessage
    -> Maybe Fingerprint
    -> Hsc HscBackendAction
    hscDesugarAndSimplify ModSummary
    mod_summary FrontendResult
    tc_result Messages GhcMessage
    tc_warnings Maybe Fingerprint
    mb_old_hash

    runHsPpPhase :: HscEnv -> FilePath -> FilePath -> FilePath -> IO FilePath
    runHsPpPhase :: HscEnv -> String -> String -> String -> IO String
    runHsPpPhase HscEnv
    hsc_env String
    orig_fn String
    input_fn String
    output_fn = do
        let dflags :: DynFlags
    dflags = HscEnv -> DynFlags
    hsc_dflags HscEnv
    hsc_env
        let logger :: Logger
    logger = HscEnv -> Logger
    hsc_logger HscEnv
    hsc_env
        Logger -> DynFlags -> [Option] -> IO ()
    GHC.SysTools.runPp Logger
    logger DynFlags
    dflags
          ( [ String -> Option
    GHC.SysTools.Option     String
    orig_fn
          , String -> Option
    GHC.SysTools.Option     String
    input_fn
          , String -> String -> Option
    GHC.SysTools.FileOption String
    "" String
    output_fn
          ] )
        String -> IO String
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return String
    output_fn

    phaseOutputFilenameNew :: Phase -- ^ The next phase
                           -> PipeEnv
                           -> HscEnv
                           -> Maybe ModLocation -- ^ A ModLocation, if we are compiling a Haskell source file
                           -> IO FilePath
    phaseOutputFilenameNew :: Phase -> PipeEnv -> HscEnv -> Maybe ModLocation -> IO String
    phaseOutputFilenameNew Phase
    next_phase PipeEnv
    pipe_env HscEnv
    hsc_env Maybe ModLocation
    maybe_loc = do
      let PipeEnv{StopPhase
    stop_phase :: StopPhase
    stop_phase :: PipeEnv -> StopPhase
    stop_phase, String
    src_basename :: PipeEnv -> String
    src_basename :: String
    src_basename, PipelineOutput
    output_spec :: PipelineOutput
    output_spec :: PipeEnv -> PipelineOutput
    output_spec} = PipeEnv
    pipe_env
      let dflags :: DynFlags
    dflags = HscEnv -> DynFlags
    hsc_dflags HscEnv
    hsc_env
          logger :: Logger
    logger = HscEnv -> Logger
    hsc_logger HscEnv
    hsc_env
          tmpfs :: TmpFs
    tmpfs = HscEnv -> TmpFs
    hsc_tmpfs HscEnv
    hsc_env
      Logger
    -> TmpFs
    -> Phase
    -> PipelineOutput
    -> String
    -> DynFlags
    -> Phase
    -> Maybe ModLocation
    -> IO String
    getOutputFilename Logger
    logger TmpFs
    tmpfs (StopPhase -> Phase
    stopPhaseToPhase StopPhase
    stop_phase) PipelineOutput
    output_spec
                        String
    src_basename DynFlags
    dflags Phase
    next_phase Maybe ModLocation
    maybe_loc

    -- | Computes the next output filename for something in the compilation
    -- pipeline.  This is controlled by several variables:
    --
    --      1. 'Phase': the last phase to be run (e.g. 'stopPhase').  This
    --         is used to tell if we're in the last phase or not, because
    --         in that case flags like @-o@ may be important.
    --      2. 'PipelineOutput': is this intended to be a 'Temporary' or
    --         'Persistent' build output?  Temporary files just go in
    --         a fresh temporary name.
    --      3. 'String': what was the basename of the original input file?
    --      4. 'DynFlags': the obvious thing
    --      5. 'Phase': the phase we want to determine the output filename of.
    --      6. @Maybe ModLocation@: the 'ModLocation' of the module we're
    --         compiling; this can be used to override the default output
    --         of an object file.  (TODO: do we actually need this?)
    getOutputFilename
      :: Logger
      -> TmpFs
      -> Phase
      -> PipelineOutput
      -> String
      -> DynFlags
      -> Phase -- next phase
      -> Maybe ModLocation
      -> IO FilePath
    getOutputFilename :: Logger
    -> TmpFs
    -> Phase
    -> PipelineOutput
    -> String
    -> DynFlags
    -> Phase
    -> Maybe ModLocation
    -> IO String
    getOutputFilename Logger
    logger TmpFs
    tmpfs Phase
    stop_phase PipelineOutput
    output String
    basename DynFlags
    dflags Phase
    next_phase Maybe ModLocation
    maybe_location
      -- 1. If we are generating object files for a .hs file, then return the odir as the ModLocation
      -- will have been modified to point to the accurate locations
     | Phase
    StopLn <- Phase
    next_phase, Just ModLocation
    loc <- Maybe ModLocation
    maybe_location  =
          String -> IO String
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (String -> IO String) -> String -> IO String
    forall a b. (a -> b) -> a -> b
    $ if DynFlags -> Bool
    dynamicNow DynFlags
    dflags then ModLocation -> String
    ml_dyn_obj_file ModLocation
    loc
                                        else ModLocation -> String
    ml_obj_file ModLocation
    loc
     -- 2. If output style is persistent then
     | Bool
    is_last_phase, PipelineOutput
    Persistent   <- PipelineOutput
    output = IO String
    persistent_fn
     -- 3. Specific file is only set when outputFile is set by -o
     -- If we are in dynamic mode but -dyno is not set then write to the same path as
     -- -o with a .dyn_* extension. This case is not triggered for object files which
     -- are always handled by the ModLocation.
     | Bool
    is_last_phase, PipelineOutput
    SpecificFile <- PipelineOutput
    output =
        String -> IO String
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (String -> IO String) -> String -> IO String
    forall a b. (a -> b) -> a -> b
    $
          if DynFlags -> Bool
    dynamicNow DynFlags
    dflags
            then case DynFlags -> Maybe String
    dynOutputFile_ DynFlags
    dflags of
                    Maybe String
    Nothing -> let ofile :: String
    ofile = DynFlags -> String
    getOutputFile_ DynFlags
    dflags
                                   new_ext :: String
    new_ext = case String -> String
    takeExtension String
    ofile of
                                                String
    "" -> String
    "dyn"
                                                String
    ext -> String
    "dyn_" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String -> String
    forall a. HasCallStack => [a] -> [a]
    tail String
    ext
                               in String -> String -> String
    replaceExtension String
    ofile String
    new_ext
                    Just String
    fn -> String
    fn
            else DynFlags -> String
    getOutputFile_ DynFlags
    dflags
     | Bool
    keep_this_output                      = IO String
    persistent_fn
     | Temporary TempFileLifetime
    lifetime <- PipelineOutput
    output          = Logger
    -> TmpFs -> TempDir -> TempFileLifetime -> String -> IO String
    newTempName Logger
    logger TmpFs
    tmpfs (DynFlags -> TempDir
    tmpDir DynFlags
    dflags) TempFileLifetime
    lifetime String
    suffix
     | Bool
    otherwise                             = Logger
    -> TmpFs -> TempDir -> TempFileLifetime -> String -> IO String
    newTempName Logger
    logger TmpFs
    tmpfs (DynFlags -> TempDir
    tmpDir DynFlags
    dflags) TempFileLifetime
    TFL_CurrentModule
       String
    suffix
        where
              getOutputFile_ :: DynFlags -> String
    getOutputFile_ DynFlags
    dflags =
                case DynFlags -> Maybe String
    outputFile_ DynFlags
    dflags of
                  Maybe String
    Nothing -> String -> SDoc -> String
    forall a. HasCallStack => String -> SDoc -> a
    pprPanic String
    "SpecificFile: No filename" (Bool -> SDoc
    forall a. Outputable a => a -> SDoc
    ppr (DynFlags -> Bool
    dynamicNow DynFlags
    dflags) SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$
                                                                   String -> SDoc
    forall doc. IsLine doc => String -> doc
    text (String -> Maybe String -> String
    forall a. a -> Maybe a -> a
    fromMaybe String
    "-" (DynFlags -> Maybe String
    dynOutputFile_ DynFlags
    dflags)))
                  Just String
    fn -> String
    fn

              hcsuf :: String
    hcsuf      = DynFlags -> String
    hcSuf DynFlags
    dflags
              odir :: Maybe String
    odir       = DynFlags -> Maybe String
    objectDir DynFlags
    dflags
              osuf :: String
    osuf       = DynFlags -> String
    objectSuf DynFlags
    dflags
              keep_hc :: Bool
    keep_hc    = GeneralFlag -> DynFlags -> Bool
    gopt GeneralFlag
    Opt_KeepHcFiles DynFlags
    dflags
              keep_hscpp :: Bool
    keep_hscpp = GeneralFlag -> DynFlags -> Bool
    gopt GeneralFlag
    Opt_KeepHscppFiles DynFlags
    dflags
              keep_s :: Bool
    keep_s     = GeneralFlag -> DynFlags -> Bool
    gopt GeneralFlag
    Opt_KeepSFiles DynFlags
    dflags
              keep_bc :: Bool
    keep_bc    = GeneralFlag -> DynFlags -> Bool
    gopt GeneralFlag
    Opt_KeepLlvmFiles DynFlags
    dflags

              myPhaseInputExt :: Phase -> String
    myPhaseInputExt Phase
    HCc       = String
    hcsuf
              myPhaseInputExt Phase
    MergeForeign = String
    osuf
              myPhaseInputExt Phase
    StopLn    = String
    osuf
              myPhaseInputExt Phase
    other     = Phase -> String
    phaseInputExt Phase
    other

              is_last_phase :: Bool
    is_last_phase = Phase
    next_phase Phase -> Phase -> Bool
    `eqPhase` Phase
    stop_phase

              -- sometimes, we keep output from intermediate stages
              keep_this_output :: Bool
    keep_this_output =
                   case Phase
    next_phase of
                           As Bool
    _    | Bool
    keep_s     -> Bool
    True
                           Phase
    LlvmOpt | Bool
    keep_bc    -> Bool
    True
                           Phase
    HCc     | Bool
    keep_hc    -> Bool
    True
                           HsPp HscSource
    _  | Bool
    keep_hscpp -> Bool
    True   -- See #10869
                           Phase
    _other               -> Bool
    False

              suffix :: String
    suffix = Phase -> String
    myPhaseInputExt Phase
    next_phase

              -- persistent object files get put in odir
              persistent_fn :: IO String
    persistent_fn
                 | Phase
    StopLn <- Phase
    next_phase = String -> IO String
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return String
    odir_persistent
                 | Bool
    otherwise            = String -> IO String
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return String
    persistent

              persistent :: String
    persistent = String
    basename String -> String -> String
    <.> String
    suffix

              odir_persistent :: String
    odir_persistent
                 | Just String
    d <- Maybe String
    odir = (String
    d String -> String -> String
    </> String
    persistent)
                 | Bool
    otherwise      = String
    persistent

    -- | LLVM Options. These are flags to be passed to opt and llc, to ensure
    -- consistency we list them in pairs, so that they form groups.
    llvmOptions :: LlvmConfig
                -> DynFlags
                -> [(String, String)]  -- ^ pairs of (opt, llc) arguments
    llvmOptions :: LlvmConfig -> DynFlags -> [(String, String)]
    llvmOptions LlvmConfig
    llvm_config DynFlags
    dflags =
           [(String
    "-relocation-model=" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    rmodel
            ,String
    "-relocation-model=" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    rmodel) | Bool -> Bool
    not (String -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null String
    rmodel)]

        -- Additional llc flags
        [(String, String)] -> [(String, String)] -> [(String, String)]
    forall a. [a] -> [a] -> [a]
    ++ [(String
    "", String
    "-mcpu=" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    mcpu)   | Bool -> Bool
    not (String -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null String
    mcpu)
                                     , Bool -> Bool
    not ((String -> Bool) -> [String] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    any (String -> String -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    isInfixOf String
    "-mcpu") (DynFlags -> (DynFlags -> [String]) -> [String]
    forall a. DynFlags -> (DynFlags -> [a]) -> [a]
    getOpts DynFlags
    dflags DynFlags -> [String]
    opt_lc)) ]
        [(String, String)] -> [(String, String)] -> [(String, String)]
    forall a. [a] -> [a] -> [a]
    ++ [(String
    "", String
    "-mattr=" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    attrs) | Bool -> Bool
    not (String -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null String
    attrs) ]
        [(String, String)] -> [(String, String)] -> [(String, String)]
    forall a. [a] -> [a] -> [a]
    ++ [(String
    "", String
    "-target-abi=" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    abi) | Bool -> Bool
    not (String -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null String
    abi) ]

      where target :: String
    target = PlatformMisc -> String
    platformMisc_llvmTarget (PlatformMisc -> String) -> PlatformMisc -> String
    forall a b. (a -> b) -> a -> b
    $ DynFlags -> PlatformMisc
    platformMisc DynFlags
    dflags
            Just (LlvmTarget String
    _ String
    mcpu [String]
    mattr) = String -> [(String, LlvmTarget)] -> Maybe LlvmTarget
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup String
    target (LlvmConfig -> [(String, LlvmTarget)]
    llvmTargets LlvmConfig
    llvm_config)

            -- Relocation models
            rmodel :: String
    rmodel | GeneralFlag -> DynFlags -> Bool
    gopt GeneralFlag
    Opt_PIC DynFlags
    dflags         = String
    "pic"
                   | DynFlags -> Bool
    positionIndependent DynFlags
    dflags  = String
    "pic"
                   | DynFlags -> Ways
    ways DynFlags
    dflags Ways -> Way -> Bool
    `hasWay` Way
    WayDyn = String
    "dynamic-no-pic"
                   | Bool
    otherwise                   = String
    "static"

            platform :: Platform
    platform = DynFlags -> Platform
    targetPlatform DynFlags
    dflags
            arch :: Arch
    arch = Platform -> Arch
    platformArch Platform
    platform

            attrs :: String
            attrs :: String
    attrs = String -> [String] -> String
    forall a. [a] -> [[a]] -> [a]
    intercalate String
    "," ([String] -> String) -> [String] -> String
    forall a b. (a -> b) -> a -> b
    $ [String]
    mattr
                  [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String
    "+sse42"   | DynFlags -> Bool
    isSse4_2Enabled DynFlags
    dflags   ]
                  [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String
    "+sse2"    | Platform -> Bool
    isSse2Enabled Platform
    platform   ]
                  [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String
    "+sse"     | Platform -> Bool
    isSseEnabled Platform
    platform    ]
                  [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String
    "+avx512f" | DynFlags -> Bool
    isAvx512fEnabled DynFlags
    dflags  ]
                  [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String
    "+avx2"    | DynFlags -> Bool
    isAvx2Enabled DynFlags
    dflags     ]
                  [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String
    "+avx"     | DynFlags -> Bool
    isAvxEnabled DynFlags
    dflags      ]
                  [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String
    "+avx512cd"| DynFlags -> Bool
    isAvx512cdEnabled DynFlags
    dflags ]
                  [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String
    "+avx512er"| DynFlags -> Bool
    isAvx512erEnabled DynFlags
    dflags ]
                  [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String
    "+avx512pf"| DynFlags -> Bool
    isAvx512pfEnabled DynFlags
    dflags ]
                  -- For Arch64 +fma is not a option (it's unconditionally available).
                  [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String
    "+fma"     | DynFlags -> Bool
    isFmaEnabled DynFlags
    dflags Bool -> Bool -> Bool
    && (Arch
    arch Arch -> Arch -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Arch
    ArchAArch64) ]
                  [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String
    "+bmi"     | DynFlags -> Bool
    isBmiEnabled DynFlags
    dflags      ]
                  [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String
    "+bmi2"    | DynFlags -> Bool
    isBmi2Enabled DynFlags
    dflags     ]

            abi :: String
            abi :: String
    abi = case Platform -> Arch
    platformArch (DynFlags -> Platform
    targetPlatform DynFlags
    dflags) of
                    Arch
    ArchRISCV64 -> String
    "lp64d"
                    Arch
    ArchLoongArch64 -> String
    "lp64d"
                    Arch
    _           -> String
    ""

    -- | What phase to run after one of the backend code generators has run
    hscPostBackendPhase :: HscSource -> Backend -> Phase
    hscPostBackendPhase :: HscSource -> Backend -> Phase
    hscPostBackendPhase (HsBootOrSig HsBootOrSig
    _) Backend
    _ =  Phase
    StopLn
    hscPostBackendPhase HscSource
    HsSrcFile Backend
    bcknd = Backend -> Phase
    backendNormalSuccessorPhase Backend
    bcknd

    compileStub :: HscEnv -> FilePath -> IO FilePath
    compileStub :: HscEnv -> String -> IO String
    compileStub HscEnv
    hsc_env String
    stub_c = HscEnv -> ForeignSrcLang -> String -> IO String
    compileForeign HscEnv
    hsc_env ForeignSrcLang
    LangC String
    stub_c

    -- ---------------------------------------------------------------------------
    -- join object files into a single relocatable object file, using ld -r

    {-
    Note [Produce big objects on Windows]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    The Windows Portable Executable object format has a limit of 32k sections, which
    we tend to blow through pretty easily. Thankfully, there is a "big object"
    extension, which raises this limit to 2^32. However, it must be explicitly
    enabled in the toolchain:

     * the assembler accepts the -mbig-obj flag, which causes it to produce a
       bigobj-enabled COFF object.

     * the linker accepts the --oformat pe-bigobj-x86-64 flag. Despite what the name
       suggests, this tells the linker to produce a bigobj-enabled COFF object, no a
       PE executable.

    Previously when we used ld.bfd we had to enable bigobj output in a few places:

     * When merging object files (GHC.Driver.Pipeline.Execute.joinObjectFiles)

     * When assembling (GHC.Driver.Pipeline.runPhase (RealPhase As ...))

    However, this is no longer necessary with ld.lld, which detects that the
    object is large on its own.

    Unfortunately the big object format is not supported on 32-bit targets so
    none of this can be used in that case.

    Note [Object merging]
    ~~~~~~~~~~~~~~~~~~~~~
    On most platforms one can "merge" a set of relocatable object files into a new,
    partially-linked-but-still-relocatable object. In a typical UNIX-style linker,
    this is accomplished with the `ld -r` command. We rely on this for two ends:

     * We rely on `ld -r` to squash together split sections, making GHCi loading
       more efficient. See Note [Merging object files for GHCi].

     * We use merging to combine a module's object code (e.g. produced by the NCG)
       with its foreign stubs (typically produced by a C compiler).

    The command used for object linking is set using the -pgmlm and -optlm
    command-line options.

    Sadly, the LLD linker that we use on Windows does not support the `-r` flag
    needed to support object merging (see #21068). For this reason on Windows we do
    not support GHCi objects.  To deal with foreign stubs we build a static archive
    of all of a module's object files instead merging them. Consequently, we can
    end up producing `.o` files which are in fact static archives. However,
    toolchains generally don't have a problem with this as they use file headers,
    not the filename, to determine the nature of inputs.

    Note that this has somewhat non-obvious consequences when producing
    initializers and finalizers. See Note [Initializers and finalizers in Cmm]
    in GHC.Cmm.InitFini for details.

    Note [Merging object files for GHCi]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    GHCi can usually loads standard linkable object files using GHC's linker
    implementation. However, most users build their projects with -split-sections,
    meaning that such object files can have an extremely high number of sections.
    As the linker must map each of these sections individually, loading such object
    files is very inefficient.

    To avoid this inefficiency, we use the linker's `-r` flag and a linker script
    to produce a merged relocatable object file. This file will contain a singe
    text section section and can consequently be mapped far more efficiently. As
    gcc tends to do unpredictable things to our linker command line, we opt to
    invoke ld directly in this case, in contrast to our usual strategy of linking
    via gcc.
    -}

    -- | See Note [Object merging].
    joinObjectFiles :: HscEnv -> [FilePath] -> FilePath -> IO ()
    joinObjectFiles :: HscEnv -> [String] -> String -> IO ()
    joinObjectFiles HscEnv
    hsc_env [String]
    o_files String
    output_fn
      | Bool
    can_merge_objs Bool -> Bool -> Bool
    && Bool -> Bool
    not Bool
    dashLSupported = do
      let toolSettings' :: ToolSettings
    toolSettings' = DynFlags -> ToolSettings
    toolSettings DynFlags
    dflags
          ldIsGnuLd :: Bool
    ldIsGnuLd = ToolSettings -> Bool
    toolSettings_ldIsGnuLd ToolSettings
    toolSettings'
          ld_r :: [Option] -> IO ()
    ld_r [Option]
    args = Logger -> TmpFs -> DynFlags -> [Option] -> IO ()
    GHC.SysTools.runMergeObjects (HscEnv -> Logger
    hsc_logger HscEnv
    hsc_env) (HscEnv -> TmpFs
    hsc_tmpfs HscEnv
    hsc_env) (HscEnv -> DynFlags
    hsc_dflags HscEnv
    hsc_env) (
                            [ String -> Option
    GHC.SysTools.Option String
    "-o",
                              String -> String -> Option
    GHC.SysTools.FileOption String
    "" String
    output_fn ]
                         [Option] -> [Option] -> [Option]
    forall a. [a] -> [a] -> [a]
    ++ [Option]
    args)

      if Bool
    ldIsGnuLd
         then do
              script <- Logger
    -> TmpFs -> TempDir -> TempFileLifetime -> String -> IO String
    newTempName Logger
    logger TmpFs
    tmpfs (DynFlags -> TempDir
    tmpDir DynFlags
    dflags) TempFileLifetime
    TFL_CurrentModule String
    "ldscript"
              cwd <- getCurrentDirectory
              let o_files_abs = (String -> String) -> [String] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map (\String
    x -> String
    "\"" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ (String
    cwd String -> String -> String
    </> String
    x) String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    "\"") [String]
    o_files
              writeFile script $ "INPUT(" ++ unwords o_files_abs ++ ")"
              ld_r [GHC.SysTools.FileOption "" script]
         else if ToolSettings -> Bool
    toolSettings_ldSupportsFilelist ToolSettings
    toolSettings'
         then do
              filelist <- Logger
    -> TmpFs -> TempDir -> TempFileLifetime -> String -> IO String
    newTempName Logger
    logger TmpFs
    tmpfs (DynFlags -> TempDir
    tmpDir DynFlags
    dflags) TempFileLifetime
    TFL_CurrentModule String
    "filelist"
              writeFile filelist $ unlines o_files
              ld_r [GHC.SysTools.Option "-filelist",
                    GHC.SysTools.FileOption "" filelist]
         else
              [Option] -> IO ()
    ld_r ((String -> Option) -> [String] -> [Option]
    forall a b. (a -> b) -> [a] -> [b]
    map (String -> String -> Option
    GHC.SysTools.FileOption String
    "") [String]
    o_files)

      | Bool
    otherwise = do
      String -> (String -> IO ()) -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    String -> (String -> m a) -> m a
    withAtomicRename String
    output_fn ((String -> IO ()) -> IO ()) -> (String -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \String
    tmp_ar ->
          IO () -> IO ()
    forall a. IO a -> IO a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ Logger -> DynFlags -> Maybe String -> [Option] -> IO ()
    runAr Logger
    logger DynFlags
    dflags Maybe String
    forall a. Maybe a
    Nothing ([Option] -> IO ()) -> [Option] -> IO ()
    forall a b. (a -> b) -> a -> b
    $ (String -> Option) -> [String] -> [Option]
    forall a b. (a -> b) -> [a] -> [b]
    map String -> Option
    Option ([String] -> [Option]) -> [String] -> [Option]
    forall a b. (a -> b) -> a -> b
    $ [String
    "qc" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    dashL, String
    tmp_ar] [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++ [String]
    o_files
      where
        dashLSupported :: Bool
    dashLSupported = Settings -> Bool
    sArSupportsDashL (DynFlags -> Settings
    settings DynFlags
    dflags)
        dashL :: String
    dashL = if Bool
    dashLSupported then String
    "L" else String
    ""
        can_merge_objs :: Bool
    can_merge_objs = Maybe (String, [Option]) -> Bool
    forall a. Maybe a -> Bool
    isJust (DynFlags -> Maybe (String, [Option])
    pgm_lm (HscEnv -> DynFlags
    hsc_dflags HscEnv
    hsc_env))
        dflags :: DynFlags
    dflags = HscEnv -> DynFlags
    hsc_dflags HscEnv
    hsc_env
        tmpfs :: TmpFs
    tmpfs = HscEnv -> TmpFs
    hsc_tmpfs HscEnv
    hsc_env
        logger :: Logger
    logger = HscEnv -> Logger
    hsc_logger HscEnv
    hsc_env

    -----------------------------------------------------------------------------
    -- Look for the /* GHC_PACKAGES ... */ comment at the top of a .hc file

    getHCFilePackages :: FilePath -> IO [UnitId]
    getHCFilePackages :: String -> IO [UnitId]
    getHCFilePackages String
    filename =
      String -> IOMode -> (Handle -> IO [UnitId]) -> IO [UnitId]
    forall r. String -> IOMode -> (Handle -> IO r) -> IO r
    withFile String
    filename IOMode
    ReadMode ((Handle -> IO [UnitId]) -> IO [UnitId])
    -> (Handle -> IO [UnitId]) -> IO [UnitId]
    forall a b. (a -> b) -> a -> b
    $ \Handle
    h -> do
        l <- Handle -> IO String
    hGetLine Handle
    h
        case l of
          Char
    '/':Char
    '*':Char
    ' ':Char
    'G':Char
    'H':Char
    'C':Char
    '_':Char
    'P':Char
    'A':Char
    'C':Char
    'K':Char
    'A':Char
    'G':Char
    'E':Char
    'S':String
    rest ->
              [UnitId] -> IO [UnitId]
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ((String -> UnitId) -> [String] -> [UnitId]
    forall a b. (a -> b) -> [a] -> [b]
    map String -> UnitId
    stringToUnitId (String -> [String]
    words String
    rest))
          String
    _other ->
              [UnitId] -> IO [UnitId]
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return []

    linkDynLibCheck :: Logger -> TmpFs -> DynFlags -> UnitEnv -> [String] -> [UnitId] -> IO ()
    linkDynLibCheck :: Logger
    -> TmpFs -> DynFlags -> UnitEnv -> [String] -> [UnitId] -> IO ()
    linkDynLibCheck Logger
    logger TmpFs
    tmpfs DynFlags
    dflags UnitEnv
    unit_env [String]
    o_files [UnitId]
    dep_units = do
      Bool -> IO () -> IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (DynFlags -> Bool
    haveRtsOptsFlags DynFlags
    dflags) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $
        Logger -> MessageClass -> SrcSpan -> SDoc -> IO ()
    logMsg Logger
    logger MessageClass
    MCInfo SrcSpan
    noSrcSpan
          (SDoc -> IO ()) -> SDoc -> IO ()
    forall a b. (a -> b) -> a -> b
    $ PprStyle -> SDoc -> SDoc
    withPprStyle PprStyle
    defaultUserStyle
          (String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "Warning: -rtsopts and -with-rtsopts have no effect with -shared." SDoc -> SDoc -> SDoc
    forall doc. IsDoc doc => doc -> doc -> doc
    $$
          String -> SDoc
    forall doc. IsLine doc => String -> doc
    text String
    "    Call hs_init_ghc() from your main() function to set these options.")
      Logger
    -> TmpFs -> DynFlags -> UnitEnv -> [String] -> [UnitId] -> IO ()
    linkDynLib Logger
    logger TmpFs
    tmpfs DynFlags
    dflags UnitEnv
    unit_env [String]
    o_files [UnitId]
    dep_units

    -- -----------------------------------------------------------------------------
    -- Misc.

    touchObjectFile :: FilePath -> IO ()
    touchObjectFile :: String -> IO ()
    touchObjectFile String
    path = do
      Bool -> String -> IO ()
    createDirectoryIfMissing Bool
    True (String -> IO ()) -> String -> IO ()
    forall a b. (a -> b) -> a -> b
    $ String -> String
    takeDirectory String
    path
      String -> IO ()
    GHC.Utils.Touch.touch String
    path

    -- Note [-fPIC for assembler]
    -- ~~~~~~~~~~~~~~~~~~~~~~~~~~
    -- When compiling .c source file GHC's driver pipeline basically
    -- does the following two things:
    --   1. ${CC}              -S 'PIC_CFLAGS' source.c
    --   2. ${CC} -x assembler -c 'PIC_CFLAGS' source.S
    --
    -- Why do we need to pass 'PIC_CFLAGS' both to C compiler and assembler?
    -- Because on some architectures (at least sparc32) assembler also chooses
    -- the relocation type!
    -- Consider the following C module:
    --
    --     /* pic-sample.c */
    --     int v;
    --     void set_v (int n) { v = n; }
    --     int  get_v (void)  { return v; }
    --
    --     $ gcc -S -fPIC pic-sample.c
    --     $ gcc -c       pic-sample.s -o pic-sample.no-pic.o # incorrect binary
    --     $ gcc -c -fPIC pic-sample.s -o pic-sample.pic.o    # correct binary
    --
    --     $ objdump -r -d pic-sample.pic.o    > pic-sample.pic.o.od
    --     $ objdump -r -d pic-sample.no-pic.o > pic-sample.no-pic.o.od
    --     $ diff -u pic-sample.pic.o.od pic-sample.no-pic.o.od
    --
    -- Most of architectures won't show any difference in this test, but on sparc32
    -- the following assembly snippet:
    --
    --    sethi   %hi(_GLOBAL_OFFSET_TABLE_-8), %l7
    --
    -- generates two kinds or relocations, only 'R_SPARC_PC22' is correct:
    --
    --       3c:  2f 00 00 00     sethi  %hi(0), %l7
    --    -                       3c: R_SPARC_PC22        _GLOBAL_OFFSET_TABLE_-0x8
    --    +                       3c: R_SPARC_HI22        _GLOBAL_OFFSET_TABLE_-0x8

    {- Note [Don't normalise input filenames]
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Summary
      We used to normalise input filenames when starting the unlit phase. This
      broke hpc in `--make` mode with imported literate modules (#2991).

    Introduction
      1) --main
      When compiling a module with --main, GHC scans its imports to find out which
      other modules it needs to compile too. It turns out that there is a small
      difference between saying `ghc --make A.hs`, when `A` imports `B`, and
      specifying both modules on the command line with `ghc --make A.hs B.hs`. In
      the former case, the filename for B is inferred to be './B.hs' instead of
      'B.hs'.

      2) unlit
      When GHC compiles a literate haskell file, the source code first needs to go
      through unlit, which turns it into normal Haskell source code. At the start
      of the unlit phase, in `Driver.Pipeline.runPhase`, we call unlit with the
      option `-h` and the name of the original file. We used to normalise this
      filename using System.FilePath.normalise, which among other things removes
      an initial './'. unlit then uses that filename in #line directives that it
      inserts in the transformed source code.

      3) SrcSpan
      A SrcSpan represents a portion of a source code file. It has fields
      linenumber, start column, end column, and also a reference to the file it
      originated from. The SrcSpans for a literate haskell file refer to the
      filename that was passed to unlit -h.

      4) -fhpc
      At some point during compilation with -fhpc, in the function
      `GHC.HsToCore.Ticks.isGoodTickSrcSpan`, we compare the filename that a
      `SrcSpan` refers to with the name of the file we are currently compiling.
      For some reason I don't yet understand, they can sometimes legitimately be
      different, and then hpc ignores that SrcSpan.

    Problem
      When running `ghc --make -fhpc A.hs`, where `A.hs` imports the literate
      module `B.lhs`, `B` is inferred to be in the file `./B.lhs` (1). At the
      start of the unlit phase, the name `./B.lhs` is normalised to `B.lhs` (2).
      Therefore the SrcSpans of `B` refer to the file `B.lhs` (3), but we are
      still compiling `./B.lhs`. Hpc thinks these two filenames are different (4),
      doesn't include ticks for B, and we have unhappy customers (#2991).

    Solution
      Do not normalise `input_fn` when starting the unlit phase.

    Alternative solution
      Another option would be to not compare the two filenames on equality, but to
      use System.FilePath.equalFilePath. That function first normalises its
      arguments. The problem is that by the time we need to do the comparison, the
      filenames have been turned into FastStrings, probably for performance
      reasons, so System.FilePath.equalFilePath can not be used directly.

    Archeology
      The call to `normalise` was added in a commit called "Fix slash
      direction on Windows with the new filePath code" (c9b6b5e8). The problem
      that commit was addressing has since been solved in a different manner, in a
      commit called "Fix the filename passed to unlit" (1eedbc6b). So the
      `normalise` is no longer necessary.
    -}

    {-
    Note [-Wa,--no-type-check on wasm32]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Wasm32 has a type system and corresponding validation rules, so it's
    possible to produce syntactically valid object code that doesn't pass
    validation.

    We have no problem with that, but we do have a problem with clang.
    When clang takes an assembly input for wasm32, it uses its internal
    type-checker, which is a huge source of trouble (see llvm ticket
    #56935 #58438): it may reject valid assembly, and even worse, it may
    silently alter the output object code!!! The worsest of all, is the
    person that added the wasm32 asm typechecker logic has moved on from
    Google/LLVM, and while other LLVM devs may be knowledgable enough to
    fix this mess, they likely got tons of other stuff on their table and
    don't care enough.

    We do have an escape hatch, just pass -Wa,--no-type-check to clang to
    bypass the entire wasm32 asm typechecking logic. There's little point
    in type-checking object code at compile-time anyway, the wasm engines
    will do type-checking at run-time. And even if we want to add some
    linting flag to do compile-time checks, we should just rely on
    battle-tested external tools instead of a completely broken horror
    story.
    -}