+ | CmmCpp -- pre-process Cmm source
+ | Cmm -- parse & compile Cmm code
+#ifdef ILX
+ | Ilx2Il
+ | Ilasm
+#endif
+
+ -- 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
+
+ deriving (Show)
+
+anyHsc :: Phase
+anyHsc = Hsc (panic "anyHsc")
+
+isStopPhase :: Phase -> Bool
+isStopPhase StopLn = True
+isStopPhase other = False
+
+eqPhase :: Phase -> Phase -> Bool
+-- Equality of constructors, ignoring the HscSource field
+eqPhase (Unlit _) (Unlit _) = True
+eqPhase (Cpp _) (Cpp _) = True
+eqPhase (HsPp _) (HsPp _) = True
+eqPhase (Hsc _) (Hsc _) = True
+eqPhase Cc Cc = True
+eqPhase HCc HCc = True
+eqPhase Mangle Mangle = True
+eqPhase SplitMangle SplitMangle = True
+eqPhase SplitAs SplitAs = True
+eqPhase As As = True
+eqPhase CmmCpp CmmCpp = True
+eqPhase Cmm Cmm = True
+eqPhase StopLn StopLn = True
+eqPhase _ _ = False
+
+-- Partial ordering on phases: we want to know which phases will occur before
+-- which others. This is used for sanity checking, to ensure that the
+-- pipeline will stop at some point (see DriverPipeline.runPipeline).
+StopLn `happensBefore` y = False
+x `happensBefore` y = after_x `eqPhase` y || after_x `happensBefore` y
+ where
+ after_x = nextPhase x
+
+nextPhase :: Phase -> Phase
+-- A conservative approximation the next phase, used in happensBefore
+nextPhase (Unlit sf) = Cpp sf
+nextPhase (Cpp sf) = HsPp sf
+nextPhase (HsPp sf) = Hsc sf
+nextPhase (Hsc sf) = HCc
+nextPhase HCc = Mangle
+nextPhase Mangle = SplitMangle
+nextPhase SplitMangle = As
+nextPhase As = SplitAs
+nextPhase SplitAs = StopLn
+nextPhase Cc = As
+nextPhase CmmCpp = Cmm
+nextPhase Cmm = HCc
+nextPhase StopLn = panic "nextPhase: nothing after StopLn"