Comments and refactoring only
[ghc.git] / compiler / cmm / Cmm.hs
1 -- Cmm representations using Hoopl's Graph CmmNode e x.
2 {-# LANGUAGE GADTs #-}
3
4 module Cmm (
5 -- * Cmm top-level datatypes
6 CmmProgram, CmmGroup, GenCmmGroup,
7 CmmDecl, GenCmmDecl(..),
8 CmmGraph, GenCmmGraph(..),
9 CmmBlock,
10 RawCmmDecl, RawCmmGroup,
11 Section(..), SectionType(..), CmmStatics(..), CmmStatic(..),
12 isSecConstant,
13
14 -- ** Blocks containing lists
15 GenBasicBlock(..), blockId,
16 ListGraph(..), pprBBlock,
17
18 -- * Info Tables
19 CmmTopInfo(..), CmmStackInfo(..), CmmInfoTable(..), topInfoTable,
20 ClosureTypeInfo(..),
21 ProfilingInfo(..), ConstrDescription,
22
23 -- * Statements, expressions and types
24 module CmmNode,
25 module CmmExpr,
26 ) where
27
28 import GhcPrelude
29
30 import Id
31 import CostCentre
32 import CLabel
33 import BlockId
34 import CmmNode
35 import SMRep
36 import CmmExpr
37 import Hoopl.Block
38 import Hoopl.Collections
39 import Hoopl.Graph
40 import Hoopl.Label
41 import Outputable
42
43 import Data.Word ( Word8 )
44
45 -----------------------------------------------------------------------------
46 -- Cmm, GenCmm
47 -----------------------------------------------------------------------------
48
49 -- A CmmProgram is a list of CmmGroups
50 -- A CmmGroup is a list of top-level declarations
51
52 -- When object-splitting is on, each group is compiled into a separate
53 -- .o file. So typically we put closely related stuff in a CmmGroup.
54 -- Section-splitting follows suit and makes one .text subsection for each
55 -- CmmGroup.
56
57 type CmmProgram = [CmmGroup]
58
59 type GenCmmGroup d h g = [GenCmmDecl d h g]
60 type CmmGroup = GenCmmGroup CmmStatics CmmTopInfo CmmGraph
61 type RawCmmGroup = GenCmmGroup CmmStatics (LabelMap CmmStatics) CmmGraph
62
63 -----------------------------------------------------------------------------
64 -- CmmDecl, GenCmmDecl
65 -----------------------------------------------------------------------------
66
67 -- GenCmmDecl is abstracted over
68 -- d, the type of static data elements in CmmData
69 -- h, the static info preceding the code of a CmmProc
70 -- g, the control-flow graph of a CmmProc
71 --
72 -- We expect there to be two main instances of this type:
73 -- (a) C--, i.e. populated with various C-- constructs
74 -- (b) Native code, populated with data/instructions
75
76 -- | A top-level chunk, abstracted over the type of the contents of
77 -- the basic blocks (Cmm or instructions are the likely instantiations).
78 data GenCmmDecl d h g
79 = CmmProc -- A procedure
80 h -- Extra header such as the info table
81 CLabel -- Entry label
82 [GlobalReg] -- Registers live on entry. Note that the set of live
83 -- registers will be correct in generated C-- code, but
84 -- not in hand-written C-- code. However,
85 -- splitAtProcPoints calculates correct liveness
86 -- information for CmmProcs.
87 g -- Control-flow graph for the procedure's code
88
89 | CmmData -- Static data
90 Section
91 d
92
93 type CmmDecl = GenCmmDecl CmmStatics CmmTopInfo CmmGraph
94
95 type RawCmmDecl
96 = GenCmmDecl
97 CmmStatics
98 (LabelMap CmmStatics)
99 CmmGraph
100
101 -----------------------------------------------------------------------------
102 -- Graphs
103 -----------------------------------------------------------------------------
104
105 type CmmGraph = GenCmmGraph CmmNode
106 data GenCmmGraph n = CmmGraph { g_entry :: BlockId, g_graph :: Graph n C C }
107 type CmmBlock = Block CmmNode C C
108
109 -----------------------------------------------------------------------------
110 -- Info Tables
111 -----------------------------------------------------------------------------
112
113 data CmmTopInfo = TopInfo { info_tbls :: LabelMap CmmInfoTable
114 , stack_info :: CmmStackInfo }
115
116 topInfoTable :: GenCmmDecl a CmmTopInfo (GenCmmGraph n) -> Maybe CmmInfoTable
117 topInfoTable (CmmProc infos _ _ g) = mapLookup (g_entry g) (info_tbls infos)
118 topInfoTable _ = Nothing
119
120 data CmmStackInfo
121 = StackInfo {
122 arg_space :: ByteOff,
123 -- number of bytes of arguments on the stack on entry to the
124 -- the proc. This is filled in by StgCmm.codeGen, and used
125 -- by the stack allocator later.
126 updfr_space :: Maybe ByteOff,
127 -- XXX: this never contains anything useful, but it should.
128 -- See comment in CmmLayoutStack.
129 do_layout :: Bool
130 -- Do automatic stack layout for this proc. This is
131 -- True for all code generated by the code generator,
132 -- but is occasionally False for hand-written Cmm where
133 -- we want to do the stack manipulation manually.
134 }
135
136 -- | Info table as a haskell data type
137 data CmmInfoTable
138 = CmmInfoTable {
139 cit_lbl :: CLabel, -- Info table label
140 cit_rep :: SMRep,
141 cit_prof :: ProfilingInfo,
142 cit_srt :: Maybe CLabel, -- empty, or a closure address
143 cit_clo :: Maybe (Id, CostCentreStack)
144 -- Just (id,ccs) <=> build a static closure later
145 -- Nothing <=> don't build a static closure
146 --
147 -- Static closures for FUNs and THUNKs are *not* generated by
148 -- the code generator, because we might want to add SRT
149 -- entries to them later (for FUNs at least; THUNKs are
150 -- treated the same for consistency). See Note [SRTs] in
151 -- CmmBuildInfoTables, in particular the [FUN] optimisation.
152 --
153 -- This is strictly speaking not a part of the info table that
154 -- will be finally generated, but it's the only convenient
155 -- place to convey this information from the code generator to
156 -- where we build the static closures in
157 -- CmmBuildInfoTables.doSRTs.
158 }
159
160 data ProfilingInfo
161 = NoProfilingInfo
162 | ProfilingInfo [Word8] [Word8] -- closure_type, closure_desc
163
164 -----------------------------------------------------------------------------
165 -- Static Data
166 -----------------------------------------------------------------------------
167
168 data SectionType
169 = Text
170 | Data
171 | ReadOnlyData
172 | RelocatableReadOnlyData
173 | UninitialisedData
174 | ReadOnlyData16 -- .rodata.cst16 on x86_64, 16-byte aligned
175 | CString
176 | OtherSection String
177 deriving (Show)
178
179 -- | Should a data in this section be considered constant
180 isSecConstant :: Section -> Bool
181 isSecConstant (Section t _) = case t of
182 Text -> True
183 ReadOnlyData -> True
184 RelocatableReadOnlyData -> True
185 ReadOnlyData16 -> True
186 CString -> True
187 Data -> False
188 UninitialisedData -> False
189 (OtherSection _) -> False
190
191 data Section = Section SectionType CLabel
192
193 data CmmStatic
194 = CmmStaticLit CmmLit
195 -- a literal value, size given by cmmLitRep of the literal.
196 | CmmUninitialised Int
197 -- uninitialised data, N bytes long
198 | CmmString [Word8]
199 -- string of 8-bit values only, not zero terminated.
200
201 data CmmStatics
202 = Statics
203 CLabel -- Label of statics
204 [CmmStatic] -- The static data itself
205
206 -- -----------------------------------------------------------------------------
207 -- Basic blocks consisting of lists
208
209 -- These are used by the LLVM and NCG backends, when populating Cmm
210 -- with lists of instructions.
211
212 data GenBasicBlock i = BasicBlock BlockId [i]
213
214 -- | The branch block id is that of the first block in
215 -- the branch, which is that branch's entry point
216 blockId :: GenBasicBlock i -> BlockId
217 blockId (BasicBlock blk_id _ ) = blk_id
218
219 newtype ListGraph i = ListGraph [GenBasicBlock i]
220
221 instance Outputable instr => Outputable (ListGraph instr) where
222 ppr (ListGraph blocks) = vcat (map ppr blocks)
223
224 instance Outputable instr => Outputable (GenBasicBlock instr) where
225 ppr = pprBBlock
226
227 pprBBlock :: Outputable stmt => GenBasicBlock stmt -> SDoc
228 pprBBlock (BasicBlock ident stmts) =
229 hang (ppr ident <> colon) 4 (vcat (map ppr stmts))
230