2 % (c) The GRASP/AQUA Project, Glasgow University, 1993-2000
4 \section[GHC_Main]{Main driver for Glasgow Haskell compiler}
7 module HscMain ( hscMain ) where
9 #include "HsVersions.h"
11 import IO ( hPutStr, stderr )
14 import RdrHsSyn ( RdrNameHsModule )
15 import FastString ( unpackFS )
16 import StringBuffer ( hGetStringBuffer )
17 import Parser ( parse )
18 import Lex ( PState(..), ParseResult(..) )
19 import SrcLoc ( mkSrcLoc )
21 import Rename ( renameModule )
23 import PrelInfo ( wiredInThings )
24 import PrelRules ( builtinRules )
25 import MkIface ( writeIface )
26 import TcModule ( TcResults(..), typecheckModule )
27 import Desugar ( deSugar )
28 import SimplCore ( core2core )
29 import OccurAnal ( occurAnalyseBinds )
30 import CoreUtils ( coreBindsSize )
31 import CoreTidy ( tidyCorePgm )
32 import CoreToStg ( topCoreBindsToStg )
33 import StgSyn ( collectFinalStgBinders )
34 import SimplStg ( stg2stg )
35 import CodeGen ( codeGen )
36 import CodeOutput ( codeOutput )
38 import Module ( ModuleName, moduleNameUserString )
40 import ErrUtils ( ghcExit, doIfSet, dumpIfSet )
41 import UniqSupply ( mkSplitUniqSupply )
44 import Char ( isSpace )
45 import StgInterp ( runStgI )
46 import HscStats ( ppSourceStats )
50 %************************************************************************
52 \subsection{The main compiler pipeline}
54 %************************************************************************
58 = HscOK ModDetails -- new details (HomeSymbolTable additions)
59 (Maybe ModIface) -- new iface (if any compilation was done)
60 (Maybe String) -- generated stub_h filename (in /tmp)
61 (Maybe String) -- generated stub_c filename (in /tmp)
62 (Maybe ([UnlinkedIBind],ItblEnv)) -- interpreted code, if any
63 PersistentCompilerState -- updated PCS
65 | HscFail PersistentCompilerState -- updated PCS
66 -- no errors or warnings; the individual passes
67 -- (parse/rename/typecheck) print messages themselves
71 -> ModSummary -- summary, including source filename
72 -> Maybe ModIFace -- old interface, if available
73 -> String -- file in which to put the output (.s, .hc, .java etc.)
74 -> HomeSymbolTable -- for home module ModDetails
75 -> PersistentCompilerState -- IN: persistent compiler state
78 hscMain dflags core_cmds stg_cmds summary maybe_old_iface
79 output_filename mod_details pcs
81 -- ????? source_unchanged :: Bool -- extracted from summary?
83 (ch_pcs, check_errs, (recomp_reqd, maybe_checked_iface))
84 <- checkOldIface dflags finder hit hst pcs mod source_unchanged
87 return (HscFail ch_pcs)
90 let no_old_iface = not (isJust maybe_checked_iface)
91 what_next | recomp_reqd || no_old_iface = hscRecomp
92 | otherwise = hscNoRecomp
94 return (what_next dflags core_cmds stg_cmds summary hit hst
95 pcs2 maybe_checked_iface)
99 hscNoRecomp dflags core_cmds stg_cmds summary hit hst pcs maybe_old_iface
101 -- we definitely expect to have the old interface available
102 old_iface = case maybe_old_iface of
103 Just old_if -> old_if
104 Nothing -> panic "hscNoRecomp:old_iface"
107 (pcs_cl, closure_errs, cl_hs_decls)
108 <- closeIfaceDecls dflags finder hit hst pcs old_iface
110 return (HscFail cl_pcs)
115 <- typecheckModule dflags mod pcs_cl hst hit pit cl_hs_decls;
116 case maybe_tc_result of {
117 Nothing -> return (HscFail cl_pcs);
118 Just tc_result -> do {
120 let pcs_tc = tc_pcs tc_result
121 env_tc = tc_env tc_result
122 binds_tc = tc_binds tc_result
123 local_tycons = tc_tycons tc_result
124 local_classes = tc_classes tc_result
125 local_insts = tc_insts tc_result
126 local_rules = tc_rules tc_result
128 -- create a new details from the closed, typechecked, old iface
129 let new_details = mkModDetailsFromIface env_tc local_insts local_rules
131 return (HscOK final_details
132 Nothing -- tells CM to use old iface and linkables
133 Nothing Nothing -- foreign export stuff
139 hscRecomp dflags core_cmds stg_cmds summary hit hst pcs maybe_old_iface
141 -- what target are we shooting for?
142 let toInterp = dopt_HscLang dflags == HscInterpreted;
145 maybe_parsed <- myParseModule dflags summary;
146 case maybe_parsed of {
147 Nothing -> return (HscFail pcs);
148 Just rdr_module -> do {
151 (pcs_rn, maybe_rn_result)
152 <- renameModule dflags finder hit hst pcs mod rdr_module;
153 case maybe_rn_result of {
154 Nothing -> return (HscFail pcs_rn);
155 Just (new_iface, rn_hs_decls) -> do {
159 <- typecheckModule dflags mod pcs_rn hst hit pit rn_hs_decls;
160 case maybe_tc_result of {
161 Nothing -> return (HscFail pcs_rn);
162 Just tc_result -> do {
164 let pcs_tc = tc_pcs tc_result
165 env_tc = tc_env tc_result
166 binds_tc = tc_binds tc_result
167 local_tycons = tc_tycons tc_result
168 local_classes = tc_classes tc_result
169 local_insts = tc_insts tc_result
171 -- DESUGAR, SIMPLIFY, TIDY-CORE
172 -- We grab the the unfoldings at this point.
173 (tidy_binds, orphan_rules, foreign_stuff)
174 <- dsThenSimplThenTidy dflags mod tc_result ds_uniqs
177 (stg_binds, cost_centre_info, top_level_ids)
178 <- myCoreToStg c2s_uniqs st_uniqs this_mod tidy_binds
180 -- cook up a new ModDetails now we (finally) have all the bits
181 let new_details = mkModDetails tc_env local_insts tidy_binds
182 top_level_ids orphan_rules
184 -- and possibly create a new ModIface
185 let maybe_final_iface = completeIface maybe_old_iface new_iface new_details
187 -- do the rest of code generation/emission
188 (maybe_ibinds, maybe_stub_h_filename, maybe_stub_c_filename)
189 <- restOfCodeGeneration toInterp
190 this_mod imported_modules cost_centre_info
191 fe_binders tc_env stg_binds
193 -- and the answer is ...
194 return (HscOK new_details maybe_final_iface
195 maybe_stub_h_filename maybe_stub_c_filename
200 myParseModule dflags summary
201 = do -------------------------- Reader ----------------
205 let src_filename -- name of the preprocessed source file
206 = case ms_ppsource summary of
207 Just (filename, fingerprint) -> filename
208 Nothing -> pprPanic "myParseModule:summary is not of a source module"
211 buf <- hGetStringBuffer True{-expand tabs-} src_filename
213 let glaexts | dopt Opt_GlasgowExts dflags = 1#
216 case parse buf PState{ bol = 0#, atbol = 1#,
217 context = [], glasgow_exts = glaexts,
218 loc = mkSrcLoc src_filename 1 } of {
220 PFailed err -> do hPutStrLn stderr (showSDoc err)
222 POk _ rdr_module@(HsModule mod_name _ _ _ _ _ _) ->
224 dumpIfSet_dyn dflags Opt_D_dump_parsed "Parser" (ppr rdr_module)
225 dumpIfSet_dyn dflags Opt_D_source_stats "Source Statistics"
226 (ppSourceStats False rdr_module)
228 return (Just rdr_module)
231 restOfCodeGeneration toInterp this_mod imported_modules cost_centre_info
232 foreign_stuff tc_env stg_binds
234 = return (Nothing, Nothing,
235 Just (stgToInterpSyn stg_binds local_tycons local_classes))
237 = do -------------------------- Code generation -------------------------------
240 abstractC <- codeGen this_mod imported_modules
241 cost_centre_info fe_binders
242 local_tycons local_classes stg_binds
244 -------------------------- Code output -------------------------------
245 show_pass "CodeOutput"
246 -- _scc_ "CodeOutput"
247 let (fe_binders, h_code, c_code) = foreign_stuff
248 (maybe_stub_h_name, maybe_stub_c_name)
249 <- codeOutput this_mod local_tycons local_classes
250 occ_anal_tidy_binds stg_binds2
251 c_code h_code abstractC ncg_uniqs
253 return (maybe_stub_h_name, maybe_stub_c_name, Nothing)
255 local_tycons = tcEnvTyCons tc_env
256 local_classes = tcEnvClasses tc_env
259 dsThenSimplThenTidy dflags mod tc_result
260 -- make up ds_uniqs here
261 = do -------------------------- Desugaring ----------------
263 (desugared, rules, h_code, c_code, fe_binders)
264 <- deSugar this_mod ds_uniqs tc_result
266 -------------------------- Main Core-language transformations ----------------
268 (simplified, orphan_rules) <- core2core core_cmds desugared rules
270 -- Do the final tidy-up
271 (tidy_binds, tidy_orphan_rules)
272 <- tidyCorePgm this_mod simplified orphan_rules
274 return (tidy_binds, tidy_orphan_rules, (fe_binders,h_code,c_code))
277 myCoreToStg c2s_uniqs st_uniqs this_mod tidy_binds
278 = do let occ_anal_tidy_binds = occurAnalyseBinds tidy_binds
280 () <- coreBindsSize occ_anal_tidy_binds `seq` return ()
281 -- TEMP: the above call zaps some space usage allocated by the
282 -- simplifier, which for reasons I don't understand, persists
283 -- thoroughout code generation
287 let stg_binds = topCoreBindsToStg c2s_uniqs occ_anal_tidy_binds
291 (stg_binds2, cost_centre_info) <- stg2stg stg_cmds this_mod st_uniqs stg_binds
292 let final_ids = collectFinalStgBinders (map fst stg_binds2)
294 return (stg_binds2, cost_centre_info, final_ids)
298 -------------------------- Reader ----------------
299 show_pass "Parser" >>
302 let src_filename -- name of the preprocessed source file
303 = case ms_ppsource summary of
304 Just (filename, fingerprint) -> filename
305 Nothing -> pprPanic "hscMain:summary is not of a source module"
308 buf <- hGetStringBuffer True{-expand tabs-} src_filename
310 let glaexts | dopt Opt_GlasgowExts dflags = 1#
313 case parse buf PState{ bol = 0#, atbol = 1#,
314 context = [], glasgow_exts = glaexts,
315 loc = mkSrcLoc src_filename 1 } of {
317 PFailed err -> return (HscErrs pcs (unitBag err) emptyBag)
319 POk _ rdr_module@(HsModule mod_name _ _ _ _ _ _) ->
321 dumpIfSet (dopt_D_dump_parsed flags) "Parser" (ppr rdr_module) >>
323 dumpIfSet (dopt_D_source_stats flags) "Source Statistics"
324 (ppSourceStats False rdr_module) >>
326 -- UniqueSupplies for later use (these are the only lower case uniques)
327 mkSplitUniqSupply 'd' >>= \ ds_uniqs -> -- desugarer
328 mkSplitUniqSupply 'r' >>= \ ru_uniqs -> -- rules
329 mkSplitUniqSupply 'c' >>= \ c2s_uniqs -> -- core-to-stg
330 mkSplitUniqSupply 'g' >>= \ st_uniqs -> -- stg-to-stg passes
331 mkSplitUniqSupply 'n' >>= \ ncg_uniqs -> -- native-code generator
333 -------------------------- Rename ----------------
334 show_pass "Renamer" >>
337 renameModule dflags finder pcs hst rdr_module
338 >>= \ (pcs_rn, maybe_rn_stuff) ->
339 case maybe_rn_stuff of {
340 Nothing -> -- Hurrah! Renamer reckons that there's no need to
342 reportCompile mod_name "Compilation NOT required!" >>
345 Just (this_mod, rn_mod,
346 old_iface, new_iface,
347 rn_name_supply, fixity_env,
349 -- Oh well, we've got to recompile for real
352 -------------------------- Typechecking ----------------
353 show_pass "TypeCheck" >>
355 typecheckModule dflags mod pcs hst hit pit rn_mod
356 -- tc_uniqs rn_name_supply
358 >>= \ maybe_tc_stuff ->
359 case maybe_tc_stuff of {
360 Nothing -> ghcExit 1; -- Type checker failed
362 Just (tc_results@(TcResults {tc_tycons = local_tycons,
363 tc_classes = local_classes,
364 tc_insts = inst_info })) ->
367 -------------------------- Desugaring ----------------
369 deSugar this_mod ds_uniqs tc_results >>= \ (desugared, rules, h_code, c_code, fe_binders) ->
372 -------------------------- Main Core-language transformations ----------------
374 core2core core_cmds desugared rules >>= \ (simplified, orphan_rules) ->
376 -- Do the final tidy-up
378 simplified orphan_rules >>= \ (tidy_binds, tidy_orphan_rules) ->
380 -- Run the occurrence analyser one last time, so that
381 -- dead binders get dead-binder info. This is exploited by
382 -- code generators to avoid spitting out redundant bindings.
383 -- The occurrence-zapping in Simplify.simplCaseBinder means
384 -- that the Simplifier nukes useful dead-var stuff especially
386 let occ_anal_tidy_binds = occurAnalyseBinds tidy_binds in
388 coreBindsSize occ_anal_tidy_binds `seq`
389 -- TEMP: the above call zaps some space usage allocated by the
390 -- simplifier, which for reasons I don't understand, persists
391 -- thoroughout code generation
395 -------------------------- Convert to STG code -------------------------------
396 show_pass "Core2Stg" >>
399 stg_binds = topCoreBindsToStg c2s_uniqs occ_anal_tidy_binds
402 -------------------------- Simplify STG code -------------------------------
403 show_pass "Stg2Stg" >>
405 stg2stg stg_cmds this_mod st_uniqs stg_binds >>= \ (stg_binds2, cost_centre_info) ->
408 runStgI local_tycons local_classes
409 (map fst stg_binds2) >>= \ i_result ->
410 putStr ("\nANSWER = " ++ show i_result ++ "\n\n")
414 -------------------------- Interface file -------------------------------
415 -- Dump instance decls and type signatures into the interface file
418 final_ids = collectFinalStgBinders (map fst stg_binds2)
420 writeIface this_mod old_iface new_iface
421 local_tycons local_classes inst_info
422 final_ids occ_anal_tidy_binds tidy_orphan_rules >>
425 -------------------------- Code generation -------------------------------
426 show_pass "CodeGen" >>
428 codeGen this_mod imported_modules
431 local_tycons local_classes
432 stg_binds2 >>= \ abstractC ->
435 -------------------------- Code output -------------------------------
436 show_pass "CodeOutput" >>
438 codeOutput this_mod local_tycons local_classes
439 occ_anal_tidy_binds stg_binds2
440 c_code h_code abstractC
444 -------------------------- Final report -------------------------------
445 reportCompile mod_name (showSDoc (ppSourceStats True rdr_module)) >>
453 -------------------------------------------------------------
454 -- ****** help functions:
457 = if opt_D_show_passes
458 then \ what -> hPutStr stderr ("*** "++what++":\n")
459 else \ what -> return ()
465 %************************************************************************
467 \subsection{Initial persistent state}
469 %************************************************************************
472 initPersistentCompilerState :: IO PersistentCompilerState
473 initPersistentCompilerState
475 = do prs <- initPersistentRenamerState
477 PCS { pcs_PST = initPackageDetails,
478 pcs_insts = emptyInstEnv,
479 pcs_rules = emptyRuleEnv,
480 pcs_PRS = initPersistentRenamerState
484 = PCS { pcs_PST = initPackageDetails,
485 pcs_insts = emptyInstEnv,
486 pcs_rules = initRules,
487 pcs_PRS = initPersistentRenamerState }
490 initPackageDetails :: PackageSymbolTable
491 initPackageDetails = extendTypeEnv emptyModuleEnv wiredInThings
493 initPersistentRenamerState :: IO PersistentRenamerState
494 = do ns <- mkSplitUniqSupply 'r'
496 PRS { prsOrig = Orig { origNames = initOrigNames,
497 origIParam = emptyFM },
498 prsDecls = emptyNameEnv,
505 initOrigNames :: FiniteMap (ModuleName,OccName) Name
506 initOrigNames = grab knownKeyNames `plusFM` grab (map getName wiredInThings)
508 grab names = foldl add emptyFM names
509 add env name = addToFM env (moduleName (nameModule name), nameOccName name) name
513 initRules = foldl add emptyVarEnv builtinRules
515 add env (name,rule) = extendNameEnv_C add1 env name [rule]
516 add1 rules _ = rule : rules
522 writeIface this_mod old_iface new_iface
523 local_tycons local_classes inst_info
524 final_ids tidy_binds tidy_orphan_rules
526 if isNothing opt_HiDir && isNothing opt_HiFile
527 then return () -- not producing any .hi file
531 hi_suf = case opt_HiSuf of { Nothing -> "hi"; Just suf -> suf }
532 filename = case opt_HiFile of {
536 Just dir -> dir ++ '/':moduleUserString this_mod
538 Nothing -> panic "writeIface"
542 do maybe_final_iface <- checkIface old_iface full_new_iface
543 case maybe_final_iface of {
544 Nothing -> when opt_D_dump_rn_trace $
545 putStrLn "Interface file unchanged" ; -- No need to update .hi file
549 do let mod_vers_unchanged = case old_iface of
550 Just iface -> pi_vers iface == pi_vers final_iface
552 when (mod_vers_unchanged && opt_D_dump_rn_trace) $
553 putStrLn "Module version unchanged, but usages differ; hence need new hi file"
555 if_hdl <- openFile filename WriteMode
556 printForIface if_hdl (pprIface final_iface)
560 full_new_iface = completeIface new_iface local_tycons local_classes
561 inst_info final_ids tidy_binds
566 %************************************************************************
568 \subsection{Printing the interface}
570 %************************************************************************
573 pprIface (ParsedIface { pi_mod = mod, pi_vers = mod_vers, pi_orphan = orphan,
574 pi_usages = usages, pi_exports = exports,
575 pi_fixity = (fix_vers, fixities),
576 pi_insts = insts, pi_decls = decls,
577 pi_rules = (rule_vers, rules), pi_deprecs = deprecs })
578 = vcat [ ptext SLIT("__interface")
579 <+> doubleQuotes (ptext opt_InPackage)
580 <+> ppr mod <+> ppr mod_vers <+> pp_sub_vers
581 <+> (if orphan then char '!' else empty)
582 <+> int opt_HiVersion
583 <+> ptext SLIT("where")
584 , vcat (map pprExport exports)
585 , vcat (map pprUsage usages)
586 , pprFixities fixities
587 , vcat [ppr i <+> semi | i <- insts]
588 , vcat [ppr_vers v <+> ppr d <> semi | (v,d) <- decls]
593 ppr_vers v | v == initialVersion = empty
596 | fix_vers == initialVersion && rule_vers == initialVersion = empty
597 | otherwise = brackets (ppr fix_vers <+> ppr rule_vers)
600 When printing export lists, we print like this:
602 AvailTC C [C, x, y] C(x,y)
603 AvailTC C [x, y] C!(x,y) -- Exporting x, y but not C
606 pprExport :: ExportItem -> SDoc
607 pprExport (mod, items)
608 = hsep [ ptext SLIT("__export "), ppr mod, hsep (map upp_avail items) ] <> semi
610 upp_avail :: RdrAvailInfo -> SDoc
611 upp_avail (Avail name) = pprOccName name
612 upp_avail (AvailTC name []) = empty
613 upp_avail (AvailTC name ns) = hcat [pprOccName name, bang, upp_export ns']
615 bang | name `elem` ns = empty
616 | otherwise = char '|'
617 ns' = filter (/= name) ns
619 upp_export [] = empty
620 upp_export names = braces (hsep (map pprOccName names))
625 pprUsage :: ImportVersion OccName -> SDoc
626 pprUsage (m, has_orphans, is_boot, whats_imported)
627 = hsep [ptext SLIT("import"), pprModuleName m,
629 upp_import_versions whats_imported
632 pp_orphan | has_orphans = char '!'
634 pp_boot | is_boot = char '@'
637 -- Importing the whole module is indicated by an empty list
638 upp_import_versions NothingAtAll = empty
639 upp_import_versions (Everything v) = dcolon <+> int v
640 upp_import_versions (Specifically vm vf vr nvs)
641 = dcolon <+> int vm <+> int vf <+> int vr <+> hsep [ ppr n <+> int v | (n,v) <- nvs ]
646 pprFixities [] = empty
647 pprFixities fixes = hsep (map ppr fixes) <> semi
650 pprRules rules = hsep [ptext SLIT("{-## __R"), hsep (map ppr rules), ptext SLIT("##-}")]
652 pprDeprecs [] = empty
653 pprDeprecs deps = hsep [ ptext SLIT("{-## __D"), guts, ptext SLIT("##-}")]
655 guts = hsep [ ppr ie <+> doubleQuotes (ppr txt) <> semi
656 | Deprecation ie txt _ <- deps ]