1 -----------------------------------------------------------------------------
5 -- (c) The University of Glasgow 2004-2006
7 -----------------------------------------------------------------------------
11 GenCmmTop(..), CmmTop,
12 GenBasicBlock(..), CmmBasicBlock, blockId, blockStmts,
13 CmmStmt(..), CmmActuals, CmmFormal, CmmFormals, CmmHintFormals,
15 CmmStatic(..), Section(..),
16 CmmExpr(..), cmmExprRep,
17 CmmReg(..), cmmRegRep,
18 CmmLit(..), cmmLitRep,
19 LocalReg(..), localRegRep, Kind(..),
20 BlockId(..), BlockEnv,
21 GlobalReg(..), globalRegRep,
23 node, nodeReg, spReg, hpReg, spLimReg
26 #include "HsVersions.h"
37 -----------------------------------------------------------------------------
38 -- Cmm, CmmTop, CmmBasicBlock
39 -----------------------------------------------------------------------------
41 -- A file is a list of top-level chunks. These may be arbitrarily
42 -- re-orderd during code generation.
44 -- GenCmm is abstracted over
45 -- (a) the type of static data elements
46 -- (b) the contents of a basic block.
47 -- We expect there to be two main instances of this type:
48 -- (a) Plain C--, i.e. populated with CmmLit and CmmExpr respectively,
49 -- (b) Native code, populated with instructions
51 newtype GenCmm d i = Cmm [GenCmmTop d i]
53 type Cmm = GenCmm CmmStatic CmmStmt
55 -- A top-level chunk, abstracted over the type of the contents of
56 -- the basic blocks (Cmm or instructions are the likely instantiations).
59 [d] -- Info table, may be empty
60 CLabel -- Used to generate both info & entry labels
61 CmmFormals -- Argument locals live on entry (C-- procedure params)
62 [GenBasicBlock i] -- Code, may be empty. The first block is
63 -- the entry point. The order is otherwise initially
64 -- unimportant, but at some point the code gen will
67 -- the BlockId of the first block does not give rise
68 -- to a label. To jump to the first block in a Proc,
69 -- use the appropriate CLabel.
72 | CmmData Section [d] -- constant values only
74 type CmmTop = GenCmmTop CmmStatic CmmStmt
76 -- A basic block containing a single label, at the beginning.
77 -- The list of basic blocks in a top-level code block may be re-ordered.
78 -- Fall-through is not allowed: there must be an explicit jump at the
79 -- end of each basic block, but the code generator might rearrange basic
80 -- blocks in order to turn some jumps into fallthroughs.
82 data GenBasicBlock i = BasicBlock BlockId [i]
83 -- ToDo: Julian suggests that we might need to annotate this type
84 -- with the out & in edges in the graph, i.e. two * [BlockId]. This
85 -- information can be derived from the contents, but it might be
86 -- helpful to cache it here.
88 type CmmBasicBlock = GenBasicBlock CmmStmt
90 blockId :: GenBasicBlock i -> BlockId
91 -- The branch block id is that of the first block in
92 -- the branch, which is that branch's entry point
93 blockId (BasicBlock blk_id _ ) = blk_id
95 blockStmts :: GenBasicBlock i -> [i]
96 blockStmts (BasicBlock _ stmts) = stmts
99 -----------------------------------------------------------------------------
101 -- A "statement". Note that all branches are explicit: there are no
102 -- control transfers to computed addresses, except when transfering
103 -- control to a new function.
104 -----------------------------------------------------------------------------
108 | CmmComment FastString
110 | CmmAssign CmmReg CmmExpr -- Assign to register
112 | CmmStore CmmExpr CmmExpr -- Assign to memory location. Size is
113 -- given by cmmExprRep of the rhs.
115 | CmmCall -- A foreign call, with
117 CmmHintFormals -- zero or more results
118 CmmActuals -- zero or more arguments
120 | CmmBranch BlockId -- branch to another BB in this fn
122 | CmmCondBranch CmmExpr BlockId -- conditional branch
124 | CmmSwitch CmmExpr [Maybe BlockId] -- Table branch
125 -- The scrutinee is zero-based;
126 -- zero -> first block
127 -- one -> second block etc
128 -- Undefined outside range, and when there's a Nothing
130 | CmmJump CmmExpr -- Jump to another function,
131 CmmActuals -- with these parameters.
133 | CmmReturn -- Return from a function,
134 CmmActuals -- with these return values.
136 type CmmActual = CmmExpr
137 type CmmActuals = [(CmmActual,MachHint)]
138 type CmmFormal = LocalReg
139 type CmmHintFormals = [(CmmFormal,MachHint)]
140 type CmmFormals = [CmmFormal]
146 One possible problem with the above type is that the only way to do a
147 non-local conditional jump is to encode it as a branch to a block that
148 contains a single jump. This leads to inefficient code in the back end.
150 One possible way to fix this would be:
154 | CmmJump CmmBranchDest
155 | CmmCondJump CmmExpr CmmBranchDest
160 | NonLocal CmmExpr [LocalReg]
164 + one fewer constructors in CmmStmt
165 + allows both cond branch and switch to jump to non-local destinations
169 - not strictly necessary: can already encode as branch+jump
170 - not always possible to implement any better in the back end
171 - could do the optimisation in the back end (but then plat-specific?)
172 - C-- doesn't have it
173 - back-end optimisation might be more general (jump shortcutting)
175 So we'll stick with the way it is, and add the optimisation to the NCG.
178 -----------------------------------------------------------------------------
181 -- The target of a CmmCall.
182 -----------------------------------------------------------------------------
185 = CmmForeignCall -- Call to a foreign function
186 CmmExpr -- literal label <=> static call
187 -- other expression <=> dynamic call
188 CCallConv -- The calling convention
190 | CmmPrim -- Call to a "primitive" (eg. sin, cos)
191 CallishMachOp -- These might be implemented as inline
192 -- code by the backend.
194 -----------------------------------------------------------------------------
196 -- An expression. Expressions have no side effects.
197 -----------------------------------------------------------------------------
200 = CmmLit CmmLit -- Literal
201 | CmmLoad CmmExpr MachRep -- Read memory location
202 | CmmReg CmmReg -- Contents of register
203 | CmmMachOp MachOp [CmmExpr] -- Machine operation (+, -, *, etc.)
204 | CmmRegOff CmmReg Int
206 -- ** is shorthand only, meaning **
207 -- CmmMachOp (MO_S_Add rep (CmmReg reg) (CmmLit (CmmInt i rep)))
208 -- where rep = cmmRegRep reg
211 cmmExprRep :: CmmExpr -> MachRep
212 cmmExprRep (CmmLit lit) = cmmLitRep lit
213 cmmExprRep (CmmLoad _ rep) = rep
214 cmmExprRep (CmmReg reg) = cmmRegRep reg
215 cmmExprRep (CmmMachOp op _) = resultRepOfMachOp op
216 cmmExprRep (CmmRegOff reg _) = cmmRegRep reg
220 | CmmGlobal GlobalReg
223 cmmRegRep :: CmmReg -> MachRep
224 cmmRegRep (CmmLocal reg) = localRegRep reg
225 cmmRegRep (CmmGlobal reg) = globalRegRep reg
227 -- | Whether a 'LocalReg' is a GC followable pointer
228 data Kind = KindPtr | KindNonPtr deriving (Eq)
232 !Unique -- ^ Identifier
234 Kind -- ^ Should the GC follow as a pointer
236 instance Eq LocalReg where
237 (LocalReg u1 _ _) == (LocalReg u2 _ _) = u1 == u2
239 instance Uniquable LocalReg where
240 getUnique (LocalReg uniq _ _) = uniq
242 localRegRep :: LocalReg -> MachRep
243 localRegRep (LocalReg _ rep _) = rep
245 localRegGCFollow (LocalReg _ _ p) = p
248 = CmmInt Integer MachRep
249 -- Interpretation: the 2's complement representation of the value
250 -- is truncated to the specified size. This is easier than trying
251 -- to keep the value within range, because we don't know whether
252 -- it will be used as a signed or unsigned value (the MachRep doesn't
253 -- distinguish between signed & unsigned).
254 | CmmFloat Rational MachRep
255 | CmmLabel CLabel -- Address of label
256 | CmmLabelOff CLabel Int -- Address of label + byte offset
258 -- Due to limitations in the C backend, the following
259 -- MUST ONLY be used inside the info table indicated by label2
260 -- (label2 must be the info label), and label1 must be an
261 -- SRT, a slow entrypoint or a large bitmap (see the Mangler)
262 -- Don't use it at all unless tablesNextToCode.
263 -- It is also used inside the NCG during when generating
264 -- position-independent code.
265 | CmmLabelDiffOff CLabel CLabel Int -- label1 - label2 + offset
268 cmmLitRep :: CmmLit -> MachRep
269 cmmLitRep (CmmInt _ rep) = rep
270 cmmLitRep (CmmFloat _ rep) = rep
271 cmmLitRep (CmmLabel _) = wordRep
272 cmmLitRep (CmmLabelOff _ _) = wordRep
273 cmmLitRep (CmmLabelDiffOff _ _ _) = wordRep
275 -----------------------------------------------------------------------------
278 -- Local labels must be unique within a single compilation unit.
280 newtype BlockId = BlockId Unique
283 instance Uniquable BlockId where
284 getUnique (BlockId u) = u
286 type BlockEnv a = UniqFM {- BlockId -} a
288 -----------------------------------------------------------------------------
290 -----------------------------------------------------------------------------
296 | RelocatableReadOnlyData
298 | ReadOnlyData16 -- .rodata.cst16 on x86_64, 16-byte aligned
299 | OtherSection String
302 = CmmStaticLit CmmLit
303 -- a literal value, size given by cmmLitRep of the literal.
304 | CmmUninitialised Int
305 -- uninitialised data, N bytes long
307 -- align to next N-byte boundary (N must be a power of 2).
308 | CmmDataLabel CLabel
309 -- label the current position in this section.
311 -- string of 8-bit values only, not zero terminated.
313 -----------------------------------------------------------------------------
314 -- Global STG registers
315 -----------------------------------------------------------------------------
318 -- Argument and return registers
319 = VanillaReg -- pointers, unboxed ints and chars
320 {-# UNPACK #-} !Int -- its number
322 | FloatReg -- single-precision floating-point registers
323 {-# UNPACK #-} !Int -- its number
325 | DoubleReg -- double-precision floating-point registers
326 {-# UNPACK #-} !Int -- its number
328 | LongReg -- long int registers (64-bit, really)
329 {-# UNPACK #-} !Int -- its number
332 | Sp -- Stack ptr; points to last occupied stack location.
333 | SpLim -- Stack limit
334 | Hp -- Heap ptr; points to last occupied heap location.
335 | HpLim -- Heap limit register
336 | CurrentTSO -- pointer to current thread's TSO
337 | CurrentNursery -- pointer to allocation area
338 | HpAlloc -- allocation count for heap check failure
340 -- We keep the address of some commonly-called
341 -- functions in the register table, to keep code
343 | GCEnter1 -- stg_gc_enter_1
344 | GCFun -- stg_gc_fun
346 -- Base offset for the register table, used for accessing registers
347 -- which do not have real registers assigned to them. This register
348 -- will only appear after we have expanded GlobalReg into memory accesses
349 -- (where necessary) in the native code generator.
352 -- Base Register for PIC (position-independent code) calculations
353 -- Only used inside the native code generator. It's exact meaning differs
354 -- from platform to platform (see module PositionIndependentCode).
363 -- convenient aliases
364 spReg, hpReg, spLimReg, nodeReg :: CmmReg
367 spLimReg = CmmGlobal SpLim
368 nodeReg = CmmGlobal node
373 globalRegRep :: GlobalReg -> MachRep
374 globalRegRep (VanillaReg _) = wordRep
375 globalRegRep (FloatReg _) = F32
376 globalRegRep (DoubleReg _) = F64
377 globalRegRep (LongReg _) = I64
378 globalRegRep _ = wordRep