DriverPhases.hs 10.2 KB
Newer Older
1
-----------------------------------------------------------------------------
2
--  $Id: DriverPhases.hs,v 1.38 2005/05/17 11:01:59 simonmar Exp $
3
4
5
--
-- GHC Driver
--
6
-- (c) The University of Glasgow 2002
7
8
9
10
--
-----------------------------------------------------------------------------

module DriverPhases (
11
   HscSource(..), isHsBoot, hscSourceString,
12
   Phase(..),
13
   happensBefore, eqPhase, anyHsc, isStopLn,
dterei's avatar
dterei committed
14
15
   startPhase,
   phaseInputExt,
16

Ian Lynagh's avatar
Ian Lynagh committed
17
   isHaskellishSuffix,
18
19
20
21
22
23
24
25
   isHaskellSrcSuffix,
   isObjectSuffix,
   isCishSuffix,
   isExtCoreSuffix,
   isDynLibSuffix,
   isHaskellUserSrcSuffix,
   isSourceSuffix,

Ian Lynagh's avatar
Ian Lynagh committed
26
   isHaskellishFilename,
27
28
29
30
31
32
   isHaskellSrcFilename,
   isObjectFilename,
   isCishFilename,
   isExtCoreFilename,
   isDynLibFilename,
   isHaskellUserSrcFilename,
dterei's avatar
dterei committed
33
   isSourceFilename
34
35
 ) where

36
37
#include "HsVersions.h"

38
import {-# SOURCE #-} DynFlags
39
import Outputable
40
import Platform
Ian Lynagh's avatar
Ian Lynagh committed
41
import System.FilePath
42
43
44
45
46
47
48

-----------------------------------------------------------------------------
-- Phases

{-
   Phase of the           | Suffix saying | Flag saying   | (suffix of)
   compilation system     | ``start here''| ``stop after''| output file
Ian Lynagh's avatar
Ian Lynagh committed
49

50
51
52
53
54
55
56
57
   literate pre-processor | .lhs          | -             | -
   C pre-processor (opt.) | -             | -E            | -
   Haskell compiler       | .hs           | -C, -S        | .hc, .s
   C compiler (opt.)      | .hc or .c     | -S            | .s
   assembler              | .s  or .S     | -c            | .o
   linker                 | other         | -             | a.out
-}

58
59
60
data HscSource
   = HsSrcFile | HsBootFile | ExtCoreFile
     deriving( Eq, Ord, Show )
Ian Lynagh's avatar
Ian Lynagh committed
61
        -- Ord needed for the finite maps we build in CompManager
62
63
64
65
66
67
68
69
70


hscSourceString :: HscSource -> String
hscSourceString HsSrcFile   = ""
hscSourceString HsBootFile  = "[boot]"
hscSourceString ExtCoreFile = "[ext core]"

isHsBoot :: HscSource -> Bool
isHsBoot HsBootFile = True
Ian Lynagh's avatar
Ian Lynagh committed
71
isHsBoot _          = False
72

Ian Lynagh's avatar
Ian Lynagh committed
73
74
75
76
77
data Phase
        = Unlit HscSource
        | Cpp   HscSource
        | HsPp  HscSource
        | Hsc   HscSource
78
        | Ccpp
Ian Lynagh's avatar
Ian Lynagh committed
79
        | Cc
80
        | Cobjc
81
        | Cobjcpp
Ian Lynagh's avatar
Ian Lynagh committed
82
        | HCc           -- Haskellised C (as opposed to vanilla C) compilation
dterei's avatar
dterei committed
83
84
85
        | Splitter      -- Assembly file splitter (part of '-split-objs')
        | SplitAs       -- Assembler for split assembly files (part of '-split-objs')
        | As            -- Assembler for regular assembly files
86
87
        | LlvmOpt       -- Run LLVM opt tool over llvm assembly
        | LlvmLlc       -- LLVM bitcode to native assembly
88
        | LlvmMangle    -- Fix up TNTC by processing assembly produced by LLVM
Ian Lynagh's avatar
Ian Lynagh committed
89
90
        | CmmCpp        -- pre-process Cmm source
        | Cmm           -- parse & compile Cmm code
91
        | MergeStub     -- merge in the stub object file
Ian Lynagh's avatar
Ian Lynagh committed
92
93
94
95

        -- The final phase is a pseudo-phase that tells the pipeline to stop.
        -- There is no runPhase case for it.
        | StopLn        -- Stop, but linking will follow, so generate .o file
96
  deriving (Eq, Show)
97

98
99
100
instance Outputable Phase where
    ppr p = text (show p)

101
102
103
anyHsc :: Phase
anyHsc = Hsc (panic "anyHsc")

104
105
isStopLn :: Phase -> Bool
isStopLn StopLn = True
Ian Lynagh's avatar
Ian Lynagh committed
106
isStopLn _      = False
107
108
109

eqPhase :: Phase -> Phase -> Bool
-- Equality of constructors, ignoring the HscSource field
110
-- NB: the HscSource field can be 'bot'; see anyHsc above
dterei's avatar
dterei committed
111
112
113
114
115
116
117
118
119
120
121
122
eqPhase (Unlit _)   (Unlit _)  = True
eqPhase (Cpp   _)   (Cpp   _)  = True
eqPhase (HsPp  _)   (HsPp  _)  = True
eqPhase (Hsc   _)   (Hsc   _)  = True
eqPhase Ccpp        Ccpp       = True
eqPhase Cc          Cc         = True
eqPhase Cobjc       Cobjc      = True
eqPhase Cobjcpp     Cobjcpp    = True
eqPhase HCc         HCc        = True
eqPhase Splitter    Splitter   = True
eqPhase SplitAs     SplitAs    = True
eqPhase As          As         = True
dterei's avatar
dterei committed
123
124
eqPhase LlvmOpt     LlvmOpt    = True
eqPhase LlvmLlc     LlvmLlc    = True
dterei's avatar
dterei committed
125
126
127
128
129
130
eqPhase LlvmMangle  LlvmMangle = True
eqPhase CmmCpp      CmmCpp     = True
eqPhase Cmm         Cmm        = True
eqPhase MergeStub   MergeStub  = True
eqPhase StopLn      StopLn     = True
eqPhase _           _          = False
Ian Lynagh's avatar
Ian Lynagh committed
131
132

-- Partial ordering on phases: we want to know which phases will occur before
133
134
-- which others.  This is used for sanity checking, to ensure that the
-- pipeline will stop at some point (see DriverPipeline.runPipeline).
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
happensBefore :: DynFlags -> Phase -> Phase -> Bool
happensBefore dflags p1 p2 = p1 `happensBefore'` p2
    where StopLn `happensBefore'` _ = False
          x      `happensBefore'` y = after_x `eqPhase` y
                                   || after_x `happensBefore'` y
              where after_x = nextPhase dflags x

nextPhase :: DynFlags -> Phase -> Phase
nextPhase dflags p
    -- A conservative approximation to the next phase, used in happensBefore
    = case p of
      Unlit sf   -> Cpp  sf
      Cpp   sf   -> HsPp sf
      HsPp  sf   -> Hsc  sf
      Hsc   _    -> maybeHCc
      Splitter   -> SplitAs
      LlvmOpt    -> LlvmLlc
      LlvmLlc    -> LlvmMangle
      LlvmMangle -> As
      SplitAs    -> MergeStub
      As         -> MergeStub
      Ccpp       -> As
      Cc         -> As
      Cobjc      -> As
      Cobjcpp    -> As
      CmmCpp     -> Cmm
      Cmm        -> maybeHCc
      HCc        -> As
      MergeStub  -> StopLn
      StopLn     -> panic "nextPhase: nothing after StopLn"
    where maybeHCc = if platformUnregisterised (targetPlatform dflags)
                     then HCc
                     else As
168

169
170
-- the first compilation phase for a given file is determined
-- by its suffix.
Ian Lynagh's avatar
Ian Lynagh committed
171
startPhase :: String -> Phase
172
173
174
175
176
177
178
179
180
startPhase "lhs"      = Unlit HsSrcFile
startPhase "lhs-boot" = Unlit HsBootFile
startPhase "hs"       = Cpp   HsSrcFile
startPhase "hs-boot"  = Cpp   HsBootFile
startPhase "hscpp"    = HsPp  HsSrcFile
startPhase "hspp"     = Hsc   HsSrcFile
startPhase "hcr"      = Hsc   ExtCoreFile
startPhase "hc"       = HCc
startPhase "c"        = Cc
181
startPhase "cpp"      = Ccpp
182
startPhase "C"        = Cc
183
startPhase "m"        = Cobjc
184
185
startPhase "M"        = Cobjcpp
startPhase "mm"       = Cobjcpp
186
187
startPhase "cc"       = Ccpp
startPhase "cxx"      = Ccpp
dterei's avatar
dterei committed
188
startPhase "split_s"  = Splitter
189
190
startPhase "s"        = As
startPhase "S"        = As
191
192
startPhase "ll"       = LlvmOpt
startPhase "bc"       = LlvmLlc
193
startPhase "lm_s"     = LlvmMangle
194
195
196
startPhase "o"        = StopLn
startPhase "cmm"      = CmmCpp
startPhase "cmmcpp"   = Cmm
Ian Lynagh's avatar
Ian Lynagh committed
197
startPhase _          = StopLn     -- all unknown file types
198

199
200
201
-- This is used to determine the extension for the output from the
-- current phase (if it generates a new file).  The extension depends
-- on the next phase in the pipeline.
Ian Lynagh's avatar
Ian Lynagh committed
202
phaseInputExt :: Phase -> String
203
204
205
phaseInputExt (Unlit HsSrcFile)   = "lhs"
phaseInputExt (Unlit HsBootFile)  = "lhs-boot"
phaseInputExt (Unlit ExtCoreFile) = "lhcr"
Ian Lynagh's avatar
Ian Lynagh committed
206
207
208
209
210
211
212
213
phaseInputExt (Cpp   _)           = "lpp"       -- intermediate only
phaseInputExt (HsPp  _)           = "hscpp"     -- intermediate only
phaseInputExt (Hsc   _)           = "hspp"      -- intermediate only
        -- NB: as things stand, phaseInputExt (Hsc x) must not evaluate x
        --     because runPipeline uses the StopBefore phase to pick the
        --     output filename.  That could be fixed, but watch out.
phaseInputExt HCc                 = "hc"
phaseInputExt Ccpp                = "cpp"
214
phaseInputExt Cobjc               = "m"
215
phaseInputExt Cobjcpp             = "mm"
Ian Lynagh's avatar
Ian Lynagh committed
216
phaseInputExt Cc                  = "c"
dterei's avatar
dterei committed
217
phaseInputExt Splitter            = "split_s"
Ian Lynagh's avatar
Ian Lynagh committed
218
phaseInputExt As                  = "s"
219
220
phaseInputExt LlvmOpt             = "ll"
phaseInputExt LlvmLlc             = "bc"
221
phaseInputExt LlvmMangle          = "lm_s"
dterei's avatar
dterei committed
222
phaseInputExt SplitAs             = "split_s"
Ian Lynagh's avatar
Ian Lynagh committed
223
224
phaseInputExt CmmCpp              = "cmm"
phaseInputExt Cmm                 = "cmmcpp"
225
phaseInputExt MergeStub           = "o"
Ian Lynagh's avatar
Ian Lynagh committed
226
phaseInputExt StopLn              = "o"
227

Ian Lynagh's avatar
Ian Lynagh committed
228
229
230
haskellish_src_suffixes, haskellish_suffixes, cish_suffixes,
    extcoreish_suffixes, haskellish_user_src_suffixes
 :: [String]
231
haskellish_src_suffixes      = haskellish_user_src_suffixes ++
232
                               [ "hspp", "hscpp", "hcr", "cmm", "cmmcpp" ]
233
haskellish_suffixes          = haskellish_src_suffixes ++ ["hc", "raw_s"]
234
cish_suffixes                = [ "c", "cpp", "C", "cc", "cxx", "s", "S", "ll", "bc", "lm_s", "m", "M", "mm" ]
235
extcoreish_suffixes          = [ "hcr" ]
Ian Lynagh's avatar
Ian Lynagh committed
236
237
-- Will not be deleted as temp files:
haskellish_user_src_suffixes = [ "hs", "lhs", "hs-boot", "lhs-boot" ]
238

239
objish_suffixes :: Platform -> [String]
Ian Lynagh's avatar
Ian Lynagh committed
240
-- Use the appropriate suffix for the system on which
241
-- the GHC-compiled code will run
242
objish_suffixes platform = case platformOS platform of
Austin Seipp's avatar
Austin Seipp committed
243
244
  OSMinGW32 -> [ "o", "O", "obj", "OBJ" ]
  _         -> [ "o" ]
245

246
247
dynlib_suffixes :: Platform -> [String]
dynlib_suffixes platform = case platformOS platform of
Austin Seipp's avatar
Austin Seipp committed
248
249
250
  OSMinGW32 -> ["dll", "DLL"]
  OSDarwin  -> ["dylib", "so"]
  _         -> ["so"]
251

Ian Lynagh's avatar
Ian Lynagh committed
252
isHaskellishSuffix, isHaskellSrcSuffix, isCishSuffix, isExtCoreSuffix,
253
    isHaskellUserSrcSuffix
Ian Lynagh's avatar
Ian Lynagh committed
254
 :: String -> Bool
255
256
257
258
259
isHaskellishSuffix     s = s `elem` haskellish_suffixes
isHaskellSrcSuffix     s = s `elem` haskellish_src_suffixes
isCishSuffix           s = s `elem` cish_suffixes
isExtCoreSuffix        s = s `elem` extcoreish_suffixes
isHaskellUserSrcSuffix s = s `elem` haskellish_user_src_suffixes
260
261
262
263

isObjectSuffix, isDynLibSuffix :: Platform -> String -> Bool
isObjectSuffix platform s = s `elem` objish_suffixes platform
isDynLibSuffix platform s = s `elem` dynlib_suffixes platform
264

Ian Lynagh's avatar
Ian Lynagh committed
265
isSourceSuffix :: String -> Bool
266
267
isSourceSuffix suff  = isHaskellishSuffix suff || isCishSuffix suff

Ian Lynagh's avatar
Ian Lynagh committed
268
isHaskellishFilename, isHaskellSrcFilename, isCishFilename,
269
    isExtCoreFilename, isHaskellUserSrcFilename, isSourceFilename
Ian Lynagh's avatar
Ian Lynagh committed
270
 :: FilePath -> Bool
Ian Lynagh's avatar
Ian Lynagh committed
271
272
273
274
275
276
277
-- takeExtension return .foo, so we drop 1 to get rid of the .
isHaskellishFilename     f = isHaskellishSuffix     (drop 1 $ takeExtension f)
isHaskellSrcFilename     f = isHaskellSrcSuffix     (drop 1 $ takeExtension f)
isCishFilename           f = isCishSuffix           (drop 1 $ takeExtension f)
isExtCoreFilename        f = isExtCoreSuffix        (drop 1 $ takeExtension f)
isHaskellUserSrcFilename f = isHaskellUserSrcSuffix (drop 1 $ takeExtension f)
isSourceFilename         f = isSourceSuffix         (drop 1 $ takeExtension f)
278

279
280
281
282
isObjectFilename, isDynLibFilename :: Platform -> FilePath -> Bool
isObjectFilename platform f = isObjectSuffix platform (drop 1 $ takeExtension f)
isDynLibFilename platform f = isDynLibSuffix platform (drop 1 $ takeExtension f)