%
-% (c) The AQUA Project, Glasgow University, 1996-98
+% (c) The University of Glasgow, 1996-2000
%
\section[CmdLineOpts]{Things to do with command-line options}
module CmdLineOpts (
CoreToDo(..),
- SimplifierSwitch(..),
+ SimplifierSwitch(..), isAmongSimpl,
StgToDo(..),
SwitchResult(..),
HscLang(..),
- classifyOpts,
+ DynFlag(..), -- needed non-abstractly by DriverFlags
+ DynFlags(..),
intSwitchSet,
switchIsOn,
+ isStaticHscFlag,
-- debugging opts
dopt_D_dump_absC,
import GlaExts
import Argv
import Constants -- Default values for some flags
+import Util
+import FastTypes
import Maybes ( firstJust )
import Panic ( panic )
for example. They therefore have the same value throughout the
invocation of hsc.
-Dynamic flags are represented by a function:
-
- checkDynFlag :: DynFlag -> SwitchResult
-
-which is passed into hsc by the compilation manager for every
-compilation. Dynamic flags are those that change on a per-compilation
-basis, perhaps because they may be present in the OPTIONS pragma at
-the top of a module.
+Dynamic flags are represented by an abstract type, DynFlags, which is
+passed into hsc by the compilation manager for every compilation.
+Dynamic flags are those that change on a per-compilation basis,
+perhaps because they may be present in the OPTIONS pragma at the top
+of a module.
Other flag-related blurb:
| CoreDoCPResult
| CoreDoGlomBinds
| CoreCSE
+
+ | CoreDoNothing -- useful when building up lists of these things
\end{code}
\begin{code}
coreToDo :: CoreToDo,
stgToDo :: StgToDo,
hscLang :: HscLang,
- flags :: [(DynFlag, SwitchResult)]
+ flags :: [DynFlag]
}
boolOpt :: DynFlag -> DynFlags -> Bool
-boolOpt f dflags
- = case lookup f (flags dflags) of
- Nothing -> False
- Just (SwBool b) -> b
- _ -> panic "boolOpt"
+boolOpt f dflags = f `elem` (flags dflags)
dopt_D_dump_all = boolOpt Opt_D_dump_all
dopt_D_dump_most = boolOpt Opt_D_dump_most
| otherwise = mAX_Real_Long_REG
\end{code}
-\begin{code}
-classifyOpts :: ([CoreToDo], -- Core-to-Core processing spec
- [StgToDo]) -- STG-to-STG processing spec
-
-classifyOpts = sep argv [] [] -- accumulators...
- where
- sep :: [FAST_STRING] -- cmd-line opts (input)
- -> [CoreToDo] -> [StgToDo] -- to_do accumulators
- -> ([CoreToDo], [StgToDo]) -- result
-
- sep [] core_td stg_td -- all done!
- = (reverse core_td, reverse stg_td)
-
-# define CORE_TD(to_do) sep opts (to_do:core_td) stg_td
-# define STG_TD(to_do) sep opts core_td (to_do:stg_td)
-
- sep (opt1:opts) core_td stg_td
- = case (_UNPK_ opt1) of -- the non-"just match a string" options are at the end...
- ',' : _ -> sep opts core_td stg_td -- it is for the parser
-
- "-fsimplify" -> -- gather up SimplifierSwitches specially...
- simpl_sep opts defaultSimplSwitches core_td stg_td
-
- "-ffloat-inwards" -> CORE_TD(CoreDoFloatInwards)
- "-ffloat-outwards" -> CORE_TD(CoreDoFloatOutwards False)
- "-ffloat-outwards-full" -> CORE_TD(CoreDoFloatOutwards True)
- "-fliberate-case" -> CORE_TD(CoreLiberateCase)
- "-fcse" -> CORE_TD(CoreCSE)
- "-fglom-binds" -> CORE_TD(CoreDoGlomBinds)
- "-fprint-core" -> CORE_TD(CoreDoPrintCore)
- "-fstatic-args" -> CORE_TD(CoreDoStaticArgs)
- "-fstrictness" -> CORE_TD(CoreDoStrictness)
- "-fworker-wrapper" -> CORE_TD(CoreDoWorkerWrapper)
- "-fspecialise" -> CORE_TD(CoreDoSpecialising)
- "-fusagesp" -> CORE_TD(CoreDoUSPInf)
- "-fcpr-analyse" -> CORE_TD(CoreDoCPResult)
-
- "-fstg-static-args" -> STG_TD(StgDoStaticArgs)
- "-dstg-stats" -> STG_TD(D_stg_stats)
- "-flambda-lift" -> STG_TD(StgDoLambdaLift)
- "-fmassage-stg-for-profiling" -> STG_TD(StgDoMassageForProfiling)
-
- _ -> -- NB: the driver is really supposed to handle bad options
- sep opts core_td stg_td
-
- ----------------
-
- simpl_sep :: [FAST_STRING] -- cmd-line opts (input)
- -> [SimplifierSwitch] -- simplifier-switch accumulator
- -> [CoreToDo] -> [StgToDo] -- to_do accumulators
- -> ([CoreToDo], [StgToDo]) -- result
-
- -- "simpl_sep" tailcalls "sep" once it's seen one set
- -- of SimplifierSwitches for a CoreDoSimplify.
-
-#ifdef DEBUG
- simpl_sep input@[] simpl_sw core_td stg_td
- = panic "simpl_sep []"
-#endif
+%************************************************************************
+%* *
+\subsection{List of static hsc flags}
+%* *
+%************************************************************************
- -- The SimplifierSwitches should be delimited by "[" and "]".
-
- simpl_sep (opt1:opts) simpl_sw core_td stg_td
- = case (_UNPK_ opt1) of
- "[" -> simpl_sep opts simpl_sw core_td stg_td
- "]" -> let
- this_simpl = CoreDoSimplify (isAmongSimpl simpl_sw)
- in
- sep opts (this_simpl : core_td) stg_td
-
- opt -> case matchSimplSw opt of
- Just sw -> simpl_sep opts (sw:simpl_sw) core_td stg_td
- Nothing -> simpl_sep opts simpl_sw core_td stg_td
-
-matchSimplSw opt
- = firstJust [ matchSwInt opt "-fmax-simplifier-iterations" MaxSimplifierIterations
- , matchSwInt opt "-finline-phase" SimplInlinePhase
- , matchSwBool opt "-fno-rules" DontApplyRules
- , matchSwBool opt "-fno-case-of-case" NoCaseOfCase
- , matchSwBool opt "-flet-to-case" SimplLetToCase
- ]
-
-matchSwBool :: String -> String -> a -> Maybe a
-matchSwBool opt str sw | opt == str = Just sw
- | otherwise = Nothing
-
-matchSwInt :: String -> String -> (Int -> a) -> Maybe a
-matchSwInt opt str sw = case startsWith str opt of
- Just opt_left -> Just (sw (read opt_left))
- Nothing -> Nothing
+\begin{code}
+isStaticHscFlag f =
+ f `elem` [
+ "-fwarn-duplicate-exports",
+ "-fwarn-hi-shadowing",
+ "-fwarn-incomplete-patterns",
+ "-fwarn-missing-fields",
+ "-fwarn-missing-methods",
+ "-fwarn-missing-signatures",
+ "-fwarn-name-shadowing",
+ "-fwarn-overlapping-patterns",
+ "-fwarn-simple-patterns",
+ "-fwarn-type-defaults",
+ "-fwarn-unused-binds",
+ "-fwarn-unused-imports",
+ "-fwarn-unused-matches",
+ "-fwarn-deprecations",
+ "-fauto-sccs-on-all-toplevs",
+ "-fauto-sccs-on-exported-toplevs",
+ "-fauto-sccs-on-individual-cafs",
+ "-fauto-sccs-on-dicts",
+ "-fscc-profiling",
+ "-fticky-ticky",
+ "-fall-strict",
+ "-fdicts-strict",
+ "-fgenerics",
+ "-firrefutable-tuples",
+ "-fnumbers-strict",
+ "-fparallel",
+ "-fsmp",
+ "-fsemi-tagging",
+ "-ffoldr-build-on",
+ "-flet-no-escape",
+ "-funfold-casms-in-hi-file",
+ "-fusagesp-on",
+ "-funbox-strict-fields",
+ "-femit-extern-decls",
+ "-fglobalise-toplev-names",
+ "-fgransim",
+ "-fignore-asserts",
+ "-fignore-interface-pragmas",
+ "-fno-hi-version-check",
+ "-fno-implicit-prelude",
+ "-dno-black-holing",
+ "-fomit-interface-pragmas",
+ "-fno-pre-inlining",
+ "-fdo-eta-reduction",
+ "-fdo-lambda-eta-expansion",
+ "-fcase-of-case",
+ "-fcase-merge",
+ "-fpedantic-bottoms",
+ "-fexcess-precision",
+ "-funfolding-update-in-place",
+ "-freport-compile",
+ "-fno-prune-decls",
+ "-fno-prune-tydecls",
+ "-static",
+ "-funregisterised",
+ "-v" ]
+ || any (flip prefixMatch f) [
+ "-fcontext-stack",
+ "-fliberate-case-threshold",
+ "-fhi-version=",
+ "-fhistory-size",
+ "-funfolding-interface-threshold",
+ "-funfolding-creation-threshold",
+ "-funfolding-use-threshold",
+ "-funfolding-fun-discount",
+ "-funfolding-keeness-factor"
+ ]
\end{code}
%************************************************************************
%* *
%************************************************************************
-In spite of the @Produce*@ constructor, these things behave just like
-enumeration types.
+These things behave just like enumeration types.
\begin{code}
instance Eq SimplifierSwitch where
- a == b = tagOf_SimplSwitch a _EQ_ tagOf_SimplSwitch b
+ a == b = tagOf_SimplSwitch a ==# tagOf_SimplSwitch b
instance Ord SimplifierSwitch where
- a < b = tagOf_SimplSwitch a _LT_ tagOf_SimplSwitch b
- a <= b = tagOf_SimplSwitch a _LE_ tagOf_SimplSwitch b
+ a < b = tagOf_SimplSwitch a <# tagOf_SimplSwitch b
+ a <= b = tagOf_SimplSwitch a <=# tagOf_SimplSwitch b
-tagOf_SimplSwitch (SimplInlinePhase _) = ILIT(1)
-tagOf_SimplSwitch (MaxSimplifierIterations _) = ILIT(2)
-tagOf_SimplSwitch DontApplyRules = ILIT(3)
-tagOf_SimplSwitch SimplLetToCase = ILIT(4)
-tagOf_SimplSwitch NoCaseOfCase = ILIT(5)
+tagOf_SimplSwitch (SimplInlinePhase _) = _ILIT(1)
+tagOf_SimplSwitch (MaxSimplifierIterations _) = _ILIT(2)
+tagOf_SimplSwitch DontApplyRules = _ILIT(3)
+tagOf_SimplSwitch SimplLetToCase = _ILIT(4)
+tagOf_SimplSwitch NoCaseOfCase = _ILIT(5)
-- If you add anything here, be sure to change lAST_SIMPL_SWITCH_TAG, too!
\begin{code}
isAmongSimpl :: [SimplifierSwitch] -> SimplifierSwitch -> SwitchResult
-
isAmongSimpl on_switches -- Switches mentioned later occur *earlier*
-- in the list; defaults right at the end.
= let
#endif
}
where
- mk_assoc_elem k@(MaxSimplifierIterations lvl) = (IBOX(tagOf_SimplSwitch k), SwInt lvl)
- mk_assoc_elem k@(SimplInlinePhase n) = (IBOX(tagOf_SimplSwitch k), SwInt n)
- mk_assoc_elem k = (IBOX(tagOf_SimplSwitch k), SwBool True) -- I'm here, Mom!
+ mk_assoc_elem k@(MaxSimplifierIterations lvl) = (_IBOX(tagOf_SimplSwitch k), SwInt lvl)
+ mk_assoc_elem k@(SimplInlinePhase n) = (_IBOX(tagOf_SimplSwitch k), SwInt n)
+ mk_assoc_elem k = (_IBOX(tagOf_SimplSwitch k), SwBool True) -- I'm here, Mom!
-- cannot have duplicates if we are going to use the array thing
rm_dups switches_so_far switch
else switch : switches_so_far
where
sw `is_elem` [] = False
- sw `is_elem` (s:ss) = (tagOf_SimplSwitch sw) _EQ_ (tagOf_SimplSwitch s)
+ sw `is_elem` (s:ss) = (tagOf_SimplSwitch sw) ==# (tagOf_SimplSwitch s)
|| sw `is_elem` ss
\end{code}