1 -----------------------------------------------------------------------------
5 -- (c) The University of Glasgow 2004-2006
7 -----------------------------------------------------------------------------
11 GenCmmTop(..), CmmTop,
12 GenBasicBlock(..), CmmBasicBlock, blockId, blockStmts,
15 CmmStatic(..), Section(..),
16 CmmExpr(..), cmmExprRep,
17 CmmReg(..), cmmRegRep,
18 CmmLit(..), cmmLitRep,
19 LocalReg(..), localRegRep,
21 GlobalReg(..), globalRegRep,
23 node, nodeReg, spReg, hpReg,
26 #include "HsVersions.h"
36 -----------------------------------------------------------------------------
37 -- Cmm, CmmTop, CmmBasicBlock
38 -----------------------------------------------------------------------------
40 -- A file is a list of top-level chunks. These may be arbitrarily
41 -- re-orderd during code generation.
43 -- GenCmm is abstracted over
44 -- (a) the type of static data elements
45 -- (b) the contents of a basic block.
46 -- We expect there to be two main instances of this type:
47 -- (a) Plain C--, i.e. populated with CmmLit and CmmExpr respectively,
48 -- (b) Native code, populated with instructions
50 newtype GenCmm d i = Cmm [GenCmmTop d i]
52 type Cmm = GenCmm CmmStatic CmmStmt
54 -- A top-level chunk, abstracted over the type of the contents of
55 -- the basic blocks (Cmm or instructions are the likely instantiations).
58 [d] -- Info table, may be empty
59 CLabel -- Used to generate both info & entry labels
60 [LocalReg] -- Argument locals live on entry (C-- procedure params)
61 [GenBasicBlock i] -- Code, may be empty. The first block is
62 -- the entry point. The order is otherwise initially
63 -- unimportant, but at some point the code gen will
66 -- the BlockId of the first block does not give rise
67 -- to a label. To jump to the first block in a Proc,
68 -- use the appropriate CLabel.
71 | CmmData Section [d] -- constant values only
73 type CmmTop = GenCmmTop CmmStatic CmmStmt
75 -- A basic block containing a single label, at the beginning.
76 -- The list of basic blocks in a top-level code block may be re-ordered.
77 -- Fall-through is not allowed: there must be an explicit jump at the
78 -- end of each basic block, but the code generator might rearrange basic
79 -- blocks in order to turn some jumps into fallthroughs.
81 data GenBasicBlock i = BasicBlock BlockId [i]
82 -- ToDo: Julian suggests that we might need to annotate this type
83 -- with the out & in edges in the graph, i.e. two * [BlockId]. This
84 -- information can be derived from the contents, but it might be
85 -- helpful to cache it here.
87 type CmmBasicBlock = GenBasicBlock CmmStmt
89 blockId :: GenBasicBlock i -> BlockId
90 -- The branch block id is that of the first block in
91 -- the branch, which is that branch's entry point
92 blockId (BasicBlock blk_id _ ) = blk_id
94 blockStmts :: GenBasicBlock i -> [i]
95 blockStmts (BasicBlock _ stmts) = stmts
98 -----------------------------------------------------------------------------
100 -- A "statement". Note that all branches are explicit: there are no
101 -- control transfers to computed addresses, except when transfering
102 -- control to a new function.
103 -----------------------------------------------------------------------------
107 | CmmComment FastString
109 | CmmAssign CmmReg CmmExpr -- Assign to register
111 | CmmStore CmmExpr CmmExpr -- Assign to memory location. Size is
112 -- given by cmmExprRep of the rhs.
114 | CmmCall -- A foreign call, with
116 [(CmmReg,MachHint)] -- zero or more results
117 [(CmmExpr,MachHint)] -- zero or more arguments
118 (Maybe [GlobalReg]) -- Global regs that may need to be saved
119 -- if they will be clobbered by the call.
120 -- Nothing <=> save *all* globals that
121 -- might be clobbered.
123 | CmmBranch BlockId -- branch to another BB in this fn
125 | CmmCondBranch CmmExpr BlockId -- conditional branch
127 | CmmSwitch CmmExpr [Maybe BlockId] -- Table branch
128 -- The scrutinee is zero-based;
129 -- zero -> first block
130 -- one -> second block etc
131 -- Undefined outside range, and when there's a Nothing
133 | CmmJump CmmExpr -- Jump to another function,
134 [(CmmExpr, MachHint)] -- with these parameters.
136 | CmmReturn -- Return from a function,
137 [(CmmExpr, MachHint)] -- with these return values.
143 One possible problem with the above type is that the only way to do a
144 non-local conditional jump is to encode it as a branch to a block that
145 contains a single jump. This leads to inefficient code in the back end.
147 One possible way to fix this would be:
151 | CmmJump CmmBranchDest
152 | CmmCondJump CmmExpr CmmBranchDest
157 | NonLocal CmmExpr [LocalReg]
161 + one fewer constructors in CmmStmt
162 + allows both cond branch and switch to jump to non-local destinations
166 - not strictly necessary: can already encode as branch+jump
167 - not always possible to implement any better in the back end
168 - could do the optimisation in the back end (but then plat-specific?)
169 - C-- doesn't have it
170 - back-end optimisation might be more general (jump shortcutting)
172 So we'll stick with the way it is, and add the optimisation to the NCG.
175 -----------------------------------------------------------------------------
178 -- The target of a CmmCall.
179 -----------------------------------------------------------------------------
182 = CmmForeignCall -- Call to a foreign function
183 CmmExpr -- literal label <=> static call
184 -- other expression <=> dynamic call
185 CCallConv -- The calling convention
187 | CmmPrim -- Call to a "primitive" (eg. sin, cos)
188 CallishMachOp -- These might be implemented as inline
189 -- code by the backend.
191 -----------------------------------------------------------------------------
193 -- An expression. Expressions have no side effects.
194 -----------------------------------------------------------------------------
197 = CmmLit CmmLit -- Literal
198 | CmmLoad CmmExpr MachRep -- Read memory location
199 | CmmReg CmmReg -- Contents of register
200 | CmmMachOp MachOp [CmmExpr] -- Machine operation (+, -, *, etc.)
201 | CmmRegOff CmmReg Int
203 -- ** is shorthand only, meaning **
204 -- CmmMachOp (MO_S_Add rep (CmmReg reg) (CmmLit (CmmInt i rep)))
205 -- where rep = cmmRegRep reg
208 cmmExprRep :: CmmExpr -> MachRep
209 cmmExprRep (CmmLit lit) = cmmLitRep lit
210 cmmExprRep (CmmLoad _ rep) = rep
211 cmmExprRep (CmmReg reg) = cmmRegRep reg
212 cmmExprRep (CmmMachOp op _) = resultRepOfMachOp op
213 cmmExprRep (CmmRegOff reg _) = cmmRegRep reg
217 | CmmGlobal GlobalReg
220 cmmRegRep :: CmmReg -> MachRep
221 cmmRegRep (CmmLocal reg) = localRegRep reg
222 cmmRegRep (CmmGlobal reg) = globalRegRep reg
225 = LocalReg !Unique MachRep
227 instance Eq LocalReg where
228 (LocalReg u1 _) == (LocalReg u2 _) = u1 == u2
230 instance Uniquable LocalReg where
231 getUnique (LocalReg uniq _) = uniq
233 localRegRep :: LocalReg -> MachRep
234 localRegRep (LocalReg _ rep) = rep
237 = CmmInt Integer MachRep
238 -- Interpretation: the 2's complement representation of the value
239 -- is truncated to the specified size. This is easier than trying
240 -- to keep the value within range, because we don't know whether
241 -- it will be used as a signed or unsigned value (the MachRep doesn't
242 -- distinguish between signed & unsigned).
243 | CmmFloat Rational MachRep
244 | CmmLabel CLabel -- Address of label
245 | CmmLabelOff CLabel Int -- Address of label + byte offset
247 -- Due to limitations in the C backend, the following
248 -- MUST ONLY be used inside the info table indicated by label2
249 -- (label2 must be the info label), and label1 must be an
250 -- SRT, a slow entrypoint or a large bitmap (see the Mangler)
251 -- Don't use it at all unless tablesNextToCode.
252 -- It is also used inside the NCG during when generating
253 -- position-independent code.
254 | CmmLabelDiffOff CLabel CLabel Int -- label1 - label2 + offset
257 cmmLitRep :: CmmLit -> MachRep
258 cmmLitRep (CmmInt _ rep) = rep
259 cmmLitRep (CmmFloat _ rep) = rep
260 cmmLitRep (CmmLabel _) = wordRep
261 cmmLitRep (CmmLabelOff _ _) = wordRep
262 cmmLitRep (CmmLabelDiffOff _ _ _) = wordRep
264 -----------------------------------------------------------------------------
267 -- Local labels must be unique within a single compilation unit.
269 newtype BlockId = BlockId Unique
272 instance Uniquable BlockId where
273 getUnique (BlockId u) = u
275 -----------------------------------------------------------------------------
277 -----------------------------------------------------------------------------
283 | RelocatableReadOnlyData
285 | ReadOnlyData16 -- .rodata.cst16 on x86_64, 16-byte aligned
286 | OtherSection String
289 = CmmStaticLit CmmLit
290 -- a literal value, size given by cmmLitRep of the literal.
291 | CmmUninitialised Int
292 -- uninitialised data, N bytes long
294 -- align to next N-byte boundary (N must be a power of 2).
295 | CmmDataLabel CLabel
296 -- label the current position in this section.
298 -- string of 8-bit values only, not zero terminated.
300 -----------------------------------------------------------------------------
301 -- Global STG registers
302 -----------------------------------------------------------------------------
305 -- Argument and return registers
306 = VanillaReg -- pointers, unboxed ints and chars
307 {-# UNPACK #-} !Int -- its number
309 | FloatReg -- single-precision floating-point registers
310 {-# UNPACK #-} !Int -- its number
312 | DoubleReg -- double-precision floating-point registers
313 {-# UNPACK #-} !Int -- its number
315 | LongReg -- long int registers (64-bit, really)
316 {-# UNPACK #-} !Int -- its number
319 | Sp -- Stack ptr; points to last occupied stack location.
320 | SpLim -- Stack limit
321 | Hp -- Heap ptr; points to last occupied heap location.
322 | HpLim -- Heap limit register
323 | CurrentTSO -- pointer to current thread's TSO
324 | CurrentNursery -- pointer to allocation area
325 | HpAlloc -- allocation count for heap check failure
327 -- We keep the address of some commonly-called
328 -- functions in the register table, to keep code
330 | GCEnter1 -- stg_gc_enter_1
331 | GCFun -- stg_gc_fun
333 -- Base offset for the register table, used for accessing registers
334 -- which do not have real registers assigned to them. This register
335 -- will only appear after we have expanded GlobalReg into memory accesses
336 -- (where necessary) in the native code generator.
339 -- Base Register for PIC (position-independent code) calculations
340 -- Only used inside the native code generator. It's exact meaning differs
341 -- from platform to platform (see module PositionIndependentCode).
350 -- convenient aliases
351 spReg, hpReg, nodeReg :: CmmReg
354 nodeReg = CmmGlobal node
359 globalRegRep :: GlobalReg -> MachRep
360 globalRegRep (VanillaReg _) = wordRep
361 globalRegRep (FloatReg _) = F32
362 globalRegRep (DoubleReg _) = F64
363 globalRegRep (LongReg _) = I64
364 globalRegRep _ = wordRep