X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2Fmain%2FDriverState.hs;h=c4b1b8c6c09de7ccc796fc1f0b2ec9e458046094;hb=9af77fa423926fbda946b31e174173d0ec5ebac8;hp=8aadde53d411541031bacc87f5a1027561f4007e;hpb=447442d1a13367a1510644e1eac2795c191fd9ea;p=ghc-hetmet.git diff --git a/ghc/compiler/main/DriverState.hs b/ghc/compiler/main/DriverState.hs index 8aadde5..c4b1b8c 100644 --- a/ghc/compiler/main/DriverState.hs +++ b/ghc/compiler/main/DriverState.hs @@ -1,32 +1,39 @@ ----------------------------------------------------------------------------- --- $Id: DriverState.hs,v 1.36 2001/03/27 10:33:03 simonmar Exp $ +-- $Id: DriverState.hs,v 1.82 2002/09/13 15:02:34 simonpj Exp $ -- -- Settings for the driver -- --- (c) The University of Glasgow 2000 +-- (c) The University of Glasgow 2002 -- ----------------------------------------------------------------------------- module DriverState where +#include "../includes/config.h" #include "HsVersions.h" -import CmStaticInfo +import SysTools ( getTopDir ) +import ParsePkgConf ( loadPackageConfig ) +import Packages ( PackageConfig(..), PackageConfigMap, + PackageName, mkPackageName, packageNameString, + packageDependents, + mungePackagePaths, emptyPkgMap, extendPkgMap, lookupPkg, + preludePackage, rtsPackage, haskell98Package ) import CmdLineOpts +import DriverPhases import DriverUtil import Util import Config -import Exception -import IOExts -#ifdef mingw32_TARGET_OS -import TmpFiles ( newTempName ) -import Directory ( removeFile ) -#endif import Panic +import DATA_IOREF ( IORef, newIORef, readIORef, writeIORef ) +import EXCEPTION + import List import Char import Monad +import Maybe ( fromJust, isJust ) +import Directory ( doesDirectoryExist ) ----------------------------------------------------------------------------- -- non-configured things @@ -34,10 +41,36 @@ import Monad cHaskell1Version = "5" -- i.e., Haskell 98 ----------------------------------------------------------------------------- --- Global compilation flags +-- GHC modes of operation + +data GhcMode + = DoMkDependHS -- ghc -M + | DoMkDLL -- ghc --mk-dll + | StopBefore Phase -- ghc -E | -C | -S | -c + | DoMake -- ghc --make + | DoInteractive -- ghc --interactive + | DoLink -- [ the default ] + deriving (Eq,Show) + +GLOBAL_VAR(v_GhcMode, DoLink, GhcMode) +GLOBAL_VAR(v_GhcModeFlag, "", String) + +setMode :: GhcMode -> String -> IO () +setMode m flag = do + old_mode <- readIORef v_GhcMode + old_flag <- readIORef v_GhcModeFlag + when (notNull old_flag && flag /= old_flag) $ + throwDyn (UsageError + ("cannot use `" ++ old_flag ++ "' with `" ++ flag ++ "'")) + writeIORef v_GhcMode m + writeIORef v_GhcModeFlag flag + +isCompManagerMode DoMake = True +isCompManagerMode DoInteractive = True +isCompManagerMode _ = False --- location of compiler-related files -GLOBAL_VAR(v_TopDir, error "no TOPDIR", String) +----------------------------------------------------------------------------- +-- Global compilation flags -- Cpp-related flags v_Hs_source_cpp_opts = global @@ -48,29 +81,38 @@ v_Hs_source_cpp_opts = global ] {-# NOINLINE v_Hs_source_cpp_opts #-} + -- Keep output from intermediate phases GLOBAL_VAR(v_Keep_hi_diffs, False, Bool) GLOBAL_VAR(v_Keep_hc_files, False, Bool) GLOBAL_VAR(v_Keep_s_files, False, Bool) GLOBAL_VAR(v_Keep_raw_s_files, False, Bool) GLOBAL_VAR(v_Keep_tmp_files, False, Bool) +#ifdef ILX +GLOBAL_VAR(v_Keep_il_files, False, Bool) +GLOBAL_VAR(v_Keep_ilx_files, False, Bool) +#endif -- Misc GLOBAL_VAR(v_Scale_sizes_by, 1.0, Double) -GLOBAL_VAR(v_Dry_run, False, Bool) GLOBAL_VAR(v_Static, True, Bool) GLOBAL_VAR(v_NoHsMain, False, Bool) GLOBAL_VAR(v_Recomp, True, Bool) GLOBAL_VAR(v_Collect_ghc_timing, False, Bool) GLOBAL_VAR(v_Do_asm_mangling, True, Bool) GLOBAL_VAR(v_Excess_precision, False, Bool) +GLOBAL_VAR(v_Read_DotGHCi, True, Bool) + +-- Preprocessor flags +GLOBAL_VAR(v_Hs_source_pp_opts, [], [String]) ----------------------------------------------------------------------------- -- Splitting object files (for libraries) GLOBAL_VAR(v_Split_object_files, False, Bool) -GLOBAL_VAR(v_Split_prefix, "", String) -GLOBAL_VAR(v_N_split_files, 0, Int) +GLOBAL_VAR(v_Split_info, ("",0), (String,Int)) + -- The split prefix and number of files + can_split :: Bool can_split = prefixMatch "i386" cTARGETPLATFORM @@ -85,17 +127,45 @@ can_split = prefixMatch "i386" cTARGETPLATFORM ----------------------------------------------------------------------------- -- Compiler output options -defaultHscLang - | cGhcWithNativeCodeGen == "YES" && - (prefixMatch "i386" cTARGETPLATFORM || - prefixMatch "sparc" cTARGETPLATFORM) = HscAsm - | otherwise = HscC - GLOBAL_VAR(v_Output_dir, Nothing, Maybe String) -GLOBAL_VAR(v_Object_suf, Nothing, Maybe String) GLOBAL_VAR(v_Output_file, Nothing, Maybe String) GLOBAL_VAR(v_Output_hi, Nothing, Maybe String) +-- called to verify that the output files & directories +-- point somewhere valid. +-- +-- The assumption is that the directory portion of these output +-- options will have to exist by the time 'verifyOutputFiles' +-- is invoked. +-- +verifyOutputFiles :: IO () +verifyOutputFiles = do + odir <- readIORef v_Output_dir + when (isJust odir) $ do + let dir = fromJust odir + flg <- doesDirectoryExist dir + when (not flg) (nonExistentDir "-odir" dir) + ofile <- readIORef v_Output_file + when (isJust ofile) $ do + let fn = fromJust ofile + flg <- doesDirNameExist fn + when (not flg) (nonExistentDir "-o" fn) + ohi <- readIORef v_Output_hi + when (isJust ohi) $ do + let hi = fromJust ohi + flg <- doesDirNameExist hi + when (not flg) (nonExistentDir "-ohi" hi) + where + nonExistentDir flg dir = + throwDyn (CmdLineError ("error: directory portion of " ++ + show dir ++ " does not exist (used with " ++ + show flg ++ " option.)")) + +GLOBAL_VAR(v_Object_suf, Nothing, Maybe String) +GLOBAL_VAR(v_HC_suf, Nothing, Maybe String) +GLOBAL_VAR(v_Hi_dir, Nothing, Maybe String) +GLOBAL_VAR(v_Hi_suf, "hi", String) + GLOBAL_VAR(v_Ld_inputs, [], [String]) odir_ify :: String -> IO String @@ -113,31 +183,22 @@ osuf_ify f = do Just s -> return (newsuf s f) ----------------------------------------------------------------------------- --- Hi Files - -GLOBAL_VAR(v_Hi_on_stdout, False, Bool) -GLOBAL_VAR(v_Hi_suf, "hi", String) - ------------------------------------------------------------------------------ -- Compiler optimisation options GLOBAL_VAR(v_OptLevel, 0, Int) -setOptLevel :: String -> IO () -setOptLevel "" = do { writeIORef v_OptLevel 1 } -setOptLevel "not" = writeIORef v_OptLevel 0 -setOptLevel [c] | isDigit c = do - let level = ord c - ord '0' - writeIORef v_OptLevel level -setOptLevel s = unknownFlagErr ("-O"++s) +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_CPR, 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 = @@ -175,82 +236,94 @@ buildCoreToDo = do max_iter <- readIORef v_MaxSimplifierIterations usageSP <- readIORef v_UsageSPInf strictness <- readIORef v_Strictness - cpr <- readIORef v_CPR cse <- readIORef v_CSE + rule_check <- readIORef v_RuleCheck if opt_level == 0 then return [ - CoreDoSimplify (isAmongSimpl [ + CoreDoSimplify (SimplPhase 0) [ MaxSimplifierIterations max_iter - ]) + ] ] else {- opt_level >= 1 -} return [ -- initial simplify: mk specialiser happy: minimum effort please - CoreDoSimplify (isAmongSimpl [ - SimplInlinePhase 0, + 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 - DontApplyRules, -- 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 False{-not full-}, + CoreDoFloatOutwards (FloatOutSw False False), CoreDoFloatInwards, - CoreDoSimplify (isAmongSimpl [ - SimplInlinePhase 1, - -- Want to run with inline phase 1 after the specialiser to give + 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 2. This made a difference in 'ansi' where an + -- 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 (isAmongSimpl [ + 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 - SimplInlinePhase 2, MaxSimplifierIterations max_iter - ]), + ], + case rule_check of { Just pat -> CoreDoRuleCheck 1 pat; Nothing -> CoreDoNothing }, - CoreDoSimplify (isAmongSimpl [ - MaxSimplifierIterations 2 - -- No -finline-phase: allow all Ids to be inlined now + 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, - if cpr then CoreDoCPResult else CoreDoNothing, CoreDoWorkerWrapper, CoreDoGlomBinds, - CoreDoSimplify (isAmongSimpl [ + CoreDoSimplify (SimplPhase 0) [ MaxSimplifierIterations max_iter - -- No -finline-phase: allow all Ids to be inlined now - ]), + ], - CoreDoFloatOutwards False{-not full-}, + 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 @@ -258,13 +331,6 @@ buildCoreToDo = do -- f_el22 (f_el21 r_midblock) --- Leave out lambda lifting for now --- "-fsimplify", -- Tidy up results of full laziness --- "[", --- "-fmax-simplifier-iterations2", --- "]", --- "-ffloat-outwards-full", - -- 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 @@ -276,6 +342,8 @@ buildCoreToDo = do -- 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 @@ -286,10 +354,9 @@ buildCoreToDo = do CoreDoNothing, -- Final clean-up simplification: - CoreDoSimplify (isAmongSimpl [ + CoreDoSimplify (SimplPhase 0) [ MaxSimplifierIterations max_iter - -- No -finline-phase: allow all Ids to be inlined now - ]) + ] ] buildStgToDo :: IO [ StgToDo ] @@ -317,53 +384,158 @@ GLOBAL_VAR(v_Library_paths, [], [String]) GLOBAL_VAR(v_Cmdline_libraries, [], [String]) +#ifdef darwin_TARGET_OS +GLOBAL_VAR(v_Framework_paths, [], [String]) +GLOBAL_VAR(v_Cmdline_frameworks, [], [String]) +#endif + addToDirList :: IORef [String] -> String -> IO () addToDirList ref path - = do paths <- readIORef ref - writeIORef ref (paths ++ split split_marker path) + = do paths <- readIORef ref + shiny_new_ones <- splitUp path + writeIORef ref (paths ++ filter notNull shiny_new_ones) + -- empty paths are ignored: there might be a trailing + -- ':' in the initial list, for example. Empty paths can + -- cause confusion when they are translated into -I options + -- for passing to gcc. + where + splitUp ::String -> IO [String] +#ifdef mingw32_TARGET_OS + -- 'hybrid' support for DOS-style paths in directory lists. + -- + -- That is, if "foo:bar:baz" is used, this interpreted as + -- consisting of three entries, 'foo', 'bar', 'baz'. + -- However, with "c:/foo:c:\\foo;x:/bar", this is interpreted + -- as four elts, "c:/foo", "c:\\foo", "x", and "/bar" -- + -- *provided* c:/foo exists and x:/bar doesn't. + -- + -- Notice that no attempt is made to fully replace the 'standard' + -- split marker ':' with the Windows / DOS one, ';'. The reason being + -- that this will cause too much breakage for users & ':' will + -- work fine even with DOS paths, if you're not insisting on being silly. + -- So, use either. + splitUp [] = return [] + splitUp (x:':':div:xs) + | div `elem` dir_markers = do + let (p,rs) = findNextPath xs + ps <- splitUp rs + {- + Consult the file system to check the interpretation + of (x:':':div:p) -- this is arguably excessive, we + could skip this test & just say that it is a valid + dir path. + -} + flg <- doesDirectoryExist (x:':':div:p) + if flg then + return ((x:':':div:p):ps) + else + return ([x]:(div:p):ps) + splitUp xs = do + let (p,rs) = findNextPath xs + ps <- splitUp rs + return (cons p ps) + + cons "" xs = xs + cons x xs = x:xs + + -- will be called either when we've consumed nought or the ":/" part of + -- a DOS path, so splitting is just a Q of finding the next split marker. + findNextPath xs = + case break (`elem` split_markers) xs of + (p, d:ds) -> (p, ds) + (p, xs) -> (p, xs) + + split_markers :: [Char] + split_markers = [':', ';'] + + dir_markers :: [Char] + dir_markers = ['/', '\\'] + +#else + splitUp xs = return (split split_marker xs) +#endif GLOBAL_VAR(v_HCHeader, "", String) ----------------------------------------------------------------------------- -- Packages -GLOBAL_VAR(v_Path_package_config, error "path_package_config", String) +------------------------ +-- The PackageConfigMap is read in from the configuration file +-- It doesn't change during a run +GLOBAL_VAR(v_Package_details, emptyPkgMap, PackageConfigMap) + +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 --- package list is maintained in dependency order -GLOBAL_VAR(v_Packages, ("std":"rts":"gmp":[]), [String]) +getPackageConfigMap :: IO PackageConfigMap +getPackageConfigMap = readIORef v_Package_details + + +------------------------ +-- 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]) + +getPackages :: IO [PackageName] +getPackages = readIORef v_Packages + +initPackageList = [haskell98Package, + preludePackage, + rtsPackage] addPackage :: String -> IO () addPackage package - = do pkg_details <- readIORef v_Package_details - case lookupPkg package pkg_details of - Nothing -> throwDyn (OtherError ("unknown package name: " ++ package)) - Just details -> do - ps <- readIORef v_Packages - unless (package `elem` ps) $ do - mapM_ addPackage (package_deps details) - ps <- readIORef v_Packages - writeIORef v_Packages (package:ps) + = do { pkg_details <- getPackageConfigMap + ; ps <- readIORef v_Packages + ; ps' <- add_package pkg_details ps (mkPackageName package) + -- Throws an exception if it fails + ; writeIORef v_Packages ps' } + +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') } + + | otherwise + = throwDyn (CmdLineError ("unknown package name: " ++ packageNameString p)) getPackageImportPath :: IO [String] getPackageImportPath = do ps <- getPackageInfo - return (nub (concat (map import_dirs ps))) + return (nub (filter notNull (concatMap import_dirs ps))) getPackageIncludePath :: IO [String] getPackageIncludePath = do ps <- getPackageInfo - return (nub (filter (not.null) (concatMap include_dirs ps))) + 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 (not.null) (concatMap c_includes ps)))) + return (reverse (nub (filter notNull (concatMap c_includes ps)))) getPackageLibraryPath :: IO [String] getPackageLibraryPath = do ps <- getPackageInfo - return (nub (concat (map library_dirs ps))) + return (nub (filter notNull (concatMap library_dirs ps))) getPackageLibraries :: IO [String] getPackageLibraries = do @@ -371,8 +543,38 @@ getPackageLibraries = do tag <- readIORef v_Build_tag let suffix = if null tag then "" else '_':tag return (concat ( - map (\p -> map (++suffix) (hs_libraries p) ++ extra_libraries p) ps + map (\p -> map (++suffix) (hACK (hs_libraries p)) ++ extra_libraries p) ps )) + where + -- This is a totally horrible (temporary) hack, for Win32. Problem is + -- that package.conf for Win32 says that the main prelude lib is + -- split into HSbase1, HSbase2 and HSbase3, which is needed due to a bug + -- in the GNU linker (PEi386 backend). However, we still only + -- have HSbase.a for static linking, not HSbase{1,2,3}.a + -- getPackageLibraries is called to find the .a's to add to the static + -- link line. On Win32, this hACK detects HSbase{1,2,3} and + -- replaces them with HSbase, so static linking still works. + -- Libraries needed for dynamic (GHCi) linking are discovered via + -- different route (in InteractiveUI.linkPackage). + -- See driver/PackageSrc.hs for the HSbase1/HSbase2 split definition. + -- THIS IS A STRICTLY TEMPORARY HACK (famous last words ...) + -- JRS 04 Sept 01: Same appalling hack for HSwin32[1,2] + -- KAA 29 Mar 02: Same appalling hack for HSobjectio[1,2,3,4] + hACK libs +# if !defined(mingw32_TARGET_OS) && !defined(cygwin32_TARGET_OS) + = libs +# else + = if "HSbase1" `elem` libs && "HSbase2" `elem` libs && "HSbase3" `elem` libs + then "HSbase" : filter (not.(isPrefixOf "HSbase")) libs + else + if "HSwin321" `elem` libs && "HSwin322" `elem` libs + then "HSwin32" : filter (not.(isPrefixOf "HSwin32")) libs + else + if "HSobjectio1" `elem` libs && "HSobjectio2" `elem` libs && "HSobjectio3" `elem` libs && "HSobjectio4" `elem` libs + then "HSobjectio" : filter (not.(isPrefixOf "HSobjectio")) libs + else + libs +# endif getPackageExtraGhcOpts :: IO [String] getPackageExtraGhcOpts = do @@ -389,23 +591,28 @@ getPackageExtraLdOpts = do ps <- getPackageInfo return (concatMap extra_ld_opts ps) +#ifdef darwin_TARGET_OS +getPackageFrameworkPath :: IO [String] +getPackageFrameworkPath = do + ps <- getPackageInfo + return (nub (filter notNull (concatMap framework_dirs ps))) + +getPackageFrameworks :: IO [String] +getPackageFrameworks = do + ps <- getPackageInfo + return (concatMap extra_frameworks ps) +#endif + getPackageInfo :: IO [PackageConfig] -getPackageInfo = do - ps <- readIORef v_Packages - getPackageDetails ps +getPackageInfo = do ps <- getPackages + getPackageDetails ps -getPackageDetails :: [String] -> IO [PackageConfig] +getPackageDetails :: [PackageName] -> IO [PackageConfig] getPackageDetails ps = do - pkg_details <- readIORef v_Package_details - return [ pkg | p <- ps, Just pkg <- [ lookupPkg p pkg_details ] ] + pkg_details <- getPackageConfigMap + return [ pkg | Just pkg <- map (lookupPkg pkg_details) ps ] -GLOBAL_VAR(v_Package_details, (error "package_details"), [PackageConfig]) -lookupPkg :: String -> [PackageConfig] -> Maybe PackageConfig -lookupPkg nm ps - = case [p | p <- ps, name p == nm] of - [] -> Nothing - (p:_) -> Just p ----------------------------------------------------------------------------- -- Ways @@ -431,6 +638,7 @@ data WayName | WayPar | WayGran | WaySMP + | WayNDP | WayDebug | WayUser_a | WayUser_b @@ -456,13 +664,15 @@ GLOBAL_VAR(v_Ways, [] ,[WayName]) allowed_combination way = way `elem` combs where -- the sub-lists must be ordered according to WayName, -- because findBuildTag sorts them - combs = [ [WayProf,WayUnreg], [WayProf,WaySMP] ] + combs = [ [WayProf, WayUnreg], + [WayProf, WaySMP] , + [WayProf, WayNDP] ] findBuildTag :: IO [String] -- new options findBuildTag = do way_names <- readIORef v_Ways case sort way_names of - [] -> do writeIORef v_Build_tag "" + [] -> do -- writeIORef v_Build_tag "" return [] [w] -> do let details = lkupWay w @@ -470,7 +680,7 @@ findBuildTag = do return (wayOpts details) ws -> if not (allowed_combination ws) - then throwDyn (OtherError $ + then throwDyn (CmdLineError $ "combination not supported: " ++ foldr1 (\a b -> a ++ '/':b) (map (wayName . lkupWay) ws)) @@ -561,6 +771,10 @@ way_details = , "-optc-DSMP" , "-fvia-C" ]), + (WayNDP, Way "ndp" "Nested data parallelism" + [ "-fparr" + , "-fflatten"]), + (WayUser_a, Way "a" "User way 'a'" ["$WAY_a_REAL_OPTS"]), (WayUser_b, Way "b" "User way 'b'" ["$WAY_b_REAL_OPTS"]), (WayUser_c, Way "c" "User way 'c'" ["$WAY_c_REAL_OPTS"]), @@ -588,16 +802,7 @@ unregFlags = , "-fvia-C" ] ----------------------------------------------------------------------------- --- Programs for particular phases - -GLOBAL_VAR(v_Pgm_L, error "pgm_L", String) -GLOBAL_VAR(v_Pgm_P, cRAWCPP, String) -GLOBAL_VAR(v_Pgm_c, cGCC, String) -GLOBAL_VAR(v_Pgm_m, error "pgm_m", String) -GLOBAL_VAR(v_Pgm_s, error "pgm_s", String) -GLOBAL_VAR(v_Pgm_a, cGCC, String) -GLOBAL_VAR(v_Pgm_l, cGCC, String) -GLOBAL_VAR(v_Pgm_dll, cMkDLL, String) +-- Options for particular phases GLOBAL_VAR(v_Opt_dep, [], [String]) GLOBAL_VAR(v_Anti_opt_C, [], [String])