X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2Fmain%2FMain.lhs;h=8a7feb96b11f789cf6f74073416683a3e5dbe665;hb=438596897ebbe25a07e1c82085cfbc5bdb00f09e;hp=27bbe1e52d549bea55cbd8d3330aed94e034afde;hpb=8f7ac3fe40d3d55743b824deab655d0797a1c55f;p=ghc-hetmet.git diff --git a/ghc/compiler/main/Main.lhs b/ghc/compiler/main/Main.lhs index 27bbe1e..8a7feb9 100644 --- a/ghc/compiler/main/Main.lhs +++ b/ghc/compiler/main/Main.lhs @@ -1,118 +1,113 @@ % -% (c) The GRASP/AQUA Project, Glasgow University, 1993-1996 +% (c) The GRASP/AQUA Project, Glasgow University, 1993-1998 % \section[GHC_Main]{Main driver for Glasgow Haskell compiler} \begin{code} -#include "HsVersions.h" - module Main ( main ) where -IMP_Ubiq(){-uitous-} -IMPORT_1_3(IO(hGetContents,stdin,stderr,hPutStr,hClose,openFile,IOMode(..))) +#include "HsVersions.h" +import IO ( IOMode(..), hPutStr, hClose, openFile, stderr ) import HsSyn -import RdrHsSyn ( RdrName ) +import BasicTypes ( NewOrData(..) ) import ReadPrefix ( rdModule ) import Rename ( renameModule ) -import RnMonad ( ExportEnv ) import MkIface -- several functions import TcModule ( typecheckModule ) -import Desugar ( deSugar, DsMatchContext, pprDsWarnings ) +import Desugar ( deSugar ) import SimplCore ( core2core ) import CoreToStg ( topCoreBindsToStg ) -import StgSyn ( collectFinalStgBinders ) +import StgSyn ( collectFinalStgBinders, pprStgBindingsWithSRTs ) import SimplStg ( stg2stg ) import CodeGen ( codeGen ) #if ! OMIT_NATIVE_CODEGEN import AsmCodeGen ( dumpRealAsm, writeRealAsm ) #endif -import AbsCSyn ( absCNop, AbstractC ) +import AbsCSyn ( absCNop ) import AbsCUtils ( flattenAbsC ) -import CoreUnfold ( Unfolding ) -import Bag ( emptyBag, isEmptyBag ) import CmdLineOpts -import ErrUtils ( pprBagOfErrors, ghcExit ) +import ErrUtils ( ghcExit, doIfSet, dumpIfSet ) import Maybes ( maybeToBool, MaybeErr(..) ) -import Specialise ( SpecialiseData(..) ) -import StgSyn ( pprPlainStgBinding, GenStgBinding ) -import TcInstUtil ( InstInfo ) import TyCon ( isDataTyCon ) +import Class ( classTyCon ) import UniqSupply ( mkSplitUniqSupply ) import PprAbsC ( dumpRealC, writeRealC ) -import PprCore ( pprCoreBinding ) -import PprStyle ( PprStyle(..) ) -import Pretty - -import Id ( GenId ) -- instances -import Name ( Name ) -- instances -import PprType ( GenType, GenTyVar ) -- instances -import TyVar ( GenTyVar ) -- instances -import Unique ( Unique ) -- instances +import FiniteMap ( emptyFM ) +import Outputable +import Char ( isSpace ) +#if REPORT_TO_MOTHERLODE && __GLASGOW_HASKELL__ >= 303 +import SocketPrim +import BSD +import IOExts ( unsafePerformIO ) +import NativeInfo ( os, arch ) +#endif + \end{code} \begin{code} -main - = hGetContents stdin >>= \ input_pgm -> - let - cmd_line_info = classifyOpts - in - doIt cmd_line_info input_pgm +main = + -- _scc_ "main" + doIt classifyOpts \end{code} \begin{code} -doIt :: ([CoreToDo], [StgToDo]) -> String -> IO () +doIt :: ([CoreToDo], [StgToDo]) -> IO () -doIt (core_cmds, stg_cmds) input_pgm - = doDump opt_Verbose "Glasgow Haskell Compiler, version 2.02, for Haskell 1.3" "" >> +doIt (core_cmds, stg_cmds) + = doIfSet opt_Verbose + (hPutStr stderr "Glasgow Haskell Compiler, version " >> + hPutStr stderr compiler_version >> + hPutStr stderr ", for Haskell 1.4\n") >> -- ******* READER show_pass "Reader" >> _scc_ "Reader" rdModule >>= \ (mod_name, rdr_module) -> - doDump opt_D_dump_rdr "Reader:" - (pp_show (ppr pprStyle rdr_module)) >> + dumpIfSet opt_D_dump_rdr "Reader" (ppr rdr_module) >> - doDump opt_D_source_stats "\nSource Statistics:" - (pp_show (ppSourceStats rdr_module)) >> + dumpIfSet opt_D_source_stats "Source Statistics" + (ppSourceStats False rdr_module) >> -- UniqueSupplies for later use (these are the only lower case uniques) +-- _scc_ "spl-rn" mkSplitUniqSupply 'r' >>= \ rn_uniqs -> -- renamer +-- _scc_ "spl-tc" mkSplitUniqSupply 'a' >>= \ tc_uniqs -> -- typechecker +-- _scc_ "spl-ds" mkSplitUniqSupply 'd' >>= \ ds_uniqs -> -- desugarer +-- _scc_ "spl-sm" mkSplitUniqSupply 's' >>= \ sm_uniqs -> -- core-to-core simplifier +-- _scc_ "spl-c2s" mkSplitUniqSupply 'c' >>= \ c2s_uniqs -> -- core-to-stg +-- _scc_ "spl-st" mkSplitUniqSupply 'g' >>= \ st_uniqs -> -- stg-to-stg passes +-- _scc_ "spl-absc" mkSplitUniqSupply 'f' >>= \ fl_uniqs -> -- absC flattener +-- _scc_ "spl-ncg" mkSplitUniqSupply 'n' >>= \ ncg_uniqs -> -- native-code generator -- ******* RENAMER show_pass "Renamer" >> _scc_ "Renamer" - renameModule rn_uniqs rdr_module >>= - \ (maybe_rn_stuff, rn_errs_bag, rn_warns_bag) -> - - checkErrors rn_errs_bag rn_warns_bag >> + renameModule rn_uniqs rdr_module >>= + \ maybe_rn_stuff -> case maybe_rn_stuff of { Nothing -> -- Hurrah! Renamer reckons that there's no need to -- go any further - hPutStr stderr "No recompilation required!\n" >> - ghcExit 0 ; - - -- Oh well, we've got to recompile for real + reportCompile (_UNPK_ mod_name) "Compilation NOT required!" >> + return (); + Just (rn_mod, iface_file_stuff, rn_name_supply, imported_modules) -> + -- Oh well, we've got to recompile for real - - doDump opt_D_dump_rn "Renamer:" - (pp_show (ppr pprStyle rn_mod)) >> - -- Safely past renaming: we can start the interface file: -- (the iface file is produced incrementally, as we have -- the information that we need...; we use "iface") @@ -122,68 +117,37 @@ doIt (core_cmds, stg_cmds) input_pgm -- ******* TYPECHECKER - show_pass "TypeCheck" >> + show_pass "TypeCheck" >> _scc_ "TypeCheck" - case (case (typecheckModule tc_uniqs {-idinfo_fm-} rn_name_supply rn_mod) of - Succeeded (stuff, warns) - -> (emptyBag, warns, stuff) - Failed (errs, warns) - -> (errs, warns, error "tc_results")) - - of { (tc_errs_bag, tc_warns_bag, tc_results) -> - - checkErrors tc_errs_bag tc_warns_bag >> - - case tc_results - of { (typechecked_quint@(recsel_binds, class_binds, inst_binds, val_binds, const_binds), - local_tycons, inst_info, pragma_tycon_specs, - ddump_deriv) -> + typecheckModule tc_uniqs rn_name_supply rn_mod >>= \ maybe_tc_stuff -> + case maybe_tc_stuff of { + Nothing -> ghcExit 1; -- Type checker failed - doDump opt_D_dump_tc "Typechecked:" - (pp_show (ppAboves [ - ppr pprStyle recsel_binds, - ppr pprStyle class_binds, - ppr pprStyle inst_binds, - ppAboves (map (\ (i,e) -> ppr pprStyle (VarMonoBind i e)) const_binds), - ppr pprStyle val_binds])) >> + Just (all_binds, + local_tycons, local_classes, inst_info, + fo_decls, + ddump_deriv, + global_env, + global_ids) -> - doDump opt_D_dump_deriv "Derived instances:" - (pp_show (ddump_deriv pprStyle)) >> -- ******* DESUGARER - show_pass "DeSugar " >> + show_pass "DeSugar" >> _scc_ "DeSugar" - let - (desugared,ds_warnings) - = deSugar ds_uniqs mod_name typechecked_quint - in - (if isEmptyBag ds_warnings then - return () - else - hPutStr stderr (ppShow pprCols (pprDsWarnings pprErrorsStyle ds_warnings)) - >> hPutStr stderr "\n" - ) >> - - doDump opt_D_dump_ds "Desugared:" (pp_show (ppAboves - (map (pprCoreBinding pprStyle) desugared))) - >> - - -- ******* CORE-TO-CORE SIMPLIFICATION (NB: I/O op) + deSugar ds_uniqs global_env mod_name all_binds fo_decls >>= \ (desugared, h_code, c_code) -> + + + -- ******* CORE-TO-CORE SIMPLIFICATION show_pass "Core2Core" >> _scc_ "Core2Core" let local_data_tycons = filter isDataTyCon local_tycons in - core2core core_cmds mod_name pprStyle - sm_uniqs local_data_tycons pragma_tycon_specs desugared + core2core core_cmds mod_name + sm_uniqs desugared >>= + \ simplified -> - \ (simplified, - SpecData _ _ _ gen_tycons all_tycon_specs _ _ _) -> - - doDump opt_D_dump_simpl "Simplified:" (pp_show (ppAboves - (map (pprCoreBinding pprStyle) simplified))) - >> -- ******* STG-TO-STG SIMPLIFICATION show_pass "Core2Stg" >> @@ -194,44 +158,45 @@ doIt (core_cmds, stg_cmds) input_pgm show_pass "Stg2Stg" >> _scc_ "Stg2Stg" - stg2stg stg_cmds mod_name pprStyle st_uniqs stg_binds + stg2stg stg_cmds mod_name st_uniqs stg_binds >>= - \ (stg_binds2, cost_centre_info) -> - doDump opt_D_dump_stg "STG syntax:" - (pp_show (ppAboves (map (pprPlainStgBinding pprStyle) stg_binds2))) - >> + dumpIfSet opt_D_dump_stg "STG syntax:" + (pprStgBindingsWithSRTs stg_binds2) >> -- Dump instance decls and type signatures into the interface file let - final_ids = collectFinalStgBinders stg_binds2 + final_ids = collectFinalStgBinders (map fst stg_binds2) in - ifaceDecls if_handle rn_mod inst_info final_ids simplified >> + _scc_ "Interface" + ifaceDecls if_handle local_tycons local_classes inst_info final_ids simplified >> endIface if_handle >> -- We are definitely done w/ interface-file stuff at this point: -- (See comments near call to "startIface".) - -- ******* "ABSTRACT", THEN "FLAT", THEN *REAL* C! show_pass "CodeGen" >> _scc_ "CodeGen" let + all_local_data_tycons = filter isDataTyCon (map classTyCon local_classes) + ++ local_data_tycons + -- Generate info tables for the data constrs arising + -- from class decls as well + + all_tycon_specs = emptyFM -- Not specialising tycons any more + abstractC = codeGen mod_name -- module name for CC labelling cost_centre_info imported_modules -- import names for CC registering - gen_tycons -- type constructors generated locally + all_local_data_tycons -- type constructors generated locally all_tycon_specs -- tycon specialisations stg_binds2 flat_abstractC = flattenAbsC fl_uniqs abstractC in - doDump opt_D_dump_absC "Abstract C:" - (dumpRealC abstractC) >> - - doDump opt_D_dump_flatC "Flat Abstract C:" - (dumpRealC flat_abstractC) >> - + show_pass "CodeOutput" >> + _scc_ "CodeOutput" -- You can have C (c_output) or assembly-language (ncg_output), -- but not both. [Allowing for both gives a space leak on -- flat_abstractC. WDP 94/10] @@ -244,6 +209,14 @@ doIt (core_cmds, stg_cmds) input_pgm (False, False) -> (absCNop, absCNop) (True, True) -> error "ERROR: Can't do both .hc and .s at the same time" + -- C stubs for "foreign export"ed functions. + stub_c_output_d = pprCode CStyle c_code + stub_c_output_w = showSDoc stub_c_output_d + + -- Header file protos for "foreign export"ed functions. + stub_h_output_d = pprCode CStyle h_code + stub_h_output_w = showSDoc stub_h_output_d + c_output_d = dumpRealC flat_absC_c c_output_w = (\ f -> writeRealC f flat_absC_c) @@ -256,19 +229,23 @@ doIt (core_cmds, stg_cmds) input_pgm #endif in - doDump opt_D_dump_asm "" ncg_output_d >> - doOutput opt_ProduceS ncg_output_w >> + dumpIfSet opt_D_dump_asm "Asm code" ncg_output_d >> + doOutput opt_ProduceS ncg_output_w >> - doDump opt_D_dump_realC "" c_output_d >> - doOutput opt_ProduceC c_output_w >> + dumpIfSet opt_D_dump_foreign "Foreign export header file" stub_h_output_d >> + outputHStub opt_ProduceExportHStubs stub_h_output_w >> - ghcExit 0 - } } } - where - ------------------------------------------------------------- - -- ****** printing styles and column width: + dumpIfSet opt_D_dump_foreign "Foreign export stubs" stub_c_output_d >> + outputCStub mod_name opt_ProduceExportCStubs stub_c_output_w >> + + dumpIfSet opt_D_dump_realC "Real C" c_output_d >> + doOutput opt_ProduceC c_output_w >> + reportCompile (_UNPK_ mod_name) (showSDoc (ppSourceStats True rdr_module)) >> + ghcExit 0 + } } + where ------------------------------------------------------------- -- ****** help functions: @@ -279,47 +256,32 @@ doIt (core_cmds, stg_cmds) input_pgm doOutput switch io_action = case switch of - Nothing -> return () + Nothing -> return () Just fname -> openFile fname WriteMode >>= \ handle -> io_action handle >> hClose handle - doDump switch hdr string - = if switch - then hPutStr stderr hdr >> - hPutStr stderr ('\n': string) >> - hPutStr stderr "\n" - else return () - - -pprCols = (80 :: Int) -- could make configurable - -(pprStyle, pprErrorsStyle) - | opt_PprStyle_All = (PprShowAll, PprShowAll) - | opt_PprStyle_Debug = (PprDebug, PprDebug) - | opt_PprStyle_User = (PprForUser, PprForUser) - | otherwise = (PprDebug, PprForUser) - -pp_show p = ppShow {-WAS:pprCols-}10000{-random-} p - -checkErrors errs_bag warns_bag - | not (isEmptyBag errs_bag) - = hPutStr stderr (ppShow pprCols (pprBagOfErrors pprErrorsStyle errs_bag)) - >> hPutStr stderr "\n" >> - hPutStr stderr (ppShow pprCols (pprBagOfErrors pprErrorsStyle warns_bag)) - >> hPutStr stderr "\n" >> - ghcExit 1 - - | not (isEmptyBag warns_bag) - = hPutStr stderr (ppShow pprCols (pprBagOfErrors pprErrorsStyle warns_bag)) >> - hPutStr stderr "\n" - - | otherwise = return () - + -- don't use doOutput for dumping the f. export stubs + -- since it is more than likely that the stubs file will + -- turn out to be empty, in which case no file should be created. + outputCStub mod_name switch "" = return () + outputCStub mod_name switch doc_str + = case switch of + Nothing -> return () + Just fname -> writeFile fname ("#include \"Rts.h\"\n#include \"RtsAPI.h\"\n"++rest) + where + rest = "#include "++show ((_UNPK_ mod_name) ++ "_stub.h") ++ '\n':doc_str + + outputHStub switch "" = return () + outputHStub switch doc_str + = case switch of + Nothing -> return () + Just fname -> writeFile fname ("#include \"Rts.h\"\n"++doc_str) -ppSourceStats (HsModule name version exports imports fixities decls src_loc) - = ppAboves (map pp_val +ppSourceStats short (HsModule name version exports imports fixities decls src_loc) + = (if short then hcat else vcat) + (map pp_val [("ExportAll ", export_all), -- 1 if no export list ("ExportDecls ", export_ds), ("ExportModules ", export_ms), @@ -352,13 +314,17 @@ ppSourceStats (HsModule name version exports imports fixities decls src_loc) ("SpecialisedBinds ", bind_specs) ]) where - pp_val (str, 0) = ppNil - pp_val (str, n) = ppBesides [ppStr str, ppInt n] + pp_val (str, 0) = empty + pp_val (str, n) + | not short = hcat [text str, int n] + | otherwise = hcat [text (trim str), equals, int n, semi] + + trim ls = takeWhile (not.isSpace) (dropWhile isSpace ls) fixity_ds = length fixities type_decls = [d | TyD d@(TySynonym _ _ _ _) <- decls] - data_decls = [d | TyD d@(TyData _ _ _ _ _ _ _) <- decls] - newt_decls = [d | TyD d@(TyNew _ _ _ _ _ _ _) <- decls] + data_decls = [d | TyD d@(TyData DataType _ _ _ _ _ _ _) <- decls] + newt_decls = [d | TyD d@(TyData NewType _ _ _ _ _ _ _) <- decls] type_ds = length type_decls data_ds = length data_decls newt_ds = length newt_decls @@ -390,14 +356,8 @@ ppSourceStats (HsModule name version exports imports fixities decls src_loc) count_binds EmptyBinds = (0,0,0,0,0) count_binds (ThenBinds b1 b2) = count_binds b1 `add5` count_binds b2 - count_binds (SingleBind b) = case count_bind b of - (vs,fs) -> (vs,fs,0,0,0) - count_binds (BindWith b sigs) = case (count_bind b, count_sigs sigs) of - ((vs,fs),(ts,_,ss,is)) -> (vs,fs,ts,ss,is) - - count_bind EmptyBind = (0,0) - count_bind (NonRecBind b) = count_monobinds b - count_bind (RecBind b) = count_monobinds b + count_binds (MonoBind b sigs _) = case (count_monobinds b, count_sigs sigs) of + ((vs,fs),(ts,_,ss,is)) -> (vs,fs,ts,ss,is) count_monobinds EmptyMonoBinds = (0,0) count_monobinds (AndMonoBinds b1 b2) = count_monobinds b1 `add2` count_monobinds b2 @@ -413,7 +373,7 @@ ppSourceStats (HsModule name version exports imports fixities decls src_loc) sig_info (InlineSig _ _) = (0,0,0,1) sig_info _ = (0,0,0,0) - import_info (ImportDecl _ qual as spec _) + import_info (ImportDecl _ qual _ as spec _) = add6 (1, qual_info qual, as_info as, 0,0,0) (spec_info spec) qual_info False = 0 qual_info True = 1 @@ -423,12 +383,10 @@ ppSourceStats (HsModule name version exports imports fixities decls src_loc) spec_info (Just (False, _)) = (0,0,0,0,1,0) spec_info (Just (True, _)) = (0,0,0,0,0,1) - data_info (TyData _ _ _ constrs derivs _ _) + data_info (TyData _ _ _ _ constrs derivs _ _) = (length constrs, case derivs of {Nothing -> 0; Just ds -> length ds}) - data_info (TyNew _ _ _ constr derivs _ _) - = (1, case derivs of {Nothing -> 0; Just ds -> length ds}) - class_info (ClassDecl _ _ _ meth_sigs def_meths _ _) + class_info (ClassDecl _ _ _ meth_sigs def_meths _ _ _ _) = case count_sigs meth_sigs of (_,classops,_,_) -> (classops, addpr (count_monobinds def_meths)) @@ -446,3 +404,54 @@ ppSourceStats (HsModule name version exports imports fixities decls src_loc) add5 (x1,x2,x3,x4,x5) (y1,y2,y3,y4,y5) = (x1+y1,x2+y2,x3+y3,x4+y4,x5+y5) add6 (x1,x2,x3,x4,x5,x6) (y1,y2,y3,y4,y5,y6) = (x1+y1,x2+y2,x3+y3,x4+y4,x5+y5,x6+y6) \end{code} + +\begin{code} +compiler_version :: String +compiler_version = + case (show opt_HiVersion) of + [x] -> ['0','.',x] + ls@[x,y] -> "0." ++ ls + ls -> go ls + where + -- 10232353 => 10232.53 + go ls@[x,y] = '.':ls + go (x:xs) = x:go xs + +\end{code} + +\begin{code} +reportCompile :: String -> String -> IO () +#if REPORT_TO_MOTHERLODE && __GLASGOW_HASKELL__ >= 303 +reportCompile mod_name info + | not opt_ReportCompile = return () + | otherwise = (do + sock <- udpSocket 0 + addr <- motherShip + sendTo sock (mod_name++ ';': compiler_version ++ ';': os ++ ';':arch ++ '\n':' ':info ++ "\n") addr + return ()) `catch` (\ _ -> return ()) + +motherShip :: IO SockAddr +motherShip = do + he <- getHostByName "laysan.dcs.gla.ac.uk" + case (hostAddresses he) of + [] -> fail (userError "No address!") + (x:_) -> return (SockAddrInet motherShipPort x) + +--magick +motherShipPort :: PortNumber +motherShipPort = mkPortNumber 12345 + +-- creates a socket capable of sending datagrams, +-- binding it to a port +-- ( 0 => have the system pick next available port no.) +udpSocket :: Int -> IO Socket +udpSocket p = do + pr <- getProtocolNumber "udp" + s <- socket AF_INET Datagram pr + bindSocket s (SockAddrInet (mkPortNumber p) iNADDR_ANY) + return s +#else +reportCompile _ _ = return () +#endif + +\end{code}