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