Split the Hsc phase into two subphases
[ghc.git] / compiler / main / HscMain.hs
index 5c3fa0d..0aab82f 100644 (file)
@@ -32,16 +32,21 @@ module HscMain
       newHscEnv
 
     -- * Compiling complete source files
-    , Compiler
-    , HscStatus' (..)
-    , InteractiveStatus, HscStatus
+    , Messager, batchMsg
+    , HscStatus (..)
     , hscCompileOneShot
-    , hscCompileBatch
-    , hscCompileNothing
-    , hscCompileInteractive
     , hscCompileCmmFile
     , hscCompileCore
 
+    , genericHscCompileGetFrontendResult
+
+    , genModDetails
+    , hscSimpleIface
+    , hscWriteIface
+    , hscNormalIface
+    , hscGenHardCode
+    , hscInteractive
+
     -- * Running passes separately
     , hscParse
     , hscTypecheckRename
@@ -50,12 +55,6 @@ module HscMain
     , makeSimpleDetails
     , hscSimplify -- ToDo, shouldn't really export this
 
-    -- ** Backends
-    , hscOneShotBackendOnly
-    , hscBatchBackendOnly
-    , hscNothingBackendOnly
-    , hscInteractiveBackendOnly
-
     -- * Support for interactive evaluation
     , hscParseIdentifier
     , hscTcRcLookupName
@@ -75,6 +74,7 @@ module HscMain
     ) where
 
 #ifdef GHCI
+import Id
 import ByteCodeGen      ( byteCodeGen, coreExprToBCOs )
 import Linker
 import CoreTidy         ( tidyExpr )
@@ -90,7 +90,6 @@ import Panic
 import GHC.Exts
 #endif
 
-import Id
 import Module
 import Packages
 import RdrName
@@ -119,14 +118,11 @@ import ProfInit
 import TyCon
 import Name
 import SimplStg         ( stg2stg )
-import CodeGen          ( codeGen )
-import qualified OldCmm as Old
-import qualified Cmm as New
+import Cmm
 import CmmParse         ( parseCmmFile )
 import CmmBuildInfoTables
 import CmmPipeline
 import CmmInfo
-import CmmCvt
 import CodeOutput
 import NameEnv          ( emptyNameEnv )
 import NameSet          ( emptyNameSet )
@@ -528,188 +524,102 @@ This is the only thing that isn't caught by the type-system.
 -}
 
 
--- | Status of a compilation to hard-code or nothing.
-data HscStatus' a
-    = HscNoRecomp
-    | HscRecomp
-          (Maybe FilePath) -- Has stub files. This is a hack. We can't compile
-                           -- C files here since it's done in DriverPipeline.
-                           -- For now we just return True if we want the caller
-                           -- to compile them for us.
-          a
-
--- This is a bit ugly. Since we use a typeclass below and would like to avoid
--- functional dependencies, we have to parameterise the typeclass over the
--- result type. Therefore we need to artificially distinguish some types. We do
--- this by adding type tags which will simply be ignored by the caller.
-type HscStatus         = HscStatus' ()
-type InteractiveStatus = HscStatus' (Maybe (CompiledByteCode, ModBreaks))
-    -- INVARIANT: result is @Nothing@ <=> input was a boot file
-
-type OneShotResult     = HscStatus
-type BatchResult       = (HscStatus, ModIface, ModDetails)
-type NothingResult     = (HscStatus, ModIface, ModDetails)
-type InteractiveResult = (InteractiveStatus, ModIface, ModDetails)
-
--- ToDo: The old interface and module index are only using in 'batch' and
---       'interactive' mode. They should be removed from 'oneshot' mode.
-type Compiler result =  HscEnv
-                     -> ModSummary
-                     -> SourceModified
-                     -> Maybe ModIface  -- Old interface, if available
-                     -> Maybe (Int,Int) -- Just (i,n) <=> module i of n (for msgs)
-                     -> IO result
-
-data HsCompiler a = HsCompiler {
-    -- | Called when no recompilation is necessary.
-    hscNoRecomp :: ModIface
-                -> Hsc a,
-
-    -- | Called to recompile the module.
-    hscRecompile :: ModSummary -> Maybe Fingerprint
-                 -> Hsc a,
-
-    hscBackend :: TcGblEnv -> ModSummary -> Maybe Fingerprint
-               -> Hsc a,
-
-    -- | Code generation for Boot modules.
-    hscGenBootOutput :: TcGblEnv -> ModSummary -> Maybe Fingerprint
-                     -> Hsc a,
-
-    -- | Code generation for normal modules.
-    hscGenOutput :: ModGuts -> ModSummary -> Maybe Fingerprint
-                 -> Hsc a
-  }
-
-genericHscCompile :: HsCompiler a
-                  -> (HscEnv -> Maybe (Int,Int) -> RecompileRequired -> ModSummary -> IO ())
-                  -> HscEnv -> ModSummary -> SourceModified
-                  -> Maybe ModIface -> Maybe (Int, Int)
-                  -> IO a
-genericHscCompile compiler hscMessage hsc_env
-                  mod_summary source_modified
-                  mb_old_iface0 mb_mod_index
-  = do
-    (recomp_reqd, mb_checked_iface)
-        <- {-# SCC "checkOldIface" #-}
-           checkOldIface hsc_env mod_summary
-                         source_modified mb_old_iface0
-    -- save the interface that comes back from checkOldIface.
-    -- In one-shot mode we don't have the old iface until this
-    -- point, when checkOldIface reads it from the disk.
-    let mb_old_hash = fmap mi_iface_hash mb_checked_iface
+-- | Status of a compilation to hard-code
+data HscStatus
+    = HscNotGeneratingCode
+    | HscUpToDate
+    | HscUpdateBoot
+    | HscRecomp CgGuts ModSummary
+
+type Messager = HscEnv -> (Int,Int) -> RecompileRequired -> ModSummary -> IO ()
+
+genericHscCompileGetFrontendResult ::
+                     Bool -- always do basic recompilation check?
+                  -> Maybe TcGblEnv
+                  -> Maybe Messager
+                  -> HscEnv
+                  -> ModSummary
+                  -> SourceModified
+                  -> Maybe ModIface  -- Old interface, if available
+                  -> (Int,Int)       -- (i,n) = module i of n (for msgs)
+                  -> IO (Either ModIface (TcGblEnv, Maybe Fingerprint))
+
+genericHscCompileGetFrontendResult always_do_basic_recompilation_check m_tc_result
+                                   mHscMessage hsc_env mod_summary source_modified mb_old_iface mod_index
+    = do
 
-    let skip iface = do
-            hscMessage hsc_env mb_mod_index UpToDate mod_summary
-            runHsc hsc_env $ hscNoRecomp compiler iface
+    let msg what = case mHscMessage of
+                   Just hscMessage -> hscMessage hsc_env mod_index what mod_summary
+                   Nothing -> return ()
 
-        compile reason = do
-            hscMessage hsc_env mb_mod_index reason mod_summary
-            runHsc hsc_env $ hscRecompile compiler mod_summary mb_old_hash
+        skip iface = do
+            msg UpToDate
+            return $ Left iface
+
+        compile mb_old_hash reason = do
+            msg reason
+            tc_result <- runHsc hsc_env $ genericHscFrontend mod_summary
+            return $ Right (tc_result, mb_old_hash)
 
         stable = case source_modified of
                      SourceUnmodifiedAndStable -> True
                      _                         -> False
 
-        -- If the module used TH splices when it was last compiled,
-        -- then the recompilation check is not accurate enough (#481)
-        -- and we must ignore it. However, if the module is stable
-        -- (none of the modules it depends on, directly or indirectly,
-        -- changed), then we *can* skip recompilation. This is why
-        -- the SourceModified type contains SourceUnmodifiedAndStable,
-        -- and it's pretty important: otherwise ghc --make would
-        -- always recompile TH modules, even if nothing at all has
-        -- changed. Stability is just the same check that make is
-        -- doing for us in one-shot mode.
-
-    case mb_checked_iface of
-        Just iface | not (recompileRequired recomp_reqd) ->
-            if mi_used_th iface && not stable
-                then compile (RecompBecause "TH")
-                else skip iface
-        _otherwise ->
-            compile recomp_reqd
-
-hscCheckRecompBackend :: HsCompiler a -> TcGblEnv -> Compiler a
-hscCheckRecompBackend compiler tc_result hsc_env mod_summary
-                      source_modified mb_old_iface _m_of_n
-  = do
-    (recomp_reqd, mb_checked_iface)
-        <- {-# SCC "checkOldIface" #-}
-           checkOldIface hsc_env mod_summary
-                         source_modified mb_old_iface
-
-    let mb_old_hash = fmap mi_iface_hash mb_checked_iface
-    case mb_checked_iface of
-        Just iface | not (recompileRequired recomp_reqd)
-            -> runHsc hsc_env $
-                   hscNoRecomp compiler
-                       iface{ mi_globals = Just (tcg_rdr_env tc_result) }
-        _otherwise
-            -> runHsc hsc_env $
-                   hscBackend compiler tc_result mod_summary mb_old_hash
-
-genericHscRecompile :: HsCompiler a
-                    -> ModSummary -> Maybe Fingerprint
-                    -> Hsc a
-genericHscRecompile compiler mod_summary mb_old_hash
+    case m_tc_result of
+         Just tc_result
+          | not always_do_basic_recompilation_check ->
+             return $ Right (tc_result, Nothing)
+         _ -> do
+            (recomp_reqd, mb_checked_iface)
+                <- {-# SCC "checkOldIface" #-}
+                   checkOldIface hsc_env mod_summary
+                                source_modified mb_old_iface
+            -- save the interface that comes back from checkOldIface.
+            -- In one-shot mode we don't have the old iface until this
+            -- point, when checkOldIface reads it from the disk.
+            let mb_old_hash = fmap mi_iface_hash mb_checked_iface
+
+            case mb_checked_iface of
+                Just iface | not (recompileRequired recomp_reqd) ->
+                    -- If the module used TH splices when it was last compiled,
+                    -- then the recompilation check is not accurate enough (#481)
+                    -- and we must ignore it. However, if the module is stable
+                    -- (none of the modules it depends on, directly or indirectly,
+                    -- changed), then we *can* skip recompilation. This is why
+                    -- the SourceModified type contains SourceUnmodifiedAndStable,
+                    -- and it's pretty important: otherwise ghc --make would
+                    -- always recompile TH modules, even if nothing at all has
+                    -- changed. Stability is just the same check that make is
+                    -- doing for us in one-shot mode.
+                    case m_tc_result of
+                    Nothing
+                     | mi_used_th iface && not stable ->
+                        compile mb_old_hash (RecompBecause "TH")
+                    _ ->
+                        skip iface
+                _ ->
+                    case m_tc_result of
+                    Nothing -> compile mb_old_hash recomp_reqd
+                    Just tc_result ->
+                        return $ Right (tc_result, mb_old_hash)
+
+genericHscFrontend :: ModSummary -> Hsc TcGblEnv
+genericHscFrontend mod_summary
     | ExtCoreFile <- ms_hsc_src mod_summary =
         panic "GHC does not currently support reading External Core files"
     | otherwise = do
-        tc_result <- hscFileFrontEnd mod_summary
-        hscBackend compiler tc_result mod_summary mb_old_hash
-
-genericHscBackend :: HsCompiler a
-                  -> TcGblEnv -> ModSummary -> Maybe Fingerprint
-                  -> Hsc a
-genericHscBackend compiler tc_result mod_summary mb_old_hash
-    | HsBootFile <- ms_hsc_src mod_summary =
-        hscGenBootOutput compiler tc_result mod_summary mb_old_hash
-    | otherwise = do
-        guts <- hscDesugar' (ms_location mod_summary) tc_result
-        hscGenOutput compiler guts mod_summary mb_old_hash
-
-compilerBackend :: HsCompiler a -> TcGblEnv -> Compiler a
-compilerBackend comp tcg hsc_env ms' _ _mb_old_iface _ =
-    runHsc hsc_env $ hscBackend comp tcg ms' Nothing
+        hscFileFrontEnd mod_summary
 
 --------------------------------------------------------------
 -- Compilers
 --------------------------------------------------------------
 
-hscOneShotCompiler :: HsCompiler OneShotResult
-hscOneShotCompiler = HsCompiler {
-
-    hscNoRecomp = \_old_iface -> do
-        hsc_env <- getHscEnv
-        liftIO $ dumpIfaceStats hsc_env
-        return HscNoRecomp
-
-  , hscRecompile = genericHscRecompile hscOneShotCompiler
-
-  , hscBackend = \tc_result mod_summary mb_old_hash -> do
-        dflags <- getDynFlags
-        case hscTarget dflags of
-            HscNothing -> return (HscRecomp Nothing ())
-            _otherw    -> genericHscBackend hscOneShotCompiler
-                              tc_result mod_summary mb_old_hash
-
-  , hscGenBootOutput = \tc_result mod_summary mb_old_iface -> do
-        (iface, changed, _) <- hscSimpleIface tc_result mb_old_iface
-        hscWriteIface iface changed mod_summary
-        return (HscRecomp Nothing ())
-
-  , hscGenOutput = \guts0 mod_summary mb_old_iface -> do
-        guts <- hscSimplify' guts0
-        (iface, changed, _details, cgguts) <- hscNormalIface guts mb_old_iface
-        hscWriteIface iface changed mod_summary
-        hasStub <- hscGenHardCode cgguts mod_summary
-        return (HscRecomp hasStub ())
-  }
-
 -- Compile Haskell, boot and extCore in OneShot mode.
-hscCompileOneShot :: Compiler OneShotResult
-hscCompileOneShot hsc_env mod_summary src_changed mb_old_iface mb_i_of_n
+hscCompileOneShot :: HscEnv
+                  -> ModSummary
+                  -> SourceModified
+                  -> IO HscStatus
+hscCompileOneShot hsc_env mod_summary src_changed
   = do
     -- One-shot mode needs a knot-tying mutable variable for interface
     -- files. See TcRnTypes.TcGblEnv.tcg_type_env_var.
@@ -717,134 +627,88 @@ hscCompileOneShot hsc_env mod_summary src_changed mb_old_iface mb_i_of_n
     let mod = ms_mod mod_summary
         hsc_env' = hsc_env{ hsc_type_env_var = Just (mod, type_env_var) }
 
-    genericHscCompile hscOneShotCompiler
-                      oneShotMsg hsc_env' mod_summary src_changed
-                      mb_old_iface mb_i_of_n
-
-hscOneShotBackendOnly :: TcGblEnv -> Compiler OneShotResult
-hscOneShotBackendOnly = compilerBackend hscOneShotCompiler
-
---------------------------------------------------------------
-
-hscBatchCompiler :: HsCompiler BatchResult
-hscBatchCompiler = HsCompiler {
-
-    hscNoRecomp = \iface -> do
-        details <- genModDetails iface
-        return (HscNoRecomp, iface, details)
-
-  , hscRecompile = genericHscRecompile hscBatchCompiler
-
-  , hscBackend = genericHscBackend hscBatchCompiler
-
-  , hscGenBootOutput = \tc_result mod_summary mb_old_iface -> do
-        (iface, changed, details) <- hscSimpleIface tc_result mb_old_iface
-        hscWriteIface iface changed mod_summary
-        return (HscRecomp Nothing (), iface, details)
-
-  , hscGenOutput = \guts0 mod_summary mb_old_iface -> do
-        guts <- hscSimplify' guts0
-        (iface, changed, details, cgguts) <- hscNormalIface guts mb_old_iface
-        hscWriteIface iface changed mod_summary
-        hasStub <- hscGenHardCode cgguts mod_summary
-        return (HscRecomp hasStub (), iface, details)
-  }
-
--- | Compile Haskell, boot and extCore in batch mode.
-hscCompileBatch :: Compiler (HscStatus, ModIface, ModDetails)
-hscCompileBatch = genericHscCompile hscBatchCompiler batchMsg
-
-hscBatchBackendOnly :: TcGblEnv -> Compiler BatchResult
-hscBatchBackendOnly = hscCheckRecompBackend hscBatchCompiler
-
---------------------------------------------------------------
-
-hscInteractiveCompiler :: HsCompiler InteractiveResult
-hscInteractiveCompiler = HsCompiler {
-    hscNoRecomp = \iface -> do
-        details <- genModDetails iface
-        return (HscNoRecomp, iface, details)
-
-  , hscRecompile = genericHscRecompile hscInteractiveCompiler
-
-  , hscBackend = genericHscBackend hscInteractiveCompiler
-
-  , hscGenBootOutput = \tc_result _mod_summary mb_old_iface -> do
-        (iface, _changed, details) <- hscSimpleIface tc_result mb_old_iface
-        return (HscRecomp Nothing Nothing, iface, details)
-
-  , hscGenOutput = \guts0 mod_summary mb_old_iface -> do
-        guts <- hscSimplify' guts0
-        (iface, _changed, details, cgguts) <- hscNormalIface guts mb_old_iface
-        hscInteractive (iface, details, cgguts) mod_summary
-  }
-
--- Compile Haskell, extCore to bytecode.
-hscCompileInteractive :: Compiler (InteractiveStatus, ModIface, ModDetails)
-hscCompileInteractive = genericHscCompile hscInteractiveCompiler batchMsg
-
-hscInteractiveBackendOnly :: TcGblEnv -> Compiler InteractiveResult
-hscInteractiveBackendOnly = compilerBackend hscInteractiveCompiler
-
---------------------------------------------------------------
-
-hscNothingCompiler :: HsCompiler NothingResult
-hscNothingCompiler = HsCompiler {
-    hscNoRecomp = \iface -> do
-        details <- genModDetails iface
-        return (HscNoRecomp, iface, details)
-
-  , hscRecompile = genericHscRecompile hscNothingCompiler
-
-  , hscBackend = \tc_result _mod_summary mb_old_iface -> do
-        handleWarnings
-        (iface, _changed, details) <- hscSimpleIface tc_result mb_old_iface
-        return (HscRecomp Nothing (), iface, details)
-
-  , hscGenBootOutput = \_ _ _ ->
-        panic "hscCompileNothing: hscGenBootOutput should not be called"
-
-  , hscGenOutput = \_ _ _ ->
-        panic "hscCompileNothing: hscGenOutput should not be called"
-  }
+        msg what = oneShotMsg hsc_env' what
+
+        skip = do msg UpToDate
+                  dumpIfaceStats hsc_env'
+                  return HscUpToDate
+
+        compile mb_old_hash reason = runHsc hsc_env' $ do
+            liftIO $ msg reason
+            tc_result <- genericHscFrontend mod_summary
+            dflags <- getDynFlags
+            case hscTarget dflags of
+                HscNothing -> return HscNotGeneratingCode
+                _ ->
+                    case ms_hsc_src mod_summary of
+                    HsBootFile ->
+                        do (iface, changed, _) <- hscSimpleIface' tc_result mb_old_hash
+                           liftIO $ hscWriteIface dflags iface changed mod_summary
+                           return HscUpdateBoot
+                    _ ->
+                        do guts0 <- hscDesugar' (ms_location mod_summary) tc_result
+                           guts <- hscSimplify' guts0
+                           (iface, changed, _details, cgguts) <- hscNormalIface' guts mb_old_hash
+                           liftIO $ hscWriteIface dflags iface changed mod_summary
+                           return $ HscRecomp cgguts mod_summary
+
+        stable = case src_changed of
+                     SourceUnmodifiedAndStable -> True
+                     _                         -> False
 
--- Type-check Haskell and .hs-boot only (no external core)
-hscCompileNothing :: Compiler (HscStatus, ModIface, ModDetails)
-hscCompileNothing = genericHscCompile hscNothingCompiler batchMsg
+    (recomp_reqd, mb_checked_iface)
+        <- {-# SCC "checkOldIface" #-}
+           checkOldIface hsc_env' mod_summary src_changed Nothing
+    -- save the interface that comes back from checkOldIface.
+    -- In one-shot mode we don't have the old iface until this
+    -- point, when checkOldIface reads it from the disk.
+    let mb_old_hash = fmap mi_iface_hash mb_checked_iface
 
-hscNothingBackendOnly :: TcGblEnv -> Compiler NothingResult
-hscNothingBackendOnly = compilerBackend hscNothingCompiler
+    case mb_checked_iface of
+        Just iface | not (recompileRequired recomp_reqd) ->
+            -- If the module used TH splices when it was last compiled,
+            -- then the recompilation check is not accurate enough (#481)
+            -- and we must ignore it. However, if the module is stable
+            -- (none of the modules it depends on, directly or indirectly,
+            -- changed), then we *can* skip recompilation. This is why
+            -- the SourceModified type contains SourceUnmodifiedAndStable,
+            -- and it's pretty important: otherwise ghc --make would
+            -- always recompile TH modules, even if nothing at all has
+            -- changed. Stability is just the same check that make is
+            -- doing for us in one-shot mode.
+            if mi_used_th iface && not stable
+            then compile mb_old_hash (RecompBecause "TH")
+            else skip
+        _ ->
+            compile mb_old_hash recomp_reqd
 
 --------------------------------------------------------------
 -- NoRecomp handlers
 --------------------------------------------------------------
 
-genModDetails :: ModIface -> Hsc ModDetails
-genModDetails old_iface
+genModDetails :: HscEnv -> ModIface -> IO ModDetails
+genModDetails hsc_env old_iface
   = do
-    hsc_env <- getHscEnv
     new_details <- {-# SCC "tcRnIface" #-}
-                   liftIO $ initIfaceCheck hsc_env (typecheckIface old_iface)
-    liftIO $ dumpIfaceStats hsc_env
+                   initIfaceCheck hsc_env (typecheckIface old_iface)
+    dumpIfaceStats hsc_env
     return new_details
 
 --------------------------------------------------------------
 -- Progress displayers.
 --------------------------------------------------------------
 
-oneShotMsg :: HscEnv -> Maybe (Int,Int) -> RecompileRequired -> ModSummary
-            -> IO ()
-oneShotMsg hsc_env _mb_mod_index recomp _mod_summary =
+oneShotMsg :: HscEnv -> RecompileRequired -> IO ()
+oneShotMsg hsc_env recomp =
     case recomp of
         UpToDate ->
             compilationProgressMsg (hsc_dflags hsc_env) $
                    "compilation IS NOT required"
-        _other ->
+        _ ->
             return ()
 
-batchMsg :: HscEnv -> Maybe (Int,Int) -> RecompileRequired -> ModSummary
-         -> IO ()
-batchMsg hsc_env mb_mod_index recomp mod_summary =
+batchMsg :: Messager
+batchMsg hsc_env mod_index recomp mod_summary =
     case recomp of
         MustCompile -> showMsg "Compiling " ""
         UpToDate
@@ -855,7 +719,7 @@ batchMsg hsc_env mb_mod_index recomp mod_summary =
         dflags = hsc_dflags hsc_env
         showMsg msg reason =
             compilationProgressMsg dflags $
-            (showModuleIndex mb_mod_index ++
+            (showModuleIndex mod_index ++
             msg ++ showModMsg dflags (hscTarget dflags)
                               (recompileRequired recomp) mod_summary)
                 ++ reason
@@ -1195,10 +1059,17 @@ hscSimplify' ds_result = do
 -- Interface generators
 --------------------------------------------------------------
 
-hscSimpleIface :: TcGblEnv
+hscSimpleIface :: HscEnv
+               -> TcGblEnv
                -> Maybe Fingerprint
-               -> Hsc (ModIface, Bool, ModDetails)
-hscSimpleIface tc_result mb_old_iface = do
+               -> IO (ModIface, Bool, ModDetails)
+hscSimpleIface hsc_env tc_result mb_old_iface
+    = runHsc hsc_env $ hscSimpleIface' tc_result mb_old_iface
+
+hscSimpleIface' :: TcGblEnv
+                -> Maybe Fingerprint
+                -> Hsc (ModIface, Bool, ModDetails)
+hscSimpleIface' tc_result mb_old_iface = do
     hsc_env   <- getHscEnv
     details   <- liftIO $ mkBootModDetailsTc hsc_env tc_result
     safe_mode <- hscGetSafeMode tc_result
@@ -1210,10 +1081,17 @@ hscSimpleIface tc_result mb_old_iface = do
     liftIO $ dumpIfaceStats hsc_env
     return (new_iface, no_change, details)
 
-hscNormalIface :: ModGuts
+hscNormalIface :: HscEnv
+               -> ModGuts
                -> Maybe Fingerprint
-               -> Hsc (ModIface, Bool, ModDetails, CgGuts)
-hscNormalIface simpl_result mb_old_iface = do
+               -> IO (ModIface, Bool, ModDetails, CgGuts)
+hscNormalIface hsc_env simpl_result mb_old_iface =
+    runHsc hsc_env $ hscNormalIface' simpl_result mb_old_iface
+
+hscNormalIface' :: ModGuts
+                -> Maybe Fingerprint
+                -> Hsc (ModIface, Bool, ModDetails, CgGuts)
+hscNormalIface' simpl_result mb_old_iface = do
     hsc_env <- getHscEnv
     (cg_guts, details) <- {-# SCC "CoreTidy" #-}
                           liftIO $ tidyProgram hsc_env simpl_result
@@ -1242,19 +1120,24 @@ hscNormalIface simpl_result mb_old_iface = do
 -- BackEnd combinators
 --------------------------------------------------------------
 
-hscWriteIface :: ModIface -> Bool -> ModSummary -> Hsc ()
-hscWriteIface iface no_change mod_summary = do
-    dflags <- getDynFlags
+hscWriteIface :: DynFlags -> ModIface -> Bool -> ModSummary -> IO ()
+hscWriteIface dflags iface no_change mod_summary = do
+    let ifaceFile = ml_hi_file (ms_location mod_summary)
     unless no_change $
         {-# SCC "writeIface" #-}
-        liftIO $ writeIfaceFile dflags (ms_location mod_summary) iface
+        writeIfaceFile dflags ifaceFile iface
+    whenGeneratingDynamicToo dflags $ do
+        -- TODO: We should do a no_change check for the dynamic
+        --       interface file too
+        let dynIfaceFile = replaceExtension ifaceFile (dynHiSuf dflags)
+            dynIfaceFile' = addBootSuffix_maybe (mi_boot iface) dynIfaceFile
+            dynDflags = doDynamicToo dflags
+        writeIfaceFile dynDflags dynIfaceFile' iface
 
 -- | Compile to hard-code.
-hscGenHardCode :: CgGuts -> ModSummary
-               -> Hsc (Maybe FilePath) -- ^ @Just f@ <=> _stub.c is f
-hscGenHardCode cgguts mod_summary = do
-    hsc_env <- getHscEnv
-    liftIO $ do
+hscGenHardCode :: HscEnv -> CgGuts -> ModSummary
+               -> IO (FilePath, Maybe FilePath) -- ^ @Just f@ <=> _stub.c is f
+hscGenHardCode hsc_env cgguts mod_summary = do
         let CgGuts{ -- This is the last use of the ModGuts in a compilation.
                     -- From now on, we just use the bits we need.
                     cg_module   = this_mod,
@@ -1284,39 +1167,34 @@ hscGenHardCode cgguts mod_summary = do
 
         ------------------  Code generation ------------------
 
-        cmms <- if dopt Opt_TryNewCodeGen dflags
-                    then {-# SCC "NewCodeGen" #-}
+        cmms <- {-# SCC "NewCodeGen" #-}
                          tryNewCodeGen hsc_env this_mod data_tycons
                              cost_centre_info
                              stg_binds hpc_info
-                    else {-# SCC "CodeGen" #-}
-                         return (codeGen dflags this_mod data_tycons
-                               cost_centre_info
-                               stg_binds hpc_info)
-
 
         ------------------  Code output -----------------------
         rawcmms0 <- {-# SCC "cmmToRawCmm" #-}
                    cmmToRawCmm dflags cmms
 
-        let dump a = do dumpIfSet_dyn dflags Opt_D_dump_raw_cmm "Raw Cmm"
+        let dump a = do dumpIfSet_dyn dflags Opt_D_dump_cmm_raw "Raw Cmm"
                            (ppr a)
                         return a
             rawcmms1 = Stream.mapM dump rawcmms0
 
-        (_stub_h_exists, stub_c_exists)
+        (output_filename, (_stub_h_exists, stub_c_exists))
             <- {-# SCC "codeOutput" #-}
                codeOutput dflags this_mod location foreign_stubs
                dependencies rawcmms1
-        return stub_c_exists
+        return (output_filename, stub_c_exists)
 
 
-hscInteractive :: (ModIface, ModDetails, CgGuts)
+hscInteractive :: HscEnv
+               -> CgGuts
                -> ModSummary
-               -> Hsc (InteractiveStatus, ModIface, ModDetails)
+               -> IO (Maybe FilePath, CompiledByteCode, ModBreaks)
 #ifdef GHCI
-hscInteractive (iface, details, cgguts) mod_summary = do
-    dflags <- getDynFlags
+hscInteractive hsc_env cgguts mod_summary = do
+    let dflags = hsc_dflags hsc_env
     let CgGuts{ -- This is the last use of the ModGuts in a compilation.
                 -- From now on, we just use the bits we need.
                cg_module   = this_mod,
@@ -1333,18 +1211,14 @@ hscInteractive (iface, details, cgguts) mod_summary = do
     -------------------
     -- PREPARE FOR CODE GENERATION
     -- Do saturation and convert to A-normal form
-    hsc_env <- getHscEnv
     prepd_binds <- {-# SCC "CorePrep" #-}
-                   liftIO $ corePrepPgm dflags hsc_env core_binds data_tycons
+                   corePrepPgm dflags hsc_env core_binds data_tycons
     -----------------  Generate byte code ------------------
-    comp_bc <- liftIO $ byteCodeGen dflags this_mod prepd_binds
-                                    data_tycons mod_breaks
+    comp_bc <- byteCodeGen dflags this_mod prepd_binds data_tycons mod_breaks
     ------------------ Create f-x-dynamic C-side stuff ---
     (_istub_h_exists, istub_c_exists)
-        <- liftIO $ outputForeignStubs dflags this_mod
-                                        location foreign_stubs
-    return (HscRecomp istub_c_exists (Just (comp_bc, mod_breaks))
-           , iface, details)
+        <- outputForeignStubs dflags this_mod location foreign_stubs
+    return (istub_c_exists, comp_bc, mod_breaks)
 #else
 hscInteractive _ _ = panic "GHC not compiled with interpreter"
 #endif
@@ -1356,7 +1230,11 @@ hscCompileCmmFile hsc_env filename = runHsc hsc_env $ do
     let dflags = hsc_dflags hsc_env
     cmm <- ioMsgMaybe $ parseCmmFile dflags filename
     liftIO $ do
-        rawCmms <- cmmToRawCmm dflags (Stream.yield cmm)
+        us <- mkSplitUniqSupply 'S'
+        let initTopSRT = initUs_ us emptySRT
+        dumpIfSet_dyn dflags Opt_D_dump_cmm "Parsed Cmm" (ppr cmm)
+        (_, cmmgroup) <- cmmPipeline hsc_env initTopSRT cmm
+        rawCmms <- cmmToRawCmm dflags (Stream.yield cmmgroup)
         _ <- codeOutput dflags no_mod no_loc NoStubs [] rawCmms
         return ()
   where
@@ -1369,9 +1247,9 @@ hscCompileCmmFile hsc_env filename = runHsc hsc_env $ do
 
 tryNewCodeGen   :: HscEnv -> Module -> [TyCon]
                 -> CollectedCCs
-                -> [(StgBinding,[(Id,[Id])])]
+                -> [StgBinding]
                 -> HpcInfo
-                -> IO (Stream IO Old.CmmGroup ())
+                -> IO (Stream IO CmmGroup ())
          -- Note we produce a 'Stream' of CmmGroups, so that the
          -- backend can be run incrementally.  Otherwise it generates all
          -- the C-- up front, which has a significant space cost.
@@ -1379,7 +1257,7 @@ tryNewCodeGen hsc_env this_mod data_tycons
               cost_centre_info stg_binds hpc_info = do
     let dflags = hsc_dflags hsc_env
 
-    let cmm_stream :: Stream IO New.CmmGroup ()
+    let cmm_stream :: Stream IO CmmGroup ()
         cmm_stream = {-# SCC "StgCmm" #-}
             StgCmm.codeGen dflags this_mod data_tycons
                            cost_centre_info stg_binds hpc_info
@@ -1389,7 +1267,7 @@ tryNewCodeGen hsc_env this_mod data_tycons
         -- CmmGroup on input may produce many CmmGroups on output due
         -- to proc-point splitting).
 
-    let dump1 a = do dumpIfSet_dyn dflags Opt_D_dump_cmmz
+    let dump1 a = do dumpIfSet_dyn dflags Opt_D_dump_cmm
                        "Cmm produced by new codegen" (ppr a)
                      return a
 
@@ -1403,14 +1281,14 @@ tryNewCodeGen hsc_env this_mod data_tycons
     -- we generate one SRT for the whole module.
     let
      pipeline_stream
-      | dopt Opt_SplitObjs dflags
+      | gopt Opt_SplitObjs dflags
         = {-# SCC "cmmPipeline" #-}
           let run_pipeline us cmmgroup = do
                 let (topSRT', us') = initUs us emptySRT
                 (topSRT, cmmgroup) <- cmmPipeline hsc_env topSRT' cmmgroup
                 let srt | isEmptySRT topSRT = []
                         | otherwise         = srtToData topSRT
-                return (us',cmmOfZgraph (srt ++ cmmgroup))
+                return (us', srt ++ cmmgroup)
 
           in do _ <- Stream.mapAccumL run_pipeline us ppr_stream1
                 return ()
@@ -1421,13 +1299,13 @@ tryNewCodeGen hsc_env this_mod data_tycons
   
           let run_pipeline topSRT cmmgroup = do
                 (topSRT, cmmgroup) <- cmmPipeline hsc_env topSRT cmmgroup
-                return (topSRT,cmmOfZgraph cmmgroup)
+                return (topSRT,cmmgroup)
   
           in do topSRT <- Stream.mapAccumL run_pipeline initTopSRT ppr_stream1
-                Stream.yield (cmmOfZgraph (srtToData topSRT))
+                Stream.yield (srtToData topSRT)
 
     let
-        dump2 a = do dumpIfSet_dyn dflags Opt_D_dump_cmmz "Output Cmm" $ ppr a
+        dump2 a = do dumpIfSet_dyn dflags Opt_D_dump_cmm "Output Cmm" $ ppr a
                      return a
 
         ppr_stream2 = Stream.mapM dump2 pipeline_stream
@@ -1437,7 +1315,7 @@ tryNewCodeGen hsc_env this_mod data_tycons
 
 
 myCoreToStg :: DynFlags -> Module -> CoreProgram
-            -> IO ( [(StgBinding,[(Id,[Id])])] -- output program
+            -> IO ( [StgBinding] -- output program
                   , CollectedCCs) -- cost centre info (declared and used)
 myCoreToStg dflags this_mod prepd_binds = do
     stg_binds
@@ -1611,6 +1489,7 @@ hscImport hsc_env str = runInteractiveHsc hsc_env $ do
                      ptext (sLit "parse error in import declaration")
 
 -- | Typecheck an expression (but don't run it)
+-- Returns its most general type
 hscTcExpr :: HscEnv
           -> String -- ^ The expression
           -> IO Type
@@ -1618,13 +1497,14 @@ hscTcExpr hsc_env0 expr = runInteractiveHsc hsc_env0 $ do
     hsc_env <- getHscEnv
     maybe_stmt <- hscParseStmt expr
     case maybe_stmt of
-        Just (L _ (ExprStmt expr _ _ _)) ->
+        Just (L _ (BodyStmt expr _ _ _)) ->
             ioMsgMaybe $ tcRnExpr hsc_env (hsc_IC hsc_env) expr
         _ ->
             throwErrors $ unitBag $ mkPlainErrMsg (hsc_dflags hsc_env) noSrcSpan
                 (text "not an expression:" <+> quotes (text expr))
 
 -- | Find the kind of a type
+-- Currently this does *not* generalise the kinds of the type
 hscKcType
   :: HscEnv
   -> Bool            -- ^ Normalise the type
@@ -1635,11 +1515,11 @@ hscKcType hsc_env0 normalise str = runInteractiveHsc hsc_env0 $ do
     ty <- hscParseType str
     ioMsgMaybe $ tcRnType hsc_env (hsc_IC hsc_env) normalise ty
 
-hscParseStmt :: String -> Hsc (Maybe (LStmt RdrName))
+hscParseStmt :: String -> Hsc (Maybe (GhciLStmt RdrName))
 hscParseStmt = hscParseThing parseStmt
 
 hscParseStmtWithLocation :: String -> Int -> String
-                         -> Hsc (Maybe (LStmt RdrName))
+                         -> Hsc (Maybe (GhciLStmt RdrName))
 hscParseStmtWithLocation source linenumber stmt =
     hscParseThingWithLocation source linenumber parseStmt stmt
 
@@ -1679,9 +1559,9 @@ hscCompileCore :: HscEnv -> Bool -> SafeHaskellMode -> ModSummary
 hscCompileCore hsc_env simplify safe_mode mod_summary binds
   = runHsc hsc_env $ do
         guts <- maybe_simplify (mkModGuts (ms_mod mod_summary) safe_mode binds)
-        (iface, changed, _details, cgguts) <- hscNormalIface guts Nothing
-        hscWriteIface iface changed mod_summary
-        _ <- hscGenHardCode cgguts mod_summary
+        (iface, changed, _details, cgguts) <- hscNormalIface' guts Nothing
+        liftIO $ hscWriteIface (hsc_dflags hsc_env) iface changed mod_summary
+        _ <- liftIO $ hscGenHardCode hsc_env cgguts mod_summary
         return ()
 
   where
@@ -1736,7 +1616,7 @@ hscCompileCoreExpr hsc_env srcspan ds_expr
 
     | otherwise = do
         let dflags = hsc_dflags hsc_env
-        let lint_on = dopt Opt_DoCoreLinting dflags
+        let lint_on = gopt Opt_DoCoreLinting dflags
 
         {- Simplify it -}
         simpl_expr <- simplifyExpr dflags ds_expr
@@ -1792,9 +1672,8 @@ dumpIfaceStats hsc_env = do
 %*                                                                      *
 %********************************************************************* -}
 
-showModuleIndex :: Maybe (Int, Int) -> String
-showModuleIndex Nothing = ""
-showModuleIndex (Just (i,n)) = "[" ++ padded ++ " of " ++ n_str ++ "] "
+showModuleIndex :: (Int, Int) -> String
+showModuleIndex (i,n) = "[" ++ padded ++ " of " ++ n_str ++ "] "
   where
     n_str = show n
     i_str = show i