\section[GHC_Main]{Main driver for Glasgow Haskell compiler}
\begin{code}
-module HscMain ( HscResult(..), hscMain, hscExpr, hscTypeExpr,
+module HscMain ( HscResult(..), hscMain,
+#ifdef GHCI
+ hscExpr,
+#endif
initPersistentCompilerState ) where
#include "HsVersions.h"
#ifdef GHCI
import RdrHsSyn ( RdrNameHsExpr )
-import CoreToStg ( coreToStgExpr )
import StringBuffer ( stringToStringBuffer, freeStringBuffer )
+import Unique ( Uniquable(..) )
+import Type ( splitTyConApp_maybe )
+import PrelNames ( ioTyConKey )
+import ByteCodeGen ( byteCodeGen )
#endif
import HsSyn
import Parser
import Lex ( PState(..), ParseResult(..) )
import SrcLoc ( mkSrcLoc )
-import Rename
+import Rename ( checkOldIface, renameModule, renameExpr, closeIfaceDecls )
import Rules ( emptyRuleBase )
import PrelInfo ( wiredInThingEnv, wiredInThings )
import PrelNames ( knownKeyNames )
writeIface, pprIface )
import TcModule
import Type
-import TcHsSyn
import InstEnv ( emptyInstEnv )
import Desugar
import SimplCore
-import OccurAnal ( occurAnalyseBinds )
import CoreUtils ( coreBindsSize )
import CoreTidy ( tidyCorePgm )
-import CoreToStg ( topCoreBindsToStg )
+import CoreSat
+import CoreToStg ( coreToStg, coreExprToStg )
import StgSyn ( collectFinalStgBinders )
import SimplStg ( stg2stg )
import CodeGen ( codeGen )
import CmdLineOpts
import ErrUtils ( dumpIfSet_dyn, showPass )
import Util ( unJust )
-import Unique ( Uniquable(..) )
-import PrelNames ( ioTyConKey )
import UniqSupply ( mkSplitUniqSupply )
import Bag ( emptyBag )
HomeSymbolTable,
OrigNameEnv(..), PackageRuleBase, HomeIfaceTable,
typeEnvClasses, typeEnvTyCons, emptyIfaceTable )
-import Type ( splitTyConApp_maybe )
import FiniteMap ( FiniteMap, plusFM, emptyFM, addToFM )
import OccName ( OccName )
import Name ( Name, nameModule, nameOccName, getName )
import Monad ( when )
import Maybe ( isJust )
-import IO ( hPutStrLn, stderr )
+import IO
\end{code}
++ ", hspp = " ++ show (ml_hspp_file location));
(pcs_ch, errs_found, (recomp_reqd, maybe_checked_iface))
- <- checkOldIface dflags hit hst pcs
+ <- checkOldIface ghci_mode dflags hit hst pcs
(unJust "hscMain" (ml_hi_file location))
source_unchanged maybe_old_iface;
-- we definitely expect to have the old interface available
hscNoRecomp ghci_mode dflags location (Just old_iface) hst hit pcs_ch
| ghci_mode == OneShot
- = let bomb = panic "hscNoRecomp:OneShot"
- in return (HscNoRecomp pcs_ch bomb bomb)
+ = do {
+ hPutStrLn stderr "compilation IS NOT required";
+ let { bomb = panic "hscNoRecomp:OneShot" };
+ return (HscNoRecomp pcs_ch bomb bomb)
+ }
| otherwise
= do {
- hPutStrLn stderr "compilation not required";
- ;
+ hPutStr stderr "compilation IS NOT required";
+ when (verbosity dflags /= 1) $ hPutStrLn stderr "";
+
-- CLOSURE
(pcs_cl, closure_errs, cl_hs_decls)
<- closeIfaceDecls dflags hit hst pcs_ch old_iface ;
Just (pcs_tc, tc_result) -> do {
let env_tc = tc_env tc_result
- local_insts = tc_insts tc_result
local_rules = tc_rules tc_result
;
-- create a new details from the closed, typechecked, old iface
- let new_details = mkModDetailsFromIface env_tc local_insts local_rules
+ let new_details = mkModDetailsFromIface env_tc local_rules
;
return (HscNoRecomp pcs_tc new_details old_iface)
}}}}
hscRecomp ghci_mode dflags location maybe_checked_iface hst hit pcs_ch
= do {
- ; hPutStrLn stderr "compilation IS required";
+ ; when (verbosity dflags >= 1) $
+ hPutStr stderr "compilation IS required";
+ -- mode -v1 tries to keep everything on one line
+ when (verbosity dflags > 1) $
+ hPutStrLn stderr "";
-- what target are we shooting for?
; let toInterp = dopt_HscLang dflags == HscInterpreted
-------------------
-- RENAME
-------------------
- ; showPass dflags "Rename"
; (pcs_rn, maybe_rn_result)
<- renameModule dflags hit hst pcs_ch this_mod rdr_module
; case maybe_rn_result of {
-------------------
-- TYPECHECK
-------------------
- ; showPass dflags "Typecheck"
; maybe_tc_result <- typecheckModule dflags pcs_rn hst new_iface
print_unqualified rn_hs_decls
; case maybe_tc_result of {
- Nothing -> do { hPutStrLn stderr "Typecheck failed"
- ; return (HscFail pcs_rn) } ;
+ Nothing -> return (HscFail pcs_rn);
Just (pcs_tc, tc_result) -> do {
- ; let env_tc = tc_env tc_result
- local_insts = tc_insts tc_result
+ ; let env_tc = tc_env tc_result
-------------------
-- DESUGAR, SIMPLIFY, TIDY-CORE
-- We grab the the unfoldings at this point.
; simpl_result <- dsThenSimplThenTidy dflags pcs_tc hst this_mod
print_unqualified is_exported tc_result
- ; let (tidy_binds, orphan_rules, foreign_stuff) = simpl_result
+ ; let (pcs_simpl, tidy_binds, orphan_rules, foreign_stuff) = simpl_result
-------------------
-- CONVERT TO STG
-------------------
- ; (stg_binds, oa_tidy_binds, cost_centre_info, top_level_ids)
+ ; (stg_binds, cost_centre_info, top_level_ids)
<- myCoreToStg dflags this_mod tidy_binds
-------------------
-- BUILD THE NEW ModDetails AND ModIface
-------------------
- ; let new_details = mkModDetails env_tc local_insts tidy_binds
+ ; let new_details = mkModDetails env_tc tidy_binds
top_level_ids orphan_rules
; final_iface <- mkFinalIface ghci_mode dflags location
maybe_checked_iface new_iface new_details
; (maybe_stub_h_filename, maybe_stub_c_filename, maybe_ibinds)
<- restOfCodeGeneration dflags toInterp this_mod
(map ideclName (hsModuleImports rdr_module))
- cost_centre_info foreign_stuff env_tc stg_binds oa_tidy_binds
- hit (pcs_PIT pcs_tc)
+ cost_centre_info foreign_stuff env_tc stg_binds tidy_binds
+ hit (pcs_PIT pcs_simpl)
-- and the answer is ...
- ; return (HscRecomp pcs_tc new_details final_iface
+ ; return (HscRecomp pcs_simpl new_details final_iface
maybe_stub_h_filename maybe_stub_c_filename
maybe_ibinds)
}}}}}}}
buf <- hGetStringBuffer True{-expand tabs-} src_filename
let glaexts | dopt Opt_GlasgowExts dflags = 1#
- | otherwise = 0#
+ | otherwise = 0#
case parse buf PState{ bol = 0#, atbol = 1#,
context = [], glasgow_exts = glaexts,
restOfCodeGeneration dflags toInterp this_mod imported_module_names cost_centre_info
- foreign_stuff env_tc stg_binds oa_tidy_binds
+ foreign_stuff env_tc stg_binds tidy_binds
hit pit -- these last two for mapping ModNames to Modules
| toInterp
= do (ibinds,itbl_env)
-- _scc_ "CodeOutput"
(maybe_stub_h_name, maybe_stub_c_name)
<- codeOutput dflags this_mod local_tycons
- oa_tidy_binds stg_binds
+ tidy_binds stg_binds
c_code h_code abstractC
return (maybe_stub_h_name, maybe_stub_c_name, Nothing)
dsThenSimplThenTidy dflags pcs hst this_mod print_unqual is_exported tc_result
- = do -------------------------- Desugaring ----------------
- showPass dflags "DeSugar"
+ = do ------------------ Desugaring ---------------------------------
-- _scc_ "DeSugar"
(desugared, rules, h_code, c_code, fe_binders)
<- deSugar dflags pcs hst this_mod print_unqual tc_result
- -------------------------- Main Core-language transformations ----------------
+ ------------------ Main Core-language transformations ---------
-- _scc_ "Core2Core"
(simplified, orphan_rules)
<- core2core dflags pcs hst is_exported desugared rules
+ -- Do saturation and convert to A-normal form
+ -- NOTE: future passes cannot transform the syntax, only annotate it
+ saturated <- coreSatPgm dflags simplified
+
-- Do the final tidy-up
- showPass dflags "TidyCore"
- (tidy_binds, tidy_orphan_rules)
- <- tidyCorePgm dflags this_mod simplified orphan_rules
+ (pcs', tidy_binds, tidy_orphan_rules)
+ <- tidyCorePgm dflags this_mod pcs saturated orphan_rules
- return (tidy_binds, tidy_orphan_rules, (fe_binders,h_code,c_code))
+ return (pcs', tidy_binds, tidy_orphan_rules, (fe_binders,h_code,c_code))
myCoreToStg dflags this_mod tidy_binds
= do
- st_uniqs <- mkSplitUniqSupply 'g'
- let occ_anal_tidy_binds = occurAnalyseBinds tidy_binds
-
- () <- coreBindsSize occ_anal_tidy_binds `seq` return ()
+ () <- coreBindsSize tidy_binds `seq` return ()
-- TEMP: the above call zaps some space usage allocated by the
-- simplifier, which for reasons I don't understand, persists
-- thoroughout code generation
+ --let bcos = byteCodeGen tidy_binds
+ --putStrLn (showSDoc (vcat (map ppr bcos)))
+
-- _scc_ "Core2Stg"
- stg_binds <- topCoreBindsToStg dflags occ_anal_tidy_binds
+ stg_binds <- coreToStg dflags this_mod tidy_binds
- showPass dflags "Stg2Stg"
-- _scc_ "Stg2Stg"
- (stg_binds2, cost_centre_info) <- stg2stg dflags this_mod st_uniqs stg_binds
+ (stg_binds2, cost_centre_info) <- stg2stg dflags this_mod stg_binds
let final_ids = collectFinalStgBinders (map fst stg_binds2)
- return (stg_binds2, occ_anal_tidy_binds, cost_centre_info, final_ids)
+ return (stg_binds2, cost_centre_info, final_ids)
\end{code}
%************************************************************************
\begin{code}
+#ifndef GHCI
+hscExpr dflags hst hit pcs this_module expr
+ = panic "hscExpr: non-interactive build"
+hscTypeExpr dflags hst hit pcs0 this_module expr
+ = panic "hscTypeExpr: non-interactive build"
+#else
+
hscExpr
:: DynFlags
-> HomeSymbolTable
-> PersistentCompilerState -- IN: persistent compiler state
-> Module -- Context for compiling
-> String -- The expression
- -> IO ( PersistentCompilerState, Maybe UnlinkedIExpr )
-
-#ifndef GHCI
-hscExpr dflags hst hit pcs this_module expr
- = panic "hscExpr: non-interactive build"
-#else
+ -> IO ( PersistentCompilerState,
+ Maybe (UnlinkedIExpr, PrintUnqualified, Type) )
hscExpr dflags hst hit pcs0 this_module expr
= do {
- -- parse, rename & typecheck the expression
- (pcs1, maybe_tc_result)
- <- hscExprFrontEnd dflags hst hit pcs0 this_module expr;
+ maybe_parsed <- hscParseExpr dflags expr;
+ case maybe_parsed of
+ Nothing -> return (pcs0, Nothing)
+ Just parsed_expr -> do {
+
+ -- Rename it
+ (pcs1, maybe_renamed_expr) <-
+ renameExpr dflags hit hst pcs0 this_module parsed_expr;
+ case maybe_renamed_expr of
+ Nothing -> return (pcs1, Nothing)
+ Just (print_unqual, rn_expr) -> do {
- case maybe_tc_result of {
- Nothing -> return (pcs1, Nothing);
- Just (print_unqual, tc_expr, ty) -> do {
+ -- Typecheck it
+ maybe_tc_return
+ <- typecheckExpr dflags pcs1 hst print_unqual this_module rn_expr;
+ case maybe_tc_return of {
+ Nothing -> return (pcs1, Nothing);
+ Just (pcs2, tc_expr, ty) -> do
-- if it isn't an IO-typed expression,
-- wrap "print" around it & recompile...
};
if (not is_IO_type)
- then hscExpr dflags hst hit pcs1 this_module
- ("print (" ++ expr ++ ")")
+ then do (new_pcs, maybe_stuff)
+ <- hscExpr dflags hst hit pcs2 this_module
+ ("print (" ++ expr ++ ")")
+ case maybe_stuff of
+ Nothing -> return (new_pcs, maybe_stuff)
+ Just (expr, _, _) ->
+ return (new_pcs, Just (expr, print_unqual, ty))
else do
-- Desugar it
- ds_expr <- deSugarExpr dflags pcs1 hst this_module
+ ds_expr <- deSugarExpr dflags pcs2 hst this_module
print_unqual tc_expr;
-- Simplify it
- simpl_expr <- simplifyExpr dflags pcs1 hst ds_expr;
+ simpl_expr <- simplifyExpr dflags pcs2 hst ds_expr;
+
+ -- Saturate it
+ sat_expr <- coreSatExpr dflags simpl_expr;
-- Convert to STG
- stg_expr <- coreToStgExpr dflags simpl_expr;
+ let stg_expr = coreExprToStg sat_expr;
- -- ToDo: need to do StgVarInfo? or SRTs?
+ -- ToDo: need to do SRTs?
-- Convert to InterpSyn
unlinked_iexpr <- stgExprToInterpSyn dflags stg_expr;
- return (pcs1, Just unlinked_iexpr);
- }}}
-
-hscExprFrontEnd
- :: DynFlags
- -> HomeSymbolTable
- -> HomeIfaceTable
- -> PersistentCompilerState -- IN: persistent compiler state
- -> Module -- Context for compiling
- -> String -- The expression
- -> IO ( PersistentCompilerState,
- Maybe (PrintUnqualified,TypecheckedHsExpr,Type)
- )
-hscExprFrontEnd dflags hst hit pcs0 this_module expr
- = do { -- Parse it
- maybe_parsed <- hscParseExpr dflags expr;
- case maybe_parsed of
- Nothing -> return (pcs0, Nothing)
- Just parsed_expr -> do {
-
- -- Rename it
- (pcs1, maybe_renamed_expr) <-
- renameExpr dflags hit hst pcs0 this_module parsed_expr;
- case maybe_renamed_expr of
- Nothing -> return (pcs1, Nothing)
- Just (print_unqual, rn_expr) -> do {
-
- -- Typecheck it
- maybe_tc_return
- <- typecheckExpr dflags pcs1 hst print_unqual this_module rn_expr;
- case maybe_tc_return of
- Nothing -> return (pcs1, Nothing)
- Just (pcs2, tc_expr, ty) ->
- return (pcs2, Just (print_unqual, tc_expr, ty))
- }}}
-
-hscTypeExpr
- :: DynFlags
- -> HomeSymbolTable
- -> HomeIfaceTable
- -> PersistentCompilerState -- IN: persistent compiler state
- -> Module -- Context for compiling
- -> String -- The expression
- -> IO (PersistentCompilerState, Maybe Type)
-hscTypeExpr dflags hst hit pcs0 this_module expr
- = do (pcs1, maybe_tc_result)
- <- hscExprFrontEnd dflags hst hit pcs0 this_module expr
- case maybe_tc_result of
- Nothing -> return (pcs1, Nothing)
- Just (_,_,ty) -> return (pcs1, Just ty)
+ return (pcs2, Just (unlinked_iexpr, print_unqual, ty));
+ }}}}
hscParseExpr :: DynFlags -> String -> IO (Maybe RdrNameHsExpr)
hscParseExpr dflags str
initPersistentRenamerState :: IO PersistentRenamerState
= do ns <- mkSplitUniqSupply 'r'
return (
- PRS { prsOrig = Orig { origNames = initOrigNames,
+ PRS { prsOrig = Orig { origNS = ns,
+ origNames = initOrigNames,
origIParam = emptyFM },
prsDecls = (emptyNameEnv, 0),
prsInsts = (emptyBag, 0),
- prsRules = (emptyBag, 0),
- prsNS = ns
+ prsRules = (emptyBag, 0)
}
)