Split the Hsc phase into two subphases
[ghc.git] / compiler / main / HscMain.hs
index 4a54c89..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,17 +55,12 @@ module HscMain
     , makeSimpleDetails
     , hscSimplify -- ToDo, shouldn't really export this
 
-    -- ** Backends
-    , hscOneShotBackendOnly
-    , hscBatchBackendOnly
-    , hscNothingBackendOnly
-    , hscInteractiveBackendOnly
-
     -- * Support for interactive evaluation
     , hscParseIdentifier
     , hscTcRcLookupName
     , hscTcRnGetInfo
     , hscCheckSafe
+    , hscGetSafe
 #ifdef GHCI
     , hscIsGHCiMonad
     , hscGetModuleInterface
@@ -74,6 +74,7 @@ module HscMain
     ) where
 
 #ifdef GHCI
+import Id
 import ByteCodeGen      ( byteCodeGen, coreExprToBCOs )
 import Linker
 import CoreTidy         ( tidyExpr )
@@ -89,7 +90,6 @@ import Panic
 import GHC.Exts
 #endif
 
-import Id
 import Module
 import Packages
 import RdrName
@@ -118,15 +118,11 @@ import ProfInit
 import TyCon
 import Name
 import SimplStg         ( stg2stg )
-import CodeGen          ( codeGen )
-import OldCmm as Old    ( CmmGroup )
-import PprCmm           ( pprCmms )
+import Cmm
 import CmmParse         ( parseCmmFile )
 import CmmBuildInfoTables
 import CmmPipeline
 import CmmInfo
-import OptimizationFuel ( initOptFuelState )
-import CmmCvt
 import CodeOutput
 import NameEnv          ( emptyNameEnv )
 import NameSet          ( emptyNameSet )
@@ -136,7 +132,6 @@ import Fingerprint      ( Fingerprint )
 
 import DynFlags
 import ErrUtils
-import UniqSupply       ( mkSplitUniqSupply )
 
 import Outputable
 import HscStats         ( ppSourceStats )
@@ -144,9 +139,13 @@ import HscTypes
 import MkExternalCore   ( emitExternalCore )
 import FastString
 import UniqFM           ( emptyUFM )
-import UniqSupply       ( initUs_ )
+import UniqSupply
 import Bag
 import Exception
+import qualified Stream
+import Stream (Stream)
+
+import Util
 
 import Data.List
 import Control.Monad
@@ -171,7 +170,6 @@ newHscEnv dflags = do
     nc_var  <- newIORef (initNameCache us knownKeyNames)
     fc_var  <- newIORef emptyUFM
     mlc_var <- newIORef emptyModuleEnv
-    optFuel <- initOptFuelState
     return HscEnv {  hsc_dflags       = dflags,
                      hsc_targets      = [],
                      hsc_mod_graph    = [],
@@ -181,7 +179,6 @@ newHscEnv dflags = do
                      hsc_NC           = nc_var,
                      hsc_FC           = fc_var,
                      hsc_MLC          = mlc_var,
-                     hsc_OptFuel      = optFuel,
                      hsc_type_env_var = Nothing }
 
 
@@ -358,7 +355,7 @@ hscParse' mod_summary = do
 
     case unP parseModule (mkPState dflags buf loc) of
         PFailed span err ->
-            liftIO $ throwOneError (mkPlainErrMsg span err)
+            liftIO $ throwOneError (mkPlainErrMsg dflags span err)
 
         POk pst rdr_module -> do
             logWarningsReportErrors (getMessages pst)
@@ -381,7 +378,7 @@ hscParse' mod_summary = do
                 srcs0 = nub $ filter (not . (tmpDir dflags `isPrefixOf`))
                             $ filter (not . (== n_hspp))
                             $ map FilePath.normalise
-                            $ filter (not . (== '<') . head)
+                            $ filter (not . (isPrefixOf "<"))
                             $ map unpackFS
                             $ srcfiles pst
                 srcs1 = case ml_hs_file (ms_location mod_summary) of
@@ -442,11 +439,11 @@ tcRnModule' hsc_env sum save_rn_syntax mod = do
             safe <- liftIO $ readIORef (tcg_safeInfer tcg_res')
             when (safe && wopt Opt_WarnSafe dflags)
                  (logWarnings $ unitBag $
-                     mkPlainWarnMsg (warnSafeOnLoc dflags) $ errSafe tcg_res')
+                     mkPlainWarnMsg dflags (warnSafeOnLoc dflags) $ errSafe tcg_res')
             return tcg_res'
   where
     pprMod t  = ppr $ moduleName $ tcg_mod t
-    errSafe t = quotes (pprMod t) <+> text "has been infered as safe!"
+    errSafe t = quotes (pprMod t) <+> text "has been inferred as safe!"
 
 -- | Convert a typechecked module to Core
 hscDesugar :: HscEnv -> ModSummary -> TcGblEnv -> IO ModGuts
@@ -527,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 msg what = case mHscMessage of
+                   Just hscMessage -> hscMessage hsc_env mod_index what mod_summary
+                   Nothing -> return ()
 
-    let skip iface = do
-            hscMessage hsc_env mb_mod_index UpToDate mod_summary
-            runHsc hsc_env $ hscNoRecomp compiler iface
+        skip iface = do
+            msg UpToDate
+            return $ Left iface
 
-        compile reason = do
-            hscMessage hsc_env mb_mod_index reason mod_summary
-            runHsc hsc_env $ hscRecompile compiler mod_summary mb_old_hash
+        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 RecompForcedByTH
-                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.
@@ -716,146 +627,100 @@ 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
             | verbosity (hsc_dflags hsc_env) >= 2 -> showMsg "Skipping  " ""
             | otherwise -> return ()
         RecompBecause reason -> showMsg "Compiling " (" [" ++ reason ++ "]")
-        RecompForcedByTH -> showMsg "Compiling " " [TH]"
     where
+        dflags = hsc_dflags hsc_env
         showMsg msg reason =
-            compilationProgressMsg (hsc_dflags hsc_env) $
-            (showModuleIndex mb_mod_index ++
-            msg ++ showModMsg (hscTarget (hsc_dflags hsc_env))
+            compilationProgressMsg dflags $
+            (showModuleIndex mod_index ++
+            msg ++ showModMsg dflags (hscTarget dflags)
                               (recompileRequired recomp) mod_summary)
                 ++ reason
 
@@ -918,22 +783,22 @@ hscCheckSafeImports tcg_env = do
     case safeLanguageOn dflags of
         True -> do
             -- we nuke user written RULES in -XSafe
-            logWarnings $ warns (tcg_rules tcg_env')
+            logWarnings $ warns dflags (tcg_rules tcg_env')
             return tcg_env' { tcg_rules = [] }
         False
               -- user defined RULES, so not safe or already unsafe
             | safeInferOn dflags && not (null $ tcg_rules tcg_env') ||
               safeHaskell dflags == Sf_None
-            -> wipeTrust tcg_env' $ warns (tcg_rules tcg_env')
+            -> wipeTrust tcg_env' $ warns dflags (tcg_rules tcg_env')
 
-              -- trustworthy OR safe infered with no RULES
+              -- trustworthy OR safe inferred with no RULES
             | otherwise
             -> return tcg_env'
 
   where
-    warns rules = listToBag $ map warnRules rules
-    warnRules (L loc (HsRule n _ _ _ _ _ _)) =
-        mkPlainWarnMsg loc $
+    warns dflags rules = listToBag $ map (warnRules dflags) rules
+    warnRules dflags (L loc (HsRule n _ _ _ _ _ _)) =
+        mkPlainWarnMsg dflags loc $
             text "Rule \"" <> ftext n <> text "\" ignored" $+$
             text "User defined rules are disabled under Safe Haskell"
 
@@ -1000,7 +865,7 @@ checkSafeImports dflags tcg_env
     cond' :: ImportedModsVal -> ImportedModsVal -> Hsc ImportedModsVal
     cond' v1@(m1,_,l1,s1) (_,_,_,s2)
         | s1 /= s2
-        = throwErrors $ unitBag $ mkPlainErrMsg l1
+        = throwErrors $ unitBag $ mkPlainErrMsg dflags l1
               (text "Module" <+> ppr m1 <+>
               (text $ "is imported both as a safe and unsafe import!"))
         | otherwise
@@ -1022,6 +887,21 @@ hscCheckSafe hsc_env m l = runHsc hsc_env $ do
     errs <- getWarnings
     return $ isEmptyBag errs
 
+-- | Return if a module is trusted and the pkgs it depends on to be trusted.
+hscGetSafe :: HscEnv -> Module -> SrcSpan -> IO (Bool, [PackageId])
+hscGetSafe hsc_env m l = runHsc hsc_env $ do
+    dflags       <- getDynFlags
+    (self, pkgs) <- hscCheckSafe' dflags m l
+    good         <- isEmptyBag `fmap` getWarnings
+    clearWarnings -- don't want them printed...
+    let pkgs' | Just p <- self = p:pkgs
+              | otherwise      = pkgs
+    return (good, pkgs')
+-- | Is a module trusted? If not, throw or log errors depending on the type.
+-- Return (regardless of trusted or not) if the trust type requires the modules
+-- own package be trusted and a list of other packages required to be trusted
+-- (these later ones haven't been checked) but the own package trust has been.
 hscCheckSafe' :: DynFlags -> Module -> SrcSpan -> Hsc (Maybe PackageId, [PackageId])
 hscCheckSafe' dflags m l = do
     (tw, pkgs) <- isModSafe m l
@@ -1030,44 +910,42 @@ hscCheckSafe' dflags m l = do
         True | isHomePkg m -> return (Nothing, pkgs)
              | otherwise   -> return (Just $ modulePackageId m, pkgs)
   where
-    -- Is a module trusted? If not, throw or log errors depending on the type.
-    -- Return (regardless of trusted or not) if the trust type requires the
-    -- modules own package be trusted and a list of other packages required to
-    -- be trusted (these later ones haven't been checked)
     isModSafe :: Module -> SrcSpan -> Hsc (Bool, [PackageId])
     isModSafe m l = do
         iface <- lookup' m
         case iface of
             -- can't load iface to check trust!
-            Nothing -> throwErrors $ unitBag $ mkPlainErrMsg l
+            Nothing -> throwErrors $ unitBag $ mkPlainErrMsg dflags l
                          $ text "Can't load the interface file for" <+> ppr m
                            <> text ", to check that it can be safely imported"
 
             -- got iface, check trust
-            Just iface' -> do
+            Just iface' ->
                 let trust = getSafeMode $ mi_trust iface'
                     trust_own_pkg = mi_trust_pkg iface'
                     -- check module is trusted
-                    safeM = trust `elem` [Sf_SafeInfered, Sf_Safe, Sf_Trustworthy]
+                    safeM = trust `elem` [Sf_SafeInferred, Sf_Safe, Sf_Trustworthy]
                     -- check package is trusted
                     safeP = packageTrusted trust trust_own_pkg m
                     -- pkg trust reqs
                     pkgRs = map fst $ filter snd $ dep_pkgs $ mi_deps iface'
-                case (safeM, safeP) of
                     -- General errors we throw but Safe errors we log
-                    (True, True ) -> return (trust == Sf_Trustworthy, pkgRs)
-                    (True, False) -> liftIO . throwIO $ pkgTrustErr
-                    (False, _   ) -> logWarnings modTrustErr >>
-                                     return (trust == Sf_Trustworthy, pkgRs)
+                    errs = case (safeM, safeP) of
+                        (True, True ) -> emptyBag
+                        (True, False) -> pkgTrustErr
+                        (False, _   ) -> modTrustErr
+                in do
+                    logWarnings errs
+                    return (trust == Sf_Trustworthy, pkgRs)
 
                 where
-                    pkgTrustErr = mkSrcErr $ unitBag $ mkPlainErrMsg l $
+                    pkgTrustErr = unitBag $ mkPlainErrMsg dflags l $
                         sep [ ppr (moduleName m)
                                 <> text ": Can't be safely imported!"
                             , text "The package (" <> ppr (modulePackageId m)
                                 <> text ") the module resides in isn't trusted."
                             ]
-                    modTrustErr = unitBag $ mkPlainErrMsg l $
+                    modTrustErr = unitBag $ mkPlainErrMsg dflags l $
                         sep [ ppr (moduleName m)
                                 <> text ": Can't be safely imported!"
                             , text "The module itself isn't safe." ]
@@ -1077,10 +955,12 @@ hscCheckSafe' dflags m l = do
     -- trustworthy modules, modules in the home package are trusted but
     -- otherwise we check the package trust flag.
     packageTrusted :: SafeHaskellMode -> Bool -> Module -> Bool
+    packageTrusted Sf_None             _ _ = False -- shouldn't hit these cases
+    packageTrusted Sf_Unsafe           _ _ = False -- prefer for completeness.
     packageTrusted _ _ _
-        | not (packageTrustOn dflags)     = True
-    packageTrusted Sf_Safe        False _ = True
-    packageTrusted Sf_SafeInfered False _ = True
+        | not (packageTrustOn dflags)      = True
+    packageTrusted Sf_Safe         False _ = True
+    packageTrusted Sf_SafeInferred False _ = True
     packageTrusted _ _ m
         | isHomePkg m = True
         | otherwise   = trusted $ getPackageDetails (pkgState dflags)
@@ -1123,13 +1003,13 @@ checkPkgTrust dflags pkgs =
             | trusted $ getPackageDetails (pkgState dflags) pkg
             = Nothing
             | otherwise
-            = Just $ mkPlainErrMsg noSrcSpan
+            = Just $ mkPlainErrMsg dflags noSrcSpan
                    $ text "The package (" <> ppr pkg <> text ") is required" <>
                      text " to be trusted but it isn't!"
 
 -- | Set module to unsafe and wipe trust information.
 --
--- Make sure to call this method to set a module to infered unsafe,
+-- Make sure to call this method to set a module to inferred unsafe,
 -- it should be a central and single failure method.
 wipeTrust :: TcGblEnv -> WarningMessages -> Hsc TcGblEnv
 wipeTrust tcg_env whyUnsafe = do
@@ -1137,7 +1017,7 @@ wipeTrust tcg_env whyUnsafe = do
 
     when (wopt Opt_WarnUnsafe dflags)
          (logWarnings $ unitBag $
-             mkPlainWarnMsg (warnUnsafeOnLoc dflags) (whyUnsafe' dflags))
+             mkPlainWarnMsg dflags (warnUnsafeOnLoc dflags) (whyUnsafe' dflags))
 
     liftIO $ writeIORef (tcg_safeInfer tcg_env) False
     return $ tcg_env { tcg_imports = wiped_trust }
@@ -1145,7 +1025,7 @@ wipeTrust tcg_env whyUnsafe = do
   where
     wiped_trust   = (tcg_imports tcg_env) { imp_trust_pkgs = [] }
     pprMod        = ppr $ moduleName $ tcg_mod tcg_env
-    whyUnsafe' df = vcat [ quotes pprMod <+> text "has been infered as unsafe!"
+    whyUnsafe' df = vcat [ quotes pprMod <+> text "has been inferred as unsafe!"
                          , text "Reason:"
                          , nest 4 $ (vcat $ badFlags df) $+$
                                     (vcat $ pprErrMsgBagWithLoc whyUnsafe)
@@ -1179,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
@@ -1194,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
@@ -1226,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,
@@ -1248,7 +1147,6 @@ hscGenHardCode cgguts mod_summary = do
                     cg_dep_pkgs = dependencies,
                     cg_hpc_info = hpc_info } = cgguts
             dflags = hsc_dflags hsc_env
-            platform = targetPlatform dflags
             location = ms_location mod_summary
             data_tycons = filter isDataTyCon tycons
             -- cg_tycons includes newtypes, for the benefit of External Core,
@@ -1258,43 +1156,45 @@ hscGenHardCode cgguts mod_summary = do
         -- PREPARE FOR CODE GENERATION
         -- Do saturation and convert to A-normal form
         prepd_binds <- {-# SCC "CorePrep" #-}
-                       corePrepPgm dflags core_binds data_tycons ;
+                       corePrepPgm dflags hsc_env core_binds data_tycons ;
         -----------------  Convert to STG ------------------
         (stg_binds, cost_centre_info)
             <- {-# SCC "CoreToStg" #-}
                myCoreToStg dflags this_mod prepd_binds
 
-        let prof_init = profilingInitCode platform this_mod cost_centre_info
+        let prof_init = profilingInitCode this_mod cost_centre_info
             foreign_stubs = foreign_stubs0 `appendStubC` prof_init
 
         ------------------  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" #-}
-                         codeGen dflags this_mod data_tycons
-                             cost_centre_info
-                             stg_binds hpc_info
 
         ------------------  Code output -----------------------
-        rawcmms <- {-# SCC "cmmToRawCmm" #-}
-                   cmmToRawCmm platform cmms
-        dumpIfSet_dyn dflags Opt_D_dump_raw_cmm "Raw Cmm" (pprPlatform platform rawcmms)
-        (_stub_h_exists, stub_c_exists)
+        rawcmms0 <- {-# SCC "cmmToRawCmm" #-}
+                   cmmToRawCmm dflags cmms
+
+        let dump a = do dumpIfSet_dyn dflags Opt_D_dump_cmm_raw "Raw Cmm"
+                           (ppr a)
+                        return a
+            rawcmms1 = Stream.mapM dump rawcmms0
+
+        (output_filename, (_stub_h_exists, stub_c_exists))
             <- {-# SCC "codeOutput" #-}
                codeOutput dflags this_mod location foreign_stubs
-               dependencies rawcmms
-        return stub_c_exists
+               dependencies rawcmms1
+        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,
@@ -1312,16 +1212,13 @@ hscInteractive (iface, details, cgguts) mod_summary = do
     -- PREPARE FOR CODE GENERATION
     -- Do saturation and convert to A-normal form
     prepd_binds <- {-# SCC "CorePrep" #-}
-                   liftIO $ corePrepPgm dflags 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
@@ -1333,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 (targetPlatform dflags) [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
@@ -1346,30 +1247,75 @@ hscCompileCmmFile hsc_env filename = runHsc hsc_env $ do
 
 tryNewCodeGen   :: HscEnv -> Module -> [TyCon]
                 -> CollectedCCs
-                -> [(StgBinding,[(Id,[Id])])]
+                -> [StgBinding]
                 -> HpcInfo
-                -> 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.
 tryNewCodeGen hsc_env this_mod data_tycons
               cost_centre_info stg_binds hpc_info = do
     let dflags = hsc_dflags hsc_env
-        platform = targetPlatform dflags
-    prog <- StgCmm.codeGen dflags this_mod data_tycons
+
+    let cmm_stream :: Stream IO CmmGroup ()
+        cmm_stream = {-# SCC "StgCmm" #-}
+            StgCmm.codeGen dflags this_mod data_tycons
                            cost_centre_info stg_binds hpc_info
-    dumpIfSet_dyn dflags Opt_D_dump_cmmz "Cmm produced by new codegen"
-                  (pprCmms platform prog)
+
+        -- codegen consumes a stream of CmmGroup, and produces a new
+        -- stream of CmmGroup (not necessarily synchronised: one
+        -- CmmGroup on input may produce many CmmGroups on output due
+        -- to proc-point splitting).
+
+    let dump1 a = do dumpIfSet_dyn dflags Opt_D_dump_cmm
+                       "Cmm produced by new codegen" (ppr a)
+                     return a
+
+        ppr_stream1 = Stream.mapM dump1 cmm_stream
 
     -- We are building a single SRT for the entire module, so
     -- we must thread it through all the procedures as we cps-convert them.
     us <- mkSplitUniqSupply 'S'
-    let initTopSRT = initUs_ us emptySRT
-    (topSRT, prog) <- foldM (cmmPipeline hsc_env) (initTopSRT, []) prog
 
-    let prog' = map cmmOfZgraph (srtToData topSRT : prog)
-    dumpIfSet_dyn dflags Opt_D_dump_cmmz "Output Cmm" (pprPlatform platform prog')
-    return prog'
+    -- When splitting, we generate one SRT per split chunk, otherwise
+    -- we generate one SRT for the whole module.
+    let
+     pipeline_stream
+      | 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', srt ++ cmmgroup)
+
+          in do _ <- Stream.mapAccumL run_pipeline us ppr_stream1
+                return ()
+
+      | otherwise
+        = {-# SCC "cmmPipeline" #-}
+          let initTopSRT = initUs_ us emptySRT in
+  
+          let run_pipeline topSRT cmmgroup = do
+                (topSRT, cmmgroup) <- cmmPipeline hsc_env topSRT cmmgroup
+                return (topSRT,cmmgroup)
+  
+          in do topSRT <- Stream.mapAccumL run_pipeline initTopSRT ppr_stream1
+                Stream.yield (srtToData topSRT)
+
+    let
+        dump2 a = do dumpIfSet_dyn dflags Opt_D_dump_cmm "Output Cmm" $ ppr a
+                     return a
+
+        ppr_stream2 = Stream.mapM dump2 pipeline_stream
+
+    return ppr_stream2
+
+
 
 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
@@ -1474,6 +1420,8 @@ hscDeclsWithLocation hsc_env0 str source linenumber =
     let finsts = tcg_fam_insts tc_gblenv
         insts  = tcg_insts     tc_gblenv
 
+    let defaults = tcg_default tc_gblenv
+
     {- Desugar it -}
     -- We use a basically null location for iNTERACTIVE
     let iNTERACTIVELoc = ModLocation{ ml_hs_file   = Nothing,
@@ -1497,7 +1445,7 @@ hscDeclsWithLocation hsc_env0 str source linenumber =
     {- Prepare For Code Generation -}
     -- Do saturation and convert to A-normal form
     prepd_binds <- {-# SCC "CorePrep" #-}
-                    liftIO $ corePrepPgm dflags core_binds data_tycons
+                    liftIO $ corePrepPgm dflags hsc_env core_binds data_tycons
 
     {- Generate byte code -}
     cbc <- liftIO $ byteCodeGen dflags this_mod
@@ -1525,7 +1473,8 @@ hscDeclsWithLocation hsc_env0 str source linenumber =
 
     let ictxt1 = extendInteractiveContext icontext tythings
         ictxt  = ictxt1 { ic_sys_vars  = sys_vars ++ ic_sys_vars ictxt1,
-                          ic_instances = (insts, finsts) }
+                          ic_instances = (insts, finsts),
+                          ic_default   = defaults }
 
     return (tythings, ictxt)
 
@@ -1536,10 +1485,11 @@ hscImport hsc_env str = runInteractiveHsc hsc_env $ do
     case is of
         [i] -> return (unLoc i)
         _ -> liftIO $ throwOneError $
-                 mkPlainErrMsg noSrcSpan $
+                 mkPlainErrMsg (hsc_dflags hsc_env) noSrcSpan $
                      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
@@ -1547,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 noSrcSpan
+            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
@@ -1564,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
 
@@ -1595,7 +1546,7 @@ hscParseThingWithLocation source linenumber parser str
 
     case unP parser (mkPState dflags buf loc) of
         PFailed span err -> do
-            let msg = mkPlainErrMsg span err
+            let msg = mkPlainErrMsg dflags span err
             throwErrors $ unitBag msg
 
         POk pst thing -> do
@@ -1608,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
@@ -1665,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
@@ -1674,7 +1625,7 @@ hscCompileCoreExpr hsc_env srcspan ds_expr
         let tidy_expr = tidyExpr emptyTidyEnv simpl_expr
 
         {- Prepare for codegen -}
-        prepd_expr <- corePrepExpr dflags tidy_expr
+        prepd_expr <- corePrepExpr dflags hsc_env tidy_expr
 
         {- Lint if necessary -}
         -- ToDo: improve SrcLoc
@@ -1706,7 +1657,7 @@ hscCompileCoreExpr hsc_env srcspan ds_expr
 dumpIfaceStats :: HscEnv -> IO ()
 dumpIfaceStats hsc_env = do
     eps <- readIORef (hsc_EPS hsc_env)
-    dumpIfSet (dump_if_trace || dump_rn_stats)
+    dumpIfSet dflags (dump_if_trace || dump_rn_stats)
               "Interface statistics"
               (ifaceStats eps)
   where
@@ -1721,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