[project @ 2000-10-25 16:44:28 by sewardj]
[ghc-hetmet.git] / ghc / compiler / main / HscMain.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1993-2000
3 %
4 \section[GHC_Main]{Main driver for Glasgow Haskell compiler}
5
6 \begin{code}
7 module HscMain ( hscMain ) where
8
9 #include "HsVersions.h"
10
11 import Monad            ( when )
12 import IO               ( hPutStr, hClose, stderr, openFile, IOMode(..) )
13 import HsSyn
14
15 import RdrHsSyn         ( RdrNameHsModule )
16 import FastString       ( unpackFS )
17 import StringBuffer     ( hGetStringBuffer )
18 import Parser           ( parse )
19 import Lex              ( PState(..), ParseResult(..) )
20 import SrcLoc           ( mkSrcLoc )
21
22 import Rename           ( renameModule, checkOldIface )
23
24 import PrelInfo         ( wiredInThings )
25 import PrelRules        ( builtinRules )
26 import MkIface          ( completeIface, mkModDetailsFromIface )
27 import TcModule         ( TcResults(..), typecheckModule )
28 import Desugar          ( deSugar )
29 import SimplCore        ( core2core )
30 import OccurAnal        ( occurAnalyseBinds )
31 import CoreUtils        ( coreBindsSize )
32 import CoreTidy         ( tidyCorePgm )
33 import CoreToStg        ( topCoreBindsToStg )
34 import StgSyn           ( collectFinalStgBinders )
35 import SimplStg         ( stg2stg )
36 import CodeGen          ( codeGen )
37 import CodeOutput       ( codeOutput )
38
39 import Module           ( ModuleName, moduleNameUserString, 
40                           moduleUserString, moduleName )
41 import CmdLineOpts
42 import ErrUtils         ( ghcExit, doIfSet, dumpIfSet )
43 import UniqSupply       ( mkSplitUniqSupply )
44
45 import Bag              ( emptyBag )
46 import Outputable
47 import Char             ( isSpace )
48 import StgInterp        ( stgToInterpSyn )
49 import HscStats         ( ppSourceStats )
50 import HscTypes         ( ModDetails, ModIface, PersistentCompilerState(..),
51                           PersistentRenamerState(..), WhatsImported(..),
52                           HomeSymbolTable, PackageSymbolTable, ImportVersion, 
53                           GenAvailInfo(..), RdrAvailInfo, OrigNameEnv(..),
54                           PackageRuleBase )
55 import RnMonad          ( ExportItem, ParsedIface(..) )
56 import CmSummarise      ( ModSummary )
57 import InterpSyn        ( UnlinkedIBind )
58 import StgInterp        ( ItblEnv )
59 import FiniteMap        ( FiniteMap, plusFM, emptyFM, addToFM )
60 import OccName          ( OccName, pprOccName )
61 import Name             ( Name, nameModule )
62 \end{code}
63
64
65 %************************************************************************
66 %*                                                                      *
67 \subsection{The main compiler pipeline}
68 %*                                                                      *
69 %************************************************************************
70
71 \begin{code}
72 data HscResult
73    = HscOK   ModDetails              -- new details (HomeSymbolTable additions)
74              (Maybe ModIface)        -- new iface (if any compilation was done)
75              (Maybe String)          -- generated stub_h filename (in /tmp)
76              (Maybe String)          -- generated stub_c filename (in /tmp)
77              (Maybe ([UnlinkedIBind],ItblEnv)) -- interpreted code, if any
78              PersistentCompilerState -- updated PCS
79
80    | HscFail PersistentCompilerState -- updated PCS
81         -- no errors or warnings; the individual passes
82         -- (parse/rename/typecheck) print messages themselves
83
84 hscMain
85   :: DynFlags   
86   -> ModSummary       -- summary, including source filename
87   -> Maybe ModIface   -- old interface, if available
88   -> String           -- file in which to put the output (.s, .hc, .java etc.)
89   -> HomeSymbolTable            -- for home module ModDetails
90   -> PersistentCompilerState    -- IN: persistent compiler state
91   -> IO HscResult
92
93 hscMain dflags core_cmds stg_cmds summary maybe_old_iface
94         output_filename mod_details pcs
95  = do {
96       -- ????? source_unchanged :: Bool -- extracted from summary?
97
98       (ch_pcs, check_errs, (recomp_reqd, maybe_checked_iface))
99          <- checkOldIface dflags finder hit hst pcs mod source_unchanged
100                           maybe_old_iface;
101       if check_errs then
102          return (HscFail ch_pcs)
103       else do {
104
105       let no_old_iface = not (isJust maybe_checked_iface)
106           what_next | recomp_reqd || no_old_iface = hscRecomp 
107                     | otherwise                   = hscNoRecomp
108       ;
109       return (what_next dflags core_cmds stg_cmds summary hit hst 
110                         pcs2 maybe_checked_iface)
111       }}
112
113
114 hscNoRecomp dflags core_cmds stg_cmds summary hit hst pcs maybe_old_iface
115  = do {
116       -- we definitely expect to have the old interface available
117       let old_iface = case maybe_old_iface of 
118                          Just old_if -> old_if
119                          Nothing -> panic "hscNoRecomp:old_iface"
120       ;
121       -- CLOSURE
122       (pcs_cl, closure_errs, cl_hs_decls) 
123          <- closeIfaceDecls dflags finder hit hst pcs old_iface ;
124       if closure_errs then 
125          return (HscFail cl_pcs) 
126       else do {
127
128       -- TYPECHECK
129       maybe_tc_result
130          <- typecheckModule dflags mod pcs_cl hst hit pit cl_hs_decls;
131       case maybe_tc_result of {
132          Nothing -> return (HscFail cl_pcs);
133          Just tc_result -> do {
134
135       let pcs_tc        = tc_pcs tc_result
136           env_tc        = tc_env tc_result
137           binds_tc      = tc_binds tc_result
138           local_tycons  = tc_tycons tc_result
139           local_classes = tc_classes tc_result
140           local_insts   = tc_insts tc_result
141           local_rules   = tc_rules tc_result
142       ;
143       -- create a new details from the closed, typechecked, old iface
144       let new_details = mkModDetailsFromIface env_tc local_insts local_rules
145       ;
146       return (HscOK final_details
147                     Nothing -- tells CM to use old iface and linkables
148                     Nothing Nothing -- foreign export stuff
149                     Nothing -- ibinds
150                     pcs_tc)
151       }}}}
152
153
154 hscRecomp dflags core_cmds stg_cmds summary hit hst pcs maybe_old_iface
155  = do {
156       -- what target are we shooting for?
157       let toInterp = dopt_HscLang dflags == HscInterpreted
158       ;
159       -- PARSE
160       maybe_parsed <- myParseModule dflags summary;
161       case maybe_parsed of {
162          Nothing -> return (HscFail pcs);
163          Just rdr_module -> do {
164
165       -- RENAME
166       (pcs_rn, maybe_rn_result) 
167          <- renameModule dflags finder hit hst pcs mod rdr_module;
168       case maybe_rn_result of {
169          Nothing -> return (HscFail pcs_rn);
170          Just (new_iface, rn_hs_decls) -> do {
171
172       -- TYPECHECK
173       maybe_tc_result
174          <- typecheckModule dflags mod pcs_rn hst hit pit rn_hs_decls;
175       case maybe_tc_result of {
176          Nothing -> return (HscFail pcs_rn);
177          Just tc_result -> do {
178
179       let pcs_tc        = tc_pcs tc_result
180           env_tc        = tc_env tc_result
181           binds_tc      = tc_binds tc_result
182           local_tycons  = tc_tycons tc_result
183           local_classes = tc_classes tc_result
184           local_insts   = tc_insts tc_result
185       ;
186       -- DESUGAR, SIMPLIFY, TIDY-CORE
187       -- We grab the the unfoldings at this point.
188       (tidy_binds, orphan_rules, foreign_stuff)
189          <- dsThenSimplThenTidy dflags mod tc_result ds_uniqs
190       ;
191       -- CONVERT TO STG
192       (stg_binds, cost_centre_info, top_level_ids) 
193          <- myCoreToStg c2s_uniqs st_uniqs this_mod tidy_binds
194       ;
195       -- cook up a new ModDetails now we (finally) have all the bits
196       let new_details = mkModDetails tc_env local_insts tidy_binds 
197                                      top_level_ids orphan_rules
198       ;
199       -- and possibly create a new ModIface
200       let maybe_final_iface = completeIface maybe_old_iface new_iface new_details 
201       ;
202       -- do the rest of code generation/emission
203       (maybe_ibinds, maybe_stub_h_filename, maybe_stub_c_filename) 
204          <- restOfCodeGeneration toInterp
205                                  this_mod imported_modules cost_centre_info 
206                                  fe_binders tc_env stg_binds
207       ;
208       -- and the answer is ...
209       return (HscOK new_details maybe_final_iface 
210                     maybe_stub_h_filename maybe_stub_c_filename
211                     maybe_ibinds pcs_tc)
212       }}}}}}}
213
214
215 myParseModule dflags summary
216  = do --------------------------  Reader  ----------------
217       show_pass "Parser"
218       -- _scc_     "Parser"
219
220       let src_filename -- name of the preprocessed source file
221             = case ms_ppsource summary of
222                  Just (filename, fingerprint) -> filename
223                  Nothing -> pprPanic 
224                                "myParseModule:summary is not of a source module"
225                                (ppr summary)
226
227       buf <- hGetStringBuffer True{-expand tabs-} src_filename
228
229       let glaexts | dopt Opt_GlasgowExts dflags = 1#
230                   | otherwise                 = 0#
231
232       case parse buf PState{ bol = 0#, atbol = 1#,
233                              context = [], glasgow_exts = glaexts,
234                              loc = mkSrcLoc src_filename 1 } of {
235
236         PFailed err -> do { hPutStrLn stderr (showSDoc err);
237                             return Nothing };
238         POk _ rdr_module@(HsModule mod_name _ _ _ _ _ _) ->
239
240       dumpIfSet_dyn dflags Opt_D_dump_parsed "Parser" (ppr rdr_module)
241       dumpIfSet_dyn dflags Opt_D_source_stats "Source Statistics"
242                            (ppSourceStats False rdr_module)
243
244       return (Just rdr_module)
245       }
246
247
248 restOfCodeGeneration toInterp this_mod imported_modules cost_centre_info 
249                      foreign_stuff tc_env stg_binds
250  | toInterp
251  = return (Nothing, Nothing, 
252            Just (stgToInterpSyn stg_binds local_tycons local_classes))
253  | otherwise
254  = do --------------------------  Code generation -------------------------------
255       show_pass "CodeGen"
256       -- _scc_     "CodeGen"
257       abstractC <- codeGen this_mod imported_modules
258                            cost_centre_info fe_binders
259                            local_tycons local_classes stg_binds
260
261       --------------------------  Code output -------------------------------
262       show_pass "CodeOutput"
263       -- _scc_     "CodeOutput"
264       let (fe_binders, h_code, c_code) = foreign_stuff
265       (maybe_stub_h_name, maybe_stub_c_name)
266          <- codeOutput this_mod local_tycons local_classes
267                        occ_anal_tidy_binds stg_binds2
268                        c_code h_code abstractC ncg_uniqs
269
270       return (maybe_stub_h_name, maybe_stub_c_name, Nothing)
271  where
272     local_tycons  = tcEnvTyCons tc_env
273     local_classes = tcEnvClasses tc_env
274
275
276 dsThenSimplThenTidy dflags mod tc_result
277 -- make up ds_uniqs here
278  = do --------------------------  Desugaring ----------------
279       -- _scc_     "DeSugar"
280       (desugared, rules, h_code, c_code, fe_binders) 
281          <- deSugar this_mod ds_uniqs tc_result
282
283       --------------------------  Main Core-language transformations ----------------
284       -- _scc_     "Core2Core"
285       (simplified, orphan_rules)  <- core2core core_cmds desugared rules
286
287       -- Do the final tidy-up
288       (tidy_binds, tidy_orphan_rules) 
289          <- tidyCorePgm this_mod simplified orphan_rules
290       
291       return (tidy_binds, tidy_orphan_rules, (fe_binders,h_code,c_code))
292
293
294 myCoreToStg c2s_uniqs st_uniqs this_mod tidy_binds
295  = do let occ_anal_tidy_binds = occurAnalyseBinds tidy_binds
296
297       () <- coreBindsSize occ_anal_tidy_binds `seq` return ()
298       -- TEMP: the above call zaps some space usage allocated by the
299       -- simplifier, which for reasons I don't understand, persists
300       -- thoroughout code generation
301
302       show_pass "Core2Stg"
303       -- _scc_     "Core2Stg"
304       let stg_binds   = topCoreBindsToStg c2s_uniqs occ_anal_tidy_binds
305
306       show_pass "Stg2Stg"
307       -- _scc_     "Stg2Stg"
308       (stg_binds2, cost_centre_info) <- stg2stg stg_cmds this_mod st_uniqs stg_binds
309       let final_ids = collectFinalStgBinders (map fst stg_binds2)
310
311       return (stg_binds2, cost_centre_info, final_ids)
312
313 #if 0
314 -- BEGIN old stuff
315     -- UniqueSupplies for later use (these are the only lower case uniques)
316     mkSplitUniqSupply 'd'       >>= \ ds_uniqs  -> -- desugarer
317     mkSplitUniqSupply 'r'       >>= \ ru_uniqs  -> -- rules
318     mkSplitUniqSupply 'c'       >>= \ c2s_uniqs -> -- core-to-stg
319     mkSplitUniqSupply 'g'       >>= \ st_uniqs  -> -- stg-to-stg passes
320     mkSplitUniqSupply 'n'       >>= \ ncg_uniqs -> -- native-code generator
321
322         --------------------------  Interface file -------------------------------
323         -- Dump instance decls and type signatures into the interface file
324     _scc_     "Interface"
325     let
326         final_ids = collectFinalStgBinders (map fst stg_binds2)
327     in
328     writeIface this_mod old_iface new_iface
329                local_tycons local_classes inst_info
330                final_ids occ_anal_tidy_binds tidy_orphan_rules          >>
331
332
333         --------------------------  Code generation -------------------------------
334     show_pass "CodeGen"                         >>
335     _scc_     "CodeGen"
336     codeGen this_mod imported_modules
337             cost_centre_info
338             fe_binders
339             local_tycons local_classes 
340             stg_binds2                          >>= \ abstractC ->
341
342
343         --------------------------  Code output -------------------------------
344     show_pass "CodeOutput"                              >>
345     _scc_     "CodeOutput"
346     codeOutput this_mod local_tycons local_classes
347                occ_anal_tidy_binds stg_binds2
348                c_code h_code abstractC 
349                ncg_uniqs                                >>
350
351
352         --------------------------  Final report -------------------------------
353     reportCompile mod_name (showSDoc (ppSourceStats True rdr_module)) >>
354
355     ghcExit 0
356     } }
357   where
358     -------------------------------------------------------------
359     -- ****** help functions:
360
361     show_pass
362       = if opt_D_show_passes
363         then \ what -> hPutStr stderr ("*** "++what++":\n")
364         else \ what -> return ()
365 -- END old stuff
366 #endif
367 \end{code}
368
369
370 %************************************************************************
371 %*                                                                      *
372 \subsection{Initial persistent state}
373 %*                                                                      *
374 %************************************************************************
375
376 \begin{code}
377 initPersistentCompilerState :: IO PersistentCompilerState
378 initPersistentCompilerState 
379   = do prs <- initPersistentRenamerState
380        return (
381         PCS { pcs_PST   = initPackageDetails,
382               pcs_insts = emptyInstEnv,
383               pcs_rules = emptyRuleEnv,
384               pcs_PRS   = prs
385             }
386         )
387
388 initPackageDetails :: PackageSymbolTable
389 initPackageDetails = extendTypeEnv emptyModuleEnv wiredInThings
390
391 initPersistentRenamerState :: IO PersistentRenamerState
392   = do ns <- mkSplitUniqSupply 'r'
393        return (
394         PRS { prsOrig  = Orig { origNames  = initOrigNames,
395                                 origIParam = emptyFM },
396               prsDecls = emptyNameEnv,
397               prsInsts = emptyBag,
398               prsRules = emptyBag,
399               prsNS    = ns
400             }
401         )
402
403 initOrigNames :: FiniteMap (ModuleName,OccName) Name
404 initOrigNames = grab knownKeyNames `plusFM` grab (map getName wiredInThings)
405               where
406                 grab names   = foldl add emptyFM names
407                 add env name = addToFM env (moduleName (nameModule name), nameOccName name) name
408
409
410 initRules :: PackageRuleBase
411 initRules = foldl add emptyVarEnv builtinRules
412           where
413             add env (name,rule) = extendNameEnv_C add1 env name [rule]
414             add1 rules _        = rule : rules
415 \end{code}
416
417
418
419 \begin{code}
420 writeIface this_mod old_iface new_iface
421            local_tycons local_classes inst_info
422            final_ids tidy_binds tidy_orphan_rules
423   = 
424     if isNothing opt_HiDir && isNothing opt_HiFile
425         then return ()  -- not producing any .hi file
426         else 
427
428     let 
429         hi_suf = case opt_HiSuf of { Nothing -> "hi"; Just suf -> suf }
430         filename = case opt_HiFile of {
431                         Just f  -> f;
432                         Nothing -> 
433                    case opt_HiDir of {
434                         Just dir -> dir ++ '/':moduleUserString this_mod 
435                                         ++ '.':hi_suf;
436                         Nothing  -> panic "writeIface"
437                 }}
438     in
439
440     do maybe_final_iface <- checkIface old_iface full_new_iface         
441        case maybe_final_iface of {
442           Nothing -> when opt_D_dump_rn_trace $
443                      putStrLn "Interface file unchanged" ;  -- No need to update .hi file
444
445           Just final_iface ->
446
447        do  let mod_vers_unchanged = case old_iface of
448                                       Just iface -> pi_vers iface == pi_vers final_iface
449                                       Nothing -> False
450            when (mod_vers_unchanged && opt_D_dump_rn_trace) $
451                 putStrLn "Module version unchanged, but usages differ; hence need new hi file"
452
453            if_hdl <- openFile filename WriteMode
454            printForIface if_hdl (pprIface final_iface)
455            hClose if_hdl
456     }   
457   where
458     full_new_iface = completeIface new_iface local_tycons local_classes
459                                              inst_info final_ids tidy_binds
460                                              tidy_orphan_rules
461     isNothing = not . isJust
462 \end{code}
463
464
465 %************************************************************************
466 %*                                                                      *
467 \subsection{Printing the interface}
468 %*                                                                      *
469 %************************************************************************
470
471 \begin{code}
472 pprIface (ParsedIface { pi_mod = mod, pi_vers = mod_vers, pi_orphan = orphan,
473                         pi_usages = usages, pi_exports = exports, 
474                         pi_fixity = (fix_vers, fixities),
475                         pi_insts = insts, pi_decls = decls, 
476                         pi_rules = (rule_vers, rules), pi_deprecs = deprecs })
477  = vcat [ ptext SLIT("__interface")
478                 <+> doubleQuotes (ptext opt_InPackage)
479                 <+> ppr mod <+> ppr mod_vers <+> pp_sub_vers
480                 <+> (if orphan then char '!' else empty)
481                 <+> int opt_HiVersion
482                 <+> ptext SLIT("where")
483         , vcat (map pprExport exports)
484         , vcat (map pprUsage usages)
485         , pprFixities fixities
486         , vcat [ppr i <+> semi | i <- insts]
487         , vcat [ppr_vers v <+> ppr d <> semi | (v,d) <- decls]
488         , pprRules rules
489         , pprDeprecs deprecs
490         ]
491   where
492     ppr_vers v | v == initialVersion = empty
493                | otherwise           = int v
494     pp_sub_vers 
495         | fix_vers == initialVersion && rule_vers == initialVersion = empty
496         | otherwise = brackets (ppr fix_vers <+> ppr rule_vers)
497 \end{code}
498
499 When printing export lists, we print like this:
500         Avail   f               f
501         AvailTC C [C, x, y]     C(x,y)
502         AvailTC C [x, y]        C!(x,y)         -- Exporting x, y but not C
503
504 \begin{code}
505 pprExport :: ExportItem -> SDoc
506 pprExport (mod, items)
507  = hsep [ ptext SLIT("__export "), ppr mod, hsep (map upp_avail items) ] <> semi
508   where
509     upp_avail :: RdrAvailInfo -> SDoc
510     upp_avail (Avail name)      = pprOccName name
511     upp_avail (AvailTC name []) = empty
512     upp_avail (AvailTC name ns) = hcat [pprOccName name, bang, upp_export ns']
513                                 where
514                                   bang | name `elem` ns = empty
515                                        | otherwise      = char '|'
516                                   ns' = filter (/= name) ns
517     
518     upp_export []    = empty
519     upp_export names = braces (hsep (map pprOccName names))
520 \end{code}
521
522
523 \begin{code}
524 pprUsage :: ImportVersion OccName -> SDoc
525 pprUsage (m, has_orphans, is_boot, whats_imported)
526   = hsep [ptext SLIT("import"), ppr (moduleName m), 
527           pp_orphan, pp_boot,
528           upp_import_versions whats_imported
529     ] <> semi
530   where
531     pp_orphan | has_orphans = char '!'
532               | otherwise   = empty
533     pp_boot   | is_boot     = char '@'
534               | otherwise   = empty
535
536         -- Importing the whole module is indicated by an empty list
537     upp_import_versions NothingAtAll   = empty
538     upp_import_versions (Everything v) = dcolon <+> int v
539     upp_import_versions (Specifically vm vf vr nvs)
540       = dcolon <+> int vm <+> int vf <+> int vr <+> hsep [ ppr n <+> int v | (n,v) <- nvs ]
541 \end{code}
542
543
544 \begin{code}
545 pprFixities []    = empty
546 pprFixities fixes = hsep (map ppr fixes) <> semi
547
548 pprRules []    = empty
549 pprRules rules = hsep [ptext SLIT("{-## __R"), hsep (map ppr rules), ptext SLIT("##-}")]
550
551 pprDeprecs []   = empty
552 pprDeprecs deps = hsep [ ptext SLIT("{-## __D"), guts, ptext SLIT("##-}")]
553                 where
554                   guts = hsep [ ppr ie <+> doubleQuotes (ppr txt) <> semi 
555                               | Deprecation ie txt _ <- deps ]
556 \end{code}
557
558