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.
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
132 | AsmTarget String -- architecture we are generating code for
135 | Haskell_1_3 -- if set => Haskell 1.3; else 1.2
136 | GlasgowExts -- Glasgow Haskell extensions allowed
137 | CompilingPrelude -- Compiling prelude source
139 | HideBuiltinNames -- fiddle builtin namespace; used for compiling Prelude
140 | HideMostBuiltinNames
141 | EnsureSplittableC String -- (by globalising all top-level Ids w/ this String)
144 | PprStyle_User -- printing "level" (mostly for debugging)
148 | DoCoreLinting -- paranoia flags
151 | OmitInterfacePragmas
153 | OmitReexportedInstances
155 | UnfoldingUseThreshold Int -- global one; see also SimplUnf...
156 | UnfoldingCreationThreshold Int -- ditto
157 | UnfoldingOverrideThreshold Int
159 | ReportWhyUnfoldingsDisallowed
160 | UseGetMentionedVars
166 | AutoSccsOnExportedToplevs
167 | AutoSccsOnAllToplevs
168 | AutoSccsOnIndividualCafs
169 | SccGroup String -- name of "group" for this cost centres in this module
175 -- ToDo: turn these into SimplifierSwitches?
176 | FoldrBuildOn -- If foldr/build-style transformations are on.
177 -- See also SimplDoFoldrBuild, which is used
178 -- inside the simplifier.
179 | FoldrBuildTrace -- show all foldr/build optimisations.
181 | SpecialiseImports -- Treat non-essential spec requests as errors
182 | ShowImportSpecs -- Output spec requests for non-essential specs
183 | OmitDefaultInstanceMethods
184 | SpecialiseOverloaded
189 -- this batch of flags is for particular experiments;
190 -- v unlikely to be used in any other circumstance
193 | IgnoreStrictnessPragmas -- ToDo: still useful?
194 | IrrefutableTuples -- We inject extra "LazyPat"s in the typechecker
195 | IrrefutableEverything -- (TcPat); doing it any earlier would mean that
196 -- deriving-generated code wouldn't be irrefutablified.
201 | ReturnInRegsThreshold Int
202 | VectoredReturnThreshold Int -- very likely UNUSED
204 | D_dump_rif2hs -- debugging: print out various things
220 --ANDY: | D_dump_core_passes_info -- A Gill-ism
222 | D_verbose_core2core
230 | PodizeVeryAggresive
231 | PodizeExtremelyAggresive
235 #endif {- Data Parallel Haskell -}
239 data SimplifierSwitch
241 | SimplFloatLetsExposingWHNF
242 | SimplOkToFloatPrimOps
243 | SimplAlwaysFloatLetsFromLets
248 | SimplMayDeleteConjurableIds
249 | SimplPedanticBottoms -- see Simplifier for an explanation
250 | SimplDoArityExpand -- expand arity of bindings
251 | SimplDoFoldrBuild -- This is the per-simplification flag;
252 -- see also FoldrBuildOn, used elsewhere
254 | SimplDoNewOccurAnal -- use the *new*, all singing, Occurance analysis
255 | SimplDoInlineFoldrBuild
256 -- inline foldr/build (*after* f/b rule is used)
259 | SimplDoLambdaEtaExpansion
260 | SimplDoEtaReduction
262 | EssentialUnfoldingsOnly -- never mind the thresholds, only
263 -- do unfoldings that *must* be done
264 -- (to saturate constructors and primitives)
266 | ShowSimplifierProgress -- report counts on every interation
268 | MaxSimplifierIterations Int
270 | SimplUnfoldingUseThreshold Int -- per-simplification variants
271 | SimplUnfoldingCreationThreshold Int
273 | KeepSpecPragmaIds -- We normally *toss* Ids we can do without
276 | SimplNoLetFromCase -- used when turning off floating entirely
277 | SimplNoLetFromApp -- (for experimentation only) WDP 95/10
278 | SimplNoLetFromStrictLet
291 %************************************************************************
293 \subsection[CmdLineOpts-classify]{Classifying command-line options}
295 %************************************************************************
298 classifyOpts :: [String] -- cmd-line args, straight from GetArgs
299 -> MainIO CmdLineInfo
300 -- The MainIO bit is because we might find an unknown flag
301 -- in which case we print an error message
305 = sep opts [] [] [] -- accumulators...
307 sep :: [String] -- cmd-line opts (input)
308 -> [GlobalSwitch] -- switch accumulator
309 -> [CoreToDo] -> [StgToDo] -- to_do accumulators
310 -> MainIO CmdLineInfo -- result
312 sep [] glob_sw core_td stg_td
319 sep (opt1:opts) glob_sw core_td stg_td
321 #else {- Data Parallel Haskell -}
323 = sep opts [] [] [] [] [] -- accumulators...
325 sep :: [String] -- cmd-line opts (input)
326 -> [GlobalSwitch] -- switch accumulator
327 -> [CoreToDo] -> [PodizeToDo] -- to_do accumulators
328 -> [CoreToDo] -> [StgToDo]
329 -> MainIO CmdLineInfo -- result
331 -- see also the related "simpl_sep" function, used
332 -- to collect up the SimplifierSwitches for a "-fsimplify".
334 sep [] glob_sw core_td pod_td pcore_td stg_td
343 sep (opt1:opts) glob_sw core_td pod_td pcore_td stg_td
344 #endif {- Data Parallel Haskell -}
347 #define GLOBAL_SW(switch) sep opts (switch:glob_sw) core_td stg_td
348 #define CORE_TD(to_do) sep opts glob_sw (to_do:core_td) stg_td
349 #define POD_TD(to_do) sep opts glob_sw core_td stg_td
350 #define PAR_CORE_TD(to_do) sep opts glob_sw core_td stg_td
351 #define BOTH_CORE_TD(to_do) sep opts glob_sw (to_do:core_td) stg_td
352 #define STG_TD(to_do) sep opts glob_sw core_td (to_do:stg_td)
353 #define IGNORE_ARG() sep opts glob_sw core_td stg_td
357 #define GLOBAL_SW(switch) sep opts (switch:glob_sw) core_td pod_td pcore_td stg_td
358 #define CORE_TD(to_do) sep opts glob_sw (to_do:core_td) pod_td pcore_td stg_td
359 #define POD_TD(to_do) sep opts glob_sw core_td (to_do:pod_td) pcore_td stg_td
360 #define PAR_CORE_TD(do) sep opts glob_sw core_td pod_td (do:pcore_td) stg_td
361 #define BOTH_CORE_TD(do) sep opts glob_sw (do:core_td) pod_td (do:pcore_td) stg_td
362 #define STG_TD(to_do) sep opts glob_sw core_td pod_td pcore_td (to_do:stg_td)
363 #define IGNORE_ARG() sep opts glob_sw core_td pod_td pcore_td stg_td
365 #endif {- Data Parallel Haskell -}
368 #define GLOBAL_SIMPL_SW(switch) simpl_sep opts (switch:simpl_sw) glob_sw core_td stg_td
371 maybe_fasm = starts_with "-fasm-" opt1
372 maybe_G = starts_with "-G" opt1
373 maybe_C = starts_with "-C" opt1
374 maybe_S = starts_with "-S" opt1
375 maybe_hi = starts_with "-hi" opt1
376 maybe_hu = starts_with "-hu" opt1
377 maybe_uut = starts_with "-funfolding-use-threshold" opt1
378 maybe_uct = starts_with "-funfolding-creation-threshold" opt1
379 maybe_uot = starts_with "-funfolding-override-threshold" opt1
380 maybe_rirt = starts_with "-freturn-in-regs-threshold" opt1
381 maybe_gtn = starts_with "-fglobalise-toplev-names" opt1
382 starts_with_fasm = maybeToBool maybe_fasm
383 starts_with_G = maybeToBool maybe_G
384 starts_with_C = maybeToBool maybe_C
385 starts_with_S = maybeToBool maybe_S
386 starts_with_hi = maybeToBool maybe_hi
387 starts_with_hu = maybeToBool maybe_hu
388 starts_with_uut = maybeToBool maybe_uut
389 starts_with_uct = maybeToBool maybe_uct
390 starts_with_uot = maybeToBool maybe_uot
391 starts_with_rirt = maybeToBool maybe_rirt
392 starts_with_gtn = maybeToBool maybe_gtn
393 (Just after_fasm) = maybe_fasm
394 (Just after_G) = maybe_G
395 (Just after_C) = maybe_C
396 (Just after_S) = maybe_S
397 (Just after_hi) = maybe_hi
398 (Just after_hu) = maybe_hu
399 (Just after_uut) = maybe_uut
400 (Just after_uct) = maybe_uct
401 (Just after_uot) = maybe_uot
402 (Just after_rirt) = maybe_rirt
403 (Just after_gtn) = maybe_gtn
405 case opt1 of -- the non-"just match a string" options are at the end...
406 ',' : _ -> IGNORE_ARG() -- it is for the parser
407 "-ddump-rif2hs" -> GLOBAL_SW(D_dump_rif2hs)
408 "-ddump-rn4" -> GLOBAL_SW(D_dump_rn4)
409 "-ddump-tc" -> GLOBAL_SW(D_dump_tc)
410 "-ddump-deriv" -> GLOBAL_SW(D_dump_deriv)
411 "-ddump-ds" -> GLOBAL_SW(D_dump_ds)
412 "-ddump-stranal" -> GLOBAL_SW(D_dump_stranal)
413 "-ddump-deforest"-> GLOBAL_SW(D_dump_deforest)
414 "-ddump-spec" -> GLOBAL_SW(D_dump_spec)
415 "-ddump-simpl" -> GLOBAL_SW(D_dump_simpl)
416 "-ddump-occur-anal" -> GLOBAL_SW(D_dump_occur_anal)
418 "-ddump-pod" -> GLOBAL_SW(D_dump_pod)
419 "-ddump-psimpl" -> GLOBAL_SW(D_dump_psimpl)
420 "-ddump-nextC" -> GLOBAL_SW(D_dump_nextC)
421 #endif {- Data Parallel Haskell -}
423 "-ddump-stg" -> GLOBAL_SW(D_dump_stg)
424 "-ddump-absC" -> GLOBAL_SW(D_dump_absC)
425 "-ddump-flatC" -> GLOBAL_SW(D_dump_flatC)
426 "-ddump-realC" -> GLOBAL_SW(D_dump_realC)
427 "-ddump-asm" -> GLOBAL_SW(D_dump_asm)
428 "-dshow-passes" -> GLOBAL_SW(D_show_passes)
430 -- ANDY: "-ddump-haskell" -> GLOBAL_SW(D_dump_core_passes_info)
431 "-dsimplifier-stats" -> GLOBAL_SW(D_simplifier_stats)
432 "-dsource-stats" -> GLOBAL_SW(D_source_stats)
434 "-dverbose-simpl" ->GLOBAL_SW(D_verbose_core2core)
435 "-dverbose-stg" -> GLOBAL_SW(D_verbose_stg2stg)
437 "-fuse-get-mentioned-vars" -> GLOBAL_SW(UseGetMentionedVars)
439 "-fhaskell-1.3" -> GLOBAL_SW(Haskell_1_3)
440 "-dcore-lint" -> GLOBAL_SW(DoCoreLinting)
441 "-fomit-interface-pragmas" -> GLOBAL_SW(OmitInterfacePragmas)
442 "-fignore-strictness-pragmas" -> GLOBAL_SW(IgnoreStrictnessPragmas)
443 "-firrefutable-tuples" -> GLOBAL_SW(IrrefutableTuples)
444 "-firrefutable-everything" -> GLOBAL_SW(IrrefutableEverything)
445 "-fall-strict" -> GLOBAL_SW(AllStrict)
446 "-fnumbers-strict" -> GLOBAL_SW(NumbersStrict)
447 "-fall-demanded" -> GLOBAL_SW(AllDemanded)
449 "-fsemi-tagging" -> GLOBAL_SW(DoSemiTagging)
451 "-fsimplify" -> -- gather up SimplifierSwitches specially...
452 simpl_sep opts [] glob_sw core_td stg_td
454 "-fcalc-inlinings1"-> CORE_TD(CoreDoCalcInlinings1)
455 "-fcalc-inlinings2"-> CORE_TD(CoreDoCalcInlinings2)
456 "-ffloat-inwards" -> CORE_TD(CoreDoFloatInwards)
457 "-ffull-laziness" -> CORE_TD(CoreDoFullLaziness)
458 "-fliberate-case" -> CORE_TD(CoreLiberateCase)
459 "-fprint-core" -> CORE_TD(CoreDoPrintCore)
460 "-fstatic-args" -> CORE_TD(CoreDoStaticArgs)
461 "-fstrictness" -> CORE_TD(CoreDoStrictness)
462 "-fspecialise" -> CORE_TD(CoreDoSpecialising)
463 "-fdeforest" -> CORE_TD(CoreDoDeforest)
464 "-fadd-auto-sccs" -> CORE_TD(CoreDoAutoCostCentres)
465 "-ffoldr-build-worker-wrapper" -> CORE_TD(CoreDoFoldrBuildWorkerWrapper)
466 "-ffoldr-build-ww-anal" -> CORE_TD(CoreDoFoldrBuildWWAnal)
467 --ANDY: "-fprint-haskell-core" -> CORE_TD(CoreDoHaskPrint)
468 -- "-fprint-haskell-letless-core" -> CORE_TD(CoreDoHaskLetlessPrint)
469 "-fomit-default-instance-methods" -> GLOBAL_SW(OmitDefaultInstanceMethods)
470 "-fspecialise-overloaded" -> GLOBAL_SW(SpecialiseOverloaded)
471 "-fspecialise-unboxed" -> GLOBAL_SW(SpecialiseUnboxed)
472 "-fspecialise-all" -> GLOBAL_SW(SpecialiseAll)
473 "-fspecialise-imports" -> GLOBAL_SW(SpecialiseImports)
474 "-fshow-import-specs" -> GLOBAL_SW(ShowImportSpecs)
475 "-ftrace-specialisation" -> GLOBAL_SW(SpecialiseTrace)
477 "-freport-disallowed-unfoldings"
478 -> GLOBAL_SW(ReportWhyUnfoldingsDisallowed)
480 "-fomit-derived-read" -> GLOBAL_SW(OmitDerivedRead)
482 "-ffoldr-build-on" -> GLOBAL_SW(FoldrBuildOn)
483 "-ffoldr-build-trace" -> GLOBAL_SW(FoldrBuildTrace)
485 "-fstg-static-args" -> STG_TD(StgDoStaticArgs)
486 "-fupdate-analysis" -> STG_TD(StgDoUpdateAnalysis)
487 "-dstg-stats" -> STG_TD(D_stg_stats)
488 "-flambda-lift" -> STG_TD(StgDoLambdaLift)
489 "-fmassage-stg-for-profiling" -> STG_TD(StgDoMassageForProfiling)
491 "-flet-no-escape" -> GLOBAL_SW(StgDoLetNoEscapes)
494 "-fpodize-vector" -> POD_TD(PodizeNeeded 1)
495 "-fpodize-matrix" -> POD_TD(PodizeNeeded 2)
496 "-fpodize-cube" -> POD_TD(PodizeNeeded 3)
497 "-fpodize-intelligent" -> GLOBAL_SW(PodizeIntelligent)
498 "-fpodize-aggresive" -> GLOBAL_SW(PodizeAggresive)
499 "-fpodize-very-aggresive" -> GLOBAL_SW(PodizeVeryAggresive)
500 "-fpodize-extremely-aggresive" -> GLOBAL_SW(PodizeExtremelyAggresive)
501 #endif {- Data Parallel Haskell -}
503 "-v" -> GLOBAL_SW(Verbose)
505 "-fglasgow-exts" -> GLOBAL_SW(GlasgowExts)
506 "-prelude" -> GLOBAL_SW(CompilingPrelude)
508 "-fscc-profiling" -> GLOBAL_SW(SccProfilingOn)
509 "-fauto-sccs-on-exported-toplevs" -> GLOBAL_SW(AutoSccsOnExportedToplevs)
510 "-fauto-sccs-on-all-toplevs" -> GLOBAL_SW(AutoSccsOnAllToplevs)
511 "-fauto-sccs-on-individual-cafs" -> GLOBAL_SW(AutoSccsOnIndividualCafs)
513 "-fticky-ticky" -> GLOBAL_SW(DoTickyProfiling)
515 "-dppr-user" -> GLOBAL_SW(PprStyle_User)
516 "-dppr-debug" -> GLOBAL_SW(PprStyle_Debug)
517 "-dppr-all" -> GLOBAL_SW(PprStyle_All)
519 "-fhide-builtin-names"-> GLOBAL_SW(HideBuiltinNames)
520 "-fmin-builtin-names" -> GLOBAL_SW(HideMostBuiltinNames)
522 "-fconcurrent" -> GLOBAL_SW(ForConcurrent)
524 "-fshow-pragma-name-errs" -> GLOBAL_SW(ShowPragmaNameErrs)
525 "-fname-shadowing-not-ok" -> GLOBAL_SW(NameShadowingNotOK)
526 "-fsignatures-required" -> GLOBAL_SW(SigsRequired)
527 "-fomit-reexported-instances" -> GLOBAL_SW(OmitReexportedInstances)
528 "-darity-checks" -> GLOBAL_SW(EmitArityChecks)
529 "-dno-black-holing"-> GLOBAL_SW(OmitBlackHoling)
531 _ | starts_with_fasm -> GLOBAL_SW(AsmTarget after_fasm)
532 | starts_with_G -> GLOBAL_SW(SccGroup after_G) -- profiling "group"
533 | starts_with_C -> GLOBAL_SW(ProduceC after_C) -- main C output
534 | starts_with_S -> GLOBAL_SW(ProduceS after_S) -- main .s output
535 | starts_with_hi -> GLOBAL_SW(ProduceHi after_hi) -- interface
536 --UNUSED: | starts_with_hu -> GLOBAL_SW(ProduceHu after_hu) -- usage info
538 | starts_with_uut -> GLOBAL_SW(UnfoldingUseThreshold (read after_uut))
539 | starts_with_uct -> GLOBAL_SW(UnfoldingCreationThreshold (read after_uct))
540 | starts_with_uot -> GLOBAL_SW(UnfoldingOverrideThreshold (read after_uot))
542 | starts_with_rirt -> -- trace ("rirt:"++after_rirt) $
543 GLOBAL_SW(ReturnInRegsThreshold (read after_rirt))
545 | starts_with_gtn -> GLOBAL_SW(EnsureSplittableC after_gtn)
548 _ -> writeMn stderr ("*** WARNING: bad option: "++opt1++"\n") `thenMn` ( \ _ ->
549 -- NB: the driver is really supposed to handle bad options
554 starts_with :: String -> String -> Maybe String
556 starts_with [] str = Just str
557 starts_with (c:cs) (s:ss)
558 = if c /= s then Nothing else starts_with cs ss
562 -- ToDo: DPH-ify "simpl_sep"!
564 simpl_sep :: [String] -- cmd-line opts (input)
565 -> [SimplifierSwitch] -- simplifier-switch accumulator
566 -> [GlobalSwitch] -- switch accumulator
567 -> [CoreToDo] -> [StgToDo] -- to_do accumulators
568 -> MainIO CmdLineInfo -- result
570 -- "simpl_sep" tailcalls "sep" once it's seen one set
571 -- of SimplifierSwitches for a CoreDoSimplify.
574 simpl_sep input@[] simpl_sw glob_sw core_td stg_td
575 = panic "simpl_sep []"
578 -- The SimplifierSwitches should be delimited by "(" and ")".
580 simpl_sep ("(":opts) [{-better be empty-}] glob_sw core_td stg_td
581 = simpl_sep opts [] glob_sw core_td stg_td
583 simpl_sep (")":opts) simpl_sw glob_sw core_td stg_td
585 this_CoreDoSimplify = CoreDoSimplify (isAmongSimpl simpl_sw)
587 sep opts glob_sw (this_CoreDoSimplify : core_td) stg_td
589 simpl_sep (opt1:opts) simpl_sw glob_sw core_td stg_td
591 maybe_suut = starts_with "-fsimpl-uf-use-threshold" opt1
592 maybe_suct = starts_with "-fsimpl-uf-creation-threshold" opt1
593 maybe_msi = starts_with "-fmax-simplifier-iterations" opt1
594 starts_with_suut = maybeToBool maybe_suut
595 starts_with_suct = maybeToBool maybe_suct
596 starts_with_msi = maybeToBool maybe_msi
597 (Just after_suut) = maybe_suut
598 (Just after_suct) = maybe_suct
599 (Just after_msi) = maybe_msi
601 case opt1 of -- the non-"just match a string" options are at the end...
602 "-fshow-simplifier-progress" -> GLOBAL_SIMPL_SW(ShowSimplifierProgress)
604 "-fcode-duplication-ok" -> GLOBAL_SIMPL_SW(SimplOkToDupCode)
605 "-ffloat-lets-exposing-whnf" -> GLOBAL_SIMPL_SW(SimplFloatLetsExposingWHNF)
606 "-ffloat-primops-ok" -> GLOBAL_SIMPL_SW(SimplOkToFloatPrimOps)
607 "-falways-float-lets-from-lets" -> GLOBAL_SIMPL_SW(SimplAlwaysFloatLetsFromLets)
608 "-fdo-case-elim" -> GLOBAL_SIMPL_SW(SimplDoCaseElim)
609 "-fdo-eta-reduction" -> GLOBAL_SIMPL_SW(SimplDoEtaReduction)
610 "-fdo-lambda-eta-expansion" -> GLOBAL_SIMPL_SW(SimplDoLambdaEtaExpansion)
611 "-fdo-foldr-build" -> GLOBAL_SIMPL_SW(SimplDoFoldrBuild)
612 "-fdo-new-occur-anal" -> GLOBAL_SIMPL_SW(SimplDoNewOccurAnal)
613 "-fdo-arity-expand" -> GLOBAL_SIMPL_SW(SimplDoArityExpand)
614 "-fdo-inline-foldr-build" -> GLOBAL_SIMPL_SW(SimplDoInlineFoldrBuild)
615 "-freuse-con" -> GLOBAL_SIMPL_SW(SimplReuseCon)
616 "-fcase-of-case" -> GLOBAL_SIMPL_SW(SimplCaseOfCase)
617 "-flet-to-case" -> GLOBAL_SIMPL_SW(SimplLetToCase)
618 "-fpedantic-bottoms" -> GLOBAL_SIMPL_SW(SimplPedanticBottoms)
619 "-fkeep-spec-pragma-ids" -> GLOBAL_SIMPL_SW(KeepSpecPragmaIds)
620 "-fkeep-unused-bindings" -> GLOBAL_SIMPL_SW(KeepUnusedBindings)
621 "-fmay-delete-conjurable-ids" -> GLOBAL_SIMPL_SW(SimplMayDeleteConjurableIds)
622 "-fessential-unfoldings-only" -> GLOBAL_SIMPL_SW(EssentialUnfoldingsOnly)
623 "-fignore-inline-pragma" -> GLOBAL_SIMPL_SW(IgnoreINLINEPragma)
624 "-fno-let-from-case" -> GLOBAL_SIMPL_SW(SimplNoLetFromCase)
625 "-fno-let-from-app" -> GLOBAL_SIMPL_SW(SimplNoLetFromApp)
626 "-fno-let-from-strict-let" -> GLOBAL_SIMPL_SW(SimplNoLetFromStrictLet)
628 _ | starts_with_msi -> GLOBAL_SIMPL_SW(MaxSimplifierIterations (read after_msi))
629 | starts_with_suut -> GLOBAL_SIMPL_SW(SimplUnfoldingUseThreshold (read after_suut))
630 | starts_with_suct -> GLOBAL_SIMPL_SW(SimplUnfoldingCreationThreshold (read after_suct))
632 _ -> writeMn stderr ("*** WARNING: bad simplifier option: "++opt1++"\n") `thenMn` ( \ _ ->
633 -- NB: the driver is really supposed to handle bad options
634 simpl_sep opts simpl_sw glob_sw core_td stg_td )
637 %************************************************************************
639 \subsection[CmdLineOpts-order]{Switch ordering}
641 %************************************************************************
643 In spite of the @Produce*@ and @SccGroup@ constructors, these things
644 behave just like enumeration types.
647 instance Eq GlobalSwitch where
648 a == b = tagOf_Switch a _EQ_ tagOf_Switch b
650 instance Ord GlobalSwitch where
651 a < b = tagOf_Switch a _LT_ tagOf_Switch b
652 a <= b = tagOf_Switch a _LE_ tagOf_Switch b
654 instance Eq SimplifierSwitch where
655 a == b = tagOf_SimplSwitch a _EQ_ tagOf_SimplSwitch b
657 instance Ord SimplifierSwitch where
658 a < b = tagOf_SimplSwitch a _LT_ tagOf_SimplSwitch b
659 a <= b = tagOf_SimplSwitch a _LE_ tagOf_SimplSwitch b
661 tagOf_Switch (ProduceC _) =(ILIT(0) :: FAST_INT)
662 tagOf_Switch (ProduceS _) = ILIT(1)
663 tagOf_Switch (ProduceHi _) = ILIT(2)
664 tagOf_Switch (AsmTarget _) = ILIT(4)
665 tagOf_Switch ForConcurrent = ILIT(6)
666 tagOf_Switch Haskell_1_3 = ILIT(8)
667 tagOf_Switch GlasgowExts = ILIT(9)
668 tagOf_Switch CompilingPrelude = ILIT(10)
669 tagOf_Switch HideBuiltinNames = ILIT(11)
670 tagOf_Switch HideMostBuiltinNames = ILIT(12)
671 tagOf_Switch (EnsureSplittableC _) = ILIT(13)
672 tagOf_Switch Verbose = ILIT(14)
673 tagOf_Switch PprStyle_User = ILIT(15)
674 tagOf_Switch PprStyle_Debug = ILIT(16)
675 tagOf_Switch PprStyle_All = ILIT(17)
676 tagOf_Switch DoCoreLinting = ILIT(18)
677 tagOf_Switch EmitArityChecks = ILIT(19)
678 tagOf_Switch OmitInterfacePragmas = ILIT(20)
679 tagOf_Switch OmitDerivedRead = ILIT(21)
680 tagOf_Switch OmitReexportedInstances = ILIT(22)
681 tagOf_Switch (UnfoldingUseThreshold _) = ILIT(23)
682 tagOf_Switch (UnfoldingCreationThreshold _) = ILIT(24)
683 tagOf_Switch (UnfoldingOverrideThreshold _) = ILIT(25)
684 tagOf_Switch ReportWhyUnfoldingsDisallowed = ILIT(26)
685 tagOf_Switch UseGetMentionedVars = ILIT(27)
686 tagOf_Switch ShowPragmaNameErrs = ILIT(28)
687 tagOf_Switch NameShadowingNotOK = ILIT(29)
688 tagOf_Switch SigsRequired = ILIT(30)
689 tagOf_Switch SccProfilingOn = ILIT(31)
690 tagOf_Switch AutoSccsOnExportedToplevs = ILIT(32)
691 tagOf_Switch AutoSccsOnAllToplevs = ILIT(33)
692 tagOf_Switch AutoSccsOnIndividualCafs = ILIT(34)
693 tagOf_Switch (SccGroup _) = ILIT(36)
694 tagOf_Switch DoTickyProfiling = ILIT(37)
695 tagOf_Switch DoSemiTagging = ILIT(38)
696 tagOf_Switch FoldrBuildOn = ILIT(39)
697 tagOf_Switch FoldrBuildTrace = ILIT(40)
698 tagOf_Switch SpecialiseImports = ILIT(41)
699 tagOf_Switch ShowImportSpecs = ILIT(42)
700 tagOf_Switch OmitDefaultInstanceMethods = ILIT(43)
701 tagOf_Switch SpecialiseOverloaded = ILIT(44)
702 tagOf_Switch SpecialiseUnboxed = ILIT(45)
703 tagOf_Switch SpecialiseAll = ILIT(46)
704 tagOf_Switch SpecialiseTrace = ILIT(47)
706 tagOf_Switch OmitBlackHoling = ILIT(49)
707 tagOf_Switch StgDoLetNoEscapes = ILIT(50)
708 tagOf_Switch IgnoreStrictnessPragmas = ILIT(51)
709 tagOf_Switch IrrefutableTuples = ILIT(52)
710 tagOf_Switch IrrefutableEverything = ILIT(53)
711 tagOf_Switch AllStrict = ILIT(54)
712 tagOf_Switch NumbersStrict = ILIT(55)
713 tagOf_Switch AllDemanded = ILIT(56)
715 tagOf_Switch (ReturnInRegsThreshold _) = ILIT(57)
716 tagOf_Switch (VectoredReturnThreshold _)= ILIT(58)
717 tagOf_Switch D_dump_rif2hs = ILIT(59)
718 tagOf_Switch D_dump_rn4 = ILIT(60)
719 tagOf_Switch D_dump_tc = ILIT(61)
720 tagOf_Switch D_dump_deriv = ILIT(62)
721 tagOf_Switch D_dump_ds = ILIT(63)
722 tagOf_Switch D_dump_simpl = ILIT(64)
723 tagOf_Switch D_dump_spec = ILIT(65)
724 tagOf_Switch D_dump_occur_anal = ILIT(66)
725 tagOf_Switch D_dump_stranal = ILIT(67)
726 tagOf_Switch D_dump_stg = ILIT(68)
727 tagOf_Switch D_dump_absC = ILIT(69)
728 tagOf_Switch D_dump_flatC = ILIT(70)
729 tagOf_Switch D_dump_realC = ILIT(71)
730 tagOf_Switch D_dump_asm = ILIT(72)
731 tagOf_Switch D_show_passes = ILIT(73)
732 --ANDY:tagOf_Switch D_dump_core_passes_info = ILIT(??)
733 tagOf_Switch D_verbose_core2core = ILIT(74)
734 tagOf_Switch D_verbose_stg2stg = ILIT(75)
735 tagOf_Switch D_simplifier_stats = ILIT(76)
736 tagOf_Switch D_source_stats = ILIT(77) {-see note below!-}
739 tagOf_Switch _ = case (panic "tagOf_Switch") of -- BUG avoidance
742 lAST_SWITCH_TAG = IBOX(tagOf_Switch D_source_stats)
744 #else {- Data Parallel Haskell -}
746 tagOf_Switch PodizeIntelligent = ILIT(90)
747 tagOf_Switch PodizeAggresive = ILIT(91)
748 tagOf_Switch PodizeVeryAggresive = ILIT(92)
749 tagOf_Switch PodizeExtremelyAggresive = ILIT(93)
750 tagOf_Switch D_dump_pod = ILIT(94)
751 tagOf_Switch D_dump_psimpl = ILIT(95)
752 tagOf_Switch D_dump_nextC = ILIT(96)
754 tagOf_Switch _ = case (panic "tagOf_Switch") of -- BUG avoidance
757 lAST_SWITCH_TAG = IBOX(tagOf_Switch D_dump_nextC)
759 #endif {- Data Parallel Haskell -}
762 (Note For Will): Could you please leave a little extra room between
763 your last option and @D_dump_spec@... Thanks... jon...
766 tagOf_SimplSwitch SimplOkToDupCode =(ILIT(0) :: FAST_INT)
767 tagOf_SimplSwitch SimplFloatLetsExposingWHNF = ILIT(1)
768 tagOf_SimplSwitch SimplOkToFloatPrimOps = ILIT(2)
769 tagOf_SimplSwitch SimplAlwaysFloatLetsFromLets = ILIT(3)
770 tagOf_SimplSwitch SimplDoCaseElim = ILIT(4)
771 tagOf_SimplSwitch SimplReuseCon = ILIT(5)
772 tagOf_SimplSwitch SimplCaseOfCase = ILIT(6)
773 tagOf_SimplSwitch SimplLetToCase = ILIT(7)
774 tagOf_SimplSwitch SimplMayDeleteConjurableIds = ILIT(9)
775 tagOf_SimplSwitch SimplPedanticBottoms = ILIT(10)
776 tagOf_SimplSwitch SimplDoArityExpand = ILIT(11)
777 tagOf_SimplSwitch SimplDoFoldrBuild = ILIT(12)
778 tagOf_SimplSwitch SimplDoNewOccurAnal = ILIT(13)
779 tagOf_SimplSwitch SimplDoInlineFoldrBuild = ILIT(14)
780 tagOf_SimplSwitch IgnoreINLINEPragma = ILIT(15)
781 tagOf_SimplSwitch SimplDoLambdaEtaExpansion = ILIT(16)
782 tagOf_SimplSwitch SimplDoEtaReduction = ILIT(18)
783 tagOf_SimplSwitch EssentialUnfoldingsOnly = ILIT(19)
784 tagOf_SimplSwitch ShowSimplifierProgress = ILIT(20)
785 tagOf_SimplSwitch (MaxSimplifierIterations _) = ILIT(21)
786 tagOf_SimplSwitch (SimplUnfoldingUseThreshold _) = ILIT(22)
787 tagOf_SimplSwitch (SimplUnfoldingCreationThreshold _) = ILIT(23)
788 tagOf_SimplSwitch KeepSpecPragmaIds = ILIT(24)
789 tagOf_SimplSwitch KeepUnusedBindings = ILIT(25)
790 tagOf_SimplSwitch SimplNoLetFromCase = ILIT(26)
791 tagOf_SimplSwitch SimplNoLetFromApp = ILIT(27)
792 tagOf_SimplSwitch SimplNoLetFromStrictLet = ILIT(28)
793 -- If you add anything here, be sure to change lAST_SIMPL_SWITCH_TAG, too!
796 tagOf_SimplSwitch Extra__SimplFlag1 = ILIT(26)
797 tagOf_SimplSwitch Extra__SimplFlag2 = ILIT(27)
798 tagOf_SimplSwitch Extra__SimplFlag3 = ILIT(28)
799 tagOf_SimplSwitch Extra__SimplFlag4 = ILIT(29)
800 tagOf_SimplSwitch Extra__SimplFlag5 = ILIT(30)
801 tagOf_SimplSwitch Extra__SimplFlag6 = ILIT(31)
802 tagOf_SimplSwitch Extra__SimplFlag8 = ILIT(32)
805 tagOf_SimplSwitch _ = case (panic "tagOf_SimplSwitch") of -- BUG avoidance
806 s -> tagOf_SimplSwitch s
808 lAST_SIMPL_SWITCH_TAG = IBOX(tagOf_SimplSwitch SimplNoLetFromStrictLet)
811 %************************************************************************
813 \subsection[CmdLineOpts-lookup]{Switch lookup}
815 %************************************************************************
818 isAmong :: [GlobalSwitch] -> GlobalSwitch -> SwitchResult
819 isAmongSimpl :: [SimplifierSwitch] -> SimplifierSwitch -> SwitchResult
823 tidied_on_switches = foldl rm_dups [] on_switches
825 sw_tbl :: Array Int SwitchResult
827 sw_tbl = (array (0, lAST_SWITCH_TAG) -- bounds...
831 all_undefined = [ i := SwBool False | i <- [0 .. lAST_SWITCH_TAG ] ]
833 defined_elems = map mk_assoc_elem tidied_on_switches
835 #ifndef __GLASGOW_HASKELL__
836 \ switch -> sw_tbl ! IBOX((tagOf_Switch switch)) -- but this is fast!
838 -- and this is faster!
839 -- (avoid some unboxing, bounds checking, and other horrible things:)
840 case sw_tbl of { _Array bounds_who_needs_'em stuff ->
842 case (indexArray# stuff (tagOf_Switch switch)) of
847 mk_assoc_elem k@(ProduceC str) = IBOX(tagOf_Switch k) := SwString str
848 mk_assoc_elem k@(ProduceS str) = IBOX(tagOf_Switch k) := SwString str
849 mk_assoc_elem k@(ProduceHi str) = IBOX(tagOf_Switch k) := SwString str
850 --UNUSED: mk_assoc_elem k@(ProduceHu str) = IBOX(tagOf_Switch k) := SwString str
851 mk_assoc_elem k@(SccGroup str) = IBOX(tagOf_Switch k) := SwString str
852 mk_assoc_elem k@(AsmTarget str) = IBOX(tagOf_Switch k) := SwString str
853 mk_assoc_elem k@(EnsureSplittableC str) = IBOX(tagOf_Switch k) := SwString str
855 mk_assoc_elem k@(UnfoldingUseThreshold lvl) = IBOX(tagOf_Switch k) := SwInt lvl
856 mk_assoc_elem k@(UnfoldingCreationThreshold lvl) = IBOX(tagOf_Switch k) := SwInt lvl
857 mk_assoc_elem k@(UnfoldingOverrideThreshold lvl) = IBOX(tagOf_Switch k) := SwInt lvl
859 mk_assoc_elem k@(ReturnInRegsThreshold lvl) = IBOX(tagOf_Switch k) := SwInt lvl
861 mk_assoc_elem k = IBOX(tagOf_Switch k) := SwBool True -- I'm here, Mom!
863 -- cannot have duplicates if we are going to use the array thing
865 rm_dups switches_so_far switch
866 = if switch `is_elem` switches_so_far
868 else switch : switches_so_far
870 sw `is_elem` [] = False
871 sw `is_elem` (s:ss) = (tagOf_Switch sw) _EQ_ (tagOf_Switch s)
875 Same thing for @SimplifierSwitches@; for efficiency reasons, we
876 probably do {\em not} want something overloaded.
878 isAmongSimpl on_switches
880 tidied_on_switches = foldl rm_dups [] on_switches
882 sw_tbl :: Array Int SwitchResult
884 sw_tbl = (array (0, lAST_SIMPL_SWITCH_TAG) -- bounds...
888 all_undefined = [ i := SwBool False | i <- [0 .. lAST_SIMPL_SWITCH_TAG ] ]
890 defined_elems = map mk_assoc_elem tidied_on_switches
892 #ifndef __GLASGOW_HASKELL__
893 \ switch -> sw_tbl ! IBOX((tagOf_SimplSwitch switch)) -- but this is fast!
895 -- and this is faster!
896 -- (avoid some unboxing, bounds checking, and other horrible things:)
897 case sw_tbl of { _Array bounds_who_needs_'em stuff ->
899 case (indexArray# stuff (tagOf_SimplSwitch switch)) of
904 mk_assoc_elem k@(MaxSimplifierIterations lvl) = IBOX(tagOf_SimplSwitch k) := SwInt lvl
905 mk_assoc_elem k@(SimplUnfoldingUseThreshold i) = IBOX(tagOf_SimplSwitch k) := SwInt i
906 mk_assoc_elem k@(SimplUnfoldingCreationThreshold i) = IBOX(tagOf_SimplSwitch k) := SwInt i
908 mk_assoc_elem k = IBOX(tagOf_SimplSwitch k) := SwBool True -- I'm here, Mom!
910 -- cannot have duplicates if we are going to use the array thing
912 rm_dups switches_so_far switch
913 = if switch `is_elem` switches_so_far
915 else switch : switches_so_far
917 sw `is_elem` [] = False
918 sw `is_elem` (s:ss) = (tagOf_SimplSwitch sw) _EQ_ (tagOf_SimplSwitch s)
922 %************************************************************************
924 \subsection[CmdLineOpts-misc]{Misc functions for command-line options}
926 %************************************************************************
930 switchIsOn :: (switch -> SwitchResult) -> switch -> Bool
932 switchIsOn lookup_fn switch
933 = case (lookup_fn switch) of
934 SwBool False -> False
937 stringSwitchSet :: (switch -> SwitchResult)
938 -> (String -> switch)
941 stringSwitchSet lookup_fn switch
942 = case (lookup_fn (switch (panic "stringSwitchSet"))) of
943 SwString str -> Just str
946 intSwitchSet :: (switch -> SwitchResult)
950 intSwitchSet lookup_fn switch
951 = -- pprTrace "intSwitchSet:" (ppInt (IBOX (tagOf_Switch (switch (panic "xxx"))))) $
952 case (lookup_fn (switch (panic "intSwitchSet"))) of
953 SwInt int -> Just int