2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
4 \section[CmdLineOpts]{Things to do with command-line options}
7 #include "HsVersions.h"
10 CmdLineInfo(..), SwitchResult(..),
11 GlobalSwitch(..), SimplifierSwitch(..),
16 #endif {- Data Parallel Haskell -}
19 switchIsOn, stringSwitchSet, intSwitchSet,
21 -- to make the interface self-sufficient
26 import Maybes ( maybeToBool, Maybe(..) )
29 #ifdef __GLASGOW_HASKELL__
30 import PreludeGlaST -- bad bad bad boy, Will
34 A command-line {\em switch} is (generally) either on or off; e.g., the
35 ``verbose'' (-v) switch is either on or off. (The \tr{-G<group>}
36 switch is an exception; it's set to a string, or nothing.)
38 A list of {\em ToDo}s is things to be done in a particular part of
39 processing. A (fictitious) example for the Core-to-Core simplifier
40 might be: run the simplifier, then run the strictness analyser, then
41 run the simplifier again (three ``todos'').
43 There are three ``to-do processing centers'' at the moment. In the
44 main loop (\tr{main/Main.lhs}), in the Core-to-Core processing loop
45 (\tr{simplCore/SimplCore.lhs), and in the STG-to-STG processing loop
46 (\tr{simplStg/SimplStg.lhs}).
48 We use function @classifyOpts@ to take raw command-line arguments from
49 @GetArgs@ and get back the @CmdLineInfo@, which is what we really
52 %************************************************************************
54 \subsection[CmdLineOpts-datatype]{Datatypes associated with command-line options}
56 %************************************************************************
60 = (GlobalSwitch -> SwitchResult, -- Switch lookup function
61 [CoreToDo], -- Core-to-core spec
63 [PodizeToDo], -- Podizer spec
64 [CoreToDo], -- post podized Core-to-core spec
66 [StgToDo] -- Stg-to-stg spec
70 = SwBool Bool -- on/off
71 | SwString String -- nothing or a String
72 | SwInt Int -- nothing or an Int
76 data CoreToDo -- These are diff core-to-core passes,
77 -- which may be invoked in any order,
78 -- as many times as you like.
80 = CoreDoSimplify -- The core-to-core simplifier.
81 (SimplifierSwitch -> SwitchResult)
82 -- Each run of the simplifier can take a different
83 -- set of simplifier-specific flags.
85 | CoreDoArityAnalysis -- UNUSED right now
86 | CoreDoCalcInlinings1
87 | CoreDoCalcInlinings2
96 | CoreDoAutoCostCentres
97 | CoreDoFoldrBuildWorkerWrapper
98 | CoreDoFoldrBuildWWAnal
101 --| CoreDoHaskLetlessPrint
107 | StgDoUpdateAnalysis
109 | StgDoMassageForProfiling -- should be (next to) last
110 -- There's also setStgVarInfo, but its absolute "lastness"
111 -- is so critical that it is hardwired in (no flag).
118 = PodizeNeeded Int -- Which dimensioned PODs need vectorizing
119 #endif {- Data Parallel Haskell -}
122 @GlobalSwitches@ may be visible everywhere in the compiler.
123 @SimplifierSwitches@ (which follow) are visible only in the main
124 Core-to-Core simplifier.
128 = ProduceC String -- generate C output into this file
129 | ProduceS String -- generate native-code assembler into this file
130 | ProduceHi String -- generate .hi interface into this file
131 --UNUSED: | ProduceHu String -- generate .hu usage-info into this file
133 | AsmTarget String -- architecture we are generating code for
136 | Haskell_1_3 -- if set => Haskell 1.3; else 1.2
137 | GlasgowExts -- Glasgow Haskell extensions allowed
138 | CompilingPrelude -- Compiling prelude source
140 | HideBuiltinNames -- fiddle builtin namespace; used for compiling Prelude
141 | HideMostBuiltinNames
142 | EnsureSplittableC String -- (by globalising all top-level Ids w/ this String)
145 | PprStyle_User -- printing "level" (mostly for debugging)
149 | DoCoreLinting -- paranoia flags
152 | OmitInterfacePragmas
154 | OmitReexportedInstances
156 | UnfoldingUseThreshold Int -- global one; see also SimplUnf...
157 | UnfoldingCreationThreshold Int -- ditto
158 | UnfoldingOverrideThreshold Int
160 | ReportWhyUnfoldingsDisallowed
161 | UseGetMentionedVars
167 | AutoSccsOnExportedToplevs
168 | AutoSccsOnAllToplevs
169 | AutoSccsOnIndividualCafs
170 --UNUSED: | AutoSccsOnIndividualDicts
171 | SccGroup String -- name of "group" for this cost centres in this module
177 -- ToDo: turn these into SimplifierSwitches?
178 | FoldrBuildOn -- If foldr/build-style transformations are on.
179 -- See also SimplDoFoldrBuild, which is used
180 -- inside the simplifier.
181 | FoldrBuildTrace -- show all foldr/build optimisations.
183 | SpecialiseImports -- Treat non-essential spec requests as errors
184 | ShowImportSpecs -- Output spec requests for non-essential specs
185 | OmitUnspecialisedCode -- ToDo? (Patrick)
186 | SpecialiseOverloaded
191 -- this batch of flags is for particular experiments;
192 -- v unlikely to be used in any other circumstance
193 --UNUSED: | OmitStkChecks
196 | IgnoreStrictnessPragmas -- ToDo: still useful?
197 | IrrefutableTuples -- We inject extra "LazyPat"s in the typechecker
198 | IrrefutableEverything -- (TcPat); doing it any earlier would mean that
199 -- deriving-generated code wouldn't be irrefutablified.
203 -- NOT REALLY USED: | D_dump_type_info -- for Robin Popplestone stuff
205 | D_dump_rif2hs -- debugging: print out various things
220 | D_dump_core_passes -- A Gill-ism
221 | D_dump_core_passes_info -- Yet another Gill-ism
223 | D_verbose_core2core
242 | PodizeVeryAggresive
243 | PodizeExtremelyAggresive
247 #endif {- Data Parallel Haskell -}
251 data SimplifierSwitch
253 | SimplFloatLetsExposingWHNF
254 | SimplOkToFloatPrimOps
255 | SimplAlwaysFloatLetsFromLets
260 --UNUSED: | SimplOkToInlineInLambdas
261 | SimplMayDeleteConjurableIds
262 | SimplPedanticBottoms -- see Simplifier for an explanation
263 | SimplDoArityExpand -- expand arity of bindings
264 | SimplDoFoldrBuild -- This is the per-simplification flag;
265 -- see also FoldrBuildOn, used elsewhere
267 | SimplDoNewOccurAnal -- use the *new*, all singing, Occurance analysis
268 | SimplDoInlineFoldrBuild
269 -- inline foldr/build (*after* f/b rule is used)
272 | SimplDoLambdaEtaExpansion
273 --UNUSED: | SimplDoMonadEtaExpansion
275 | SimplDoEtaReduction
277 | EssentialUnfoldingsOnly -- never mind the thresholds, only
278 -- do unfoldings that *must* be done
279 -- (to saturate constructors and primitives)
281 | ShowSimplifierProgress -- report counts on every interation
283 | MaxSimplifierIterations Int
285 | SimplUnfoldingUseThreshold Int -- per-simplification variants
286 | SimplUnfoldingCreationThreshold Int
288 | KeepSpecPragmaIds -- We normally *toss* Ids we can do without
303 %************************************************************************
305 \subsection[CmdLineOpts-classify]{Classifying command-line options}
307 %************************************************************************
310 classifyOpts :: [String] -- cmd-line args, straight from GetArgs
311 -> MainIO CmdLineInfo
312 -- The MainIO bit is because we might find an unknown flag
313 -- in which case we print an error message
317 = sep opts [] [] [] -- accumulators...
319 sep :: [String] -- cmd-line opts (input)
320 -> [GlobalSwitch] -- switch accumulator
321 -> [CoreToDo] -> [StgToDo] -- to_do accumulators
322 -> MainIO CmdLineInfo -- result
324 sep [] glob_sw core_td stg_td
331 sep (opt1:opts) glob_sw core_td stg_td
333 #else {- Data Parallel Haskell -}
335 = sep opts [] [] [] [] [] -- accumulators...
337 sep :: [String] -- cmd-line opts (input)
338 -> [GlobalSwitch] -- switch accumulator
339 -> [CoreToDo] -> [PodizeToDo] -- to_do accumulators
340 -> [CoreToDo] -> [StgToDo]
341 -> MainIO CmdLineInfo -- result
343 -- see also the related "simpl_sep" function, used
344 -- to collect up the SimplifierSwitches for a "-fsimplify".
346 sep [] glob_sw core_td pod_td pcore_td stg_td
355 sep (opt1:opts) glob_sw core_td pod_td pcore_td stg_td
356 #endif {- Data Parallel Haskell -}
359 #define GLOBAL_SW(switch) sep opts (switch:glob_sw) core_td stg_td
360 #define CORE_TD(to_do) sep opts glob_sw (to_do:core_td) stg_td
361 #define POD_TD(to_do) sep opts glob_sw core_td stg_td
362 #define PAR_CORE_TD(to_do) sep opts glob_sw core_td stg_td
363 #define BOTH_CORE_TD(to_do) sep opts glob_sw (to_do:core_td) stg_td
364 #define STG_TD(to_do) sep opts glob_sw core_td (to_do:stg_td)
365 #define IGNORE_ARG() sep opts glob_sw core_td stg_td
369 #define GLOBAL_SW(switch) sep opts (switch:glob_sw) core_td pod_td pcore_td stg_td
370 #define CORE_TD(to_do) sep opts glob_sw (to_do:core_td) pod_td pcore_td stg_td
371 #define POD_TD(to_do) sep opts glob_sw core_td (to_do:pod_td) pcore_td stg_td
372 #define PAR_CORE_TD(do) sep opts glob_sw core_td pod_td (do:pcore_td) stg_td
373 #define BOTH_CORE_TD(do) sep opts glob_sw (do:core_td) pod_td (do:pcore_td) stg_td
374 #define STG_TD(to_do) sep opts glob_sw core_td pod_td pcore_td (to_do:stg_td)
375 #define IGNORE_ARG() sep opts glob_sw core_td pod_td pcore_td stg_td
377 #endif {- Data Parallel Haskell -}
380 #define GLOBAL_SIMPL_SW(switch) simpl_sep opts (switch:simpl_sw) glob_sw core_td stg_td
383 maybe_fasm = starts_with "-fasm-" opt1
384 maybe_G = starts_with "-G" opt1
385 maybe_C = starts_with "-C" opt1
386 maybe_S = starts_with "-S" opt1
387 maybe_hi = starts_with "-hi" opt1
388 maybe_hu = starts_with "-hu" opt1
389 maybe_uut = starts_with "-funfolding-use-threshold" opt1
390 maybe_uct = starts_with "-funfolding-creation-threshold" opt1
391 maybe_uot = starts_with "-funfolding-override-threshold" opt1
392 maybe_gtn = starts_with "-fglobalise-toplev-names" opt1
393 starts_with_fasm = maybeToBool maybe_fasm
394 starts_with_G = maybeToBool maybe_G
395 starts_with_C = maybeToBool maybe_C
396 starts_with_S = maybeToBool maybe_S
397 starts_with_hi = maybeToBool maybe_hi
398 starts_with_hu = maybeToBool maybe_hu
399 starts_with_uut = maybeToBool maybe_uut
400 starts_with_uct = maybeToBool maybe_uct
401 starts_with_uot = maybeToBool maybe_uot
402 starts_with_gtn = maybeToBool maybe_gtn
403 (Just after_fasm) = maybe_fasm
404 (Just after_G) = maybe_G
405 (Just after_C) = maybe_C
406 (Just after_S) = maybe_S
407 (Just after_hi) = maybe_hi
408 (Just after_hu) = maybe_hu
409 (Just after_uut) = maybe_uut
410 (Just after_uct) = maybe_uct
411 (Just after_uot) = maybe_uot
412 (Just after_gtn) = maybe_gtn
414 case opt1 of -- the non-"just match a string" options are at the end...
415 ',' : _ -> IGNORE_ARG() -- it is for the parser
416 "-ddump-rif2hs" -> GLOBAL_SW(D_dump_rif2hs)
417 "-ddump-rn4" -> GLOBAL_SW(D_dump_rn4)
418 "-ddump-tc" -> GLOBAL_SW(D_dump_tc)
419 "-ddump-deriv" -> GLOBAL_SW(D_dump_deriv)
420 "-ddump-ds" -> GLOBAL_SW(D_dump_ds)
421 "-ddump-stranal" -> GLOBAL_SW(D_dump_stranal)
422 "-ddump-deforest"-> GLOBAL_SW(D_dump_deforest)
423 "-ddump-spec" -> GLOBAL_SW(D_dump_spec)
424 "-ddump-simpl" -> GLOBAL_SW(D_dump_simpl)
425 "-ddump-occur-anal" -> GLOBAL_SW(D_dump_occur_anal)
426 -- NOT REALLY USED: "-ddump-type-info" -> GLOBAL_SW(D_dump_type_info)
428 "-ddump-pod" -> GLOBAL_SW(D_dump_pod)
429 "-ddump-psimpl"-> GLOBAL_SW(D_dump_psimpl)
430 "-ddump-nextC" -> GLOBAL_SW(D_dump_nextC)
431 #endif {- Data Parallel Haskell -}
433 "-ddump-stg" -> GLOBAL_SW(D_dump_stg)
434 "-ddump-absC" -> GLOBAL_SW(D_dump_absC)
435 "-ddump-flatC"-> GLOBAL_SW(D_dump_flatC)
436 "-ddump-realC"-> GLOBAL_SW(D_dump_realC)
437 "-ddump-asm" -> GLOBAL_SW(D_dump_asm)
439 "-ddump-core-passes" -> GLOBAL_SW(D_dump_core_passes)
440 -- ANDY: "-ddump-haskell" -> GLOBAL_SW(D_dump_core_passes_info)
441 "-dsimplifier-stats" -> GLOBAL_SW(D_simplifier_stats)
443 "-dverbose-simpl" ->GLOBAL_SW(D_verbose_core2core)
444 "-dverbose-stg" -> GLOBAL_SW(D_verbose_stg2stg)
446 "-fuse-get-mentioned-vars" -> GLOBAL_SW(UseGetMentionedVars)
448 "-fhaskell-1.3" -> GLOBAL_SW(Haskell_1_3)
449 "-dcore-lint" -> GLOBAL_SW(DoCoreLinting)
450 "-fomit-interface-pragmas" -> GLOBAL_SW(OmitInterfacePragmas)
451 "-fignore-strictness-pragmas" -> GLOBAL_SW(IgnoreStrictnessPragmas)
452 "-firrefutable-tuples" -> GLOBAL_SW(IrrefutableTuples)
453 "-firrefutable-everything" -> GLOBAL_SW(IrrefutableEverything)
454 "-fall-strict" -> GLOBAL_SW(AllStrict)
455 "-fall-demanded" -> GLOBAL_SW(AllDemanded)
457 "-fsemi-tagging" -> GLOBAL_SW(DoSemiTagging)
459 "-fsimplify" -> -- gather up SimplifierSwitches specially...
460 simpl_sep opts [] glob_sw core_td stg_td
462 --UNUSED: "-farity-analysis" -> CORE_TD(CoreDoArityAnalysis)
463 "-fcalc-inlinings1"-> CORE_TD(CoreDoCalcInlinings1)
464 "-fcalc-inlinings2"-> CORE_TD(CoreDoCalcInlinings2)
465 "-ffloat-inwards" -> CORE_TD(CoreDoFloatInwards)
466 "-ffull-laziness" -> CORE_TD(CoreDoFullLaziness)
467 "-fliberate-case" -> CORE_TD(CoreLiberateCase)
468 "-fprint-core" -> CORE_TD(CoreDoPrintCore)
469 "-fstatic-args" -> CORE_TD(CoreDoStaticArgs)
470 "-fstrictness" -> CORE_TD(CoreDoStrictness)
471 "-fspecialise" -> CORE_TD(CoreDoSpecialising)
472 "-fdeforest" -> CORE_TD(CoreDoDeforest)
473 "-fadd-auto-sccs" -> CORE_TD(CoreDoAutoCostCentres)
474 "-ffoldr-build-worker-wrapper" -> CORE_TD(CoreDoFoldrBuildWorkerWrapper)
475 "-ffoldr-build-ww-anal" -> CORE_TD(CoreDoFoldrBuildWWAnal)
476 --ANDY: "-fprint-haskell-core" -> CORE_TD(CoreDoHaskPrint)
477 -- "-fprint-haskell-letless-core" -> CORE_TD(CoreDoHaskLetlessPrint)
479 "-fspecialise-overloaded" -> GLOBAL_SW(SpecialiseOverloaded)
480 "-fspecialise-unboxed" -> GLOBAL_SW(SpecialiseUnboxed)
481 "-fspecialise-all" -> GLOBAL_SW(SpecialiseAll)
482 "-fspecialise-imports" -> GLOBAL_SW(SpecialiseImports)
483 "-fshow-import-specs" -> GLOBAL_SW(ShowImportSpecs)
484 "-ftrace-specialisation" -> GLOBAL_SW(SpecialiseTrace)
486 "-freport-disallowed-unfoldings"
487 -> GLOBAL_SW(ReportWhyUnfoldingsDisallowed)
489 "-fomit-derived-read" -> GLOBAL_SW(OmitDerivedRead)
491 "-ffoldr-build-on" -> GLOBAL_SW(FoldrBuildOn)
492 "-ffoldr-build-trace" -> GLOBAL_SW(FoldrBuildTrace)
494 "-fstg-static-args" -> STG_TD(StgDoStaticArgs)
495 "-fupdate-analysis" -> STG_TD(StgDoUpdateAnalysis)
496 "-dstg-stats" -> STG_TD(D_stg_stats)
497 "-flambda-lift" -> STG_TD(StgDoLambdaLift)
498 "-fmassage-stg-for-profiling" -> STG_TD(StgDoMassageForProfiling)
500 "-flet-no-escape" -> GLOBAL_SW(StgDoLetNoEscapes)
503 "-fpodize-vector" -> POD_TD(PodizeNeeded 1)
504 "-fpodize-matrix" -> POD_TD(PodizeNeeded 2)
505 "-fpodize-cube" -> POD_TD(PodizeNeeded 3)
506 "-fpodize-intelligent" -> GLOBAL_SW(PodizeIntelligent)
507 "-fpodize-aggresive" -> GLOBAL_SW(PodizeAggresive)
508 "-fpodize-very-aggresive" -> GLOBAL_SW(PodizeVeryAggresive)
509 "-fpodize-extremely-aggresive" -> GLOBAL_SW(PodizeExtremelyAggresive)
510 #endif {- Data Parallel Haskell -}
512 "-v" -> GLOBAL_SW(Verbose)
514 "-fglasgow-exts" -> GLOBAL_SW(GlasgowExts)
515 "-prelude" -> GLOBAL_SW(CompilingPrelude)
517 "-fscc-profiling" -> GLOBAL_SW(SccProfilingOn)
518 "-fauto-sccs-on-exported-toplevs" -> GLOBAL_SW(AutoSccsOnExportedToplevs)
519 "-fauto-sccs-on-all-toplevs" -> GLOBAL_SW(AutoSccsOnAllToplevs)
520 "-fauto-sccs-on-individual-cafs" -> GLOBAL_SW(AutoSccsOnIndividualCafs)
521 --UNUSED: "-fauto-sccs-on-individual-dicts" -> GLOBAL_SW(AutoSccsOnIndividualDicts)
523 "-fstg-reduction-counts" -> GLOBAL_SW(DoTickyProfiling)
525 "-dppr-user" -> GLOBAL_SW(PprStyle_User)
526 "-dppr-debug" -> GLOBAL_SW(PprStyle_Debug)
527 "-dppr-all" -> GLOBAL_SW(PprStyle_All)
529 "-fhide-builtin-names"-> GLOBAL_SW(HideBuiltinNames)
530 "-fmin-builtin-names" -> GLOBAL_SW(HideMostBuiltinNames)
532 "-fconcurrent" -> GLOBAL_SW(ForConcurrent)
534 "-fomit-unspecialised-code" -> GLOBAL_SW(OmitUnspecialisedCode)
535 "-fshow-pragma-name-errs" -> GLOBAL_SW(ShowPragmaNameErrs)
536 "-fname-shadowing-not-ok" -> GLOBAL_SW(NameShadowingNotOK)
537 "-fsignatures-required" -> GLOBAL_SW(SigsRequired)
538 "-fomit-reexported-instances" -> GLOBAL_SW(OmitReexportedInstances)
539 "-darity-checks" -> GLOBAL_SW(EmitArityChecks)
540 --UNUSED: "-dno-stk-chks" -> GLOBAL_SW(OmitStkChecks)
541 "-dno-black-holing"-> GLOBAL_SW(OmitBlackHoling)
543 _ | starts_with_fasm -> GLOBAL_SW(AsmTarget after_fasm)
544 | starts_with_G -> GLOBAL_SW(SccGroup after_G) -- profiling "group"
545 | starts_with_C -> GLOBAL_SW(ProduceC after_C) -- main C output
546 | starts_with_S -> GLOBAL_SW(ProduceS after_S) -- main .s output
547 | starts_with_hi -> GLOBAL_SW(ProduceHi after_hi) -- interface
548 --UNUSED: | starts_with_hu -> GLOBAL_SW(ProduceHu after_hu) -- usage info
550 | starts_with_uut -> GLOBAL_SW(UnfoldingUseThreshold (read after_uut))
551 | starts_with_uct -> GLOBAL_SW(UnfoldingCreationThreshold (read after_uct))
552 | starts_with_uot -> GLOBAL_SW(UnfoldingOverrideThreshold (read after_uot))
554 | starts_with_gtn -> GLOBAL_SW(EnsureSplittableC after_gtn)
556 _ -> writeMn stderr ("*** WARNING: bad option: "++opt1++"\n") `thenMn` ( \ _ ->
557 -- NB: the driver is really supposed to handle bad options
562 starts_with :: String -> String -> Maybe String
564 starts_with [] str = Just str
565 starts_with (c:cs) (s:ss)
566 = if c /= s then Nothing else starts_with cs ss
570 -- ToDo: DPH-ify "simpl_sep"!
572 simpl_sep :: [String] -- cmd-line opts (input)
573 -> [SimplifierSwitch] -- simplifier-switch accumulator
574 -> [GlobalSwitch] -- switch accumulator
575 -> [CoreToDo] -> [StgToDo] -- to_do accumulators
576 -> MainIO CmdLineInfo -- result
578 -- "simpl_sep" tailcalls "sep" once it's seen one set
579 -- of SimplifierSwitches for a CoreDoSimplify.
582 simpl_sep input@[] simpl_sw glob_sw core_td stg_td
583 = panic "simpl_sep []"
586 -- The SimplifierSwitches should be delimited by "(" and ")".
588 simpl_sep ("(":opts) [{-better be empty-}] glob_sw core_td stg_td
589 = simpl_sep opts [] glob_sw core_td stg_td
591 simpl_sep (")":opts) simpl_sw glob_sw core_td stg_td
593 this_CoreDoSimplify = CoreDoSimplify (isAmongSimpl simpl_sw)
595 sep opts glob_sw (this_CoreDoSimplify : core_td) stg_td
597 simpl_sep (opt1:opts) simpl_sw glob_sw core_td stg_td
599 maybe_suut = starts_with "-fsimpl-uf-use-threshold" opt1
600 maybe_suct = starts_with "-fsimpl-uf-creation-threshold" opt1
601 maybe_msi = starts_with "-fmax-simplifier-iterations" opt1
602 starts_with_suut = maybeToBool maybe_suut
603 starts_with_suct = maybeToBool maybe_suct
604 starts_with_msi = maybeToBool maybe_msi
605 (Just after_suut) = maybe_suut
606 (Just after_suct) = maybe_suct
607 (Just after_msi) = maybe_msi
609 case opt1 of -- the non-"just match a string" options are at the end...
610 "-fshow-simplifier-progress" -> GLOBAL_SIMPL_SW(ShowSimplifierProgress)
612 "-fcode-duplication-ok" -> GLOBAL_SIMPL_SW(SimplOkToDupCode)
613 "-ffloat-lets-exposing-whnf" -> GLOBAL_SIMPL_SW(SimplFloatLetsExposingWHNF)
614 "-ffloat-primops-ok" -> GLOBAL_SIMPL_SW(SimplOkToFloatPrimOps)
615 "-falways-float-lets-from-lets" -> GLOBAL_SIMPL_SW(SimplAlwaysFloatLetsFromLets)
616 "-fdo-case-elim" -> GLOBAL_SIMPL_SW(SimplDoCaseElim)
617 "-fdo-eta-reduction" -> GLOBAL_SIMPL_SW(SimplDoEtaReduction)
618 "-fdo-lambda-eta-expansion" -> GLOBAL_SIMPL_SW(SimplDoLambdaEtaExpansion)
619 --UNUSED: "-fdo-monad-eta-expansion" -> GLOBAL_SIMPL_SW(SimplDoMonadEtaExpansion)
620 "-fdo-foldr-build" -> GLOBAL_SIMPL_SW(SimplDoFoldrBuild)
621 "-fdo-new-occur-anal" -> GLOBAL_SIMPL_SW(SimplDoNewOccurAnal)
622 "-fdo-arity-expand" -> GLOBAL_SIMPL_SW(SimplDoArityExpand)
623 "-fdo-inline-foldr-build" -> GLOBAL_SIMPL_SW(SimplDoInlineFoldrBuild)
624 "-freuse-con" -> GLOBAL_SIMPL_SW(SimplReuseCon)
625 "-fcase-of-case" -> GLOBAL_SIMPL_SW(SimplCaseOfCase)
626 "-flet-to-case" -> GLOBAL_SIMPL_SW(SimplLetToCase)
627 "-fpedantic-bottoms" -> GLOBAL_SIMPL_SW(SimplPedanticBottoms)
628 "-fkeep-spec-pragma-ids" -> GLOBAL_SIMPL_SW(KeepSpecPragmaIds)
629 "-fkeep-unused-bindings" -> GLOBAL_SIMPL_SW(KeepUnusedBindings)
630 --UNUSED: "-finline-in-lambdas-ok" -> GLOBAL_SIMPL_SW(SimplOkToInlineInLambdas)
631 "-fmay-delete-conjurable-ids" -> GLOBAL_SIMPL_SW(SimplMayDeleteConjurableIds)
632 "-fessential-unfoldings-only" -> GLOBAL_SIMPL_SW(EssentialUnfoldingsOnly)
633 "-fignore-inline-pragma" -> GLOBAL_SIMPL_SW(IgnoreINLINEPragma)
635 _ | starts_with_msi -> GLOBAL_SIMPL_SW(MaxSimplifierIterations (read after_msi))
636 | starts_with_suut -> GLOBAL_SIMPL_SW(SimplUnfoldingUseThreshold (read after_suut))
637 | starts_with_suct -> GLOBAL_SIMPL_SW(SimplUnfoldingCreationThreshold (read after_suct))
639 _ -> writeMn stderr ("*** WARNING: bad simplifier option: "++opt1++"\n") `thenMn` ( \ _ ->
640 -- NB: the driver is really supposed to handle bad options
641 simpl_sep opts simpl_sw glob_sw core_td stg_td )
644 %************************************************************************
646 \subsection[CmdLineOpts-order]{Switch ordering}
648 %************************************************************************
650 In spite of the @Produce*@ and @SccGroup@ constructors, these things
651 behave just like enumeration types.
654 instance Eq GlobalSwitch where
655 a == b = tagOf_Switch a _EQ_ tagOf_Switch b
657 instance Ord GlobalSwitch where
658 a < b = tagOf_Switch a _LT_ tagOf_Switch b
659 a <= b = tagOf_Switch a _LE_ tagOf_Switch b
661 instance Eq SimplifierSwitch where
662 a == b = tagOf_SimplSwitch a _EQ_ tagOf_SimplSwitch b
664 instance Ord SimplifierSwitch where
665 a < b = tagOf_SimplSwitch a _LT_ tagOf_SimplSwitch b
666 a <= b = tagOf_SimplSwitch a _LE_ tagOf_SimplSwitch b
668 tagOf_Switch (ProduceC _) =(ILIT(0) :: FAST_INT)
669 tagOf_Switch (ProduceS _) = ILIT(1)
670 tagOf_Switch (ProduceHi _) = ILIT(2)
671 --UNUSED:tagOf_Switch (ProduceHu _) = ILIT(3)
672 tagOf_Switch (AsmTarget _) = ILIT(4)
673 --UNUSED:tagOf_Switch ForParallel = ILIT(5)
674 tagOf_Switch ForConcurrent = ILIT(6)
675 --UNUSED:tagOf_Switch ForGRIP = ILIT(7)
676 tagOf_Switch Haskell_1_3 = ILIT(8)
677 tagOf_Switch GlasgowExts = ILIT(9)
678 tagOf_Switch CompilingPrelude = ILIT(10)
679 tagOf_Switch HideBuiltinNames = ILIT(11)
680 tagOf_Switch HideMostBuiltinNames = ILIT(12)
681 tagOf_Switch (EnsureSplittableC _) = ILIT(13)
682 tagOf_Switch Verbose = ILIT(14)
683 tagOf_Switch PprStyle_User = ILIT(15)
684 tagOf_Switch PprStyle_Debug = ILIT(16)
685 tagOf_Switch PprStyle_All = ILIT(17)
686 tagOf_Switch DoCoreLinting = ILIT(18)
687 tagOf_Switch EmitArityChecks = ILIT(19)
688 tagOf_Switch OmitInterfacePragmas = ILIT(20)
689 tagOf_Switch OmitDerivedRead = ILIT(21)
690 tagOf_Switch OmitReexportedInstances = ILIT(22)
691 tagOf_Switch (UnfoldingUseThreshold _) = ILIT(23)
692 tagOf_Switch (UnfoldingCreationThreshold _) = ILIT(24)
693 tagOf_Switch (UnfoldingOverrideThreshold _) = ILIT(25)
694 tagOf_Switch ReportWhyUnfoldingsDisallowed = ILIT(26)
695 tagOf_Switch UseGetMentionedVars = ILIT(27)
696 tagOf_Switch ShowPragmaNameErrs = ILIT(28)
697 tagOf_Switch NameShadowingNotOK = ILIT(29)
698 tagOf_Switch SigsRequired = ILIT(30)
699 tagOf_Switch SccProfilingOn = ILIT(31)
700 tagOf_Switch AutoSccsOnExportedToplevs = ILIT(32)
701 tagOf_Switch AutoSccsOnAllToplevs = ILIT(33)
702 tagOf_Switch AutoSccsOnIndividualCafs = ILIT(34)
703 --UNUSED:tagOf_Switch AutoSccsOnIndividualDicts = ILIT(35)
704 tagOf_Switch (SccGroup _) = ILIT(36)
705 tagOf_Switch DoTickyProfiling = ILIT(37)
706 tagOf_Switch DoSemiTagging = ILIT(38)
707 tagOf_Switch FoldrBuildOn = ILIT(39)
708 tagOf_Switch FoldrBuildTrace = ILIT(40)
709 tagOf_Switch SpecialiseImports = ILIT(41)
710 tagOf_Switch ShowImportSpecs = ILIT(42)
711 tagOf_Switch OmitUnspecialisedCode = ILIT(43)
712 tagOf_Switch SpecialiseOverloaded = ILIT(44)
713 tagOf_Switch SpecialiseUnboxed = ILIT(45)
714 tagOf_Switch SpecialiseAll = ILIT(46)
715 tagOf_Switch SpecialiseTrace = ILIT(47)
716 --UNUSED:tagOf_Switch OmitStkChecks = ILIT(48)
717 tagOf_Switch OmitBlackHoling = ILIT(49)
718 tagOf_Switch StgDoLetNoEscapes = ILIT(50)
719 tagOf_Switch IgnoreStrictnessPragmas = ILIT(51)
720 tagOf_Switch IrrefutableTuples = ILIT(52)
721 tagOf_Switch IrrefutableEverything = ILIT(53)
722 tagOf_Switch AllStrict = ILIT(54)
723 tagOf_Switch AllDemanded = ILIT(55)
724 -- NOT REALLY USED: tagOf_Switch D_dump_type_info = ILIT(56)
725 tagOf_Switch D_dump_rif2hs = ILIT(57)
726 tagOf_Switch D_dump_rn4 = ILIT(58)
727 tagOf_Switch D_dump_tc = ILIT(59)
728 tagOf_Switch D_dump_deriv = ILIT(60)
729 tagOf_Switch D_dump_ds = ILIT(61)
730 tagOf_Switch D_dump_simpl = ILIT(62)
731 tagOf_Switch D_dump_spec = ILIT(63)
732 tagOf_Switch D_dump_occur_anal = ILIT(64)
733 tagOf_Switch D_dump_stranal = ILIT(65)
734 tagOf_Switch D_dump_stg = ILIT(66)
735 tagOf_Switch D_dump_absC = ILIT(67)
736 tagOf_Switch D_dump_flatC = ILIT(68)
737 tagOf_Switch D_dump_realC = ILIT(69)
738 tagOf_Switch D_dump_asm = ILIT(70)
739 tagOf_Switch D_dump_core_passes = ILIT(71)
740 tagOf_Switch D_dump_core_passes_info = ILIT(72)
741 tagOf_Switch D_verbose_core2core = ILIT(73)
742 tagOf_Switch D_verbose_stg2stg = ILIT(74)
743 tagOf_Switch D_simplifier_stats = ILIT(75) {-note below-}
746 tagOf_Switch Extra__Flag1 = ILIT(76)
747 tagOf_Switch Extra__Flag2 = ILIT(77)
748 tagOf_Switch Extra__Flag3 = ILIT(78)
749 tagOf_Switch Extra__Flag4 = ILIT(79)
750 tagOf_Switch Extra__Flag5 = ILIT(80)
751 tagOf_Switch Extra__Flag6 = ILIT(81)
752 tagOf_Switch Extra__Flag7 = ILIT(82)
753 tagOf_Switch Extra__Flag8 = ILIT(83)
754 tagOf_Switch Extra__Flag9 = ILIT(84)
758 tagOf_Switch _ = case (panic "tagOf_Switch") of -- BUG avoidance
761 lAST_SWITCH_TAG = IBOX(tagOf_Switch D_simplifier_stats)
763 #else {- Data Parallel Haskell -}
765 tagOf_Switch PodizeIntelligent = ILIT(90)
766 tagOf_Switch PodizeAggresive = ILIT(91)
767 tagOf_Switch PodizeVeryAggresive = ILIT(92)
768 tagOf_Switch PodizeExtremelyAggresive = ILIT(93)
769 tagOf_Switch D_dump_pod = ILIT(94)
770 tagOf_Switch D_dump_psimpl = ILIT(95)
771 tagOf_Switch D_dump_nextC = ILIT(96)
773 tagOf_Switch _ = case (panic "tagOf_Switch") of -- BUG avoidance
776 lAST_SWITCH_TAG = IBOX(tagOf_Switch D_dump_nextC)
778 #endif {- Data Parallel Haskell -}
781 (Note For Will): Could you please leave a little extra room between
782 your last option and @D_dump_spec@... Thanks... jon...
785 tagOf_SimplSwitch SimplOkToDupCode =(ILIT(0) :: FAST_INT)
786 tagOf_SimplSwitch SimplFloatLetsExposingWHNF = ILIT(1)
787 tagOf_SimplSwitch SimplOkToFloatPrimOps = ILIT(2)
788 tagOf_SimplSwitch SimplAlwaysFloatLetsFromLets = ILIT(3)
789 tagOf_SimplSwitch SimplDoCaseElim = ILIT(4)
790 tagOf_SimplSwitch SimplReuseCon = ILIT(5)
791 tagOf_SimplSwitch SimplCaseOfCase = ILIT(6)
792 tagOf_SimplSwitch SimplLetToCase = ILIT(7)
793 --UNUSED:tagOf_SimplSwitch SimplOkToInlineInLambdas = ILIT(8)
794 tagOf_SimplSwitch SimplMayDeleteConjurableIds = ILIT(9)
795 tagOf_SimplSwitch SimplPedanticBottoms = ILIT(10)
796 tagOf_SimplSwitch SimplDoArityExpand = ILIT(11)
797 tagOf_SimplSwitch SimplDoFoldrBuild = ILIT(12)
798 tagOf_SimplSwitch SimplDoNewOccurAnal = ILIT(13)
799 tagOf_SimplSwitch SimplDoInlineFoldrBuild = ILIT(14)
800 tagOf_SimplSwitch IgnoreINLINEPragma = ILIT(15)
801 tagOf_SimplSwitch SimplDoLambdaEtaExpansion = ILIT(16)
802 --UNUSED:tagOf_SimplSwitch SimplDoMonadEtaExpansion = ILIT(17)
803 tagOf_SimplSwitch SimplDoEtaReduction = ILIT(18)
804 tagOf_SimplSwitch EssentialUnfoldingsOnly = ILIT(19)
805 tagOf_SimplSwitch ShowSimplifierProgress = ILIT(20)
806 tagOf_SimplSwitch (MaxSimplifierIterations _) = ILIT(21)
807 tagOf_SimplSwitch (SimplUnfoldingUseThreshold _) = ILIT(22)
808 tagOf_SimplSwitch (SimplUnfoldingCreationThreshold _) = ILIT(23)
809 tagOf_SimplSwitch KeepSpecPragmaIds = ILIT(24)
810 tagOf_SimplSwitch KeepUnusedBindings = ILIT(25)
813 tagOf_SimplSwitch Extra__SimplFlag1 = ILIT(26)
814 tagOf_SimplSwitch Extra__SimplFlag2 = ILIT(27)
815 tagOf_SimplSwitch Extra__SimplFlag3 = ILIT(28)
816 tagOf_SimplSwitch Extra__SimplFlag4 = ILIT(29)
817 tagOf_SimplSwitch Extra__SimplFlag5 = ILIT(30)
818 tagOf_SimplSwitch Extra__SimplFlag6 = ILIT(31)
819 tagOf_SimplSwitch Extra__SimplFlag8 = ILIT(32)
822 tagOf_SimplSwitch _ = case (panic "tagOf_SimplSwitch") of -- BUG avoidance
823 s -> tagOf_SimplSwitch s
825 lAST_SIMPL_SWITCH_TAG = IBOX(tagOf_SimplSwitch KeepUnusedBindings)
828 %************************************************************************
830 \subsection[CmdLineOpts-lookup]{Switch lookup}
832 %************************************************************************
835 isAmong :: [GlobalSwitch] -> GlobalSwitch -> SwitchResult
836 isAmongSimpl :: [SimplifierSwitch] -> SimplifierSwitch -> SwitchResult
840 tidied_on_switches = foldl rm_dups [] on_switches
842 sw_tbl :: Array Int SwitchResult
844 sw_tbl = (array (0, lAST_SWITCH_TAG) -- bounds...
848 all_undefined = [ i := SwBool False | i <- [0 .. lAST_SWITCH_TAG ] ]
850 defined_elems = map mk_assoc_elem tidied_on_switches
852 #ifndef __GLASGOW_HASKELL__
853 \ switch -> sw_tbl ! IBOX((tagOf_Switch switch)) -- but this is fast!
855 -- and this is faster!
856 -- (avoid some unboxing, bounds checking, and other horrible things:)
857 case sw_tbl of { _Array bounds_who_needs_'em stuff ->
859 case (indexArray# stuff (tagOf_Switch switch)) of
864 mk_assoc_elem k@(ProduceC str) = IBOX(tagOf_Switch k) := SwString str
865 mk_assoc_elem k@(ProduceS str) = IBOX(tagOf_Switch k) := SwString str
866 mk_assoc_elem k@(ProduceHi str) = IBOX(tagOf_Switch k) := SwString str
867 --UNUSED: mk_assoc_elem k@(ProduceHu str) = IBOX(tagOf_Switch k) := SwString str
868 mk_assoc_elem k@(SccGroup str) = IBOX(tagOf_Switch k) := SwString str
869 mk_assoc_elem k@(AsmTarget str) = IBOX(tagOf_Switch k) := SwString str
870 mk_assoc_elem k@(EnsureSplittableC str) = IBOX(tagOf_Switch k) := SwString str
872 mk_assoc_elem k@(UnfoldingUseThreshold lvl) = IBOX(tagOf_Switch k) := SwInt lvl
873 mk_assoc_elem k@(UnfoldingCreationThreshold lvl) = IBOX(tagOf_Switch k) := SwInt lvl
874 mk_assoc_elem k@(UnfoldingOverrideThreshold lvl) = IBOX(tagOf_Switch k) := SwInt lvl
876 mk_assoc_elem k = IBOX(tagOf_Switch k) := SwBool True -- I'm here, Mom!
878 -- cannot have duplicates if we are going to use the array thing
880 rm_dups switches_so_far switch
881 = if switch `is_elem` switches_so_far
883 else switch : switches_so_far
885 sw `is_elem` [] = False
886 sw `is_elem` (s:ss) = (tagOf_Switch sw) _EQ_ (tagOf_Switch s)
890 Same thing for @SimplifierSwitches@; for efficiency reasons, we
891 probably do {\em not} want something overloaded.
893 isAmongSimpl on_switches
895 tidied_on_switches = foldl rm_dups [] on_switches
897 sw_tbl :: Array Int SwitchResult
899 sw_tbl = (array (0, lAST_SIMPL_SWITCH_TAG) -- bounds...
903 all_undefined = [ i := SwBool False | i <- [0 .. lAST_SIMPL_SWITCH_TAG ] ]
905 defined_elems = map mk_assoc_elem tidied_on_switches
907 #ifndef __GLASGOW_HASKELL__
908 \ switch -> sw_tbl ! IBOX((tagOf_SimplSwitch switch)) -- but this is fast!
910 -- and this is faster!
911 -- (avoid some unboxing, bounds checking, and other horrible things:)
912 case sw_tbl of { _Array bounds_who_needs_'em stuff ->
914 case (indexArray# stuff (tagOf_SimplSwitch switch)) of
919 mk_assoc_elem k@(MaxSimplifierIterations lvl) = IBOX(tagOf_SimplSwitch k) := SwInt lvl
920 mk_assoc_elem k@(SimplUnfoldingUseThreshold i) = IBOX(tagOf_SimplSwitch k) := SwInt i
921 mk_assoc_elem k@(SimplUnfoldingCreationThreshold i) = IBOX(tagOf_SimplSwitch k) := SwInt i
923 mk_assoc_elem k = IBOX(tagOf_SimplSwitch k) := SwBool True -- I'm here, Mom!
925 -- cannot have duplicates if we are going to use the array thing
927 rm_dups switches_so_far switch
928 = if switch `is_elem` switches_so_far
930 else switch : switches_so_far
932 sw `is_elem` [] = False
933 sw `is_elem` (s:ss) = (tagOf_SimplSwitch sw) _EQ_ (tagOf_SimplSwitch s)
937 %************************************************************************
939 \subsection[CmdLineOpts-misc]{Misc functions for command-line options}
941 %************************************************************************
945 switchIsOn :: (switch -> SwitchResult) -> switch -> Bool
947 switchIsOn lookup_fn switch
948 = case (lookup_fn switch) of
949 SwBool False -> False
952 stringSwitchSet :: (switch -> SwitchResult)
953 -> (String -> switch)
956 stringSwitchSet lookup_fn switch
957 = case (lookup_fn (switch (panic "stringSwitchSet"))) of
958 SwString str -> Just str
961 intSwitchSet :: (switch -> SwitchResult)
965 intSwitchSet lookup_fn switch
966 = case (lookup_fn (switch (panic "intSwitchSet"))) of
967 SwInt int -> Just int