[project @ 2000-10-27 11:48:54 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 ( HscResult(..), hscMain, 
8                  initPersistentCompilerState ) where
9
10 #include "HsVersions.h"
11
12 import Maybe            ( isJust )
13 import Monad            ( when )
14 import IO               ( hPutStr, hPutStrLn, hClose, stderr, 
15                           openFile, IOMode(..) )
16 import HsSyn
17
18 import RdrHsSyn         ( RdrNameHsModule )
19 import FastString       ( unpackFS )
20 import StringBuffer     ( hGetStringBuffer )
21 import Parser           ( parse )
22 import Lex              ( PState(..), ParseResult(..) )
23 import SrcLoc           ( mkSrcLoc )
24
25 import Rename           ( renameModule, checkOldIface, closeIfaceDecls )
26
27 import Rules            ( emptyRuleBase )
28 import PrelInfo         ( wiredInThings )
29 import PrelNames        ( knownKeyNames )
30 import PrelRules        ( builtinRules )
31 import MkIface          ( completeIface, mkModDetailsFromIface, mkModDetails,
32                           writeIface )
33 import TcModule         ( TcResults(..), typecheckModule )
34 import TcEnv            ( tcEnvTyCons, tcEnvClasses )
35 import InstEnv          ( emptyInstEnv )
36 import Desugar          ( deSugar )
37 import SimplCore        ( core2core )
38 import OccurAnal        ( occurAnalyseBinds )
39 import CoreUtils        ( coreBindsSize )
40 import CoreTidy         ( tidyCorePgm )
41 import CoreToStg        ( topCoreBindsToStg )
42 import StgSyn           ( collectFinalStgBinders )
43 import SimplStg         ( stg2stg )
44 import CodeGen          ( codeGen )
45 import CodeOutput       ( codeOutput )
46
47 import Module           ( ModuleName, moduleNameUserString, 
48                           moduleUserString, moduleName, emptyModuleEnv,
49                           extendModuleEnv )
50 import CmdLineOpts
51 import ErrUtils         ( ghcExit, doIfSet, dumpIfSet_dyn )
52 import UniqSupply       ( mkSplitUniqSupply )
53
54 import Bag              ( emptyBag )
55 import Outputable
56 import Char             ( isSpace )
57 import StgInterp        ( stgToInterpSyn )
58 import HscStats         ( ppSourceStats )
59 import HscTypes         ( ModDetails, ModIface(..), PersistentCompilerState(..),
60                           PersistentRenamerState(..), WhatsImported(..),
61                           HomeSymbolTable, PackageSymbolTable, ImportVersion, 
62                           GenAvailInfo(..), RdrAvailInfo, OrigNameEnv(..),
63                           PackageRuleBase, HomeIfaceTable, PackageIfaceTable,
64                           extendTypeEnv, groupTyThings, TypeEnv, TyThing,
65                           typeEnvClasses, typeEnvTyCons )
66 import RnMonad          ( ExportItem, ParsedIface(..) )
67 import CmSummarise      ( ModSummary(..), name_of_summary, ms_get_imports,
68                           mimp_name )
69 import InterpSyn        ( UnlinkedIBind )
70 import StgInterp        ( ItblEnv )
71 import FiniteMap        ( FiniteMap, plusFM, emptyFM, addToFM )
72 import OccName          ( OccName, pprOccName )
73 import Name             ( Name, nameModule, emptyNameEnv, nameOccName, 
74                           getName, extendNameEnv_C, nameEnvElts )
75 import VarEnv           ( emptyVarEnv )
76 import Module           ( Module, mkModuleName, lookupModuleEnvByName )
77
78 \end{code}
79
80
81 %************************************************************************
82 %*                                                                      *
83 \subsection{The main compiler pipeline}
84 %*                                                                      *
85 %************************************************************************
86
87 \begin{code}
88 data HscResult
89    = HscOK   ModDetails              -- new details (HomeSymbolTable additions)
90              (Maybe ModIface)        -- new iface (if any compilation was done)
91              (Maybe String)          -- generated stub_h filename (in /tmp)
92              (Maybe String)          -- generated stub_c filename (in /tmp)
93              (Maybe ([UnlinkedIBind],ItblEnv)) -- interpreted code, if any
94              PersistentCompilerState -- updated PCS
95
96    | HscFail PersistentCompilerState -- updated PCS
97         -- no errors or warnings; the individual passes
98         -- (parse/rename/typecheck) print messages themselves
99
100 hscMain
101   :: DynFlags
102   -> ModSummary       -- summary, including source filename
103   -> Maybe ModIface   -- old interface, if available
104   -> HomeSymbolTable            -- for home module ModDetails
105   -> HomeIfaceTable
106   -> PersistentCompilerState    -- IN: persistent compiler state
107   -> IO HscResult
108
109 hscMain dflags summary maybe_old_iface hst hit pcs
110  = do {
111       -- ????? source_unchanged :: Bool -- extracted from summary?
112       let source_unchanged = trace "WARNING: source_unchanged?!" False
113       ;
114       (pcs_ch, check_errs, (recomp_reqd, maybe_checked_iface))
115          <- checkOldIface dflags hit hst pcs (ms_mod summary)
116                           source_unchanged maybe_old_iface;
117       if check_errs then
118          return (HscFail pcs_ch)
119       else do {
120
121       let no_old_iface = not (isJust maybe_checked_iface)
122           what_next | recomp_reqd || no_old_iface = hscRecomp 
123                     | otherwise                   = hscNoRecomp
124       ;
125       what_next dflags summary maybe_checked_iface
126                 hst hit pcs_ch
127       }}
128
129
130 hscNoRecomp dflags summary maybe_checked_iface hst hit pcs_ch
131  = do {
132       -- we definitely expect to have the old interface available
133       let old_iface = case maybe_checked_iface of 
134                          Just old_if -> old_if
135                          Nothing -> panic "hscNoRecomp:old_iface"
136       ;
137       -- CLOSURE
138       (pcs_cl, closure_errs, cl_hs_decls) 
139          <- closeIfaceDecls dflags hit hst pcs_ch old_iface ;
140       if closure_errs then 
141          return (HscFail pcs_cl) 
142       else do {
143
144       -- TYPECHECK
145       maybe_tc_result
146          <- typecheckModule dflags (ms_mod summary) pcs_cl hst hit cl_hs_decls;
147       case maybe_tc_result of {
148          Nothing -> return (HscFail pcs_cl);
149          Just tc_result -> do {
150
151       let pcs_tc        = tc_pcs tc_result
152           env_tc        = tc_env tc_result
153           binds_tc      = tc_binds tc_result
154           local_insts   = tc_insts tc_result
155           local_rules   = tc_rules tc_result
156       ;
157       -- create a new details from the closed, typechecked, old iface
158       let new_details = mkModDetailsFromIface env_tc local_insts local_rules
159       ;
160       return (HscOK new_details
161                     Nothing -- tells CM to use old iface and linkables
162                     Nothing Nothing -- foreign export stuff
163                     Nothing -- ibinds
164                     pcs_tc)
165       }}}}
166
167
168 hscRecomp dflags summary maybe_checked_iface hst hit pcs_ch
169  = do {
170       -- what target are we shooting for?
171       let toInterp = dopt_HscLang dflags == HscInterpreted
172           this_mod = ms_mod summary
173       ;
174       -- PARSE
175       maybe_parsed <- myParseModule dflags summary;
176       case maybe_parsed of {
177          Nothing -> return (HscFail pcs_ch);
178          Just rdr_module -> do {
179
180       -- RENAME
181       show_pass dflags "Renamer";
182       (pcs_rn, maybe_rn_result) 
183          <- renameModule dflags hit hst pcs_ch this_mod rdr_module;
184       case maybe_rn_result of {
185          Nothing -> return (HscFail pcs_rn);
186          Just (new_iface, rn_hs_decls) -> do {
187
188       -- TYPECHECK
189       show_pass dflags "Typechecker";
190       maybe_tc_result
191          <- typecheckModule dflags this_mod pcs_rn hst hit rn_hs_decls;
192       case maybe_tc_result of {
193          Nothing -> return (HscFail pcs_rn);
194          Just tc_result -> do {
195
196       let pcs_tc        = tc_pcs tc_result
197           env_tc        = tc_env tc_result
198           binds_tc      = tc_binds tc_result
199           local_insts   = tc_insts tc_result
200       ;
201       -- DESUGAR, SIMPLIFY, TIDY-CORE
202       -- We grab the the unfoldings at this point.
203       (tidy_binds, orphan_rules, foreign_stuff)
204          <- dsThenSimplThenTidy dflags (pcs_rules pcs_tc) this_mod tc_result hst
205       ;
206       -- CONVERT TO STG
207       (stg_binds, oa_tidy_binds, cost_centre_info, top_level_ids) 
208          <- myCoreToStg dflags this_mod tidy_binds
209       ;
210       -- cook up a new ModDetails now we (finally) have all the bits
211       let new_details = mkModDetails env_tc local_insts tidy_binds 
212                                      top_level_ids orphan_rules
213       ;
214       -- and possibly create a new ModIface
215       let maybe_final_iface_and_sdoc 
216              = completeIface maybe_checked_iface new_iface new_details 
217           maybe_final_iface
218              = case maybe_final_iface_and_sdoc of 
219                   Just (fif, sdoc) -> Just fif; Nothing -> Nothing
220       ;
221       -- Write the interface file
222       writeIface maybe_final_iface
223       ;
224       -- do the rest of code generation/emission
225       (maybe_stub_h_filename, maybe_stub_c_filename, maybe_ibinds)
226          <- restOfCodeGeneration dflags toInterp summary
227                cost_centre_info foreign_stuff env_tc stg_binds oa_tidy_binds
228                hit (pcs_PIT pcs_tc)       
229       ;
230       -- and the answer is ...
231       return (HscOK new_details maybe_final_iface 
232                     maybe_stub_h_filename maybe_stub_c_filename
233                     maybe_ibinds pcs_tc)
234       }}}}}}}
235
236
237 myParseModule dflags summary
238  = do --------------------------  Parser  ----------------
239       show_pass dflags "Parser"
240       -- _scc_     "Parser"
241
242       let src_filename -- name of the preprocessed source file
243             = case ms_ppsource summary of
244                  Just (filename, fingerprint) -> filename
245                  Nothing -> pprPanic 
246                                "myParseModule:summary is not of a source module"
247                                (ppr summary)
248
249       buf <- hGetStringBuffer True{-expand tabs-} src_filename
250
251       let glaexts | dopt Opt_GlasgowExts dflags = 1#
252                   | otherwise                 = 0#
253
254       case parse buf PState{ bol = 0#, atbol = 1#,
255                              context = [], glasgow_exts = glaexts,
256                              loc = mkSrcLoc (_PK_ src_filename) 1 } of {
257
258         PFailed err -> do { hPutStrLn stderr (showSDoc err);
259                             return Nothing };
260         POk _ rdr_module@(HsModule mod_name _ _ _ _ _ _) -> do {
261
262       dumpIfSet_dyn dflags Opt_D_dump_parsed "Parser" (ppr rdr_module) ;
263       
264       dumpIfSet_dyn dflags Opt_D_source_stats "Source Statistics"
265                            (ppSourceStats False rdr_module) ;
266       
267       return (Just rdr_module)
268       }}
269
270
271 restOfCodeGeneration dflags toInterp summary cost_centre_info 
272                      foreign_stuff env_tc stg_binds oa_tidy_binds
273                      hit pit -- these last two for mapping ModNames to Modules
274  | toInterp
275  = do (ibinds,itbl_env) 
276          <- stgToInterpSyn (map fst stg_binds) local_tycons local_classes
277       return (Nothing, Nothing, Just (ibinds,itbl_env))
278  | otherwise
279  = do --------------------------  Code generation -------------------------------
280       show_pass dflags "CodeGen"
281       -- _scc_     "CodeGen"
282       abstractC <- codeGen dflags this_mod imported_modules
283                            cost_centre_info fe_binders
284                            local_tycons local_classes stg_binds
285
286       --------------------------  Code output -------------------------------
287       show_pass dflags "CodeOutput"
288       -- _scc_     "CodeOutput"
289       ncg_uniqs <- mkSplitUniqSupply 'n'
290       (maybe_stub_h_name, maybe_stub_c_name)
291          <- codeOutput dflags this_mod local_tycons local_classes
292                        oa_tidy_binds stg_binds
293                        c_code h_code abstractC ncg_uniqs
294
295       return (maybe_stub_h_name, maybe_stub_c_name, Nothing)
296  where
297     local_tycons     = typeEnvTyCons env_tc
298     local_classes    = typeEnvClasses env_tc
299     this_mod         = ms_mod summary
300     imported_modules = map (mod_name_to_Module.mimp_name) 
301                            (ms_get_imports summary)
302     (fe_binders,h_code,c_code) = foreign_stuff
303
304     mod_name_to_Module :: ModuleName -> Module
305     mod_name_to_Module nm
306        = let str_mi = case lookupModuleEnvByName hit nm of
307                           Just mi -> mi
308                           Nothing -> case lookupModuleEnvByName pit nm of
309                                         Just mi -> mi
310                                         Nothing -> barf nm
311          in  mi_module str_mi
312     barf nm = pprPanic "mod_name_to_Module: no hst or pst mapping for" 
313                        (ppr nm)
314
315
316 dsThenSimplThenTidy dflags rule_base this_mod tc_result hst
317  = do --------------------------  Desugaring ----------------
318       -- _scc_     "DeSugar"
319       show_pass dflags "DeSugar"
320       ds_uniqs <- mkSplitUniqSupply 'd'
321       (desugared, rules, h_code, c_code, fe_binders) 
322          <- deSugar dflags this_mod ds_uniqs hst tc_result
323
324       --------------------------  Main Core-language transformations ----------------
325       -- _scc_     "Core2Core"
326       show_pass dflags "Core2Core"
327       (simplified, orphan_rules) 
328          <- core2core dflags rule_base hst desugared rules
329
330       -- Do the final tidy-up
331       show_pass dflags "CoreTidy"
332       (tidy_binds, tidy_orphan_rules) 
333          <- tidyCorePgm dflags this_mod simplified orphan_rules
334       
335       return (tidy_binds, tidy_orphan_rules, (fe_binders,h_code,c_code))
336
337
338 myCoreToStg dflags this_mod tidy_binds
339  = do 
340       c2s_uniqs <- mkSplitUniqSupply 'c'
341       st_uniqs  <- mkSplitUniqSupply 'g'
342       let occ_anal_tidy_binds = occurAnalyseBinds tidy_binds
343
344       () <- coreBindsSize occ_anal_tidy_binds `seq` return ()
345       -- TEMP: the above call zaps some space usage allocated by the
346       -- simplifier, which for reasons I don't understand, persists
347       -- thoroughout code generation
348
349       show_pass dflags "Core2Stg"
350       -- _scc_     "Core2Stg"
351       let stg_binds   = topCoreBindsToStg c2s_uniqs occ_anal_tidy_binds
352
353       show_pass dflags "Stg2Stg"
354       -- _scc_     "Stg2Stg"
355       (stg_binds2, cost_centre_info) <- stg2stg dflags this_mod st_uniqs stg_binds
356       let final_ids = collectFinalStgBinders (map fst stg_binds2)
357
358       return (stg_binds2, occ_anal_tidy_binds, cost_centre_info, final_ids)
359
360
361 show_pass dflags what
362   = if   dopt Opt_D_show_passes dflags
363     then hPutStr stderr ("*** "++what++":\n")
364     else return ()
365 \end{code}
366
367
368 %************************************************************************
369 %*                                                                      *
370 \subsection{Initial persistent state}
371 %*                                                                      *
372 %************************************************************************
373
374 \begin{code}
375 initPersistentCompilerState :: IO PersistentCompilerState
376 initPersistentCompilerState 
377   = do prs <- initPersistentRenamerState
378        return (
379         PCS { pcs_PST   = initPackageDetails,
380               pcs_insts = emptyInstEnv,
381               pcs_rules = emptyRuleBase,
382               pcs_PRS   = prs
383             }
384         )
385
386 initPackageDetails :: PackageSymbolTable
387 initPackageDetails = extendTypeEnv emptyModuleEnv (groupTyThings wiredInThings)
388
389 --initPackageDetails = panic "initPackageDetails"
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 
405    = grab knownKeyNames `plusFM` grab (map getName wiredInThings)
406      where
407         grab names = foldl add emptyFM names
408         add env name 
409            = addToFM env (moduleName (nameModule name), nameOccName name) name
410
411
412 initRules :: PackageRuleBase
413 initRules = emptyRuleBase
414 {- SHOULD BE (ish)
415             foldl add emptyVarEnv builtinRules
416           where
417             add env (name,rule) 
418               = extendRuleBase env name rule
419 -}
420 \end{code}