21cb1bcf45f082205cb4121014fd7f33b87d883c
[ghc-hetmet.git] / ghc / compiler / main / DriverState.hs
1 -----------------------------------------------------------------------------
2 -- $Id: DriverState.hs,v 1.45 2001/06/15 08:29:58 simonpj Exp $
3 --
4 -- Settings for the driver
5 --
6 -- (c) The University of Glasgow 2000
7 --
8 -----------------------------------------------------------------------------
9
10 module DriverState where
11
12 #include "../includes/config.h"
13 #include "HsVersions.h"
14
15 import Packages         ( PackageConfig(..) )
16 import CmdLineOpts
17 import DriverUtil
18 import Util
19 import Config
20 import Exception
21 import IOExts
22 import Panic
23
24 import List
25 import Char  
26 import Monad
27
28 -----------------------------------------------------------------------------
29 -- non-configured things
30
31 cHaskell1Version = "5" -- i.e., Haskell 98
32
33 -----------------------------------------------------------------------------
34 -- Global compilation flags
35
36 -- Cpp-related flags
37 v_Hs_source_cpp_opts = global
38         [ "-D__HASKELL1__="++cHaskell1Version
39         , "-D__GLASGOW_HASKELL__="++cProjectVersionInt                          
40         , "-D__HASKELL98__"
41         , "-D__CONCURRENT_HASKELL__"
42         ]
43 {-# NOINLINE v_Hs_source_cpp_opts #-}
44
45 -- Keep output from intermediate phases
46 GLOBAL_VAR(v_Keep_hi_diffs,             False,          Bool)
47 GLOBAL_VAR(v_Keep_hc_files,             False,          Bool)
48 GLOBAL_VAR(v_Keep_s_files,              False,          Bool)
49 GLOBAL_VAR(v_Keep_raw_s_files,          False,          Bool)
50 GLOBAL_VAR(v_Keep_tmp_files,            False,          Bool)
51
52 -- Misc
53 GLOBAL_VAR(v_Scale_sizes_by,            1.0,            Double)
54 GLOBAL_VAR(v_Static,                    True,           Bool)
55 GLOBAL_VAR(v_NoHsMain,                  False,          Bool)
56 GLOBAL_VAR(v_Recomp,                    True,           Bool)
57 GLOBAL_VAR(v_Collect_ghc_timing,        False,          Bool)
58 GLOBAL_VAR(v_Do_asm_mangling,           True,           Bool)
59 GLOBAL_VAR(v_Excess_precision,          False,          Bool)
60
61 -----------------------------------------------------------------------------
62 -- Splitting object files (for libraries)
63
64 GLOBAL_VAR(v_Split_object_files,        False,          Bool)
65 GLOBAL_VAR(v_Split_info,                ("",0),         (String,Int))
66         -- The split prefix and number of files
67
68         
69 can_split :: Bool
70 can_split =  prefixMatch "i386"    cTARGETPLATFORM
71           || prefixMatch "alpha"   cTARGETPLATFORM
72           || prefixMatch "hppa"    cTARGETPLATFORM
73           || prefixMatch "m68k"    cTARGETPLATFORM
74           || prefixMatch "mips"    cTARGETPLATFORM
75           || prefixMatch "powerpc" cTARGETPLATFORM
76           || prefixMatch "rs6000"  cTARGETPLATFORM
77           || prefixMatch "sparc"   cTARGETPLATFORM
78
79 -----------------------------------------------------------------------------
80 -- Compiler output options
81
82 defaultHscLang
83   | cGhcWithNativeCodeGen == "YES" && 
84         (prefixMatch "i386" cTARGETPLATFORM ||
85          prefixMatch "sparc" cTARGETPLATFORM)   =  HscAsm
86   | otherwise                                   =  HscC
87
88 GLOBAL_VAR(v_Output_dir,  Nothing, Maybe String)
89 GLOBAL_VAR(v_Output_file, Nothing, Maybe String)
90 GLOBAL_VAR(v_Output_hi,   Nothing, Maybe String)
91
92 GLOBAL_VAR(v_Object_suf,  Nothing, Maybe String)
93 GLOBAL_VAR(v_HC_suf,      Nothing, Maybe String)
94 GLOBAL_VAR(v_Hi_dir,      Nothing, Maybe String)
95 GLOBAL_VAR(v_Hi_suf,      "hi",    String)
96
97 GLOBAL_VAR(v_Ld_inputs, [],      [String])
98
99 odir_ify :: String -> IO String
100 odir_ify f = do
101   odir_opt <- readIORef v_Output_dir
102   case odir_opt of
103         Nothing -> return f
104         Just d  -> return (newdir d f)
105
106 osuf_ify :: String -> IO String
107 osuf_ify f = do
108   osuf_opt <- readIORef v_Object_suf
109   case osuf_opt of
110         Nothing -> return f
111         Just s  -> return (newsuf s f)
112
113 -----------------------------------------------------------------------------
114 -- Compiler optimisation options
115
116 GLOBAL_VAR(v_OptLevel, 0, Int)
117
118 setOptLevel :: String -> IO ()
119 setOptLevel ""              = do { writeIORef v_OptLevel 1 }
120 setOptLevel "not"           = writeIORef v_OptLevel 0
121 setOptLevel [c] | isDigit c = do
122    let level = ord c - ord '0'
123    writeIORef v_OptLevel level
124 setOptLevel s = unknownFlagErr ("-O"++s)
125
126 GLOBAL_VAR(v_minus_o2_for_C,            False, Bool)
127 GLOBAL_VAR(v_MaxSimplifierIterations,   4,     Int)
128 GLOBAL_VAR(v_StgStats,                  False, Bool)
129 GLOBAL_VAR(v_UsageSPInf,                False, Bool)  -- Off by default
130 GLOBAL_VAR(v_Strictness,                True,  Bool)
131 GLOBAL_VAR(v_CPR,                       True,  Bool)
132 GLOBAL_VAR(v_CSE,                       True,  Bool)
133
134 -- these are the static flags you get without -O.
135 hsc_minusNoO_flags =
136        [ 
137         "-fignore-interface-pragmas",
138         "-fomit-interface-pragmas",
139         "-fdo-lambda-eta-expansion",    -- This one is important for a tiresome reason:
140                                         -- we want to make sure that the bindings for data 
141                                         -- constructors are eta-expanded.  This is probably
142                                         -- a good thing anyway, but it seems fragile.
143         "-flet-no-escape"
144         ]
145
146 -- these are the static flags you get when -O is on.
147 hsc_minusO_flags =
148   [ 
149         "-fignore-asserts",
150         "-ffoldr-build-on",
151         "-fdo-eta-reduction",
152         "-fdo-lambda-eta-expansion",
153         "-fcase-merge",
154         "-flet-to-case",
155         "-flet-no-escape"
156    ]
157
158 hsc_minusO2_flags = hsc_minusO_flags    -- for now
159
160 getStaticOptimisationFlags 0 = hsc_minusNoO_flags
161 getStaticOptimisationFlags 1 = hsc_minusO_flags
162 getStaticOptimisationFlags n = hsc_minusO2_flags
163
164 buildCoreToDo :: IO [CoreToDo]
165 buildCoreToDo = do
166    opt_level  <- readIORef v_OptLevel
167    max_iter   <- readIORef v_MaxSimplifierIterations
168    usageSP    <- readIORef v_UsageSPInf
169    strictness <- readIORef v_Strictness
170    cpr        <- readIORef v_CPR
171    cse        <- readIORef v_CSE
172
173    if opt_level == 0 then return
174       [
175         CoreDoSimplify (isAmongSimpl [
176             MaxSimplifierIterations max_iter
177         ])
178       ]
179
180     else {- opt_level >= 1 -} return [ 
181
182         -- initial simplify: mk specialiser happy: minimum effort please
183         CoreDoSimplify (isAmongSimpl [
184             SimplInlinePhase 0,
185                         -- Don't inline anything till full laziness has bitten
186                         -- In particular, inlining wrappers inhibits floating
187                         -- e.g. ...(case f x of ...)...
188                         --  ==> ...(case (case x of I# x# -> fw x#) of ...)...
189                         --  ==> ...(case x of I# x# -> case fw x# of ...)...
190                         -- and now the redex (f x) isn't floatable any more
191             DontApplyRules,
192                         -- Similarly, don't apply any rules until after full 
193                         -- laziness.  Notably, list fusion can prevent floating.
194             NoCaseOfCase,
195                         -- Don't do case-of-case transformations.
196                         -- This makes full laziness work better
197             MaxSimplifierIterations max_iter
198         ]),
199
200         -- Specialisation is best done before full laziness
201         -- so that overloaded functions have all their dictionary lambdas manifest
202         CoreDoSpecialising,
203
204         CoreDoFloatOutwards False{-not full-},
205         CoreDoFloatInwards,
206
207         CoreDoSimplify (isAmongSimpl [
208            SimplInlinePhase 1,
209                 -- Want to run with inline phase 1 after the specialiser to give
210                 -- maximum chance for fusion to work before we inline build/augment
211                 -- in phase 2.  This made a difference in 'ansi' where an 
212                 -- overloaded function wasn't inlined till too late.
213            MaxSimplifierIterations max_iter
214         ]),
215
216         -- infer usage information here in case we need it later.
217         -- (add more of these where you need them --KSW 1999-04)
218         if usageSP then CoreDoUSPInf else CoreDoNothing,
219
220         CoreDoSimplify (isAmongSimpl [
221                 -- Need inline-phase2 here so that build/augment get 
222                 -- inlined.  I found that spectral/hartel/genfft lost some useful
223                 -- strictness in the function sumcode' if augment is not inlined
224                 -- before strictness analysis runs
225            SimplInlinePhase 2,
226            MaxSimplifierIterations max_iter
227         ]),
228
229         CoreDoSimplify (isAmongSimpl [
230            MaxSimplifierIterations 2
231                 -- No -finline-phase: allow all Ids to be inlined now
232                 -- This gets foldr inlined before strictness analysis
233         ]),
234
235         if strictness then CoreDoStrictness else CoreDoNothing,
236         if cpr        then CoreDoCPResult   else CoreDoNothing,
237         CoreDoWorkerWrapper,
238         CoreDoGlomBinds,
239
240         CoreDoSimplify (isAmongSimpl [
241            MaxSimplifierIterations max_iter
242                 -- No -finline-phase: allow all Ids to be inlined now
243         ]),
244
245         CoreDoFloatOutwards False{-not full-},
246                 -- nofib/spectral/hartel/wang doubles in speed if you
247                 -- do full laziness late in the day.  It only happens
248                 -- after fusion and other stuff, so the early pass doesn't
249                 -- catch it.  For the record, the redex is 
250                 --        f_el22 (f_el21 r_midblock)
251
252
253 -- Leave out lambda lifting for now
254 --        "-fsimplify", -- Tidy up results of full laziness
255 --          "[", 
256 --                "-fmax-simplifier-iterations2",
257 --          "]",
258 --        "-ffloat-outwards-full",      
259
260         -- We want CSE to follow the final full-laziness pass, because it may
261         -- succeed in commoning up things floated out by full laziness.
262         -- CSE used to rely on the no-shadowing invariant, but it doesn't any more
263
264         if cse then CoreCSE else CoreDoNothing,
265
266         CoreDoFloatInwards,
267
268 -- Case-liberation for -O2.  This should be after
269 -- strictness analysis and the simplification which follows it.
270
271         if opt_level >= 2 then
272            CoreLiberateCase
273         else
274            CoreDoNothing,
275         if opt_level >= 2 then
276            CoreDoSpecConstr
277         else
278            CoreDoNothing,
279
280         -- Final clean-up simplification:
281         CoreDoSimplify (isAmongSimpl [
282           MaxSimplifierIterations max_iter
283                 -- No -finline-phase: allow all Ids to be inlined now
284         ])
285      ]
286
287 buildStgToDo :: IO [ StgToDo ]
288 buildStgToDo = do
289   stg_stats <- readIORef v_StgStats
290   let flags1 | stg_stats = [ D_stg_stats ]
291              | otherwise = [ ]
292
293         -- STG passes
294   ways_ <- readIORef v_Ways
295   let flags2 | WayProf `elem` ways_ = StgDoMassageForProfiling : flags1
296              | otherwise            = flags1
297
298   return flags2
299
300 -----------------------------------------------------------------------------
301 -- Paths & Libraries
302
303 split_marker = ':'   -- not configurable (ToDo)
304
305 v_Import_paths, v_Include_paths, v_Library_paths :: IORef [String]
306 GLOBAL_VAR(v_Import_paths,  ["."], [String])
307 GLOBAL_VAR(v_Include_paths, ["."], [String])
308 GLOBAL_VAR(v_Library_paths, [],  [String])
309
310 GLOBAL_VAR(v_Cmdline_libraries,   [], [String])
311
312 addToDirList :: IORef [String] -> String -> IO ()
313 addToDirList ref path
314   = do paths <- readIORef ref
315        writeIORef ref (paths ++ split split_marker path)
316
317 GLOBAL_VAR(v_HCHeader, "", String)
318
319 -----------------------------------------------------------------------------
320 -- Packages
321
322 -- package list is maintained in dependency order
323 GLOBAL_VAR(v_Packages, ("std":"rts":"gmp":[]), [String])
324
325 addPackage :: String -> IO ()
326 addPackage package
327   = do pkg_details <- readIORef v_Package_details
328        case lookupPkg package pkg_details of
329           Nothing -> throwDyn (CmdLineError ("unknown package name: " ++ package))
330           Just details -> do
331             ps <- readIORef v_Packages
332             unless (package `elem` ps) $ do
333                 mapM_ addPackage (package_deps details)
334                 ps <- readIORef v_Packages
335                 writeIORef v_Packages (package:ps)
336
337 getPackageImportPath   :: IO [String]
338 getPackageImportPath = do
339   ps <- getPackageInfo
340   return (nub (filter (not.null) (concatMap import_dirs ps)))
341
342 getPackageIncludePath   :: IO [String]
343 getPackageIncludePath = do
344   ps <- getPackageInfo
345   return (nub (filter (not.null) (concatMap include_dirs ps)))
346
347         -- includes are in reverse dependency order (i.e. rts first)
348 getPackageCIncludes   :: IO [String]
349 getPackageCIncludes = do
350   ps <- getPackageInfo
351   return (reverse (nub (filter (not.null) (concatMap c_includes ps))))
352
353 getPackageLibraryPath  :: IO [String]
354 getPackageLibraryPath = do
355   ps <- getPackageInfo
356   return (nub (filter (not.null) (concatMap library_dirs ps)))
357
358 getPackageLibraries    :: IO [String]
359 getPackageLibraries = do
360   ps <- getPackageInfo
361   tag <- readIORef v_Build_tag
362   let suffix = if null tag then "" else '_':tag
363   return (concat (
364         map (\p -> map (++suffix) (hs_libraries p) ++ extra_libraries p) ps
365      ))
366
367 getPackageExtraGhcOpts :: IO [String]
368 getPackageExtraGhcOpts = do
369   ps <- getPackageInfo
370   return (concatMap extra_ghc_opts ps)
371
372 getPackageExtraCcOpts  :: IO [String]
373 getPackageExtraCcOpts = do
374   ps <- getPackageInfo
375   return (concatMap extra_cc_opts ps)
376
377 getPackageExtraLdOpts  :: IO [String]
378 getPackageExtraLdOpts = do
379   ps <- getPackageInfo
380   return (concatMap extra_ld_opts ps)
381
382 getPackageInfo :: IO [PackageConfig]
383 getPackageInfo = do
384   ps <- readIORef v_Packages
385   getPackageDetails ps
386
387 getPackageDetails :: [String] -> IO [PackageConfig]
388 getPackageDetails ps = do
389   pkg_details <- readIORef v_Package_details
390   return [ pkg | p <- ps, Just pkg <- [ lookupPkg p pkg_details ] ]
391
392 GLOBAL_VAR(v_Package_details, (error "package_details"), [PackageConfig])
393
394 lookupPkg :: String -> [PackageConfig] -> Maybe PackageConfig
395 lookupPkg nm ps
396    = case [p | p <- ps, name p == nm] of
397         []    -> Nothing
398         (p:_) -> Just p
399
400 -----------------------------------------------------------------------------
401 -- Ways
402
403 -- The central concept of a "way" is that all objects in a given
404 -- program must be compiled in the same "way".  Certain options change
405 -- parameters of the virtual machine, eg. profiling adds an extra word
406 -- to the object header, so profiling objects cannot be linked with
407 -- non-profiling objects.
408
409 -- After parsing the command-line options, we determine which "way" we
410 -- are building - this might be a combination way, eg. profiling+ticky-ticky.
411
412 -- We then find the "build-tag" associated with this way, and this
413 -- becomes the suffix used to find .hi files and libraries used in
414 -- this compilation.
415
416 GLOBAL_VAR(v_Build_tag, "", String)
417
418 data WayName
419   = WayProf
420   | WayUnreg
421   | WayTicky
422   | WayPar
423   | WayGran
424   | WaySMP
425   | WayDebug
426   | WayUser_a
427   | WayUser_b
428   | WayUser_c
429   | WayUser_d
430   | WayUser_e
431   | WayUser_f
432   | WayUser_g
433   | WayUser_h
434   | WayUser_i
435   | WayUser_j
436   | WayUser_k
437   | WayUser_l
438   | WayUser_m
439   | WayUser_n
440   | WayUser_o
441   | WayUser_A
442   | WayUser_B
443   deriving (Eq,Ord)
444
445 GLOBAL_VAR(v_Ways, [] ,[WayName])
446
447 allowed_combination way = way `elem` combs
448   where  -- the sub-lists must be ordered according to WayName, 
449          -- because findBuildTag sorts them
450     combs                = [ [WayProf,WayUnreg], [WayProf,WaySMP] ]
451
452 findBuildTag :: IO [String]  -- new options
453 findBuildTag = do
454   way_names <- readIORef v_Ways
455   case sort way_names of
456      []  -> do  -- writeIORef v_Build_tag ""
457                 return []
458
459      [w] -> do let details = lkupWay w
460                writeIORef v_Build_tag (wayTag details)
461                return (wayOpts details)
462
463      ws  -> if not (allowed_combination ws)
464                 then throwDyn (CmdLineError $
465                                 "combination not supported: "  ++
466                                 foldr1 (\a b -> a ++ '/':b) 
467                                 (map (wayName . lkupWay) ws))
468                 else let stuff = map lkupWay ws
469                          tag   = concat (map wayTag stuff)
470                          flags = map wayOpts stuff
471                      in do
472                      writeIORef v_Build_tag tag
473                      return (concat flags)
474
475 lkupWay w = 
476    case lookup w way_details of
477         Nothing -> error "findBuildTag"
478         Just details -> details
479
480 data Way = Way {
481   wayTag   :: String,
482   wayName  :: String,
483   wayOpts  :: [String]
484   }
485
486 way_details :: [ (WayName, Way) ]
487 way_details =
488   [ (WayProf, Way  "p" "Profiling"  
489         [ "-fscc-profiling"
490         , "-DPROFILING"
491         , "-optc-DPROFILING"
492         , "-fvia-C" ]),
493
494     (WayTicky, Way  "t" "Ticky-ticky Profiling"  
495         [ "-fticky-ticky"
496         , "-DTICKY_TICKY"
497         , "-optc-DTICKY_TICKY"
498         , "-fvia-C" ]),
499
500     (WayUnreg, Way  "u" "Unregisterised" 
501         unregFlags ),
502
503     -- optl's below to tell linker where to find the PVM library -- HWL
504     (WayPar, Way  "mp" "Parallel" 
505         [ "-fparallel"
506         , "-D__PARALLEL_HASKELL__"
507         , "-optc-DPAR"
508         , "-package concurrent"
509         , "-optc-w"
510         , "-optl-L${PVM_ROOT}/lib/${PVM_ARCH}"
511         , "-optl-lpvm3"
512         , "-optl-lgpvm3"
513         , "-fvia-C" ]),
514
515     -- at the moment we only change the RTS and could share compiler and libs!
516     (WayPar, Way  "mt" "Parallel ticky profiling" 
517         [ "-fparallel"
518         , "-D__PARALLEL_HASKELL__"
519         , "-optc-DPAR"
520         , "-optc-DPAR_TICKY"
521         , "-package concurrent"
522         , "-optc-w"
523         , "-optl-L${PVM_ROOT}/lib/${PVM_ARCH}"
524         , "-optl-lpvm3"
525         , "-optl-lgpvm3"
526         , "-fvia-C" ]),
527
528     (WayPar, Way  "md" "Distributed" 
529         [ "-fparallel"
530         , "-D__PARALLEL_HASKELL__"
531         , "-D__DISTRIBUTED_HASKELL__"
532         , "-optc-DPAR"
533         , "-optc-DDIST"
534         , "-package concurrent"
535         , "-optc-w"
536         , "-optl-L${PVM_ROOT}/lib/${PVM_ARCH}"
537         , "-optl-lpvm3"
538         , "-optl-lgpvm3"
539         , "-fvia-C" ]),
540
541     (WayGran, Way  "mg" "GranSim" 
542         [ "-fgransim"
543         , "-D__GRANSIM__"
544         , "-optc-DGRAN"
545         , "-package concurrent"
546         , "-fvia-C" ]),
547
548     (WaySMP, Way  "s" "SMP"
549         [ "-fsmp"
550         , "-optc-pthread"
551         , "-optl-pthread"
552         , "-optc-DSMP"
553         , "-fvia-C" ]),
554
555     (WayUser_a,  Way  "a"  "User way 'a'"  ["$WAY_a_REAL_OPTS"]),       
556     (WayUser_b,  Way  "b"  "User way 'b'"  ["$WAY_b_REAL_OPTS"]),       
557     (WayUser_c,  Way  "c"  "User way 'c'"  ["$WAY_c_REAL_OPTS"]),       
558     (WayUser_d,  Way  "d"  "User way 'd'"  ["$WAY_d_REAL_OPTS"]),       
559     (WayUser_e,  Way  "e"  "User way 'e'"  ["$WAY_e_REAL_OPTS"]),       
560     (WayUser_f,  Way  "f"  "User way 'f'"  ["$WAY_f_REAL_OPTS"]),       
561     (WayUser_g,  Way  "g"  "User way 'g'"  ["$WAY_g_REAL_OPTS"]),       
562     (WayUser_h,  Way  "h"  "User way 'h'"  ["$WAY_h_REAL_OPTS"]),       
563     (WayUser_i,  Way  "i"  "User way 'i'"  ["$WAY_i_REAL_OPTS"]),       
564     (WayUser_j,  Way  "j"  "User way 'j'"  ["$WAY_j_REAL_OPTS"]),       
565     (WayUser_k,  Way  "k"  "User way 'k'"  ["$WAY_k_REAL_OPTS"]),       
566     (WayUser_l,  Way  "l"  "User way 'l'"  ["$WAY_l_REAL_OPTS"]),       
567     (WayUser_m,  Way  "m"  "User way 'm'"  ["$WAY_m_REAL_OPTS"]),       
568     (WayUser_n,  Way  "n"  "User way 'n'"  ["$WAY_n_REAL_OPTS"]),       
569     (WayUser_o,  Way  "o"  "User way 'o'"  ["$WAY_o_REAL_OPTS"]),       
570     (WayUser_A,  Way  "A"  "User way 'A'"  ["$WAY_A_REAL_OPTS"]),       
571     (WayUser_B,  Way  "B"  "User way 'B'"  ["$WAY_B_REAL_OPTS"]) 
572   ]
573
574 unregFlags = 
575    [ "-optc-DNO_REGS"
576    , "-optc-DUSE_MINIINTERPRETER"
577    , "-fno-asm-mangling"
578    , "-funregisterised"
579    , "-fvia-C" ]
580
581 -----------------------------------------------------------------------------
582 -- Programs for particular phases
583
584 GLOBAL_VAR(v_Opt_dep,    [], [String])
585 GLOBAL_VAR(v_Anti_opt_C, [], [String])
586 GLOBAL_VAR(v_Opt_C,      [], [String])
587 GLOBAL_VAR(v_Opt_l,      [], [String])
588 GLOBAL_VAR(v_Opt_dll,    [], [String])
589
590 getStaticOpts :: IORef [String] -> IO [String]
591 getStaticOpts ref = readIORef ref >>= return . reverse