[project @ 1996-07-19 18:36:04 by partain]
[ghc-hetmet.git] / ghc / compiler / main / CmdLineOpts.lhs
index 104a7e5..13abecb 100644 (file)
@@ -1,5 +1,5 @@
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
+% (c) The AQUA Project, Glasgow University, 1996
 %
 \section[CmdLineOpts]{Things to do with command-line options}
 
@@ -7,28 +7,99 @@
 #include "HsVersions.h"
 
 module CmdLineOpts (
-       CmdLineInfo(..), SwitchResult(..),
-       GlobalSwitch(..), SimplifierSwitch(..),
        CoreToDo(..),
+       SimplifierSwitch(..),
        StgToDo(..),
-#ifdef DPH
-       PodizeToDo(..),
-#endif {- Data Parallel Haskell -}
-       
+       SwitchResult(..),
        classifyOpts,
-       switchIsOn, stringSwitchSet, intSwitchSet,
-       
-       -- to make the interface self-sufficient
-       Maybe, MainIO(..)
+
+       intSwitchSet,
+       switchIsOn,
+
+       maybe_CompilingGhcInternals,
+       opt_AllDemanded,
+       opt_AllStrict,
+       opt_AutoSccsOnAllToplevs,
+       opt_AutoSccsOnExportedToplevs,
+       opt_AutoSccsOnIndividualCafs,
+       opt_CompilingGhcInternals,
+       opt_UsingGhcInternals,
+       opt_D_dump_absC,
+       opt_D_dump_asm,
+       opt_D_dump_deforest,
+       opt_D_dump_deriv,
+       opt_D_dump_ds,
+       opt_D_dump_flatC,
+       opt_D_dump_occur_anal,
+       opt_D_dump_rdr,
+       opt_D_dump_realC,
+       opt_D_dump_rn,
+       opt_D_dump_simpl,
+       opt_D_dump_spec,
+       opt_D_dump_stg,
+       opt_D_dump_stranal,
+       opt_D_dump_tc,
+       opt_D_show_passes,
+       opt_D_simplifier_stats,
+       opt_D_source_stats,
+       opt_D_verbose_core2core,
+       opt_D_verbose_stg2stg,
+       opt_DoCoreLinting,
+       opt_DoSemiTagging,
+       opt_DoTickyProfiling,
+       opt_EnsureSplittableC,
+       opt_FoldrBuildOn,
+       opt_FoldrBuildTrace,
+       opt_ForConcurrent,
+       opt_GlasgowExts,
+       opt_GranMacros,
+       opt_Haskell_1_3,
+       opt_HiMap,
+       opt_IgnoreIfacePragmas,
+       opt_IgnoreStrictnessPragmas,
+       opt_IrrefutableEverything,
+       opt_IrrefutableTuples,
+       opt_NoImplicitPrelude,
+       opt_NumbersStrict,
+       opt_OmitBlackHoling,
+       opt_OmitDefaultInstanceMethods,
+       opt_OmitInterfacePragmas,
+       opt_PprStyle_All,
+       opt_PprStyle_Debug,
+       opt_PprStyle_User,
+       opt_ProduceC,
+       opt_ProduceHi,
+       opt_ProduceS,
+       opt_ReportWhyUnfoldingsDisallowed,
+       opt_ReturnInRegsThreshold,
+       opt_SccGroup,
+       opt_SccProfilingOn,
+       opt_ShowImportSpecs,
+       opt_ShowPragmaNameErrs,
+       opt_SigsRequired,
+       opt_SpecialiseAll,
+       opt_SpecialiseImports,
+       opt_SpecialiseOverloaded,
+       opt_SpecialiseTrace,
+       opt_SpecialiseUnboxed,
+       opt_StgDoLetNoEscapes,
+       opt_UnfoldingCreationThreshold,
+       opt_UnfoldingOverrideThreshold,
+       opt_UnfoldingUseThreshold,
+       opt_Verbose,
+       opt_WarnNameShadowing
     ) where
 
-import MainMonad
-import Maybes          ( maybeToBool, Maybe(..) )
-import Outputable
-import Util
-#ifdef __GLASGOW_HASKELL__
-import PreludeGlaST    -- bad bad bad boy, Will
-#endif
+IMPORT_1_3(Array(array, (//)))
+import PreludeGlaST    -- bad bad bad boy, Will (_Array internals)
+import Argv
+
+CHK_Ubiq() -- debugging consistency check
+
+import CgCompInfo      -- Default values for some flags
+
+import Maybes          ( assocMaybe, firstJust, maybeToBool )
+import Util            ( startsWith, panic, panic#, assertPanic )
 \end{code}
 
 A command-line {\em switch} is (generally) either on or off; e.g., the
@@ -45,31 +116,17 @@ main loop (\tr{main/Main.lhs}), in the Core-to-Core processing loop
 (\tr{simplCore/SimplCore.lhs), and in the STG-to-STG processing loop
 (\tr{simplStg/SimplStg.lhs}).
 
-We use function @classifyOpts@ to take raw command-line arguments from
-@GetArgs@ and get back the @CmdLineInfo@, which is what we really
-want.
-
 %************************************************************************
 %*                                                                     *
-\subsection[CmdLineOpts-datatype]{Datatypes associated with command-line options}
+\subsection{Datatypes associated with command-line options}
 %*                                                                     *
 %************************************************************************
 
 \begin{code}
-type CmdLineInfo 
-  = (GlobalSwitch -> SwitchResult,     -- Switch lookup function
-     [CoreToDo],                       -- Core-to-core spec
-#ifdef DPH 
-     [PodizeToDo],                     -- Podizer spec
-     [CoreToDo],                       -- post podized Core-to-core spec 
-#endif
-     [StgToDo]                         -- Stg-to-stg spec
-    )
-
 data SwitchResult
-  = SwBool     Bool    -- on/off
-  | SwString   String  -- nothing or a String
-  | SwInt      Int     -- nothing or an Int
+  = SwBool     Bool            -- on/off
+  | SwString   FAST_STRING     -- nothing or a String
+  | SwInt      Int             -- nothing or an Int
 \end{code}
 
 \begin{code}
@@ -81,8 +138,6 @@ data CoreToDo                -- These are diff core-to-core passes,
        (SimplifierSwitch -> SwitchResult)
                        -- Each run of the simplifier can take a different
                        -- set of simplifier-specific flags.
-
-  | CoreDoArityAnalysis -- UNUSED right now
   | CoreDoCalcInlinings1
   | CoreDoCalcInlinings2
   | CoreDoFloatInwards
@@ -93,12 +148,8 @@ data CoreToDo               -- These are diff core-to-core passes,
   | CoreDoStrictness
   | CoreDoSpecialising
   | CoreDoDeforest
-  | CoreDoAutoCostCentres
   | CoreDoFoldrBuildWorkerWrapper
   | CoreDoFoldrBuildWWAnal
--- ANDY:
---| CoreDoHaskPrint
---| CoreDoHaskLetlessPrint
 \end{code}
 
 \begin{code}
@@ -113,141 +164,6 @@ data StgToDo
 \end{code}
 
 \begin{code}
-#ifdef DPH
-data PodizeToDo
-  = PodizeNeeded Int           -- Which dimensioned PODs need vectorizing
-#endif {- Data Parallel Haskell -}
-\end{code}
-
-@GlobalSwitches@ may be visible everywhere in the compiler.
-@SimplifierSwitches@ (which follow) are visible only in the main
-Core-to-Core simplifier.
-
-\begin{code}
-data GlobalSwitch
-  = ProduceC   String  -- generate C output into this file
-  | ProduceS   String  -- generate native-code assembler into this file
-  | ProduceHi  String  -- generate .hi interface  into this file
---UNUSED:  | ProduceHu String  -- generate .hu usage-info into this file
-
-  | AsmTarget  String  -- architecture we are generating code for
-  | ForConcurrent
-
-  | Haskell_1_3                -- if set => Haskell 1.3; else 1.2
-  | GlasgowExts                -- Glasgow Haskell extensions allowed
-  | CompilingPrelude   -- Compiling prelude source
-
-  | HideBuiltinNames   -- fiddle builtin namespace; used for compiling Prelude
-  | HideMostBuiltinNames
-  | EnsureSplittableC String -- (by globalising all top-level Ids w/ this String)
-
-  | Verbose
-  | PprStyle_User      -- printing "level" (mostly for debugging)
-  | PprStyle_Debug
-  | PprStyle_All
-
-  | DoCoreLinting      -- paranoia flags
-  | EmitArityChecks
-
-  | OmitInterfacePragmas
-  | OmitDerivedRead
-  | OmitReexportedInstances
-
-  | UnfoldingUseThreshold      Int  -- global one; see also SimplUnf...
-  | UnfoldingCreationThreshold Int  -- ditto
-  | UnfoldingOverrideThreshold Int
-
-  | ReportWhyUnfoldingsDisallowed
-  | UseGetMentionedVars
-  | ShowPragmaNameErrs
-  | NameShadowingNotOK
-  | SigsRequired
-
-  | SccProfilingOn
-  | AutoSccsOnExportedToplevs
-  | AutoSccsOnAllToplevs
-  | AutoSccsOnIndividualCafs
---UNUSED:  | AutoSccsOnIndividualDicts
-  | SccGroup String    -- name of "group" for this cost centres in this module
-
-  | DoTickyProfiling
-
-  | DoSemiTagging
-
-  -- ToDo: turn these into SimplifierSwitches?
-  | FoldrBuildOn       -- If foldr/build-style transformations are on.
-                       -- See also SimplDoFoldrBuild, which is used
-                       -- inside the simplifier.
-  | FoldrBuildTrace    -- show all foldr/build optimisations.
-
-  | SpecialiseImports     -- Treat non-essential spec requests as errors
-  | ShowImportSpecs       -- Output spec requests for non-essential specs
-  | OmitUnspecialisedCode  -- ToDo? (Patrick)
-  | SpecialiseOverloaded
-  | SpecialiseUnboxed
-  | SpecialiseAll
-  | SpecialiseTrace
-
-  -- this batch of flags is for particular experiments;
-  -- v unlikely to be used in any other circumstance
---UNUSED:  | OmitStkChecks
-  | OmitBlackHoling
-  | StgDoLetNoEscapes
-  | IgnoreStrictnessPragmas -- ToDo: still useful?
-  | IrrefutableTuples      -- We inject extra "LazyPat"s in the typechecker
-  | IrrefutableEverything   -- (TcPat); doing it any earlier would mean that
-                           -- deriving-generated code wouldn't be irrefutablified.
-  | AllStrict
-  | AllDemanded
-
--- NOT REALLY USED:  | D_dump_type_info        -- for Robin Popplestone stuff
-
-  | D_dump_rif2hs      -- debugging: print out various things
-  | D_dump_rn4
-  | D_dump_tc
-  | D_dump_deriv
-  | D_dump_ds
-  | D_dump_occur_anal
-  | D_dump_simpl
-  | D_dump_spec
-  | D_dump_stranal
-  | D_dump_deforest
-  | D_dump_stg
-  | D_dump_absC
-  | D_dump_flatC
-  | D_dump_realC
-  | D_dump_asm
-  | D_dump_core_passes         -- A Gill-ism
-  | D_dump_core_passes_info    -- Yet another Gill-ism
-
-  | D_verbose_core2core
-  | D_verbose_stg2stg
-  | D_simplifier_stats
-
-{- ????
-  | Extra__Flag1
-  | Extra__Flag2
-  | Extra__Flag3
-  | Extra__Flag4
-  | Extra__Flag5
-  | Extra__Flag6
-  | Extra__Flag7
-  | Extra__Flag8
-  | Extra__Flag9
--}
-
-#ifdef DPH
-  | PodizeIntelligent
-  | PodizeAggresive
-  | PodizeVeryAggresive
-  | PodizeExtremelyAggresive
-  | D_dump_pod
-  | D_dump_psimpl
-  | D_dump_nextC
-#endif {- Data Parallel Haskell -}
-\end{code}
-
-\begin{code}
 data SimplifierSwitch
   = SimplOkToDupCode
   | SimplFloatLetsExposingWHNF
@@ -257,21 +173,17 @@ data SimplifierSwitch
   | SimplReuseCon
   | SimplCaseOfCase
   | SimplLetToCase
---UNUSED:  | SimplOkToInlineInLambdas
   | SimplMayDeleteConjurableIds
   | SimplPedanticBottoms -- see Simplifier for an explanation
   | SimplDoArityExpand  -- expand arity of bindings
   | SimplDoFoldrBuild   -- This is the per-simplification flag;
                         -- see also FoldrBuildOn, used elsewhere
                         -- in the compiler.
-  | SimplDoNewOccurAnal         --  use the *new*, all singing, Occurance analysis
   | SimplDoInlineFoldrBuild
                         -- inline foldr/build (*after* f/b rule is used)
 
   | IgnoreINLINEPragma
   | SimplDoLambdaEtaExpansion
---UNUSED:  | SimplDoMonadEtaExpansion
-
   | SimplDoEtaReduction
 
   | EssentialUnfoldingsOnly -- never mind the thresholds, only
@@ -283,213 +195,167 @@ data SimplifierSwitch
   | MaxSimplifierIterations Int
 
   | SimplUnfoldingUseThreshold      Int -- per-simplification variants
+  | SimplUnfoldingConDiscount       Int
   | SimplUnfoldingCreationThreshold Int
 
   | KeepSpecPragmaIds      -- We normally *toss* Ids we can do without
   | KeepUnusedBindings
 
-{-
-  | Extra__SimplFlag1
-  | Extra__SimplFlag2
-  | Extra__SimplFlag3
-  | Extra__SimplFlag4
-  | Extra__SimplFlag5
-  | Extra__SimplFlag6
-  | Extra__SimplFlag7
-  | Extra__SimplFlag8
--}
+  | SimplNoLetFromCase     -- used when turning off floating entirely
+  | SimplNoLetFromApp      -- (for experimentation only) WDP 95/10
+  | SimplNoLetFromStrictLet
+
+  | SimplDontFoldBackAppend
+                       -- we fold `foldr (:)' back into flip (++),
+                       -- but we *don't* want to do it when compiling
+                       -- List.hs, otherwise
+                       -- xs ++ ys = foldr (:) ys xs
+                       -- {- via our loopback -}
+                       -- xs ++ ys = xs ++ ys
+                       -- Oops!
+                       -- So only use this flag inside List.hs
+                       -- (Sigh, what a HACK, Andy.  WDP 96/01)
+
+  | SimplCaseMerge
 \end{code}
 
 %************************************************************************
 %*                                                                     *
-\subsection[CmdLineOpts-classify]{Classifying command-line options}
+\subsection{Classifying command-line options}
 %*                                                                     *
 %************************************************************************
 
 \begin{code}
-classifyOpts :: [String]           -- cmd-line args, straight from GetArgs
-            -> MainIO CmdLineInfo
--- The MainIO bit is because we might find an unknown flag
--- in which case we print an error message
-
-#ifndef DPH
-classifyOpts opts
-  = sep opts [] [] [] -- accumulators...
-  where
-    sep :: [String]                             -- cmd-line opts (input)
-       -> [GlobalSwitch]                        -- switch accumulator
-       -> [CoreToDo] -> [StgToDo]               -- to_do accumulators
-       -> MainIO CmdLineInfo                    -- result
-
-    sep [] glob_sw core_td stg_td
-      = returnMn (
-         isAmong glob_sw,
-         reverse core_td,
-         reverse stg_td
-       )
-
-    sep (opt1:opts) glob_sw core_td stg_td
-
-#else {- Data Parallel Haskell -}
-classifyOpts opts
-  = sep opts [] [] [] [] [] -- accumulators...
+lookUp    :: FAST_STRING -> Bool
+lookup_int :: String -> Maybe Int
+lookup_str :: String -> Maybe String
+
+lookUp     sw = maybeToBool (assoc_opts sw)
+       
+lookup_str sw = firstJust (map (startsWith sw) unpacked_opts)
+
+lookup_int sw = case (lookup_str sw) of
+                 Nothing -> Nothing
+                 Just xx -> Just (read xx)
+
+assoc_opts    = assocMaybe [ (a, True) | a <- argv ]
+unpacked_opts = map _UNPK_ argv
+\end{code}
+
+\begin{code}
+opt_AllDemanded                        = lookUp  SLIT("-fall-demanded")
+opt_AllStrict                  = lookUp  SLIT("-fall-strict")
+opt_AutoSccsOnAllToplevs       = lookUp  SLIT("-fauto-sccs-on-all-toplevs")
+opt_AutoSccsOnExportedToplevs  = lookUp  SLIT("-fauto-sccs-on-exported-toplevs")
+opt_AutoSccsOnIndividualCafs   = lookUp  SLIT("-fauto-sccs-on-individual-cafs")
+opt_D_dump_absC                        = lookUp  SLIT("-ddump-absC")
+opt_D_dump_asm                 = lookUp  SLIT("-ddump-asm")
+opt_D_dump_deforest            = lookUp  SLIT("-ddump-deforest")
+opt_D_dump_deriv               = lookUp  SLIT("-ddump-deriv")
+opt_D_dump_ds                  = lookUp  SLIT("-ddump-ds")
+opt_D_dump_flatC               = lookUp  SLIT("-ddump-flatC")
+opt_D_dump_occur_anal          = lookUp  SLIT("-ddump-occur-anal")
+opt_D_dump_rdr                 = lookUp  SLIT("-ddump-rdr")
+opt_D_dump_realC               = lookUp  SLIT("-ddump-realC")
+opt_D_dump_rn                  = lookUp  SLIT("-ddump-rn")
+opt_D_dump_simpl               = lookUp  SLIT("-ddump-simpl")
+opt_D_dump_spec                        = lookUp  SLIT("-ddump-spec")
+opt_D_dump_stg                 = lookUp  SLIT("-ddump-stg")
+opt_D_dump_stranal             = lookUp  SLIT("-ddump-stranal")
+opt_D_dump_tc                  = lookUp  SLIT("-ddump-tc")
+opt_D_show_passes              = lookUp  SLIT("-dshow-passes")
+opt_D_simplifier_stats         = lookUp  SLIT("-dsimplifier-stats")
+opt_D_source_stats             = lookUp  SLIT("-dsource-stats")
+opt_D_verbose_core2core                = lookUp  SLIT("-dverbose-simpl")
+opt_D_verbose_stg2stg          = lookUp  SLIT("-dverbose-stg")
+opt_DoCoreLinting              = lookUp  SLIT("-dcore-lint")
+opt_DoSemiTagging              = lookUp  SLIT("-fsemi-tagging")
+opt_DoTickyProfiling           = lookUp  SLIT("-fticky-ticky")
+opt_FoldrBuildOn               = lookUp  SLIT("-ffoldr-build-on")
+opt_FoldrBuildTrace            = lookUp  SLIT("-ffoldr-build-trace")
+opt_ForConcurrent              = lookUp  SLIT("-fconcurrent")
+opt_GranMacros                 = lookUp  SLIT("-fgransim")
+opt_GlasgowExts                        = lookUp  SLIT("-fglasgow-exts")
+opt_Haskell_1_3                        = lookUp  SLIT("-fhaskell-1.3")
+opt_IgnoreStrictnessPragmas    = lookUp  SLIT("-fignore-strictness-pragmas")
+opt_IrrefutableEverything      = lookUp  SLIT("-firrefutable-everything")
+opt_IrrefutableTuples          = lookUp  SLIT("-firrefutable-tuples")
+opt_WarnNameShadowing          = lookUp  SLIT("-fwarn-name-shadowing")
+opt_NumbersStrict              = lookUp  SLIT("-fnumbers-strict")
+opt_OmitBlackHoling            = lookUp  SLIT("-dno-black-holing")
+opt_OmitDefaultInstanceMethods = lookUp  SLIT("-fomit-default-instance-methods")
+opt_OmitInterfacePragmas       = lookUp  SLIT("-fomit-interface-pragmas")
+opt_PprStyle_All               = lookUp  SLIT("-dppr-all")
+opt_PprStyle_Debug             = lookUp  SLIT("-dppr-debug")
+opt_PprStyle_User              = lookUp  SLIT("-dppr-user")
+opt_ReportWhyUnfoldingsDisallowed= lookUp SLIT("-freport-disallowed-unfoldings")
+opt_SccProfilingOn             = lookUp  SLIT("-fscc-profiling")
+opt_ShowImportSpecs            = lookUp  SLIT("-fshow-import-specs")
+opt_ShowPragmaNameErrs         = lookUp  SLIT("-fshow-pragma-name-errs")
+opt_SigsRequired               = lookUp  SLIT("-fsignatures-required")
+opt_SpecialiseAll              = lookUp  SLIT("-fspecialise-all")
+opt_SpecialiseImports          = lookUp  SLIT("-fspecialise-imports")
+opt_SpecialiseOverloaded       = lookUp  SLIT("-fspecialise-overloaded")
+opt_SpecialiseTrace            = lookUp  SLIT("-ftrace-specialisation")
+opt_SpecialiseUnboxed          = lookUp  SLIT("-fspecialise-unboxed")
+opt_StgDoLetNoEscapes          = lookUp  SLIT("-flet-no-escape")
+opt_Verbose                    = lookUp  SLIT("-v")
+opt_UsingGhcInternals          = lookUp  SLIT("-fusing-ghc-internals")
+opt_CompilingGhcInternals      = maybeToBool maybe_CompilingGhcInternals
+maybe_CompilingGhcInternals    = lookup_str "-fcompiling-ghc-internals="
+opt_SccGroup                   = lookup_str "-G="
+opt_ProduceC                   = lookup_str "-C="
+opt_ProduceS                   = lookup_str "-S="
+opt_ProduceHi                  = lookup_str "-hifile=" -- the one to produce this time 
+opt_HiMap                      = lookup_str "-himap="  -- file saying where to look for .hi files
+opt_EnsureSplittableC          = lookup_str "-fglobalise-toplev-names="
+opt_UnfoldingUseThreshold      = lookup_int "-funfolding-use-threshold"
+opt_UnfoldingCreationThreshold = lookup_int "-funfolding-creation-threshold"
+opt_UnfoldingOverrideThreshold = lookup_int "-funfolding-override-threshold"
+opt_ReturnInRegsThreshold      = lookup_int "-freturn-in-regs-threshold"
+
+opt_NoImplicitPrelude          = lookUp  SLIT("-fno-implicit-prelude")
+opt_IgnoreIfacePragmas         = lookUp  SLIT("-fignore-interface-pragmas")
+\end{code}
+
+\begin{code}
+classifyOpts :: ([CoreToDo],   -- Core-to-Core processing spec
+                [StgToDo])     -- STG-to-STG   processing spec
+
+classifyOpts = sep argv [] [] -- accumulators...
   where
-    sep :: [String]                             -- cmd-line opts (input)
-       -> [GlobalSwitch]                        -- switch accumulator
-       -> [CoreToDo] -> [PodizeToDo]            -- to_do accumulators
-       -> [CoreToDo] -> [StgToDo]
-       -> MainIO CmdLineInfo                    -- result
-
-    -- see also the related "simpl_sep" function, used
-    -- to collect up the SimplifierSwitches for a "-fsimplify".
-
-    sep [] glob_sw core_td pod_td pcore_td stg_td
-      = returnMn (
-         isAmong glob_sw,
-         reverse core_td,
-         reverse pod_td,
-         reverse pcore_td,
-         reverse stg_td
-       )
-
-    sep (opt1:opts) glob_sw core_td pod_td pcore_td stg_td
-#endif {- Data Parallel Haskell -}
-
-#ifndef DPH
-#define GLOBAL_SW(switch)   sep opts (switch:glob_sw) core_td stg_td
-#define CORE_TD(to_do)     sep opts glob_sw (to_do:core_td) stg_td
-#define POD_TD(to_do)       sep opts glob_sw core_td stg_td
-#define PAR_CORE_TD(to_do)  sep opts glob_sw core_td stg_td
-#define BOTH_CORE_TD(to_do) sep opts glob_sw (to_do:core_td) stg_td
-#define STG_TD(to_do)      sep opts glob_sw core_td (to_do:stg_td)
-#define IGNORE_ARG()       sep opts glob_sw core_td stg_td
+    sep :: [FAST_STRING]                        -- cmd-line opts (input)
+       -> [CoreToDo] -> [StgToDo]       -- to_do accumulators
+       -> ([CoreToDo], [StgToDo])       -- result
 
-#else
+    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)
+#      define IGNORE_ARG()   sep opts core_td stg_td
+
+    sep (opt1:opts) core_td stg_td
+      =
+       case (_UNPK_ opt1) of -- the non-"just match a string" options are at the end...
+
+         ',' : _       -> IGNORE_ARG() -- it is for the parser
+
+         "-fsimplify"  -> -- gather up SimplifierSwitches specially...
+                          simpl_sep opts defaultSimplSwitches core_td stg_td
 
-#define GLOBAL_SW(switch) sep opts (switch:glob_sw) core_td pod_td pcore_td stg_td
-#define CORE_TD(to_do)   sep opts glob_sw (to_do:core_td) pod_td pcore_td stg_td
-#define POD_TD(to_do)    sep opts glob_sw core_td (to_do:pod_td) pcore_td stg_td
-#define PAR_CORE_TD(do)          sep opts glob_sw core_td pod_td (do:pcore_td) stg_td
-#define BOTH_CORE_TD(do)  sep opts glob_sw (do:core_td) pod_td (do:pcore_td) stg_td
-#define STG_TD(to_do)    sep opts glob_sw core_td pod_td pcore_td (to_do:stg_td)
-#define IGNORE_ARG()     sep opts glob_sw core_td pod_td pcore_td stg_td
-
-#endif {- Data Parallel Haskell -}
-
--- ToDo: DPH-ify
-#define GLOBAL_SIMPL_SW(switch) simpl_sep opts (switch:simpl_sw) glob_sw core_td stg_td
-
-      = let
-           maybe_fasm          = starts_with "-fasm-"  opt1
-           maybe_G             = starts_with "-G"      opt1
-           maybe_C             = starts_with "-C"      opt1
-           maybe_S             = starts_with "-S"      opt1
-           maybe_hi            = starts_with "-hi"     opt1
-           maybe_hu            = starts_with "-hu"     opt1
-           maybe_uut           = starts_with "-funfolding-use-threshold"      opt1
-           maybe_uct           = starts_with "-funfolding-creation-threshold" opt1
-           maybe_uot           = starts_with "-funfolding-override-threshold" opt1
-           maybe_gtn           = starts_with "-fglobalise-toplev-names"       opt1
-           starts_with_fasm    = maybeToBool maybe_fasm
-           starts_with_G       = maybeToBool maybe_G
-           starts_with_C       = maybeToBool maybe_C
-           starts_with_S       = maybeToBool maybe_S
-           starts_with_hi      = maybeToBool maybe_hi
-           starts_with_hu      = maybeToBool maybe_hu
-           starts_with_uut     = maybeToBool maybe_uut
-           starts_with_uct     = maybeToBool maybe_uct
-           starts_with_uot     = maybeToBool maybe_uot
-           starts_with_gtn     = maybeToBool maybe_gtn
-           (Just after_fasm)   = maybe_fasm
-           (Just after_G)      = maybe_G
-           (Just after_C)      = maybe_C
-           (Just after_S)      = maybe_S
-           (Just after_hi)     = maybe_hi
-           (Just after_hu)     = maybe_hu
-           (Just after_uut)    = maybe_uut
-           (Just after_uct)    = maybe_uct
-           (Just after_uot)    = maybe_uot
-           (Just after_gtn)    = maybe_gtn
-       in
-       case opt1 of -- the non-"just match a string" options are at the end...
-         ',' : _          -> IGNORE_ARG() -- it is for the parser
-         "-ddump-rif2hs"  -> GLOBAL_SW(D_dump_rif2hs)
-         "-ddump-rn4"     -> GLOBAL_SW(D_dump_rn4)
-         "-ddump-tc"      -> GLOBAL_SW(D_dump_tc)
-         "-ddump-deriv"   -> GLOBAL_SW(D_dump_deriv)
-         "-ddump-ds"      -> GLOBAL_SW(D_dump_ds)
-         "-ddump-stranal" -> GLOBAL_SW(D_dump_stranal)
-         "-ddump-deforest"-> GLOBAL_SW(D_dump_deforest)
-         "-ddump-spec"    -> GLOBAL_SW(D_dump_spec)
-         "-ddump-simpl"   -> GLOBAL_SW(D_dump_simpl)
-         "-ddump-occur-anal" -> GLOBAL_SW(D_dump_occur_anal)
--- NOT REALLY USED:      "-ddump-type-info"  -> GLOBAL_SW(D_dump_type_info)
-#ifdef DPH
-         "-ddump-pod"   ->   GLOBAL_SW(D_dump_pod)
-         "-ddump-psimpl"->   GLOBAL_SW(D_dump_psimpl)
-         "-ddump-nextC" ->   GLOBAL_SW(D_dump_nextC)
-#endif {- Data Parallel Haskell -}
-
-         "-ddump-stg"  ->    GLOBAL_SW(D_dump_stg)
-         "-ddump-absC" ->    GLOBAL_SW(D_dump_absC)
-         "-ddump-flatC"->    GLOBAL_SW(D_dump_flatC)
-         "-ddump-realC"->    GLOBAL_SW(D_dump_realC)
-          "-ddump-asm"  ->    GLOBAL_SW(D_dump_asm)
-
-          "-ddump-core-passes"      -> GLOBAL_SW(D_dump_core_passes)
--- ANDY:  "-ddump-haskell"         -> GLOBAL_SW(D_dump_core_passes_info)
-         "-dsimplifier-stats"      -> GLOBAL_SW(D_simplifier_stats)
-
-         "-dverbose-simpl" ->GLOBAL_SW(D_verbose_core2core)
-         "-dverbose-stg" ->  GLOBAL_SW(D_verbose_stg2stg)
-
-         "-fuse-get-mentioned-vars" -> GLOBAL_SW(UseGetMentionedVars)
-
-         "-fhaskell-1.3"               -> GLOBAL_SW(Haskell_1_3)
-         "-dcore-lint"                 -> GLOBAL_SW(DoCoreLinting)
-         "-fomit-interface-pragmas"    -> GLOBAL_SW(OmitInterfacePragmas)
-         "-fignore-strictness-pragmas" -> GLOBAL_SW(IgnoreStrictnessPragmas)
-         "-firrefutable-tuples"        -> GLOBAL_SW(IrrefutableTuples)
-         "-firrefutable-everything"    -> GLOBAL_SW(IrrefutableEverything)
-         "-fall-strict"                -> GLOBAL_SW(AllStrict)
-         "-fall-demanded"              -> GLOBAL_SW(AllDemanded)
-
-         "-fsemi-tagging"   -> GLOBAL_SW(DoSemiTagging)
-
-         "-fsimplify"       -> -- gather up SimplifierSwitches specially...
-                               simpl_sep opts [] glob_sw core_td stg_td
-
---UNUSED: "-farity-analysis" -> CORE_TD(CoreDoArityAnalysis)
          "-fcalc-inlinings1"-> CORE_TD(CoreDoCalcInlinings1)
          "-fcalc-inlinings2"-> CORE_TD(CoreDoCalcInlinings2)
          "-ffloat-inwards"  -> CORE_TD(CoreDoFloatInwards)
          "-ffull-laziness"  -> CORE_TD(CoreDoFullLaziness)
-          "-fliberate-case"  -> CORE_TD(CoreLiberateCase)
-          "-fprint-core"     -> CORE_TD(CoreDoPrintCore)
+         "-fliberate-case"  -> CORE_TD(CoreLiberateCase)
+         "-fprint-core"     -> CORE_TD(CoreDoPrintCore)
          "-fstatic-args"    -> CORE_TD(CoreDoStaticArgs)
          "-fstrictness"     -> CORE_TD(CoreDoStrictness)
          "-fspecialise"     -> CORE_TD(CoreDoSpecialising)
          "-fdeforest"       -> CORE_TD(CoreDoDeforest)
-         "-fadd-auto-sccs"  -> CORE_TD(CoreDoAutoCostCentres)
          "-ffoldr-build-worker-wrapper"  -> CORE_TD(CoreDoFoldrBuildWorkerWrapper)
          "-ffoldr-build-ww-anal"  -> CORE_TD(CoreDoFoldrBuildWWAnal)
---ANDY:   "-fprint-haskell-core" -> CORE_TD(CoreDoHaskPrint)
---        "-fprint-haskell-letless-core" -> CORE_TD(CoreDoHaskLetlessPrint)
-
-         "-fspecialise-overloaded" -> GLOBAL_SW(SpecialiseOverloaded)
-         "-fspecialise-unboxed"    -> GLOBAL_SW(SpecialiseUnboxed)
-         "-fspecialise-all"        -> GLOBAL_SW(SpecialiseAll)
-         "-fspecialise-imports"    -> GLOBAL_SW(SpecialiseImports)
-         "-fshow-import-specs"     -> GLOBAL_SW(ShowImportSpecs)
-         "-ftrace-specialisation"  -> GLOBAL_SW(SpecialiseTrace)
-
-         "-freport-disallowed-unfoldings"
-                            -> GLOBAL_SW(ReportWhyUnfoldingsDisallowed)
-
-         "-fomit-derived-read" -> GLOBAL_SW(OmitDerivedRead)
-
-          "-ffoldr-build-on"       -> GLOBAL_SW(FoldrBuildOn)
-          "-ffoldr-build-trace"            -> GLOBAL_SW(FoldrBuildTrace)
 
          "-fstg-static-args" -> STG_TD(StgDoStaticArgs)
          "-fupdate-analysis" -> STG_TD(StgDoUpdateAnalysis)
@@ -497,153 +363,88 @@ classifyOpts opts
          "-flambda-lift"     -> STG_TD(StgDoLambdaLift)
          "-fmassage-stg-for-profiling" -> STG_TD(StgDoMassageForProfiling)
 
-         "-flet-no-escape"   -> GLOBAL_SW(StgDoLetNoEscapes)
-
-#ifdef DPH
-         "-fpodize-vector"              -> POD_TD(PodizeNeeded 1)
-         "-fpodize-matrix"              -> POD_TD(PodizeNeeded 2)
-         "-fpodize-cube"                -> POD_TD(PodizeNeeded 3)
-         "-fpodize-intelligent"         -> GLOBAL_SW(PodizeIntelligent)
-         "-fpodize-aggresive"           -> GLOBAL_SW(PodizeAggresive)
-         "-fpodize-very-aggresive"      -> GLOBAL_SW(PodizeVeryAggresive)
-         "-fpodize-extremely-aggresive" -> GLOBAL_SW(PodizeExtremelyAggresive)
-#endif {- Data Parallel Haskell -}
-
-         "-v"          ->          GLOBAL_SW(Verbose)
-
-         "-fglasgow-exts" ->       GLOBAL_SW(GlasgowExts)
-         "-prelude"    ->          GLOBAL_SW(CompilingPrelude)
-
-         "-fscc-profiling"                 -> GLOBAL_SW(SccProfilingOn)
-         "-fauto-sccs-on-exported-toplevs" -> GLOBAL_SW(AutoSccsOnExportedToplevs)
-         "-fauto-sccs-on-all-toplevs"      -> GLOBAL_SW(AutoSccsOnAllToplevs)
-         "-fauto-sccs-on-individual-cafs"  -> GLOBAL_SW(AutoSccsOnIndividualCafs)
---UNUSED: "-fauto-sccs-on-individual-dicts" -> GLOBAL_SW(AutoSccsOnIndividualDicts)
-
-         "-fstg-reduction-counts"  -> GLOBAL_SW(DoTickyProfiling)
-
-         "-dppr-user"  ->          GLOBAL_SW(PprStyle_User)
-         "-dppr-debug" ->          GLOBAL_SW(PprStyle_Debug)
-         "-dppr-all"   ->          GLOBAL_SW(PprStyle_All)
-
-         "-fhide-builtin-names"->      GLOBAL_SW(HideBuiltinNames)
-         "-fmin-builtin-names" ->      GLOBAL_SW(HideMostBuiltinNames)
-
-         "-fconcurrent"            -> GLOBAL_SW(ForConcurrent)
-
-         "-fomit-unspecialised-code" -> GLOBAL_SW(OmitUnspecialisedCode)
-         "-fshow-pragma-name-errs" -> GLOBAL_SW(ShowPragmaNameErrs)
-         "-fname-shadowing-not-ok" -> GLOBAL_SW(NameShadowingNotOK)
-         "-fsignatures-required"   -> GLOBAL_SW(SigsRequired)
-         "-fomit-reexported-instances" -> GLOBAL_SW(OmitReexportedInstances)
-         "-darity-checks"  -> GLOBAL_SW(EmitArityChecks)
---UNUSED:        "-dno-stk-chks"   -> GLOBAL_SW(OmitStkChecks)
-         "-dno-black-holing"-> GLOBAL_SW(OmitBlackHoling)
-
-         _ | starts_with_fasm -> GLOBAL_SW(AsmTarget after_fasm)
-           | starts_with_G    -> GLOBAL_SW(SccGroup  after_G)  -- profiling "group"
-           | starts_with_C    -> GLOBAL_SW(ProduceC  after_C)  -- main C output 
-           | starts_with_S    -> GLOBAL_SW(ProduceS  after_S)  -- main .s output 
-           | starts_with_hi   -> GLOBAL_SW(ProduceHi after_hi) -- interface 
---UNUSED:   | starts_with_hu   -> GLOBAL_SW(ProduceHu after_hu)        -- usage info
-
-           | starts_with_uut  -> GLOBAL_SW(UnfoldingUseThreshold      (read after_uut))
-           | starts_with_uct  -> GLOBAL_SW(UnfoldingCreationThreshold (read after_uct))
-           | starts_with_uot  -> GLOBAL_SW(UnfoldingOverrideThreshold (read after_uot))
-
-           | starts_with_gtn  -> GLOBAL_SW(EnsureSplittableC after_gtn)
-
-         _ -> writeMn stderr ("*** WARNING: bad option: "++opt1++"\n") `thenMn` ( \ _ ->
-               -- NB: the driver is really supposed to handle bad options
-              IGNORE_ARG() )
+         _ -> -- NB: the driver is really supposed to handle bad options
+              IGNORE_ARG()
 
     ----------------
 
-    starts_with :: String -> String -> Maybe String
-
-    starts_with []     str = Just str
-    starts_with (c:cs) (s:ss)
-      = if c /= s then Nothing else starts_with cs ss
-
-    ----------------
-
-    -- ToDo: DPH-ify "simpl_sep"!
-
-    simpl_sep :: [String]                      -- cmd-line opts (input)
-       -> [SimplifierSwitch]                   -- simplifier-switch accumulator
-       -> [GlobalSwitch]                       -- switch accumulator
-       -> [CoreToDo] -> [StgToDo]              -- to_do accumulators
-       -> MainIO CmdLineInfo                   -- result
+    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 glob_sw core_td stg_td
+    simpl_sep input@[] simpl_sw core_td stg_td
       = panic "simpl_sep []"
 #endif
 
        -- The SimplifierSwitches should be delimited by "(" and ")".
 
-    simpl_sep ("(":opts) [{-better be empty-}] glob_sw core_td stg_td
-      = simpl_sep opts [] glob_sw core_td stg_td
-
-    simpl_sep (")":opts) simpl_sw glob_sw core_td stg_td
-      = let
-           this_CoreDoSimplify = CoreDoSimplify (isAmongSimpl simpl_sw)
-       in
-       sep opts glob_sw (this_CoreDoSimplify : core_td) stg_td
-
-    simpl_sep (opt1:opts) simpl_sw glob_sw core_td stg_td
-      = let
-           maybe_suut          = starts_with "-fsimpl-uf-use-threshold"      opt1
-           maybe_suct          = starts_with "-fsimpl-uf-creation-threshold" opt1
-           maybe_msi           = starts_with "-fmax-simplifier-iterations"   opt1
+    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
+
+#        define SIMPL_SW(sw) simpl_sep opts (sw:simpl_sw) core_td stg_td
+
+         -- the non-"just match a string" options are at the end...
+         "-fshow-simplifier-progress"      -> SIMPL_SW(ShowSimplifierProgress)
+         "-fcode-duplication-ok"           -> SIMPL_SW(SimplOkToDupCode)
+         "-ffloat-lets-exposing-whnf"      -> SIMPL_SW(SimplFloatLetsExposingWHNF)
+         "-ffloat-primops-ok"              -> SIMPL_SW(SimplOkToFloatPrimOps)
+         "-falways-float-lets-from-lets"   -> SIMPL_SW(SimplAlwaysFloatLetsFromLets)
+         "-fdo-case-elim"                  -> SIMPL_SW(SimplDoCaseElim)
+         "-fdo-eta-reduction"              -> SIMPL_SW(SimplDoEtaReduction)
+         "-fdo-lambda-eta-expansion"       -> SIMPL_SW(SimplDoLambdaEtaExpansion)
+         "-fdo-foldr-build"                -> SIMPL_SW(SimplDoFoldrBuild)
+         "-fdo-not-fold-back-append"       -> SIMPL_SW(SimplDontFoldBackAppend)
+         "-fdo-arity-expand"               -> SIMPL_SW(SimplDoArityExpand)
+         "-fdo-inline-foldr-build"         -> SIMPL_SW(SimplDoInlineFoldrBuild)
+         "-freuse-con"                     -> SIMPL_SW(SimplReuseCon)
+         "-fcase-of-case"                  -> SIMPL_SW(SimplCaseOfCase)
+         "-fcase-merge"                    -> SIMPL_SW(SimplCaseMerge)
+         "-flet-to-case"                   -> SIMPL_SW(SimplLetToCase)
+         "-fpedantic-bottoms"              -> SIMPL_SW(SimplPedanticBottoms)
+         "-fkeep-spec-pragma-ids"          -> SIMPL_SW(KeepSpecPragmaIds)
+         "-fkeep-unused-bindings"          -> SIMPL_SW(KeepUnusedBindings)
+         "-fmay-delete-conjurable-ids"     -> SIMPL_SW(SimplMayDeleteConjurableIds)
+         "-fessential-unfoldings-only"     -> SIMPL_SW(EssentialUnfoldingsOnly)
+         "-fignore-inline-pragma"          -> SIMPL_SW(IgnoreINLINEPragma)
+         "-fno-let-from-case"              -> SIMPL_SW(SimplNoLetFromCase)
+         "-fno-let-from-app"               -> SIMPL_SW(SimplNoLetFromApp)
+         "-fno-let-from-strict-let"        -> SIMPL_SW(SimplNoLetFromStrictLet)
+
+         o | starts_with_msi  -> SIMPL_SW(MaxSimplifierIterations (read after_msi))
+           | starts_with_suut -> SIMPL_SW(SimplUnfoldingUseThreshold (read after_suut))
+           | starts_with_suct -> SIMPL_SW(SimplUnfoldingCreationThreshold (read after_suct))
+           | starts_with_sucd -> SIMPL_SW(SimplUnfoldingConDiscount (read after_sucd))
+          where
+           maybe_suut          = startsWith "-fsimpl-uf-use-threshold"      o
+           maybe_suct          = startsWith "-fsimpl-uf-creation-threshold" o
+           maybe_sucd          = startsWith "-fsimpl-uf-con-discount" o
+           maybe_msi           = startsWith "-fmax-simplifier-iterations"   o
            starts_with_suut    = maybeToBool maybe_suut
            starts_with_suct    = maybeToBool maybe_suct
+           starts_with_sucd    = maybeToBool maybe_sucd
            starts_with_msi     = maybeToBool maybe_msi
            (Just after_suut)   = maybe_suut
            (Just after_suct)   = maybe_suct
+           (Just after_sucd)   = maybe_sucd
            (Just after_msi)    = maybe_msi
-       in
-       case opt1 of -- the non-"just match a string" options are at the end...
-         "-fshow-simplifier-progress" -> GLOBAL_SIMPL_SW(ShowSimplifierProgress)
-
-         "-fcode-duplication-ok" -> GLOBAL_SIMPL_SW(SimplOkToDupCode)
-         "-ffloat-lets-exposing-whnf"  -> GLOBAL_SIMPL_SW(SimplFloatLetsExposingWHNF)
-         "-ffloat-primops-ok"  -> GLOBAL_SIMPL_SW(SimplOkToFloatPrimOps)
-         "-falways-float-lets-from-lets" -> GLOBAL_SIMPL_SW(SimplAlwaysFloatLetsFromLets)
-         "-fdo-case-elim" -> GLOBAL_SIMPL_SW(SimplDoCaseElim)
-         "-fdo-eta-reduction" -> GLOBAL_SIMPL_SW(SimplDoEtaReduction)
-         "-fdo-lambda-eta-expansion" -> GLOBAL_SIMPL_SW(SimplDoLambdaEtaExpansion)
---UNUSED:        "-fdo-monad-eta-expansion" -> GLOBAL_SIMPL_SW(SimplDoMonadEtaExpansion)
-         "-fdo-foldr-build"  -> GLOBAL_SIMPL_SW(SimplDoFoldrBuild)
-         "-fdo-new-occur-anal"  -> GLOBAL_SIMPL_SW(SimplDoNewOccurAnal)
-         "-fdo-arity-expand"  -> GLOBAL_SIMPL_SW(SimplDoArityExpand)
-         "-fdo-inline-foldr-build"  -> GLOBAL_SIMPL_SW(SimplDoInlineFoldrBuild)
-         "-freuse-con"       -> GLOBAL_SIMPL_SW(SimplReuseCon)
-         "-fcase-of-case"    ->    GLOBAL_SIMPL_SW(SimplCaseOfCase)
-         "-flet-to-case"     -> GLOBAL_SIMPL_SW(SimplLetToCase)
-         "-fpedantic-bottoms" -> GLOBAL_SIMPL_SW(SimplPedanticBottoms)
-         "-fkeep-spec-pragma-ids" -> GLOBAL_SIMPL_SW(KeepSpecPragmaIds)
-         "-fkeep-unused-bindings" -> GLOBAL_SIMPL_SW(KeepUnusedBindings)
---UNUSED:        "-finline-in-lambdas-ok" -> GLOBAL_SIMPL_SW(SimplOkToInlineInLambdas)
-         "-fmay-delete-conjurable-ids" -> GLOBAL_SIMPL_SW(SimplMayDeleteConjurableIds)
-         "-fessential-unfoldings-only" -> GLOBAL_SIMPL_SW(EssentialUnfoldingsOnly) 
-         "-fignore-inline-pragma"  -> GLOBAL_SIMPL_SW(IgnoreINLINEPragma)
-
-         _ | starts_with_msi  -> GLOBAL_SIMPL_SW(MaxSimplifierIterations (read after_msi))
-           | starts_with_suut  -> GLOBAL_SIMPL_SW(SimplUnfoldingUseThreshold (read after_suut))
-           | starts_with_suct  -> GLOBAL_SIMPL_SW(SimplUnfoldingCreationThreshold (read after_suct))
-
-         _ -> writeMn stderr ("*** WARNING: bad simplifier option: "++opt1++"\n") `thenMn` ( \ _ ->
-               -- NB: the driver is really supposed to handle bad options
-              simpl_sep opts simpl_sw glob_sw core_td stg_td )
+
+         _ -> -- NB: the driver is really supposed to handle bad options
+              simpl_sep opts simpl_sw core_td stg_td
 \end{code}
 
 %************************************************************************
 %*                                                                     *
-\subsection[CmdLineOpts-order]{Switch ordering}
+\subsection{Switch ordering}
 %*                                                                     *
 %************************************************************************
 
@@ -651,13 +452,6 @@ In spite of the @Produce*@ and @SccGroup@ constructors, these things
 behave just like enumeration types.
 
 \begin{code}
-instance Eq GlobalSwitch where
-    a == b = tagOf_Switch a _EQ_ tagOf_Switch b
-
-instance Ord GlobalSwitch where
-    a <  b  = tagOf_Switch a _LT_ tagOf_Switch b
-    a <= b  = tagOf_Switch a _LE_ tagOf_Switch b
-
 instance Eq SimplifierSwitch where
     a == b = tagOf_SimplSwitch a _EQ_ tagOf_SimplSwitch b
 
@@ -665,123 +459,6 @@ instance Ord SimplifierSwitch where
     a <  b  = tagOf_SimplSwitch a _LT_ tagOf_SimplSwitch b
     a <= b  = tagOf_SimplSwitch a _LE_ tagOf_SimplSwitch b
 
-tagOf_Switch (ProduceC _)              =(ILIT(0) :: FAST_INT)
-tagOf_Switch (ProduceS _)              = ILIT(1)
-tagOf_Switch (ProduceHi        _)              = ILIT(2)
---UNUSED:tagOf_Switch (ProduceHu       _)              = ILIT(3)
-tagOf_Switch (AsmTarget _)              = ILIT(4)
---UNUSED:tagOf_Switch ForParallel              = ILIT(5)
-tagOf_Switch ForConcurrent             = ILIT(6)
---UNUSED:tagOf_Switch ForGRIP                  = ILIT(7)
-tagOf_Switch Haskell_1_3               = ILIT(8)
-tagOf_Switch GlasgowExts               = ILIT(9)
-tagOf_Switch CompilingPrelude          = ILIT(10)
-tagOf_Switch HideBuiltinNames          = ILIT(11)
-tagOf_Switch HideMostBuiltinNames      = ILIT(12)
-tagOf_Switch (EnsureSplittableC _)     = ILIT(13)
-tagOf_Switch Verbose                   = ILIT(14)
-tagOf_Switch PprStyle_User             = ILIT(15)
-tagOf_Switch PprStyle_Debug            = ILIT(16)
-tagOf_Switch PprStyle_All              = ILIT(17)
-tagOf_Switch DoCoreLinting             = ILIT(18)
-tagOf_Switch EmitArityChecks           = ILIT(19)
-tagOf_Switch OmitInterfacePragmas      = ILIT(20)
-tagOf_Switch OmitDerivedRead           = ILIT(21)
-tagOf_Switch OmitReexportedInstances   = ILIT(22)
-tagOf_Switch (UnfoldingUseThreshold _)  = ILIT(23)
-tagOf_Switch (UnfoldingCreationThreshold _) = ILIT(24)
-tagOf_Switch (UnfoldingOverrideThreshold _) = ILIT(25)
-tagOf_Switch ReportWhyUnfoldingsDisallowed = ILIT(26)
-tagOf_Switch UseGetMentionedVars       = ILIT(27)
-tagOf_Switch ShowPragmaNameErrs                = ILIT(28)
-tagOf_Switch NameShadowingNotOK                = ILIT(29)
-tagOf_Switch SigsRequired              = ILIT(30)
-tagOf_Switch SccProfilingOn            = ILIT(31)
-tagOf_Switch AutoSccsOnExportedToplevs = ILIT(32)
-tagOf_Switch AutoSccsOnAllToplevs      = ILIT(33)
-tagOf_Switch AutoSccsOnIndividualCafs  = ILIT(34)
---UNUSED:tagOf_Switch AutoSccsOnIndividualDicts        = ILIT(35)
-tagOf_Switch (SccGroup _)              = ILIT(36)
-tagOf_Switch DoTickyProfiling          = ILIT(37)
-tagOf_Switch DoSemiTagging             = ILIT(38)
-tagOf_Switch FoldrBuildOn              = ILIT(39)
-tagOf_Switch FoldrBuildTrace           = ILIT(40)
-tagOf_Switch SpecialiseImports         = ILIT(41)
-tagOf_Switch ShowImportSpecs           = ILIT(42)
-tagOf_Switch OmitUnspecialisedCode     = ILIT(43)
-tagOf_Switch SpecialiseOverloaded      = ILIT(44)
-tagOf_Switch SpecialiseUnboxed         = ILIT(45)
-tagOf_Switch SpecialiseAll             = ILIT(46)
-tagOf_Switch SpecialiseTrace           = ILIT(47)
---UNUSED:tagOf_Switch OmitStkChecks            = ILIT(48)
-tagOf_Switch OmitBlackHoling           = ILIT(49)
-tagOf_Switch StgDoLetNoEscapes         = ILIT(50)
-tagOf_Switch IgnoreStrictnessPragmas   = ILIT(51)
-tagOf_Switch IrrefutableTuples         = ILIT(52)
-tagOf_Switch IrrefutableEverything     = ILIT(53)
-tagOf_Switch AllStrict                 = ILIT(54)
-tagOf_Switch AllDemanded               = ILIT(55)
--- NOT REALLY USED: tagOf_Switch D_dump_type_info              = ILIT(56)
-tagOf_Switch D_dump_rif2hs             = ILIT(57)
-tagOf_Switch D_dump_rn4                        = ILIT(58)
-tagOf_Switch D_dump_tc                 = ILIT(59)
-tagOf_Switch D_dump_deriv              = ILIT(60)
-tagOf_Switch D_dump_ds                 = ILIT(61)
-tagOf_Switch D_dump_simpl              = ILIT(62)
-tagOf_Switch D_dump_spec               = ILIT(63)
-tagOf_Switch D_dump_occur_anal         = ILIT(64)
-tagOf_Switch D_dump_stranal            = ILIT(65)
-tagOf_Switch D_dump_stg                        = ILIT(66)
-tagOf_Switch D_dump_absC               = ILIT(67)
-tagOf_Switch D_dump_flatC              = ILIT(68)
-tagOf_Switch D_dump_realC              = ILIT(69)
-tagOf_Switch D_dump_asm                        = ILIT(70)
-tagOf_Switch D_dump_core_passes                = ILIT(71)
-tagOf_Switch D_dump_core_passes_info   = ILIT(72)
-tagOf_Switch D_verbose_core2core       = ILIT(73)
-tagOf_Switch D_verbose_stg2stg         = ILIT(74)
-tagOf_Switch D_simplifier_stats                = ILIT(75) {-note below-}
-
-{-
-tagOf_Switch Extra__Flag1              = ILIT(76)
-tagOf_Switch Extra__Flag2              = ILIT(77)
-tagOf_Switch Extra__Flag3              = ILIT(78)
-tagOf_Switch Extra__Flag4              = ILIT(79)
-tagOf_Switch Extra__Flag5              = ILIT(80)
-tagOf_Switch Extra__Flag6              = ILIT(81)
-tagOf_Switch Extra__Flag7              = ILIT(82)
-tagOf_Switch Extra__Flag8              = ILIT(83)
-tagOf_Switch Extra__Flag9              = ILIT(84)
--}
-
-#ifndef DPH
-tagOf_Switch _ = case (panic "tagOf_Switch") of -- BUG avoidance
-                  s -> tagOf_Switch s
-
-lAST_SWITCH_TAG = IBOX(tagOf_Switch D_simplifier_stats)
-
-#else {- Data Parallel Haskell -}
-
-tagOf_Switch PodizeIntelligent         = ILIT(90)
-tagOf_Switch PodizeAggresive           = ILIT(91)
-tagOf_Switch PodizeVeryAggresive       = ILIT(92)
-tagOf_Switch PodizeExtremelyAggresive  = ILIT(93)
-tagOf_Switch D_dump_pod                        = ILIT(94)
-tagOf_Switch D_dump_psimpl             = ILIT(95)
-tagOf_Switch D_dump_nextC              = ILIT(96)
-
-tagOf_Switch _ = case (panic "tagOf_Switch") of -- BUG avoidance
-                  s -> tagOf_Switch s
-
-lAST_SWITCH_TAG = IBOX(tagOf_Switch D_dump_nextC)
-
-#endif {- Data Parallel Haskell -}
-\end{code}
-
-(Note For Will): Could you please leave a little extra room between
-your last option and @D_dump_spec@... Thanks... jon...
-
-\begin{code}
 tagOf_SimplSwitch SimplOkToDupCode             =(ILIT(0) :: FAST_INT)
 tagOf_SimplSwitch SimplFloatLetsExposingWHNF   = ILIT(1)
 tagOf_SimplSwitch SimplOkToFloatPrimOps                = ILIT(2)
@@ -790,109 +467,60 @@ tagOf_SimplSwitch SimplDoCaseElim                = ILIT(4)
 tagOf_SimplSwitch SimplReuseCon                        = ILIT(5)
 tagOf_SimplSwitch SimplCaseOfCase              = ILIT(6)
 tagOf_SimplSwitch SimplLetToCase               = ILIT(7)
---UNUSED:tagOf_SimplSwitch SimplOkToInlineInLambdas    = ILIT(8)
 tagOf_SimplSwitch SimplMayDeleteConjurableIds  = ILIT(9)
 tagOf_SimplSwitch SimplPedanticBottoms         = ILIT(10)
 tagOf_SimplSwitch SimplDoArityExpand           = ILIT(11)
 tagOf_SimplSwitch SimplDoFoldrBuild            = ILIT(12)
-tagOf_SimplSwitch SimplDoNewOccurAnal          = ILIT(13)
 tagOf_SimplSwitch SimplDoInlineFoldrBuild      = ILIT(14)
 tagOf_SimplSwitch IgnoreINLINEPragma           = ILIT(15)
 tagOf_SimplSwitch SimplDoLambdaEtaExpansion    = ILIT(16)
---UNUSED:tagOf_SimplSwitch SimplDoMonadEtaExpansion    = ILIT(17)
 tagOf_SimplSwitch SimplDoEtaReduction          = ILIT(18)
 tagOf_SimplSwitch EssentialUnfoldingsOnly      = ILIT(19)
 tagOf_SimplSwitch ShowSimplifierProgress       = ILIT(20)
 tagOf_SimplSwitch (MaxSimplifierIterations _)  = ILIT(21)
 tagOf_SimplSwitch (SimplUnfoldingUseThreshold _)      = ILIT(22)
-tagOf_SimplSwitch (SimplUnfoldingCreationThreshold _) = ILIT(23)
-tagOf_SimplSwitch KeepSpecPragmaIds            = ILIT(24)
-tagOf_SimplSwitch KeepUnusedBindings           = ILIT(25)
-
-{-
-tagOf_SimplSwitch Extra__SimplFlag1            = ILIT(26)
-tagOf_SimplSwitch Extra__SimplFlag2            = ILIT(27)
-tagOf_SimplSwitch Extra__SimplFlag3            = ILIT(28)
-tagOf_SimplSwitch Extra__SimplFlag4            = ILIT(29)
-tagOf_SimplSwitch Extra__SimplFlag5            = ILIT(30)
-tagOf_SimplSwitch Extra__SimplFlag6            = ILIT(31)
-tagOf_SimplSwitch Extra__SimplFlag8            = ILIT(32)
--}
-
-tagOf_SimplSwitch _ = case (panic "tagOf_SimplSwitch") of -- BUG avoidance
-                       s -> tagOf_SimplSwitch s
-
-lAST_SIMPL_SWITCH_TAG = IBOX(tagOf_SimplSwitch KeepUnusedBindings)
+tagOf_SimplSwitch (SimplUnfoldingConDiscount _)       = ILIT(23)
+tagOf_SimplSwitch (SimplUnfoldingCreationThreshold _) = ILIT(24)
+tagOf_SimplSwitch KeepSpecPragmaIds            = ILIT(25)
+tagOf_SimplSwitch KeepUnusedBindings           = ILIT(26)
+tagOf_SimplSwitch SimplNoLetFromCase           = ILIT(27)
+tagOf_SimplSwitch SimplNoLetFromApp            = ILIT(28)
+tagOf_SimplSwitch SimplNoLetFromStrictLet      = ILIT(29)
+tagOf_SimplSwitch SimplDontFoldBackAppend       = ILIT(30)
+tagOf_SimplSwitch SimplCaseMerge               = ILIT(31)
+-- If you add anything here, be sure to change lAST_SIMPL_SWITCH_TAG, too!
+
+tagOf_SimplSwitch _ = panic# "tagOf_SimplSwitch"
+
+lAST_SIMPL_SWITCH_TAG = IBOX(tagOf_SimplSwitch SimplCaseMerge)
 \end{code}
 
 %************************************************************************
 %*                                                                     *
-\subsection[CmdLineOpts-lookup]{Switch lookup}
+\subsection{Switch lookup}
 %*                                                                     *
 %************************************************************************
 
 \begin{code}
-isAmong             :: [GlobalSwitch]     -> GlobalSwitch     -> SwitchResult
-isAmongSimpl :: [SimplifierSwitch] -> SimplifierSwitch -> SwitchResult
-
-isAmong on_switches
-  = let
-       tidied_on_switches = foldl rm_dups [] on_switches
-
-       sw_tbl :: Array Int SwitchResult
-
-       sw_tbl = (array (0, lAST_SWITCH_TAG) -- bounds...
-                       all_undefined)
-                // defined_elems
-
-       all_undefined = [ i := SwBool False | i <- [0 .. lAST_SWITCH_TAG ] ]
-
-       defined_elems = map mk_assoc_elem tidied_on_switches
-    in
-#ifndef __GLASGOW_HASKELL__
-    \ switch -> sw_tbl ! IBOX((tagOf_Switch switch))   -- but this is fast!
+#if __GLASGOW_HASKELL__ >= 200
+# define ARRAY     Array
+# define LIFT      GHCbase.Lift
+# define SET_TO            =:
+(=:) a b = (a,b)
 #else
-    -- and this is faster!
-    -- (avoid some unboxing, bounds checking, and other horrible things:)
-    case sw_tbl of { _Array bounds_who_needs_'em stuff ->
-    \ switch ->
-       case (indexArray# stuff (tagOf_Switch switch)) of
-         _Lift v -> v
-    }
+# define ARRAY     _Array
+# define LIFT      _Lift
+# define SET_TO            :=
 #endif
-  where
-    mk_assoc_elem k@(ProduceC  str) = IBOX(tagOf_Switch k) := SwString str
-    mk_assoc_elem k@(ProduceS  str) = IBOX(tagOf_Switch k) := SwString str
-    mk_assoc_elem k@(ProduceHi str) = IBOX(tagOf_Switch k) := SwString str
---UNUSED:    mk_assoc_elem k@(ProduceHu str) = IBOX(tagOf_Switch k) := SwString str
-    mk_assoc_elem k@(SccGroup  str) = IBOX(tagOf_Switch k) := SwString str
-    mk_assoc_elem k@(AsmTarget str) = IBOX(tagOf_Switch k) := SwString str
-    mk_assoc_elem k@(EnsureSplittableC str) = IBOX(tagOf_Switch k) := SwString str
-
-    mk_assoc_elem k@(UnfoldingUseThreshold      lvl) = IBOX(tagOf_Switch k) := SwInt lvl
-    mk_assoc_elem k@(UnfoldingCreationThreshold lvl) = IBOX(tagOf_Switch k) := SwInt lvl
-    mk_assoc_elem k@(UnfoldingOverrideThreshold lvl) = IBOX(tagOf_Switch k) := SwInt lvl
 
-    mk_assoc_elem k = IBOX(tagOf_Switch 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
-      = if switch `is_elem` switches_so_far
-       then switches_so_far
-       else switch : switches_so_far
-      where
-       sw `is_elem` []     = False
-       sw `is_elem` (s:ss) = (tagOf_Switch sw) _EQ_ (tagOf_Switch s)
-                           || sw `is_elem` ss
-\end{code}
+isAmongSimpl :: [SimplifierSwitch] -> SimplifierSwitch -> SwitchResult
 
-Same thing for @SimplifierSwitches@; for efficiency reasons, we
-probably do {\em not} want something overloaded.
- \begin{code}
-isAmongSimpl on_switches
+isAmongSimpl on_switches               -- Switches mentioned later occur *earlier*
+                                       -- in the list; defaults right at the end.
   = let
        tidied_on_switches = foldl rm_dups [] on_switches
+               -- The fold*l* ensures that we keep the latest switches;
+               -- ie the ones that occur earliest in the list.
 
        sw_tbl :: Array Int SwitchResult
 
@@ -900,30 +528,25 @@ isAmongSimpl on_switches
                        all_undefined)
                 // defined_elems
 
-       all_undefined = [ i := SwBool False | i <- [0 .. lAST_SIMPL_SWITCH_TAG ] ]
+       all_undefined = [ i SET_TO SwBool False | i <- [0 .. lAST_SIMPL_SWITCH_TAG ] ]
 
        defined_elems = map mk_assoc_elem tidied_on_switches
     in
-#ifndef __GLASGOW_HASKELL__
-    \ switch -> sw_tbl ! IBOX((tagOf_SimplSwitch switch)) -- but this is fast!
-#else
-    -- and this is faster!
     -- (avoid some unboxing, bounds checking, and other horrible things:)
-    case sw_tbl of { _Array bounds_who_needs_'em stuff ->
+    case sw_tbl of { ARRAY bounds_who_needs_'em stuff ->
     \ switch ->
        case (indexArray# stuff (tagOf_SimplSwitch switch)) of
-         _Lift v -> v
+         LIFT v -> v
     }
-#endif
   where
-    mk_assoc_elem k@(MaxSimplifierIterations lvl) = IBOX(tagOf_SimplSwitch k) := SwInt lvl
-    mk_assoc_elem k@(SimplUnfoldingUseThreshold      i) = IBOX(tagOf_SimplSwitch k) := SwInt i
-    mk_assoc_elem k@(SimplUnfoldingCreationThreshold i) = IBOX(tagOf_SimplSwitch k) := SwInt i
+    mk_assoc_elem k@(MaxSimplifierIterations lvl)       = IBOX(tagOf_SimplSwitch k) SET_TO SwInt lvl
+    mk_assoc_elem k@(SimplUnfoldingUseThreshold      i) = IBOX(tagOf_SimplSwitch k) SET_TO SwInt i
+    mk_assoc_elem k@(SimplUnfoldingConDiscount       i) = IBOX(tagOf_SimplSwitch k) SET_TO SwInt i
+    mk_assoc_elem k@(SimplUnfoldingCreationThreshold i) = IBOX(tagOf_SimplSwitch k) SET_TO SwInt i
 
-    mk_assoc_elem k = IBOX(tagOf_SimplSwitch k) := SwBool   True -- I'm here, Mom!
+    mk_assoc_elem k = IBOX(tagOf_SimplSwitch k) SET_TO SwBool   True -- I'm here, Mom!
 
     -- cannot have duplicates if we are going to use the array thing
-
     rm_dups switches_so_far switch
       = if switch `is_elem` switches_so_far
        then switches_so_far
@@ -934,9 +557,19 @@ isAmongSimpl on_switches
                            || sw `is_elem` ss
 \end{code}
 
+Default settings for simplifier switches
+
+\begin{code}
+defaultSimplSwitches = [SimplUnfoldingCreationThreshold uNFOLDING_CREATION_THRESHOLD,
+                       SimplUnfoldingUseThreshold      uNFOLDING_USE_THRESHOLD,
+                       SimplUnfoldingConDiscount       uNFOLDING_CON_DISCOUNT_WEIGHT,
+                       MaxSimplifierIterations         1
+                      ]
+\end{code}
+
 %************************************************************************
 %*                                                                     *
-\subsection[CmdLineOpts-misc]{Misc functions for command-line options}
+\subsection{Misc functions for command-line options}
 %*                                                                     *
 %************************************************************************
 
@@ -950,8 +583,8 @@ switchIsOn lookup_fn switch
       _                   -> True
 
 stringSwitchSet :: (switch -> SwitchResult)
-               -> (String -> switch)
-               -> Maybe String
+               -> (FAST_STRING -> switch)
+               -> Maybe FAST_STRING
 
 stringSwitchSet lookup_fn switch
   = case (lookup_fn (switch (panic "stringSwitchSet"))) of