1 -----------------------------------------------------------------------------
5 -- (c) The University of Glasgow 2004-2006
7 -----------------------------------------------------------------------------
10 GenCmm(..), Cmm, RawCmm,
11 GenCmmTop(..), CmmTop, RawCmmTop,
12 CmmInfo(..), ClosureTypeInfo(..), ProfilingInfo(..),
13 GenBasicBlock(..), CmmBasicBlock, blockId, blockStmts,
14 CmmStmt(..), CmmActuals, CmmFormal, CmmFormals, CmmHintFormals,
16 CmmStatic(..), Section(..),
17 CmmExpr(..), cmmExprRep,
18 CmmReg(..), cmmRegRep,
19 CmmLit(..), cmmLitRep,
20 LocalReg(..), localRegRep, localRegGCFollow, Kind(..),
21 BlockId(..), BlockEnv,
22 GlobalReg(..), globalRegRep,
24 node, nodeReg, spReg, hpReg, spLimReg
27 #include "HsVersions.h"
40 -----------------------------------------------------------------------------
41 -- Cmm, CmmTop, CmmBasicBlock
42 -----------------------------------------------------------------------------
44 -- A file is a list of top-level chunks. These may be arbitrarily
45 -- re-orderd during code generation.
47 -- GenCmm is abstracted over
48 -- (a) the type of static data elements
49 -- (b) the contents of a basic block.
50 -- We expect there to be two main instances of this type:
51 -- (a) Plain C--, i.e. populated with CmmLit and CmmExpr respectively,
52 -- (b) Native code, populated with instructions
54 newtype GenCmm d h i = Cmm [GenCmmTop d h i]
56 -- | Cmm with the info table as a data type
57 type Cmm = GenCmm CmmStatic CmmInfo CmmStmt
59 -- | Cmm with the info tables converted to a list of 'CmmStatic'
60 type RawCmm = GenCmm CmmStatic [CmmStatic] CmmStmt
62 -- A top-level chunk, abstracted over the type of the contents of
63 -- the basic blocks (Cmm or instructions are the likely instantiations).
66 h -- Extra header such as the info table
67 CLabel -- Used to generate both info & entry labels
68 CmmFormals -- Argument locals live on entry (C-- procedure params)
69 [GenBasicBlock i] -- Code, may be empty. The first block is
70 -- the entry point. The order is otherwise initially
71 -- unimportant, but at some point the code gen will
74 -- the BlockId of the first block does not give rise
75 -- to a label. To jump to the first block in a Proc,
76 -- use the appropriate CLabel.
79 | CmmData Section [d] -- constant values only
81 type CmmTop = GenCmmTop CmmStatic CmmInfo CmmStmt
82 type RawCmmTop = GenCmmTop CmmStatic [CmmStatic] CmmStmt
84 -- A basic block containing a single label, at the beginning.
85 -- The list of basic blocks in a top-level code block may be re-ordered.
86 -- Fall-through is not allowed: there must be an explicit jump at the
87 -- end of each basic block, but the code generator might rearrange basic
88 -- blocks in order to turn some jumps into fallthroughs.
90 data GenBasicBlock i = BasicBlock BlockId [i]
91 -- ToDo: Julian suggests that we might need to annotate this type
92 -- with the out & in edges in the graph, i.e. two * [BlockId]. This
93 -- information can be derived from the contents, but it might be
94 -- helpful to cache it here.
96 type CmmBasicBlock = GenBasicBlock CmmStmt
98 blockId :: GenBasicBlock i -> BlockId
99 -- The branch block id is that of the first block in
100 -- the branch, which is that branch's entry point
101 blockId (BasicBlock blk_id _ ) = blk_id
103 blockStmts :: GenBasicBlock i -> [i]
104 blockStmts (BasicBlock _ stmts) = stmts
106 -----------------------------------------------------------------------------
108 -----------------------------------------------------------------------------
110 -- Info table as a haskell data type
114 (Maybe BlockId) -- GC target
115 ClosureTypeTag -- Int
117 | CmmNonInfo -- Procedure doesn't need an info table
120 = ConstrInfo ClosureLayout ConstrTag ConstrDescription
121 | FunInfo ClosureLayout C_SRT FunType FunArity ArgDescr SlowEntry
122 | ThunkInfo ClosureLayout C_SRT
124 [Maybe LocalReg] -- Forced stack parameters
127 -- TODO: These types may need refinement
128 data ProfilingInfo = ProfilingInfo CmmLit CmmLit -- closure_type, closure_desc
129 type ClosureTypeTag = StgHalfWord
130 type ClosureLayout = (StgHalfWord, StgHalfWord) -- pts, nptrs
131 type ConstrTag = StgHalfWord
132 type ConstrDescription = CLabel
133 type FunType = StgHalfWord
134 type FunArity = StgHalfWord
135 type SlowEntry = CLabel
137 -----------------------------------------------------------------------------
139 -- A "statement". Note that all branches are explicit: there are no
140 -- control transfers to computed addresses, except when transfering
141 -- control to a new function.
142 -----------------------------------------------------------------------------
146 | CmmComment FastString
148 | CmmAssign CmmReg CmmExpr -- Assign to register
150 | CmmStore CmmExpr CmmExpr -- Assign to memory location. Size is
151 -- given by cmmExprRep of the rhs.
153 | CmmCall -- A foreign call, with
155 CmmHintFormals -- zero or more results
156 CmmActuals -- zero or more arguments
157 C_SRT -- SRT for the continuation of the call
159 | CmmBranch BlockId -- branch to another BB in this fn
161 | CmmCondBranch CmmExpr BlockId -- conditional branch
163 | CmmSwitch CmmExpr [Maybe BlockId] -- Table branch
164 -- The scrutinee is zero-based;
165 -- zero -> first block
166 -- one -> second block etc
167 -- Undefined outside range, and when there's a Nothing
169 | CmmJump CmmExpr -- Jump to another function,
170 CmmActuals -- with these parameters.
172 | CmmReturn -- Return from a function,
173 CmmActuals -- with these return values.
175 type CmmActual = CmmExpr
176 type CmmActuals = [(CmmActual,MachHint)]
177 type CmmFormal = LocalReg
178 type CmmHintFormals = [(CmmFormal,MachHint)]
179 type CmmFormals = [CmmFormal]
185 One possible problem with the above type is that the only way to do a
186 non-local conditional jump is to encode it as a branch to a block that
187 contains a single jump. This leads to inefficient code in the back end.
189 One possible way to fix this would be:
193 | CmmJump CmmBranchDest
194 | CmmCondJump CmmExpr CmmBranchDest
199 | NonLocal CmmExpr [LocalReg]
203 + one fewer constructors in CmmStmt
204 + allows both cond branch and switch to jump to non-local destinations
208 - not strictly necessary: can already encode as branch+jump
209 - not always possible to implement any better in the back end
210 - could do the optimisation in the back end (but then plat-specific?)
211 - C-- doesn't have it
212 - back-end optimisation might be more general (jump shortcutting)
214 So we'll stick with the way it is, and add the optimisation to the NCG.
217 -----------------------------------------------------------------------------
220 -- The target of a CmmCall.
221 -----------------------------------------------------------------------------
224 = CmmForeignCall -- Call to a foreign function
225 CmmExpr -- literal label <=> static call
226 -- other expression <=> dynamic call
227 CCallConv -- The calling convention
229 | CmmPrim -- Call to a "primitive" (eg. sin, cos)
230 CallishMachOp -- These might be implemented as inline
231 -- code by the backend.
233 -----------------------------------------------------------------------------
235 -- An expression. Expressions have no side effects.
236 -----------------------------------------------------------------------------
239 = CmmLit CmmLit -- Literal
240 | CmmLoad CmmExpr MachRep -- Read memory location
241 | CmmReg CmmReg -- Contents of register
242 | CmmMachOp MachOp [CmmExpr] -- Machine operation (+, -, *, etc.)
243 | CmmRegOff CmmReg Int
245 -- ** is shorthand only, meaning **
246 -- CmmMachOp (MO_S_Add rep (CmmReg reg) (CmmLit (CmmInt i rep)))
247 -- where rep = cmmRegRep reg
250 cmmExprRep :: CmmExpr -> MachRep
251 cmmExprRep (CmmLit lit) = cmmLitRep lit
252 cmmExprRep (CmmLoad _ rep) = rep
253 cmmExprRep (CmmReg reg) = cmmRegRep reg
254 cmmExprRep (CmmMachOp op _) = resultRepOfMachOp op
255 cmmExprRep (CmmRegOff reg _) = cmmRegRep reg
259 | CmmGlobal GlobalReg
262 cmmRegRep :: CmmReg -> MachRep
263 cmmRegRep (CmmLocal reg) = localRegRep reg
264 cmmRegRep (CmmGlobal reg) = globalRegRep reg
266 -- | Whether a 'LocalReg' is a GC followable pointer
267 data Kind = KindPtr | KindNonPtr deriving (Eq)
271 !Unique -- ^ Identifier
273 Kind -- ^ Should the GC follow as a pointer
275 instance Eq LocalReg where
276 (LocalReg u1 _ _) == (LocalReg u2 _ _) = u1 == u2
278 instance Uniquable LocalReg where
279 getUnique (LocalReg uniq _ _) = uniq
281 localRegRep :: LocalReg -> MachRep
282 localRegRep (LocalReg _ rep _) = rep
284 localRegGCFollow (LocalReg _ _ p) = p
287 = CmmInt Integer MachRep
288 -- Interpretation: the 2's complement representation of the value
289 -- is truncated to the specified size. This is easier than trying
290 -- to keep the value within range, because we don't know whether
291 -- it will be used as a signed or unsigned value (the MachRep doesn't
292 -- distinguish between signed & unsigned).
293 | CmmFloat Rational MachRep
294 | CmmLabel CLabel -- Address of label
295 | CmmLabelOff CLabel Int -- Address of label + byte offset
297 -- Due to limitations in the C backend, the following
298 -- MUST ONLY be used inside the info table indicated by label2
299 -- (label2 must be the info label), and label1 must be an
300 -- SRT, a slow entrypoint or a large bitmap (see the Mangler)
301 -- Don't use it at all unless tablesNextToCode.
302 -- It is also used inside the NCG during when generating
303 -- position-independent code.
304 | CmmLabelDiffOff CLabel CLabel Int -- label1 - label2 + offset
307 cmmLitRep :: CmmLit -> MachRep
308 cmmLitRep (CmmInt _ rep) = rep
309 cmmLitRep (CmmFloat _ rep) = rep
310 cmmLitRep (CmmLabel _) = wordRep
311 cmmLitRep (CmmLabelOff _ _) = wordRep
312 cmmLitRep (CmmLabelDiffOff _ _ _) = wordRep
314 -----------------------------------------------------------------------------
317 -- Local labels must be unique within a single compilation unit.
319 newtype BlockId = BlockId Unique
322 instance Uniquable BlockId where
323 getUnique (BlockId u) = u
325 type BlockEnv a = UniqFM {- BlockId -} a
327 -----------------------------------------------------------------------------
329 -----------------------------------------------------------------------------
335 | RelocatableReadOnlyData
337 | ReadOnlyData16 -- .rodata.cst16 on x86_64, 16-byte aligned
338 | OtherSection String
341 = CmmStaticLit CmmLit
342 -- a literal value, size given by cmmLitRep of the literal.
343 | CmmUninitialised Int
344 -- uninitialised data, N bytes long
346 -- align to next N-byte boundary (N must be a power of 2).
347 | CmmDataLabel CLabel
348 -- label the current position in this section.
350 -- string of 8-bit values only, not zero terminated.
352 -----------------------------------------------------------------------------
353 -- Global STG registers
354 -----------------------------------------------------------------------------
357 -- Argument and return registers
358 = VanillaReg -- pointers, unboxed ints and chars
359 {-# UNPACK #-} !Int -- its number
361 | FloatReg -- single-precision floating-point registers
362 {-# UNPACK #-} !Int -- its number
364 | DoubleReg -- double-precision floating-point registers
365 {-# UNPACK #-} !Int -- its number
367 | LongReg -- long int registers (64-bit, really)
368 {-# UNPACK #-} !Int -- its number
371 | Sp -- Stack ptr; points to last occupied stack location.
372 | SpLim -- Stack limit
373 | Hp -- Heap ptr; points to last occupied heap location.
374 | HpLim -- Heap limit register
375 | CurrentTSO -- pointer to current thread's TSO
376 | CurrentNursery -- pointer to allocation area
377 | HpAlloc -- allocation count for heap check failure
379 -- We keep the address of some commonly-called
380 -- functions in the register table, to keep code
382 | GCEnter1 -- stg_gc_enter_1
383 | GCFun -- stg_gc_fun
385 -- Base offset for the register table, used for accessing registers
386 -- which do not have real registers assigned to them. This register
387 -- will only appear after we have expanded GlobalReg into memory accesses
388 -- (where necessary) in the native code generator.
391 -- Base Register for PIC (position-independent code) calculations
392 -- Only used inside the native code generator. It's exact meaning differs
393 -- from platform to platform (see module PositionIndependentCode).
402 -- convenient aliases
403 spReg, hpReg, spLimReg, nodeReg :: CmmReg
406 spLimReg = CmmGlobal SpLim
407 nodeReg = CmmGlobal node
412 globalRegRep :: GlobalReg -> MachRep
413 globalRegRep (VanillaReg _) = wordRep
414 globalRegRep (FloatReg _) = F32
415 globalRegRep (DoubleReg _) = F64
416 globalRegRep (LongReg _) = I64
417 globalRegRep _ = wordRep