[project @ 2001-06-01 17:14:07 by apt]
[ghc-hetmet.git] / ghc / compiler / main / CmdLineOpts.lhs
1
2 % (c) The University of Glasgow, 1996-2000
3 %
4 \section[CmdLineOpts]{Things to do with command-line options}
5
6 \begin{code}
7
8 module CmdLineOpts (
9         CoreToDo(..),
10         SimplifierSwitch(..), isAmongSimpl,
11         StgToDo(..),
12         SwitchResult(..),
13
14         HscLang(..),
15         DynFlag(..),    -- needed non-abstractly by DriverFlags
16         DynFlags(..),
17         defaultDynFlags,
18
19         v_Static_hsc_opts,
20
21         intSwitchSet,
22         switchIsOn,
23         isStaticHscFlag,
24
25         opt_PprStyle_NoPrags,
26         opt_PprStyle_RawTypes,
27         opt_PprUserLength,
28         opt_PprStyle_Debug,
29
30         dopt,
31         dopt_set,
32         dopt_unset,
33
34         -- other dynamic flags
35         dopt_CoreToDo,
36         dopt_StgToDo,
37         dopt_HscLang,
38         dopt_OutName,
39
40         -- sets of warning opts
41         standardWarnings,
42         minusWOpts,
43         minusWallOpts,
44
45         -- profiling opts
46         opt_AutoSccsOnAllToplevs,
47         opt_AutoSccsOnExportedToplevs,
48         opt_AutoSccsOnIndividualCafs,
49         opt_AutoSccsOnDicts,
50         opt_SccProfilingOn,
51         opt_DoTickyProfiling,
52
53         -- language opts
54         opt_AllStrict,
55         opt_DictsStrict,
56         opt_MaxContextReductionDepth,
57         opt_IrrefutableTuples,
58         opt_NumbersStrict,
59         opt_Parallel,
60         opt_SMP,
61         opt_NoMonomorphismRestriction,
62         opt_RuntimeTypes,
63
64         -- optimisation opts
65         opt_NoMethodSharing,
66         opt_DoSemiTagging,
67         opt_FoldrBuildOn,
68         opt_LiberateCaseThreshold,
69         opt_StgDoLetNoEscapes,
70         opt_UnfoldCasms,
71         opt_UsageSPOn,
72         opt_UnboxStrictFields,
73         opt_SimplNoPreInlining,
74         opt_SimplDoEtaReduction,
75         opt_SimplDoLambdaEtaExpansion,
76         opt_SimplCaseMerge,
77         opt_SimplExcessPrecision,
78
79         -- Unfolding control
80         opt_UF_CreationThreshold,
81         opt_UF_UseThreshold,
82         opt_UF_FunAppDiscount,
83         opt_UF_KeenessFactor,
84         opt_UF_UpdateInPlace,
85         opt_UF_CheapOp,
86         opt_UF_DearOp,
87
88         -- misc opts
89         opt_InPackage,
90         opt_EmitCExternDecls,
91         opt_EnsureSplittableC,
92         opt_GranMacros,
93         opt_HiVersion,
94         opt_HistorySize,
95         opt_IgnoreAsserts,
96         opt_IgnoreIfacePragmas,
97         opt_NoHiCheck,
98         opt_OmitBlackHoling,
99         opt_OmitInterfacePragmas,
100         opt_NoPruneTyDecls,
101         opt_NoPruneDecls,
102         opt_Static,
103         opt_Unregisterised,
104         opt_EmitExternalCore
105     ) where
106
107 #include "HsVersions.h"
108
109 import Array    ( array, (//) )
110 import GlaExts
111 import IOExts   ( IORef, readIORef )
112 import Constants        -- Default values for some flags
113 import Util
114 import FastTypes
115 import Config
116
117 import Maybes           ( firstJust )
118 import Panic            ( panic )
119
120 #if __GLASGOW_HASKELL__ < 301
121 import ArrBase  ( Array(..) )
122 #else
123 import PrelArr  ( Array(..) )
124 #endif
125 \end{code}
126
127 %************************************************************************
128 %*                                                                      *
129 \subsection{Command-line options}
130 %*                                                                      *
131 %************************************************************************
132
133 The hsc command-line options are split into two categories:
134
135   - static flags
136   - dynamic flags
137
138 Static flags are represented by top-level values of type Bool or Int,
139 for example.  They therefore have the same value throughout the
140 invocation of hsc.
141
142 Dynamic flags are represented by an abstract type, DynFlags, which is
143 passed into hsc by the compilation manager for every compilation.
144 Dynamic flags are those that change on a per-compilation basis,
145 perhaps because they may be present in the OPTIONS pragma at the top
146 of a module.
147
148 Other flag-related blurb:
149
150 A list of {\em ToDo}s is things to be done in a particular part of
151 processing.  A (fictitious) example for the Core-to-Core simplifier
152 might be: run the simplifier, then run the strictness analyser, then
153 run the simplifier again (three ``todos'').
154
155 There are three ``to-do processing centers'' at the moment.  In the
156 main loop (\tr{main/Main.lhs}), in the Core-to-Core processing loop
157 (\tr{simplCore/SimplCore.lhs), and in the STG-to-STG processing loop
158 (\tr{simplStg/SimplStg.lhs}).
159
160 %************************************************************************
161 %*                                                                      *
162 \subsection{Datatypes associated with command-line options}
163 %*                                                                      *
164 %************************************************************************
165
166 \begin{code}
167 data SwitchResult
168   = SwBool      Bool            -- on/off
169   | SwString    FAST_STRING     -- nothing or a String
170   | SwInt       Int             -- nothing or an Int
171 \end{code}
172
173 \begin{code}
174 data CoreToDo           -- These are diff core-to-core passes,
175                         -- which may be invoked in any order,
176                         -- as many times as you like.
177
178   = CoreDoSimplify      -- The core-to-core simplifier.
179         (SimplifierSwitch -> SwitchResult)
180                         -- Each run of the simplifier can take a different
181                         -- set of simplifier-specific flags.
182   | CoreDoFloatInwards
183   | CoreDoFloatOutwards Bool    -- True <=> float lambdas to top level
184   | CoreLiberateCase
185   | CoreDoPrintCore
186   | CoreDoStaticArgs
187   | CoreDoStrictness
188   | CoreDoWorkerWrapper
189   | CoreDoSpecialising
190   | CoreDoSpecConstr
191   | CoreDoUSPInf
192   | CoreDoCPResult
193   | CoreDoGlomBinds
194   | CoreCSE
195
196   | CoreDoNothing        -- useful when building up lists of these things
197 \end{code}
198
199 \begin{code}
200 data StgToDo
201   = StgDoMassageForProfiling  -- should be (next to) last
202   -- There's also setStgVarInfo, but its absolute "lastness"
203   -- is so critical that it is hardwired in (no flag).
204   | D_stg_stats
205 \end{code}
206
207 \begin{code}
208 data SimplifierSwitch
209   = MaxSimplifierIterations Int
210   | SimplInlinePhase Int
211   | DontApplyRules
212   | NoCaseOfCase
213   | SimplLetToCase
214 \end{code}
215
216 %************************************************************************
217 %*                                                                      *
218 \subsection{Dynamic command-line options}
219 %*                                                                      *
220 %************************************************************************
221
222 \begin{code}
223 data DynFlag
224
225    -- debugging flags
226    = Opt_D_dump_absC
227    | Opt_D_dump_asm
228    | Opt_D_dump_cpranal
229    | Opt_D_dump_deriv
230    | Opt_D_dump_ds
231    | Opt_D_dump_flatC
232    | Opt_D_dump_foreign
233    | Opt_D_dump_inlinings
234    | Opt_D_dump_occur_anal
235    | Opt_D_dump_parsed
236    | Opt_D_dump_realC
237    | Opt_D_dump_rn
238    | Opt_D_dump_simpl
239    | Opt_D_dump_simpl_iterations
240    | Opt_D_dump_spec
241    | Opt_D_dump_sat
242    | Opt_D_dump_stg
243    | Opt_D_dump_stranal
244    | Opt_D_dump_tc
245    | Opt_D_dump_types
246    | Opt_D_dump_rules
247    | Opt_D_dump_usagesp
248    | Opt_D_dump_cse
249    | Opt_D_dump_worker_wrapper
250    | Opt_D_dump_rn_trace
251    | Opt_D_dump_rn_stats
252    | Opt_D_dump_stix
253    | Opt_D_dump_simpl_stats
254    | Opt_D_dump_tc_trace
255    | Opt_D_dump_BCOs
256    | Opt_D_source_stats
257    | Opt_D_verbose_core2core
258    | Opt_D_verbose_stg2stg
259    | Opt_D_dump_hi
260    | Opt_D_dump_hi_diffs
261    | Opt_D_dump_minimal_imports
262    | Opt_DoCoreLinting
263    | Opt_DoStgLinting
264    | Opt_DoUSPLinting
265
266    | Opt_WarnDuplicateExports
267    | Opt_WarnHiShadows
268    | Opt_WarnIncompletePatterns
269    | Opt_WarnMissingFields
270    | Opt_WarnMissingMethods
271    | Opt_WarnMissingSigs
272    | Opt_WarnNameShadowing
273    | Opt_WarnOverlappingPatterns
274    | Opt_WarnSimplePatterns
275    | Opt_WarnTypeDefaults
276    | Opt_WarnUnusedBinds
277    | Opt_WarnUnusedImports
278    | Opt_WarnUnusedMatches
279    | Opt_WarnDeprecations
280    | Opt_WarnMisc
281
282    -- language opts
283    | Opt_AllowOverlappingInstances
284    | Opt_AllowUndecidableInstances
285    | Opt_GlasgowExts
286    | Opt_Generics
287    | Opt_NoImplicitPrelude 
288
289    deriving (Eq)
290
291 data DynFlags = DynFlags {
292   coreToDo              :: [CoreToDo],
293   stgToDo               :: [StgToDo],
294   hscLang               :: HscLang,
295   hscOutName            :: String,      -- name of the output file
296   hscStubHOutName       :: String,      -- name of the .stub_h output file
297   hscStubCOutName       :: String,      -- name of the .stub_c output file
298   extCoreName           :: String,      -- name of the .core output file
299   verbosity             :: Int,         -- verbosity level
300   cppFlag               :: Bool,        -- preprocess with cpp?
301   stolen_x86_regs       :: Int,         
302   cmdlineHcIncludes     :: [String],    -- -#includes
303
304   -- options for particular phases
305   opt_L                 :: [String],
306   opt_P                 :: [String],
307   opt_c                 :: [String],
308   opt_a                 :: [String],
309   opt_m                 :: [String],
310
311   -- hsc dynamic flags
312   flags                 :: [DynFlag]
313  }
314
315 defaultDynFlags = DynFlags {
316   coreToDo = [], stgToDo = [], 
317   hscLang = HscC, 
318   hscOutName = "", 
319   hscStubHOutName = "", hscStubCOutName = "",
320   extCoreName = "",
321   verbosity = 0, 
322   cppFlag               = False,
323   stolen_x86_regs       = 4,
324   cmdlineHcIncludes     = [],
325   opt_L                 = [],
326   opt_P                 = [],
327   opt_c                 = [],
328   opt_a                 = [],
329   opt_m                 = [],
330   flags = standardWarnings,
331   }
332
333 {- 
334     Verbosity levels:
335         
336     0   |   print errors & warnings only
337     1   |   minimal verbosity: print "compiling M ... done." for each module.
338     2   |   equivalent to -dshow-passes
339     3   |   equivalent to existing "ghc -v"
340     4   |   "ghc -v -ddump-most"
341     5   |   "ghc -v -ddump-all"
342 -}
343
344 dopt :: DynFlag -> DynFlags -> Bool
345 dopt f dflags  = f `elem` (flags dflags)
346
347 dopt_CoreToDo :: DynFlags -> [CoreToDo]
348 dopt_CoreToDo = coreToDo
349
350 dopt_StgToDo :: DynFlags -> [StgToDo]
351 dopt_StgToDo = stgToDo
352
353 dopt_OutName :: DynFlags -> String
354 dopt_OutName = hscOutName
355
356 dopt_set :: DynFlags -> DynFlag -> DynFlags
357 dopt_set dfs f = dfs{ flags = f : flags dfs }
358
359 dopt_unset :: DynFlags -> DynFlag -> DynFlags
360 dopt_unset dfs f = dfs{ flags = filter (/= f) (flags dfs) }
361
362 data HscLang
363   = HscC
364   | HscAsm
365   | HscJava
366   | HscILX
367   | HscInterpreted
368     deriving (Eq, Show)
369
370 dopt_HscLang :: DynFlags -> HscLang
371 dopt_HscLang = hscLang
372 \end{code}
373
374 %************************************************************************
375 %*                                                                      *
376 \subsection{Warnings}
377 %*                                                                      *
378 %************************************************************************
379
380 \begin{code}
381 standardWarnings
382     = [ Opt_WarnDeprecations,
383         Opt_WarnOverlappingPatterns,
384         Opt_WarnMissingFields,
385         Opt_WarnMissingMethods,
386         Opt_WarnDuplicateExports
387       ]
388
389 minusWOpts
390     = standardWarnings ++ 
391       [ Opt_WarnUnusedBinds,
392         Opt_WarnUnusedMatches,
393         Opt_WarnUnusedImports,
394         Opt_WarnIncompletePatterns,
395         Opt_WarnMisc
396       ]
397
398 minusWallOpts
399     = minusWOpts ++
400       [ Opt_WarnTypeDefaults,
401         Opt_WarnNameShadowing,
402         Opt_WarnMissingSigs,
403         Opt_WarnHiShadows
404       ]
405 \end{code}
406
407 %************************************************************************
408 %*                                                                      *
409 \subsection{Classifying command-line options}
410 %*                                                                      *
411 %************************************************************************
412
413 \begin{code}
414 -- v_Statis_hsc_opts is here to avoid a circular dependency with
415 -- main/DriverState.
416 GLOBAL_VAR(v_Static_hsc_opts, [], [String])
417
418 lookUp           :: FAST_STRING -> Bool
419 lookup_int       :: String -> Maybe Int
420 lookup_def_int   :: String -> Int -> Int
421 lookup_def_float :: String -> Float -> Float
422 lookup_str       :: String -> Maybe String
423
424 unpacked_static_opts = unsafePerformIO (readIORef v_Static_hsc_opts)
425 packed_static_opts   = map _PK_ unpacked_static_opts
426
427 lookUp     sw = sw `elem` packed_static_opts
428         
429 lookup_str sw = firstJust (map (startsWith sw) unpacked_static_opts)
430
431 lookup_int sw = case (lookup_str sw) of
432                   Nothing -> Nothing
433                   Just xx -> Just (read xx)
434
435 lookup_def_int sw def = case (lookup_str sw) of
436                             Nothing -> def              -- Use default
437                             Just xx -> read xx
438
439 lookup_def_float sw def = case (lookup_str sw) of
440                             Nothing -> def              -- Use default
441                             Just xx -> read xx
442
443
444 {-
445  Putting the compiler options into temporary at-files
446  may turn out to be necessary later on if we turn hsc into
447  a pure Win32 application where I think there's a command-line
448  length limit of 255. unpacked_opts understands the @ option.
449
450 unpacked_opts :: [String]
451 unpacked_opts =
452   concat $
453   map (expandAts) $
454   map _UNPK_ argv  -- NOT ARGV any more: v_Static_hsc_opts
455   where
456    expandAts ('@':fname) = words (unsafePerformIO (readFile fname))
457    expandAts l = [l]
458 -}
459 \end{code}
460
461 %************************************************************************
462 %*                                                                      *
463 \subsection{Static options}
464 %*                                                                      *
465 %************************************************************************
466
467 \begin{code}
468 -- debugging opts
469 opt_PprStyle_NoPrags            = lookUp  SLIT("-dppr-noprags")
470 opt_PprStyle_Debug              = lookUp  SLIT("-dppr-debug")
471 opt_PprStyle_RawTypes           = lookUp  SLIT("-dppr-rawtypes")
472 opt_PprUserLength               = lookup_def_int "-dppr-user-length" 5 --ToDo: give this a name
473
474 -- profiling opts
475 opt_AutoSccsOnAllToplevs        = lookUp  SLIT("-fauto-sccs-on-all-toplevs")
476 opt_AutoSccsOnExportedToplevs   = lookUp  SLIT("-fauto-sccs-on-exported-toplevs")
477 opt_AutoSccsOnIndividualCafs    = lookUp  SLIT("-fauto-sccs-on-individual-cafs")
478 opt_AutoSccsOnDicts             = lookUp  SLIT("-fauto-sccs-on-dicts")
479 opt_SccProfilingOn              = lookUp  SLIT("-fscc-profiling")
480 opt_DoTickyProfiling            = lookUp  SLIT("-fticky-ticky")
481
482 -- language opts
483 opt_AllStrict                   = lookUp  SLIT("-fall-strict")
484 opt_NoMonomorphismRestriction   = lookUp  SLIT("-fno-monomorphism-restriction")
485 opt_DictsStrict                 = lookUp  SLIT("-fdicts-strict")
486 opt_IrrefutableTuples           = lookUp  SLIT("-firrefutable-tuples")
487 opt_MaxContextReductionDepth    = lookup_def_int "-fcontext-stack" mAX_CONTEXT_REDUCTION_DEPTH
488 opt_NumbersStrict               = lookUp  SLIT("-fnumbers-strict")
489 opt_Parallel                    = lookUp  SLIT("-fparallel")
490 opt_SMP                         = lookUp  SLIT("-fsmp")
491
492 -- optimisation opts
493 opt_NoMethodSharing             = lookUp  SLIT("-fno-method-sharing")
494 opt_DoSemiTagging               = lookUp  SLIT("-fsemi-tagging")
495 opt_FoldrBuildOn                = lookUp  SLIT("-ffoldr-build-on")
496 opt_LiberateCaseThreshold       = lookup_def_int "-fliberate-case-threshold" (10::Int)
497 opt_StgDoLetNoEscapes           = lookUp  SLIT("-flet-no-escape")
498 opt_UnfoldCasms                 = lookUp  SLIT("-funfold-casms-in-hi-file")
499 opt_UsageSPOn                   = lookUp  SLIT("-fusagesp-on")
500 opt_UnboxStrictFields           = lookUp  SLIT("-funbox-strict-fields")
501
502 {-
503    The optional '-inpackage=P' flag tells what package
504    we are compiling this module for.
505    The Prelude, for example is compiled with '-inpackage std'
506 -}
507 opt_InPackage                   = case lookup_str "-inpackage=" of
508                                     Just p  -> _PK_ p
509                                     Nothing -> SLIT("Main")     -- The package name if none is specified
510
511 opt_EmitCExternDecls            = lookUp  SLIT("-femit-extern-decls")
512 opt_EnsureSplittableC           = lookUp  SLIT("-fglobalise-toplev-names")
513 opt_GranMacros                  = lookUp  SLIT("-fgransim")
514 opt_HiVersion                   = read cProjectVersionInt :: Int
515 opt_HistorySize                 = lookup_def_int "-fhistory-size" 20
516 opt_IgnoreAsserts               = lookUp  SLIT("-fignore-asserts")
517 opt_IgnoreIfacePragmas          = lookUp  SLIT("-fignore-interface-pragmas")
518 opt_NoHiCheck                   = lookUp  SLIT("-fno-hi-version-check")
519 opt_OmitBlackHoling             = lookUp  SLIT("-dno-black-holing")
520 opt_OmitInterfacePragmas        = lookUp  SLIT("-fomit-interface-pragmas")
521 opt_RuntimeTypes                = lookUp  SLIT("-fruntime-types")
522
523 -- Simplifier switches
524 opt_SimplNoPreInlining          = lookUp  SLIT("-fno-pre-inlining")
525         -- NoPreInlining is there just to see how bad things
526         -- get if you don't do it!
527 opt_SimplDoEtaReduction         = lookUp  SLIT("-fdo-eta-reduction")
528 opt_SimplDoLambdaEtaExpansion   = lookUp  SLIT("-fdo-lambda-eta-expansion")
529 opt_SimplCaseMerge              = lookUp  SLIT("-fcase-merge")
530 opt_SimplExcessPrecision        = lookUp  SLIT("-fexcess-precision")
531
532 -- Unfolding control
533 opt_UF_CreationThreshold        = lookup_def_int "-funfolding-creation-threshold"  (45::Int)
534 opt_UF_UseThreshold             = lookup_def_int "-funfolding-use-threshold"       (8::Int)     -- Discounts can be big
535 opt_UF_FunAppDiscount           = lookup_def_int "-funfolding-fun-discount"        (6::Int)     -- It's great to inline a fn
536 opt_UF_KeenessFactor            = lookup_def_float "-funfolding-keeness-factor"    (1.5::Float)
537 opt_UF_UpdateInPlace            = lookUp  SLIT("-funfolding-update-in-place")
538
539 opt_UF_CheapOp  = ( 1 :: Int)   -- Only one instruction; and the args are charged for
540 opt_UF_DearOp   = ( 4 :: Int)
541                         
542 opt_NoPruneDecls                = lookUp  SLIT("-fno-prune-decls")
543 opt_NoPruneTyDecls              = lookUp  SLIT("-fno-prune-tydecls")
544 opt_Static                      = lookUp  SLIT("-static")
545 opt_Unregisterised              = lookUp  SLIT("-funregisterised")
546 opt_EmitExternalCore            = lookUp  SLIT("-fext-core")
547 \end{code}
548
549 %************************************************************************
550 %*                                                                      *
551 \subsection{List of static hsc flags}
552 %*                                                                      *
553 %************************************************************************
554
555 \begin{code}
556 isStaticHscFlag f =
557   f `elem` [
558         "fauto-sccs-on-all-toplevs",
559         "fauto-sccs-on-exported-toplevs",
560         "fauto-sccs-on-individual-cafs",
561         "fauto-sccs-on-dicts",
562         "fscc-profiling",
563         "fticky-ticky",
564         "fall-strict",
565         "fdicts-strict",
566         "firrefutable-tuples",
567         "fnumbers-strict",
568         "fparallel",
569         "fsmp",
570         "fsemi-tagging",
571         "ffoldr-build-on",
572         "flet-no-escape",
573         "funfold-casms-in-hi-file",
574         "fusagesp-on",
575         "funbox-strict-fields",
576         "femit-extern-decls",
577         "fglobalise-toplev-names",
578         "fgransim",
579         "fignore-asserts",
580         "fignore-interface-pragmas",
581         "fno-hi-version-check",
582         "dno-black-holing",
583         "fno-method-sharing",
584         "fno-monomorphism-restriction",
585         "fomit-interface-pragmas",
586         "fruntime-types",
587         "fno-pre-inlining",
588         "fdo-eta-reduction",
589         "fdo-lambda-eta-expansion",
590         "fcase-merge",
591         "fexcess-precision",
592         "funfolding-update-in-place",
593         "fno-prune-decls",
594         "fno-prune-tydecls",
595         "static",
596         "funregisterised",
597         "fext-core"
598         ]
599   || any (flip prefixMatch f) [
600         "fcontext-stack",
601         "fliberate-case-threshold",
602         "fhistory-size",
603         "funfolding-creation-threshold",
604         "funfolding-use-threshold",
605         "funfolding-fun-discount",
606         "funfolding-keeness-factor"
607      ]
608 \end{code}
609
610 %************************************************************************
611 %*                                                                      *
612 \subsection{Switch ordering}
613 %*                                                                      *
614 %************************************************************************
615
616 These things behave just like enumeration types.
617
618 \begin{code}
619 instance Eq SimplifierSwitch where
620     a == b = tagOf_SimplSwitch a ==# tagOf_SimplSwitch b
621
622 instance Ord SimplifierSwitch where
623     a <  b  = tagOf_SimplSwitch a <# tagOf_SimplSwitch b
624     a <= b  = tagOf_SimplSwitch a <=# tagOf_SimplSwitch b
625
626
627 tagOf_SimplSwitch (SimplInlinePhase _)          = _ILIT(1)
628 tagOf_SimplSwitch (MaxSimplifierIterations _)   = _ILIT(2)
629 tagOf_SimplSwitch DontApplyRules                = _ILIT(3)
630 tagOf_SimplSwitch SimplLetToCase                = _ILIT(4)
631 tagOf_SimplSwitch NoCaseOfCase                  = _ILIT(5)
632
633 -- If you add anything here, be sure to change lAST_SIMPL_SWITCH_TAG, too!
634
635 lAST_SIMPL_SWITCH_TAG = 5
636 \end{code}
637
638 %************************************************************************
639 %*                                                                      *
640 \subsection{Switch lookup}
641 %*                                                                      *
642 %************************************************************************
643
644 \begin{code}
645 isAmongSimpl :: [SimplifierSwitch] -> SimplifierSwitch -> SwitchResult
646 isAmongSimpl on_switches                -- Switches mentioned later occur *earlier*
647                                         -- in the list; defaults right at the end.
648   = let
649         tidied_on_switches = foldl rm_dups [] on_switches
650                 -- The fold*l* ensures that we keep the latest switches;
651                 -- ie the ones that occur earliest in the list.
652
653         sw_tbl :: Array Int SwitchResult
654         sw_tbl = (array (0, lAST_SIMPL_SWITCH_TAG) -- bounds...
655                         all_undefined)
656                  // defined_elems
657
658         all_undefined = [ (i, SwBool False) | i <- [0 .. lAST_SIMPL_SWITCH_TAG ] ]
659
660         defined_elems = map mk_assoc_elem tidied_on_switches
661     in
662     -- (avoid some unboxing, bounds checking, and other horrible things:)
663 #if __GLASGOW_HASKELL__ < 405
664     case sw_tbl of { Array bounds_who_needs_'em stuff ->
665 #else
666     case sw_tbl of { Array _ _ stuff ->
667 #endif
668     \ switch ->
669         case (indexArray# stuff (tagOf_SimplSwitch switch)) of
670 #if __GLASGOW_HASKELL__ < 400
671           Lift v -> v
672 #elif __GLASGOW_HASKELL__ < 403
673           (# _, v #) -> v
674 #else
675           (# v #) -> v
676 #endif
677     }
678   where
679     mk_assoc_elem k@(MaxSimplifierIterations lvl)
680         = (iBox (tagOf_SimplSwitch k), SwInt lvl)
681     mk_assoc_elem k@(SimplInlinePhase n)
682         = (iBox (tagOf_SimplSwitch k), SwInt n)
683     mk_assoc_elem k
684         = (iBox (tagOf_SimplSwitch k), SwBool True) -- I'm here, Mom!
685
686     -- cannot have duplicates if we are going to use the array thing
687     rm_dups switches_so_far switch
688       = if switch `is_elem` switches_so_far
689         then switches_so_far
690         else switch : switches_so_far
691       where
692         sw `is_elem` []     = False
693         sw `is_elem` (s:ss) = (tagOf_SimplSwitch sw) ==# (tagOf_SimplSwitch s)
694                             || sw `is_elem` ss
695 \end{code}
696
697
698 %************************************************************************
699 %*                                                                      *
700 \subsection{Misc functions for command-line options}
701 %*                                                                      *
702 %************************************************************************
703
704
705 \begin{code}
706 switchIsOn :: (switch -> SwitchResult) -> switch -> Bool
707
708 switchIsOn lookup_fn switch
709   = case (lookup_fn switch) of
710       SwBool False -> False
711       _            -> True
712
713 intSwitchSet :: (switch -> SwitchResult)
714              -> (Int -> switch)
715              -> Maybe Int
716
717 intSwitchSet lookup_fn switch
718   = case (lookup_fn (switch (panic "intSwitchSet"))) of
719       SwInt int -> Just int
720       _         -> Nothing
721 \end{code}
722
723 \begin{code}
724 startsWith :: String -> String -> Maybe String
725 -- startsWith pfx (pfx++rest) = Just rest
726
727 startsWith []     str = Just str
728 startsWith (c:cs) (s:ss)
729   = if c /= s then Nothing else startsWith cs ss
730 startsWith  _     []  = Nothing
731
732 endsWith  :: String -> String -> Maybe String
733 endsWith cs ss
734   = case (startsWith (reverse cs) (reverse ss)) of
735       Nothing -> Nothing
736       Just rs -> Just (reverse rs)
737 \end{code}