[project @ 2004-02-12 02:04:59 by mthomas]
[ghc-hetmet.git] / ghc / compiler / main / DriverState.hs
index fe5ff52..74d82e8 100644 (file)
@@ -1,5 +1,5 @@
 -----------------------------------------------------------------------------
--- $Id: DriverState.hs,v 1.87 2002/12/17 13:50:29 simonmar Exp $
+-- $Id: DriverState.hs,v 1.97 2003/09/23 14:33:00 simonmar Exp $
 --
 -- Settings for the driver
 --
@@ -12,16 +12,13 @@ module DriverState where
 #include "../includes/config.h"
 #include "HsVersions.h"
 
-import SysTools                ( getTopDir )
 import ParsePkgConf    ( loadPackageConfig )
-import Packages                ( PackageConfig(..), PackageConfigMap, 
-                         PackageName, mkPackageName, packageNameString,
-                         packageDependents,
-                         mungePackagePaths, emptyPkgMap, extendPkgMap, lookupPkg,
-                         basePackage, rtsPackage, haskell98Package  )
+import SysTools                ( getTopDir )
+import Packages
 import CmdLineOpts
 import DriverPhases
 import DriverUtil
+import UniqFM          ( eltsUFM )
 import Util
 import Config
 import Panic
@@ -32,8 +29,8 @@ import EXCEPTION
 import List
 import Char  
 import Monad
-import Maybe     ( fromJust, isJust )
-import Directory ( doesDirectoryExist )
+import Maybe           ( fromJust, isJust )
+import Directory       ( doesDirectoryExist )
 
 -----------------------------------------------------------------------------
 -- non-configured things
@@ -50,6 +47,7 @@ data GhcMode
   | DoMake                             -- ghc --make
   | DoInteractive                      -- ghc --interactive
   | DoLink                             -- [ the default ]
+  | DoEval String                      -- ghc -e
   deriving (Eq,Show)
 
 GLOBAL_VAR(v_GhcMode,     DoLink, GhcMode)
@@ -98,6 +96,8 @@ GLOBAL_VAR(v_Scale_sizes_by,          1.0,            Double)
 GLOBAL_VAR(v_Static,                   True,           Bool)
 GLOBAL_VAR(v_NoLink,                   False,          Bool)
 GLOBAL_VAR(v_NoHsMain,                         False,          Bool)
+GLOBAL_VAR(v_MainModIs,                        Nothing,        Maybe String)
+GLOBAL_VAR(v_MainFunIs,                        Nothing,        Maybe String)
 GLOBAL_VAR(v_Recomp,                   True,           Bool)
 GLOBAL_VAR(v_Collect_ghc_timing,       False,          Bool)
 GLOBAL_VAR(v_Do_asm_mangling,          True,           Bool)
@@ -181,182 +181,7 @@ osuf_ify f = do
   osuf <- readIORef v_Object_suf
   return (replaceFilenameSuffix f osuf)
 
------------------------------------------------------------------------------
--- Compiler optimisation options
-
-GLOBAL_VAR(v_OptLevel, 0, Int)
-
-setOptLevel :: Int -> IO ()
-setOptLevel n = do
-  when (n >= 1) $ setLang HscC         -- turn on -fvia-C with -O
-  writeIORef v_OptLevel n
-
-GLOBAL_VAR(v_minus_o2_for_C,            False, Bool)
-GLOBAL_VAR(v_MaxSimplifierIterations,   4,     Int)
 GLOBAL_VAR(v_StgStats,                  False, Bool)
-GLOBAL_VAR(v_UsageSPInf,               False, Bool)  -- Off by default
-GLOBAL_VAR(v_Strictness,               True,  Bool)
-GLOBAL_VAR(v_CSE,                      True,  Bool)
-GLOBAL_VAR(v_RuleCheck,                Nothing,  Maybe String)
-
--- these are the static flags you get without -O.
-hsc_minusNoO_flags =
-       [ 
-       "-fignore-interface-pragmas",
-       "-fomit-interface-pragmas",
-       "-fdo-lambda-eta-expansion",    -- This one is important for a tiresome reason:
-                                       -- we want to make sure that the bindings for data 
-                                       -- constructors are eta-expanded.  This is probably
-                                       -- a good thing anyway, but it seems fragile.
-       "-flet-no-escape"
-       ]
-
--- these are the static flags you get when -O is on.
-hsc_minusO_flags =
-  [ 
-       "-fignore-asserts",
-       "-ffoldr-build-on",
-        "-fdo-eta-reduction",
-       "-fdo-lambda-eta-expansion",
-       "-fcase-merge",
-       "-flet-to-case",
-       "-flet-no-escape"
-   ]
-
-hsc_minusO2_flags = hsc_minusO_flags   -- for now
-
-getStaticOptimisationFlags 0 = hsc_minusNoO_flags
-getStaticOptimisationFlags 1 = hsc_minusO_flags
-getStaticOptimisationFlags n = hsc_minusO2_flags
-
-buildCoreToDo :: IO [CoreToDo]
-buildCoreToDo = do
-   opt_level  <- readIORef v_OptLevel
-   max_iter   <- readIORef v_MaxSimplifierIterations
-   usageSP    <- readIORef v_UsageSPInf
-   strictness <- readIORef v_Strictness
-   cse        <- readIORef v_CSE
-   rule_check <- readIORef v_RuleCheck
-
-   if opt_level == 0 then return
-      [
-       CoreDoSimplify (SimplPhase 0) [
-           MaxSimplifierIterations max_iter
-       ]
-      ]
-
-    else {- opt_level >= 1 -} return [ 
-
-       -- initial simplify: mk specialiser happy: minimum effort please
-       CoreDoSimplify SimplGently [
-                       --      Simplify "gently"
-                       -- Don't inline anything till full laziness has bitten
-                       -- In particular, inlining wrappers inhibits floating
-                       -- e.g. ...(case f x of ...)...
-                       --  ==> ...(case (case x of I# x# -> fw x#) of ...)...
-                       --  ==> ...(case x of I# x# -> case fw x# of ...)...
-                       -- and now the redex (f x) isn't floatable any more
-                       -- Similarly, don't apply any rules until after full 
-                       -- laziness.  Notably, list fusion can prevent floating.
-
-            NoCaseOfCase,
-                       -- Don't do case-of-case transformations.
-                       -- This makes full laziness work better
-           MaxSimplifierIterations max_iter
-       ],
-
-       -- Specialisation is best done before full laziness
-       -- so that overloaded functions have all their dictionary lambdas manifest
-       CoreDoSpecialising,
-
-       CoreDoFloatOutwards (FloatOutSw False False),
-       CoreDoFloatInwards,
-
-       CoreDoSimplify (SimplPhase 2) [
-               -- Want to run with inline phase 2 after the specialiser to give
-               -- maximum chance for fusion to work before we inline build/augment
-               -- in phase 1.  This made a difference in 'ansi' where an 
-               -- overloaded function wasn't inlined till too late.
-          MaxSimplifierIterations max_iter
-       ],
-       case rule_check of { Just pat -> CoreDoRuleCheck 2 pat; Nothing -> CoreDoNothing },
-
-       -- infer usage information here in case we need it later.
-        -- (add more of these where you need them --KSW 1999-04)
-        if usageSP then CoreDoUSPInf else CoreDoNothing,
-
-       CoreDoSimplify (SimplPhase 1) [
-               -- Need inline-phase2 here so that build/augment get 
-               -- inlined.  I found that spectral/hartel/genfft lost some useful
-               -- strictness in the function sumcode' if augment is not inlined
-               -- before strictness analysis runs
-          MaxSimplifierIterations max_iter
-       ],
-       case rule_check of { Just pat -> CoreDoRuleCheck 1 pat; Nothing -> CoreDoNothing },
-
-       CoreDoSimplify (SimplPhase 0) [
-               -- Phase 0: allow all Ids to be inlined now
-               -- This gets foldr inlined before strictness analysis
-
-          MaxSimplifierIterations 3
-               -- At least 3 iterations because otherwise we land up with
-               -- huge dead expressions because of an infelicity in the 
-               -- simpifier.   
-               --      let k = BIG in foldr k z xs
-               -- ==>  let k = BIG in letrec go = \xs -> ...(k x).... in go xs
-               -- ==>  let k = BIG in letrec go = \xs -> ...(BIG x).... in go xs
-               -- Don't stop now!
-
-       ],
-       case rule_check of { Just pat -> CoreDoRuleCheck 0 pat; Nothing -> CoreDoNothing },
-
-#ifdef OLD_STRICTNESS
-       CoreDoOldStrictness
-#endif
-       if strictness then CoreDoStrictness else CoreDoNothing,
-       CoreDoWorkerWrapper,
-       CoreDoGlomBinds,
-
-       CoreDoSimplify (SimplPhase 0) [
-          MaxSimplifierIterations max_iter
-       ],
-
-       CoreDoFloatOutwards (FloatOutSw False   -- Not lambdas
-                                       True),  -- Float constants
-               -- nofib/spectral/hartel/wang doubles in speed if you
-               -- do full laziness late in the day.  It only happens
-               -- after fusion and other stuff, so the early pass doesn't
-               -- catch it.  For the record, the redex is 
-               --        f_el22 (f_el21 r_midblock)
-
-
-       -- We want CSE to follow the final full-laziness pass, because it may
-       -- succeed in commoning up things floated out by full laziness.
-       -- CSE used to rely on the no-shadowing invariant, but it doesn't any more
-
-       if cse then CoreCSE else CoreDoNothing,
-
-       CoreDoFloatInwards,
-
--- Case-liberation for -O2.  This should be after
--- strictness analysis and the simplification which follows it.
-
-       case rule_check of { Just pat -> CoreDoRuleCheck 0 pat; Nothing -> CoreDoNothing },
-
-       if opt_level >= 2 then
-          CoreLiberateCase
-       else
-          CoreDoNothing,
-       if opt_level >= 2 then
-          CoreDoSpecConstr
-       else
-          CoreDoNothing,
-
-       -- Final clean-up simplification:
-       CoreDoSimplify (SimplPhase 0) [
-         MaxSimplifierIterations max_iter
-       ]
-     ]
 
 buildStgToDo :: IO [ StgToDo ]
 buildStgToDo = do
@@ -452,91 +277,107 @@ addToDirList ref path
     splitUp xs = return (split split_marker xs)
 #endif
 
-GLOBAL_VAR(v_HCHeader, "", String)
-
------------------------------------------------------------------------------
--- Packages
-
-------------------------
--- The PackageConfigMap is read in from the configuration file
--- It doesn't change during a run
-GLOBAL_VAR(v_Package_details, emptyPkgMap, PackageConfigMap)
+-- ----------------------------------------------------------------------------
+-- Loading the package config file
 
 readPackageConf :: String -> IO ()
 readPackageConf conf_file = do
   proto_pkg_configs <- loadPackageConfig conf_file
   top_dir          <- getTopDir
-  old_pkg_map      <- readIORef v_Package_details
-
   let pkg_configs = mungePackagePaths top_dir proto_pkg_configs
-      new_pkg_map = extendPkgMap old_pkg_map pkg_configs
-   
-  writeIORef v_Package_details new_pkg_map
+  extendPackageConfigMap pkg_configs
+
+mungePackagePaths :: String -> [PackageConfig] -> [PackageConfig]
+-- Replace the string "$libdir" at the beginning of a path
+-- with the current libdir (obtained from the -B option).
+mungePackagePaths top_dir ps = map munge_pkg ps
+ where 
+  munge_pkg p = p{ import_dirs  = munge_paths (import_dirs p),
+                  include_dirs = munge_paths (include_dirs p),
+                  library_dirs = munge_paths (library_dirs p),
+                  framework_dirs = munge_paths (framework_dirs p) }
+
+  munge_paths = map munge_path
 
-getPackageConfigMap :: IO PackageConfigMap
-getPackageConfigMap = readIORef v_Package_details
+  munge_path p 
+         | Just p' <- maybePrefixMatch "$libdir" p = top_dir ++ p'
+         | otherwise                               = p
 
 
-------------------------
--- The package list reflects what was given as command-line options,
---     plus their dependent packages.
--- It is maintained in dependency order;
---     earlier ones depend on later ones, but not vice versa
-GLOBAL_VAR(v_Packages, initPackageList, [PackageName])
+-- -----------------------------------------------------------------------------
+-- The list of packages requested on the command line
 
-getPackages :: IO [PackageName]
-getPackages = readIORef v_Packages
+-- The package list reflects what packages were given as command-line options,
+-- plus their dependent packages.  It is maintained in dependency order;
+-- earlier packages may depend on later ones, but not vice versa
+GLOBAL_VAR(v_ExplicitPackages, initPackageList, [PackageName])
 
-initPackageList = [haskell98Package,
-                  basePackage,
-                  rtsPackage]
+initPackageList = [basePackage, rtsPackage]
+       -- basePackage is part of this list entirely because of 
+       -- wired-in names in GHCi.  See the notes on wired-in names in
+       -- Linker.linkExpr.  By putting the base backage in initPackageList
+       -- we make sure that it'll always by linked.
 
+
+-- add a package requested from the command-line
 addPackage :: String -> IO ()
-addPackage package
-  = do { pkg_details <- getPackageConfigMap
-       ; ps  <- readIORef v_Packages
-       ; ps' <- add_package pkg_details ps (mkPackageName package)
+addPackage package = do
+  pkg_details <- getPackageConfigMap
+  ps  <- readIORef v_ExplicitPackages
+  ps' <- add_package pkg_details ps (mkPackageName package)
                -- Throws an exception if it fails
-       ; writeIORef v_Packages ps' }
+  writeIORef v_ExplicitPackages ps'
 
+-- internal helper
 add_package :: PackageConfigMap -> [PackageName]
            -> PackageName -> IO [PackageName]
 add_package pkg_details ps p   
   | p `elem` ps        -- Check if we've already added this package
   = return ps
   | Just details <- lookupPkg pkg_details p
-  = do {       -- Add the package's dependents first
-         ps' <- foldM  (add_package pkg_details) ps 
-                       (packageDependents details)
-       ; return (p : ps') }
-
+  -- Add the package's dependents also
+  = do ps' <- foldM (add_package pkg_details) ps (packageDependents details)
+       return (p : ps')
   | otherwise
   = throwDyn (CmdLineError ("unknown package name: " ++ packageNameString p))
 
-getPackageImportPath   :: IO [String]
+
+-- -----------------------------------------------------------------------------
+-- Extracting information from the packages in scope
+
+-- Many of these functions take a list of packages: in those cases,
+-- the list is expected to contain the "dependent packages",
+-- i.e. those packages that were found to be depended on by the
+-- current module/program.  These can be auto or non-auto packages, it
+-- doesn't really matter.  The list is always combined with the list
+-- of explicit (command-line) packages to determine which packages to
+-- use.
+
+getPackageImportPath :: IO [String]
 getPackageImportPath = do
-  ps <- getPackageInfo
+  ps <- getExplicitAndAutoPackageConfigs
+                 -- import dirs are always derived from the 'auto' 
+                 -- packages as well as the explicit ones
   return (nub (filter notNull (concatMap import_dirs ps)))
 
-getPackageIncludePath   :: IO [String]
-getPackageIncludePath = do
-  ps <- getPackageInfo
+getPackageIncludePath :: [PackageName] -> IO [String]
+getPackageIncludePath pkgs = do
+  ps <- getExplicitPackagesAnd pkgs
   return (nub (filter notNull (concatMap include_dirs ps)))
 
        -- includes are in reverse dependency order (i.e. rts first)
-getPackageCIncludes   :: IO [String]
-getPackageCIncludes = do
-  ps <- getPackageInfo
-  return (reverse (nub (filter notNull (concatMap c_includes ps))))
-
-getPackageLibraryPath  :: IO [String]
-getPackageLibraryPath = do
-  ps <- getPackageInfo
+getPackageCIncludes :: [PackageConfig] -> IO [String]
+getPackageCIncludes pkg_configs = do
+  return (reverse (nub (filter notNull (concatMap c_includes pkg_configs))))
+
+getPackageLibraryPath :: [PackageName] -> IO [String]
+getPackageLibraryPath pkgs = do 
+  ps <- getExplicitPackagesAnd pkgs
   return (nub (filter notNull (concatMap library_dirs ps)))
 
-getPackageLinkOpts :: IO [String]
-getPackageLinkOpts = do
-  ps <- getPackageInfo
+getPackageLinkOpts :: [PackageName] -> IO [String]
+getPackageLinkOpts pkgs = do
+  ps <- getExplicitPackagesAnd pkgs
   tag <- readIORef v_Build_tag
   static <- readIORef v_Static
   let 
@@ -580,35 +421,42 @@ getPackageLinkOpts = do
 
 getPackageExtraGhcOpts :: IO [String]
 getPackageExtraGhcOpts = do
-  ps <- getPackageInfo
+  ps <- getExplicitAndAutoPackageConfigs
   return (concatMap extra_ghc_opts ps)
 
-getPackageExtraCcOpts  :: IO [String]
-getPackageExtraCcOpts = do
-  ps <- getPackageInfo
+getPackageExtraCcOpts :: [PackageName] -> IO [String]
+getPackageExtraCcOpts pkgs = do
+  ps <- getExplicitPackagesAnd pkgs
   return (concatMap extra_cc_opts ps)
 
 #ifdef darwin_TARGET_OS
-getPackageFrameworkPath  :: IO [String]
-getPackageFrameworkPath = do
-  ps <- getPackageInfo
+getPackageFrameworkPath  :: [PackageName] -> IO [String]
+getPackageFrameworkPath pkgs = do
+  ps <- getExplicitPackagesAnd pkgs
   return (nub (filter notNull (concatMap framework_dirs ps)))
 
-getPackageFrameworks  :: IO [String]
-getPackageFrameworks = do
-  ps <- getPackageInfo
+getPackageFrameworks  :: [PackageName] -> IO [String]
+getPackageFrameworks pkgs = do
+  ps <- getExplicitPackagesAnd pkgs
   return (concatMap extra_frameworks ps)
 #endif
 
-getPackageInfo :: IO [PackageConfig]
-getPackageInfo = do ps <- getPackages  
-                   getPackageDetails ps
+-- -----------------------------------------------------------------------------
+-- Package Utils
 
-getPackageDetails :: [PackageName] -> IO [PackageConfig]
-getPackageDetails ps = do
-  pkg_details <- getPackageConfigMap
-  return [ pkg | Just pkg <- map (lookupPkg pkg_details) ps ]
+getExplicitPackagesAnd :: [PackageName] -> IO [PackageConfig]
+getExplicitPackagesAnd pkg_names = do
+  pkg_map <- getPackageConfigMap
+  expl <- readIORef v_ExplicitPackages
+  all_pkgs <- foldM (add_package pkg_map) expl pkg_names
+  getPackageDetails all_pkgs
 
+-- return all packages, including both the auto packages and the explicit ones
+getExplicitAndAutoPackageConfigs :: IO [PackageConfig]
+getExplicitAndAutoPackageConfigs = do
+  pkg_map <- getPackageConfigMap
+  let auto_packages = [ mkPackageName (name p) | p <- eltsUFM pkg_map, auto p ]
+  getExplicitPackagesAnd auto_packages
 
 -----------------------------------------------------------------------------
 -- Ways
@@ -764,7 +612,9 @@ way_details =
     (WaySMP, Way  "s" "SMP"
        [ "-fsmp"
        , "-optc-pthread"
+#ifndef freebsd_TARGET_OS
        , "-optl-pthread"
+#endif
        , "-optc-DSMP"
        , "-fvia-C" ]),