Typos in non-code
[ghc.git] / compiler / ghci / ByteCodeGen.hs
1 {-# LANGUAGE CPP, MagicHash, RecordWildCards #-}
2 --
3 -- (c) The University of Glasgow 2002-2006
4 --
5
6 -- | ByteCodeGen: Generate bytecode from Core
7 module ByteCodeGen ( UnlinkedBCO, byteCodeGen, coreExprToBCOs ) where
8
9 #include "HsVersions.h"
10
11 import ByteCodeInstr
12 import ByteCodeAsm
13 import ByteCodeTypes
14
15 import GHCi
16 import GHCi.FFI
17 import GHCi.RemoteTypes
18 import BasicTypes
19 import DynFlags
20 import Outputable
21 import Platform
22 import Name
23 import MkId
24 import Id
25 import ForeignCall
26 import HscTypes
27 import CoreUtils
28 import CoreSyn
29 import PprCore
30 import Literal
31 import PrimOp
32 import CoreFVs
33 import Type
34 import DataCon
35 import TyCon
36 import Util
37 import VarSet
38 import TysPrim
39 import ErrUtils
40 import Unique
41 import FastString
42 import Panic
43 import StgCmmLayout ( ArgRep(..), toArgRep, argRepSizeW )
44 import SMRep
45 import Bitmap
46 import OrdList
47 import Maybes
48
49 import Data.List
50 import Foreign
51 import Control.Monad
52 import Data.Char
53
54 import UniqSupply
55 import Module
56 import Control.Arrow ( second )
57
58 import Data.Array
59 import Data.Map (Map)
60 import Data.IntMap (IntMap)
61 import qualified Data.Map as Map
62 import qualified Data.IntMap as IntMap
63 import qualified FiniteMap as Map
64 import Data.Ord
65 import GHC.Stack.CCS
66
67 -- -----------------------------------------------------------------------------
68 -- Generating byte code for a complete module
69
70 byteCodeGen :: HscEnv
71 -> Module
72 -> CoreProgram
73 -> [TyCon]
74 -> Maybe ModBreaks
75 -> IO CompiledByteCode
76 byteCodeGen hsc_env this_mod binds tycs mb_modBreaks
77 = withTiming (pure dflags)
78 (text "ByteCodeGen"<+>brackets (ppr this_mod))
79 (const ()) $ do
80 let flatBinds = [ (bndr, simpleFreeVars rhs)
81 | (bndr, rhs) <- flattenBinds binds]
82
83 us <- mkSplitUniqSupply 'y'
84 (BcM_State{..}, proto_bcos) <-
85 runBc hsc_env us this_mod mb_modBreaks $
86 mapM schemeTopBind flatBinds
87
88 when (notNull ffis)
89 (panic "ByteCodeGen.byteCodeGen: missing final emitBc?")
90
91 dumpIfSet_dyn dflags Opt_D_dump_BCOs
92 "Proto-BCOs" (vcat (intersperse (char ' ') (map ppr proto_bcos)))
93
94 assembleBCOs hsc_env proto_bcos tycs
95 (case modBreaks of
96 Nothing -> Nothing
97 Just mb -> Just mb{ modBreaks_breakInfo = breakInfo })
98 where dflags = hsc_dflags hsc_env
99
100 -- -----------------------------------------------------------------------------
101 -- Generating byte code for an expression
102
103 -- Returns: the root BCO for this expression
104 coreExprToBCOs :: HscEnv
105 -> Module
106 -> CoreExpr
107 -> IO UnlinkedBCO
108 coreExprToBCOs hsc_env this_mod expr
109 = withTiming (pure dflags)
110 (text "ByteCodeGen"<+>brackets (ppr this_mod))
111 (const ()) $ do
112 -- create a totally bogus name for the top-level BCO; this
113 -- should be harmless, since it's never used for anything
114 let invented_name = mkSystemVarName (mkPseudoUniqueE 0) (fsLit "ExprTopLevel")
115 invented_id = Id.mkLocalId invented_name (panic "invented_id's type")
116
117 -- the uniques are needed to generate fresh variables when we introduce new
118 -- let bindings for ticked expressions
119 us <- mkSplitUniqSupply 'y'
120 (BcM_State _dflags _us _this_mod _final_ctr mallocd _ _ , proto_bco)
121 <- runBc hsc_env us this_mod Nothing $
122 schemeTopBind (invented_id, simpleFreeVars expr)
123
124 when (notNull mallocd)
125 (panic "ByteCodeGen.coreExprToBCOs: missing final emitBc?")
126
127 dumpIfSet_dyn dflags Opt_D_dump_BCOs "Proto-BCOs" (ppr proto_bco)
128
129 assembleOneBCO hsc_env proto_bco
130 where dflags = hsc_dflags hsc_env
131
132 -- The regular freeVars function gives more information than is useful to
133 -- us here. simpleFreeVars does the impedence matching.
134 simpleFreeVars :: CoreExpr -> AnnExpr Id DVarSet
135 simpleFreeVars = go . freeVars
136 where
137 go :: AnnExpr Id FVAnn -> AnnExpr Id DVarSet
138 go (ann, e) = (freeVarsOfAnn ann, go' e)
139
140 go' :: AnnExpr' Id FVAnn -> AnnExpr' Id DVarSet
141 go' (AnnVar id) = AnnVar id
142 go' (AnnLit lit) = AnnLit lit
143 go' (AnnLam bndr body) = AnnLam bndr (go body)
144 go' (AnnApp fun arg) = AnnApp (go fun) (go arg)
145 go' (AnnCase scrut bndr ty alts) = AnnCase (go scrut) bndr ty (map go_alt alts)
146 go' (AnnLet bind body) = AnnLet (go_bind bind) (go body)
147 go' (AnnCast expr (ann, co)) = AnnCast (go expr) (freeVarsOfAnn ann, co)
148 go' (AnnTick tick body) = AnnTick tick (go body)
149 go' (AnnType ty) = AnnType ty
150 go' (AnnCoercion co) = AnnCoercion co
151
152 go_alt (con, args, expr) = (con, args, go expr)
153
154 go_bind (AnnNonRec bndr rhs) = AnnNonRec bndr (go rhs)
155 go_bind (AnnRec pairs) = AnnRec (map (second go) pairs)
156
157 -- -----------------------------------------------------------------------------
158 -- Compilation schema for the bytecode generator
159
160 type BCInstrList = OrdList BCInstr
161
162 type Sequel = Word -- back off to this depth before ENTER
163
164 -- Maps Ids to the offset from the stack _base_ so we don't have
165 -- to mess with it after each push/pop.
166 type BCEnv = Map Id Word -- To find vars on the stack
167
168 {-
169 ppBCEnv :: BCEnv -> SDoc
170 ppBCEnv p
171 = text "begin-env"
172 $$ nest 4 (vcat (map pp_one (sortBy cmp_snd (Map.toList p))))
173 $$ text "end-env"
174 where
175 pp_one (var, offset) = int offset <> colon <+> ppr var <+> ppr (bcIdArgRep var)
176 cmp_snd x y = compare (snd x) (snd y)
177 -}
178
179 -- Create a BCO and do a spot of peephole optimisation on the insns
180 -- at the same time.
181 mkProtoBCO
182 :: DynFlags
183 -> name
184 -> BCInstrList
185 -> Either [AnnAlt Id DVarSet] (AnnExpr Id DVarSet)
186 -> Int
187 -> Word16
188 -> [StgWord]
189 -> Bool -- True <=> is a return point, rather than a function
190 -> [FFIInfo]
191 -> ProtoBCO name
192 mkProtoBCO dflags nm instrs_ordlist origin arity bitmap_size bitmap is_ret ffis
193 = ProtoBCO {
194 protoBCOName = nm,
195 protoBCOInstrs = maybe_with_stack_check,
196 protoBCOBitmap = bitmap,
197 protoBCOBitmapSize = bitmap_size,
198 protoBCOArity = arity,
199 protoBCOExpr = origin,
200 protoBCOFFIs = ffis
201 }
202 where
203 -- Overestimate the stack usage (in words) of this BCO,
204 -- and if >= iNTERP_STACK_CHECK_THRESH, add an explicit
205 -- stack check. (The interpreter always does a stack check
206 -- for iNTERP_STACK_CHECK_THRESH words at the start of each
207 -- BCO anyway, so we only need to add an explicit one in the
208 -- (hopefully rare) cases when the (overestimated) stack use
209 -- exceeds iNTERP_STACK_CHECK_THRESH.
210 maybe_with_stack_check
211 | is_ret && stack_usage < fromIntegral (aP_STACK_SPLIM dflags) = peep_d
212 -- don't do stack checks at return points,
213 -- everything is aggregated up to the top BCO
214 -- (which must be a function).
215 -- That is, unless the stack usage is >= AP_STACK_SPLIM,
216 -- see bug #1466.
217 | stack_usage >= fromIntegral iNTERP_STACK_CHECK_THRESH
218 = STKCHECK stack_usage : peep_d
219 | otherwise
220 = peep_d -- the supposedly common case
221
222 -- We assume that this sum doesn't wrap
223 stack_usage = sum (map bciStackUse peep_d)
224
225 -- Merge local pushes
226 peep_d = peep (fromOL instrs_ordlist)
227
228 peep (PUSH_L off1 : PUSH_L off2 : PUSH_L off3 : rest)
229 = PUSH_LLL off1 (off2-1) (off3-2) : peep rest
230 peep (PUSH_L off1 : PUSH_L off2 : rest)
231 = PUSH_LL off1 (off2-1) : peep rest
232 peep (i:rest)
233 = i : peep rest
234 peep []
235 = []
236
237 argBits :: DynFlags -> [ArgRep] -> [Bool]
238 argBits _ [] = []
239 argBits dflags (rep : args)
240 | isFollowableArg rep = False : argBits dflags args
241 | otherwise = take (argRepSizeW dflags rep) (repeat True) ++ argBits dflags args
242
243 -- -----------------------------------------------------------------------------
244 -- schemeTopBind
245
246 -- Compile code for the right-hand side of a top-level binding
247
248 schemeTopBind :: (Id, AnnExpr Id DVarSet) -> BcM (ProtoBCO Name)
249
250
251 schemeTopBind (id, rhs)
252 | Just data_con <- isDataConWorkId_maybe id,
253 isNullaryRepDataCon data_con = do
254 dflags <- getDynFlags
255 -- Special case for the worker of a nullary data con.
256 -- It'll look like this: Nil = /\a -> Nil a
257 -- If we feed it into schemeR, we'll get
258 -- Nil = Nil
259 -- because mkConAppCode treats nullary constructor applications
260 -- by just re-using the single top-level definition. So
261 -- for the worker itself, we must allocate it directly.
262 -- ioToBc (putStrLn $ "top level BCO")
263 emitBc (mkProtoBCO dflags (getName id) (toOL [PACK data_con 0, ENTER])
264 (Right rhs) 0 0 [{-no bitmap-}] False{-not alts-})
265
266 | otherwise
267 = schemeR [{- No free variables -}] (id, rhs)
268
269
270 -- -----------------------------------------------------------------------------
271 -- schemeR
272
273 -- Compile code for a right-hand side, to give a BCO that,
274 -- when executed with the free variables and arguments on top of the stack,
275 -- will return with a pointer to the result on top of the stack, after
276 -- removing the free variables and arguments.
277 --
278 -- Park the resulting BCO in the monad. Also requires the
279 -- variable to which this value was bound, so as to give the
280 -- resulting BCO a name.
281
282 schemeR :: [Id] -- Free vars of the RHS, ordered as they
283 -- will appear in the thunk. Empty for
284 -- top-level things, which have no free vars.
285 -> (Id, AnnExpr Id DVarSet)
286 -> BcM (ProtoBCO Name)
287 schemeR fvs (nm, rhs)
288 {-
289 | trace (showSDoc (
290 (char ' '
291 $$ (ppr.filter (not.isTyVar).varSetElems.fst) rhs
292 $$ pprCoreExpr (deAnnotate rhs)
293 $$ char ' '
294 ))) False
295 = undefined
296 | otherwise
297 -}
298 = schemeR_wrk fvs nm rhs (collect rhs)
299
300 collect :: AnnExpr Id DVarSet -> ([Var], AnnExpr' Id DVarSet)
301 collect (_, e) = go [] e
302 where
303 go xs e | Just e' <- bcView e = go xs e'
304 go xs (AnnLam x (_,e))
305 | UbxTupleRep _ <- repType (idType x)
306 = unboxedTupleException
307 | otherwise
308 = go (x:xs) e
309 go xs not_lambda = (reverse xs, not_lambda)
310
311 schemeR_wrk :: [Id] -> Id -> AnnExpr Id DVarSet -> ([Var], AnnExpr' Var DVarSet) -> BcM (ProtoBCO Name)
312 schemeR_wrk fvs nm original_body (args, body)
313 = do
314 dflags <- getDynFlags
315 let
316 all_args = reverse args ++ fvs
317 arity = length all_args
318 -- all_args are the args in reverse order. We're compiling a function
319 -- \fv1..fvn x1..xn -> e
320 -- i.e. the fvs come first
321
322 szsw_args = map (fromIntegral . idSizeW dflags) all_args
323 szw_args = sum szsw_args
324 p_init = Map.fromList (zip all_args (mkStackOffsets 0 szsw_args))
325
326 -- make the arg bitmap
327 bits = argBits dflags (reverse (map bcIdArgRep all_args))
328 bitmap_size = genericLength bits
329 bitmap = mkBitmap dflags bits
330 body_code <- schemeER_wrk szw_args p_init body
331
332 emitBc (mkProtoBCO dflags (getName nm) body_code (Right original_body)
333 arity bitmap_size bitmap False{-not alts-})
334
335 -- introduce break instructions for ticked expressions
336 schemeER_wrk :: Word -> BCEnv -> AnnExpr' Id DVarSet -> BcM BCInstrList
337 schemeER_wrk d p rhs
338 | AnnTick (Breakpoint tick_no fvs) (_annot, newRhs) <- rhs
339 = do code <- schemeE (fromIntegral d) 0 p newRhs
340 cc_arr <- getCCArray
341 this_mod <- moduleName <$> getCurrentModule
342 let idOffSets = getVarOffSets d p fvs
343 let breakInfo = CgBreakInfo
344 { cgb_vars = idOffSets
345 , cgb_resty = exprType (deAnnotate' newRhs)
346 }
347 newBreakInfo tick_no breakInfo
348 dflags <- getDynFlags
349 let cc | interpreterProfiled dflags = cc_arr ! tick_no
350 | otherwise = toRemotePtr nullPtr
351 let breakInstr = BRK_FUN (fromIntegral tick_no) (getUnique this_mod) cc
352 return $ breakInstr `consOL` code
353 | otherwise = schemeE (fromIntegral d) 0 p rhs
354
355 getVarOffSets :: Word -> BCEnv -> [Id] -> [(Id, Word16)]
356 getVarOffSets d p = catMaybes . map (getOffSet d p)
357
358 getOffSet :: Word -> BCEnv -> Id -> Maybe (Id, Word16)
359 getOffSet d env id
360 = case lookupBCEnv_maybe id env of
361 Nothing -> Nothing
362 Just offset -> Just (id, trunc16 $ d - offset)
363
364 trunc16 :: Word -> Word16
365 trunc16 w
366 | w > fromIntegral (maxBound :: Word16)
367 = panic "stack depth overflow"
368 | otherwise
369 = fromIntegral w
370
371 fvsToEnv :: BCEnv -> DVarSet -> [Id]
372 -- Takes the free variables of a right-hand side, and
373 -- delivers an ordered list of the local variables that will
374 -- be captured in the thunk for the RHS
375 -- The BCEnv argument tells which variables are in the local
376 -- environment: these are the ones that should be captured
377 --
378 -- The code that constructs the thunk, and the code that executes
379 -- it, have to agree about this layout
380 fvsToEnv p fvs = [v | v <- dVarSetElems fvs,
381 isId v, -- Could be a type variable
382 v `Map.member` p]
383
384 -- -----------------------------------------------------------------------------
385 -- schemeE
386
387 returnUnboxedAtom :: Word -> Sequel -> BCEnv
388 -> AnnExpr' Id DVarSet -> ArgRep
389 -> BcM BCInstrList
390 -- Returning an unlifted value.
391 -- Heave it on the stack, SLIDE, and RETURN.
392 returnUnboxedAtom d s p e e_rep
393 = do (push, szw) <- pushAtom d p e
394 return (push -- value onto stack
395 `appOL` mkSLIDE szw (d-s) -- clear to sequel
396 `snocOL` RETURN_UBX e_rep) -- go
397
398 -- Compile code to apply the given expression to the remaining args
399 -- on the stack, returning a HNF.
400 schemeE :: Word -> Sequel -> BCEnv -> AnnExpr' Id DVarSet -> BcM BCInstrList
401
402 schemeE d s p e
403 | Just e' <- bcView e
404 = schemeE d s p e'
405
406 -- Delegate tail-calls to schemeT.
407 schemeE d s p e@(AnnApp _ _) = schemeT d s p e
408
409 schemeE d s p e@(AnnLit lit) = returnUnboxedAtom d s p e (typeArgRep (literalType lit))
410 schemeE d s p e@(AnnCoercion {}) = returnUnboxedAtom d s p e V
411
412 schemeE d s p e@(AnnVar v)
413 | isUnliftedType (idType v) = returnUnboxedAtom d s p e (bcIdArgRep v)
414 | otherwise = schemeT d s p e
415
416 schemeE d s p (AnnLet (AnnNonRec x (_,rhs)) (_,body))
417 | (AnnVar v, args_r_to_l) <- splitApp rhs,
418 Just data_con <- isDataConWorkId_maybe v,
419 dataConRepArity data_con == length args_r_to_l
420 = do -- Special case for a non-recursive let whose RHS is a
421 -- saturatred constructor application.
422 -- Just allocate the constructor and carry on
423 alloc_code <- mkConAppCode d s p data_con args_r_to_l
424 body_code <- schemeE (d+1) s (Map.insert x d p) body
425 return (alloc_code `appOL` body_code)
426
427 -- General case for let. Generates correct, if inefficient, code in
428 -- all situations.
429 schemeE d s p (AnnLet binds (_,body)) = do
430 dflags <- getDynFlags
431 let (xs,rhss) = case binds of AnnNonRec x rhs -> ([x],[rhs])
432 AnnRec xs_n_rhss -> unzip xs_n_rhss
433 n_binds = genericLength xs
434
435 fvss = map (fvsToEnv p' . fst) rhss
436
437 -- Sizes of free vars
438 sizes = map (\rhs_fvs -> sum (map (fromIntegral . idSizeW dflags) rhs_fvs)) fvss
439
440 -- the arity of each rhs
441 arities = map (genericLength . fst . collect) rhss
442
443 -- This p', d' defn is safe because all the items being pushed
444 -- are ptrs, so all have size 1. d' and p' reflect the stack
445 -- after the closures have been allocated in the heap (but not
446 -- filled in), and pointers to them parked on the stack.
447 p' = Map.insertList (zipE xs (mkStackOffsets d (genericReplicate n_binds 1))) p
448 d' = d + fromIntegral n_binds
449 zipE = zipEqual "schemeE"
450
451 -- ToDo: don't build thunks for things with no free variables
452 build_thunk _ [] size bco off arity
453 = return (PUSH_BCO bco `consOL` unitOL (mkap (off+size) size))
454 where
455 mkap | arity == 0 = MKAP
456 | otherwise = MKPAP
457 build_thunk dd (fv:fvs) size bco off arity = do
458 (push_code, pushed_szw) <- pushAtom dd p' (AnnVar fv)
459 more_push_code <- build_thunk (dd + fromIntegral pushed_szw) fvs size bco off arity
460 return (push_code `appOL` more_push_code)
461
462 alloc_code = toOL (zipWith mkAlloc sizes arities)
463 where mkAlloc sz 0
464 | is_tick = ALLOC_AP_NOUPD sz
465 | otherwise = ALLOC_AP sz
466 mkAlloc sz arity = ALLOC_PAP arity sz
467
468 is_tick = case binds of
469 AnnNonRec id _ -> occNameFS (getOccName id) == tickFS
470 _other -> False
471
472 compile_bind d' fvs x rhs size arity off = do
473 bco <- schemeR fvs (x,rhs)
474 build_thunk d' fvs size bco off arity
475
476 compile_binds =
477 [ compile_bind d' fvs x rhs size arity n
478 | (fvs, x, rhs, size, arity, n) <-
479 zip6 fvss xs rhss sizes arities [n_binds, n_binds-1 .. 1]
480 ]
481 body_code <- schemeE d' s p' body
482 thunk_codes <- sequence compile_binds
483 return (alloc_code `appOL` concatOL thunk_codes `appOL` body_code)
484
485 -- introduce a let binding for a ticked case expression. This rule
486 -- *should* only fire when the expression was not already let-bound
487 -- (the code gen for let bindings should take care of that). Todo: we
488 -- call exprFreeVars on a deAnnotated expression, this may not be the
489 -- best way to calculate the free vars but it seemed like the least
490 -- intrusive thing to do
491 schemeE d s p exp@(AnnTick (Breakpoint _id _fvs) _rhs)
492 = if isUnliftedType ty
493 then do
494 -- If the result type is unlifted, then we must generate
495 -- let f = \s . tick<n> e
496 -- in f realWorld#
497 -- When we stop at the breakpoint, _result will have an unlifted
498 -- type and hence won't be bound in the environment, but the
499 -- breakpoint will otherwise work fine.
500 id <- newId (mkFunTy realWorldStatePrimTy ty)
501 st <- newId realWorldStatePrimTy
502 let letExp = AnnLet (AnnNonRec id (fvs, AnnLam st (emptyDVarSet, exp)))
503 (emptyDVarSet, (AnnApp (emptyDVarSet, AnnVar id)
504 (emptyDVarSet, AnnVar realWorldPrimId)))
505 schemeE d s p letExp
506 else do
507 id <- newId ty
508 -- Todo: is emptyVarSet correct on the next line?
509 let letExp = AnnLet (AnnNonRec id (fvs, exp)) (emptyDVarSet, AnnVar id)
510 schemeE d s p letExp
511 where exp' = deAnnotate' exp
512 fvs = exprFreeVarsDSet exp'
513 ty = exprType exp'
514
515 -- ignore other kinds of tick
516 schemeE d s p (AnnTick _ (_, rhs)) = schemeE d s p rhs
517
518 schemeE d s p (AnnCase (_,scrut) _ _ []) = schemeE d s p scrut
519 -- no alts: scrut is guaranteed to diverge
520
521 schemeE d s p (AnnCase scrut bndr _ [(DataAlt dc, [bind1, bind2], rhs)])
522 | isUnboxedTupleCon dc
523 , UnaryRep rep_ty1 <- repType (idType bind1), UnaryRep rep_ty2 <- repType (idType bind2)
524 -- Convert
525 -- case .... of x { (# V'd-thing, a #) -> ... }
526 -- to
527 -- case .... of a { DEFAULT -> ... }
528 -- because the return convention for both are identical.
529 --
530 -- Note that it does not matter losing the void-rep thing from the
531 -- envt (it won't be bound now) because we never look such things up.
532 , Just res <- case () of
533 _ | VoidRep <- typePrimRep rep_ty1
534 -> Just $ doCase d s p scrut bind2 [(DEFAULT, [], rhs)] (Just bndr){-unboxed tuple-}
535 | VoidRep <- typePrimRep rep_ty2
536 -> Just $ doCase d s p scrut bind1 [(DEFAULT, [], rhs)] (Just bndr){-unboxed tuple-}
537 | otherwise
538 -> Nothing
539 = res
540
541 schemeE d s p (AnnCase scrut bndr _ [(DataAlt dc, [bind1], rhs)])
542 | isUnboxedTupleCon dc, UnaryRep _ <- repType (idType bind1)
543 -- Similarly, convert
544 -- case .... of x { (# a #) -> ... }
545 -- to
546 -- case .... of a { DEFAULT -> ... }
547 = --trace "automagic mashing of case alts (# a #)" $
548 doCase d s p scrut bind1 [(DEFAULT, [], rhs)] (Just bndr){-unboxed tuple-}
549
550 schemeE d s p (AnnCase scrut bndr _ [(DEFAULT, [], rhs)])
551 | Just (tc, tys) <- splitTyConApp_maybe (idType bndr)
552 , isUnboxedTupleTyCon tc
553 , Just res <- case tys of
554 [ty] | UnaryRep _ <- repType ty
555 , let bind = bndr `setIdType` ty
556 -> Just $ doCase d s p scrut bind [(DEFAULT, [], rhs)] (Just bndr){-unboxed tuple-}
557 [ty1, ty2] | UnaryRep rep_ty1 <- repType ty1
558 , UnaryRep rep_ty2 <- repType ty2
559 -> case () of
560 _ | VoidRep <- typePrimRep rep_ty1
561 , let bind2 = bndr `setIdType` ty2
562 -> Just $ doCase d s p scrut bind2 [(DEFAULT, [], rhs)] (Just bndr){-unboxed tuple-}
563 | VoidRep <- typePrimRep rep_ty2
564 , let bind1 = bndr `setIdType` ty1
565 -> Just $ doCase d s p scrut bind1 [(DEFAULT, [], rhs)] (Just bndr){-unboxed tuple-}
566 | otherwise
567 -> Nothing
568 _ -> Nothing
569 = res
570
571 schemeE d s p (AnnCase scrut bndr _ alts)
572 = doCase d s p scrut bndr alts Nothing{-not an unboxed tuple-}
573
574 schemeE _ _ _ expr
575 = pprPanic "ByteCodeGen.schemeE: unhandled case"
576 (pprCoreExpr (deAnnotate' expr))
577
578 {-
579 Ticked Expressions
580 ------------------
581
582 The idea is that the "breakpoint<n,fvs> E" is really just an annotation on
583 the code. When we find such a thing, we pull out the useful information,
584 and then compile the code as if it was just the expression E.
585
586 -}
587
588 -- Compile code to do a tail call. Specifically, push the fn,
589 -- slide the on-stack app back down to the sequel depth,
590 -- and enter. Four cases:
591 --
592 -- 0. (Nasty hack).
593 -- An application "GHC.Prim.tagToEnum# <type> unboxed-int".
594 -- The int will be on the stack. Generate a code sequence
595 -- to convert it to the relevant constructor, SLIDE and ENTER.
596 --
597 -- 1. The fn denotes a ccall. Defer to generateCCall.
598 --
599 -- 2. (Another nasty hack). Spot (# a::V, b #) and treat
600 -- it simply as b -- since the representations are identical
601 -- (the V takes up zero stack space). Also, spot
602 -- (# b #) and treat it as b.
603 --
604 -- 3. Application of a constructor, by defn saturated.
605 -- Split the args into ptrs and non-ptrs, and push the nonptrs,
606 -- then the ptrs, and then do PACK and RETURN.
607 --
608 -- 4. Otherwise, it must be a function call. Push the args
609 -- right to left, SLIDE and ENTER.
610
611 schemeT :: Word -- Stack depth
612 -> Sequel -- Sequel depth
613 -> BCEnv -- stack env
614 -> AnnExpr' Id DVarSet
615 -> BcM BCInstrList
616
617 schemeT d s p app
618
619 -- | trace ("schemeT: env in = \n" ++ showSDocDebug (ppBCEnv p)) False
620 -- = panic "schemeT ?!?!"
621
622 -- | trace ("\nschemeT\n" ++ showSDoc (pprCoreExpr (deAnnotate' app)) ++ "\n") False
623 -- = error "?!?!"
624
625 -- Case 0
626 | Just (arg, constr_names) <- maybe_is_tagToEnum_call app
627 = implement_tagToId d s p arg constr_names
628
629 -- Case 1
630 | Just (CCall ccall_spec) <- isFCallId_maybe fn
631 = if isSupportedCConv ccall_spec
632 then generateCCall d s p ccall_spec fn args_r_to_l
633 else unsupportedCConvException
634
635
636 -- Case 2: Constructor application
637 | Just con <- maybe_saturated_dcon,
638 isUnboxedTupleCon con
639 = case args_r_to_l of
640 [arg1,arg2] | isVAtom arg1 ->
641 unboxedTupleReturn d s p arg2
642 [arg1,arg2] | isVAtom arg2 ->
643 unboxedTupleReturn d s p arg1
644 _other -> unboxedTupleException
645
646 -- Case 3: Ordinary data constructor
647 | Just con <- maybe_saturated_dcon
648 = do alloc_con <- mkConAppCode d s p con args_r_to_l
649 return (alloc_con `appOL`
650 mkSLIDE 1 (d - s) `snocOL`
651 ENTER)
652
653 -- Case 4: Tail call of function
654 | otherwise
655 = doTailCall d s p fn args_r_to_l
656
657 where
658 -- Extract the args (R->L) and fn
659 -- The function will necessarily be a variable,
660 -- because we are compiling a tail call
661 (AnnVar fn, args_r_to_l) = splitApp app
662
663 -- Only consider this to be a constructor application iff it is
664 -- saturated. Otherwise, we'll call the constructor wrapper.
665 n_args = length args_r_to_l
666 maybe_saturated_dcon
667 = case isDataConWorkId_maybe fn of
668 Just con | dataConRepArity con == n_args -> Just con
669 _ -> Nothing
670
671 -- -----------------------------------------------------------------------------
672 -- Generate code to build a constructor application,
673 -- leaving it on top of the stack
674
675 mkConAppCode :: Word -> Sequel -> BCEnv
676 -> DataCon -- The data constructor
677 -> [AnnExpr' Id DVarSet] -- Args, in *reverse* order
678 -> BcM BCInstrList
679
680 mkConAppCode _ _ _ con [] -- Nullary constructor
681 = ASSERT( isNullaryRepDataCon con )
682 return (unitOL (PUSH_G (getName (dataConWorkId con))))
683 -- Instead of doing a PACK, which would allocate a fresh
684 -- copy of this constructor, use the single shared version.
685
686 mkConAppCode orig_d _ p con args_r_to_l
687 = ASSERT( dataConRepArity con == length args_r_to_l )
688 do_pushery orig_d (non_ptr_args ++ ptr_args)
689 where
690 -- The args are already in reverse order, which is the way PACK
691 -- expects them to be. We must push the non-ptrs after the ptrs.
692 (ptr_args, non_ptr_args) = partition isPtrAtom args_r_to_l
693
694 do_pushery d (arg:args)
695 = do (push, arg_words) <- pushAtom d p arg
696 more_push_code <- do_pushery (d + fromIntegral arg_words) args
697 return (push `appOL` more_push_code)
698 do_pushery d []
699 = return (unitOL (PACK con n_arg_words))
700 where
701 n_arg_words = trunc16 $ d - orig_d
702
703
704 -- -----------------------------------------------------------------------------
705 -- Returning an unboxed tuple with one non-void component (the only
706 -- case we can handle).
707 --
708 -- Remember, we don't want to *evaluate* the component that is being
709 -- returned, even if it is a pointed type. We always just return.
710
711 unboxedTupleReturn
712 :: Word -> Sequel -> BCEnv
713 -> AnnExpr' Id DVarSet -> BcM BCInstrList
714 unboxedTupleReturn d s p arg = returnUnboxedAtom d s p arg (atomRep arg)
715
716 -- -----------------------------------------------------------------------------
717 -- Generate code for a tail-call
718
719 doTailCall
720 :: Word -> Sequel -> BCEnv
721 -> Id -> [AnnExpr' Id DVarSet]
722 -> BcM BCInstrList
723 doTailCall init_d s p fn args
724 = do_pushes init_d args (map atomRep args)
725 where
726 do_pushes d [] reps = do
727 ASSERT( null reps ) return ()
728 (push_fn, sz) <- pushAtom d p (AnnVar fn)
729 ASSERT( sz == 1 ) return ()
730 return (push_fn `appOL` (
731 mkSLIDE (trunc16 $ d - init_d + 1) (init_d - s) `appOL`
732 unitOL ENTER))
733 do_pushes d args reps = do
734 let (push_apply, n, rest_of_reps) = findPushSeq reps
735 (these_args, rest_of_args) = splitAt n args
736 (next_d, push_code) <- push_seq d these_args
737 instrs <- do_pushes (next_d + 1) rest_of_args rest_of_reps
738 -- ^^^ for the PUSH_APPLY_ instruction
739 return (push_code `appOL` (push_apply `consOL` instrs))
740
741 push_seq d [] = return (d, nilOL)
742 push_seq d (arg:args) = do
743 (push_code, sz) <- pushAtom d p arg
744 (final_d, more_push_code) <- push_seq (d + fromIntegral sz) args
745 return (final_d, push_code `appOL` more_push_code)
746
747 -- v. similar to CgStackery.findMatch, ToDo: merge
748 findPushSeq :: [ArgRep] -> (BCInstr, Int, [ArgRep])
749 findPushSeq (P: P: P: P: P: P: rest)
750 = (PUSH_APPLY_PPPPPP, 6, rest)
751 findPushSeq (P: P: P: P: P: rest)
752 = (PUSH_APPLY_PPPPP, 5, rest)
753 findPushSeq (P: P: P: P: rest)
754 = (PUSH_APPLY_PPPP, 4, rest)
755 findPushSeq (P: P: P: rest)
756 = (PUSH_APPLY_PPP, 3, rest)
757 findPushSeq (P: P: rest)
758 = (PUSH_APPLY_PP, 2, rest)
759 findPushSeq (P: rest)
760 = (PUSH_APPLY_P, 1, rest)
761 findPushSeq (V: rest)
762 = (PUSH_APPLY_V, 1, rest)
763 findPushSeq (N: rest)
764 = (PUSH_APPLY_N, 1, rest)
765 findPushSeq (F: rest)
766 = (PUSH_APPLY_F, 1, rest)
767 findPushSeq (D: rest)
768 = (PUSH_APPLY_D, 1, rest)
769 findPushSeq (L: rest)
770 = (PUSH_APPLY_L, 1, rest)
771 findPushSeq _
772 = panic "ByteCodeGen.findPushSeq"
773
774 -- -----------------------------------------------------------------------------
775 -- Case expressions
776
777 doCase :: Word -> Sequel -> BCEnv
778 -> AnnExpr Id DVarSet -> Id -> [AnnAlt Id DVarSet]
779 -> Maybe Id -- Just x <=> is an unboxed tuple case with scrut binder, don't enter the result
780 -> BcM BCInstrList
781 doCase d s p (_,scrut) bndr alts is_unboxed_tuple
782 | UbxTupleRep _ <- repType (idType bndr)
783 = unboxedTupleException
784 | otherwise
785 = do
786 dflags <- getDynFlags
787 let
788 profiling
789 | gopt Opt_ExternalInterpreter dflags = gopt Opt_SccProfilingOn dflags
790 | otherwise = rtsIsProfiled
791
792 -- Top of stack is the return itbl, as usual.
793 -- underneath it is the pointer to the alt_code BCO.
794 -- When an alt is entered, it assumes the returned value is
795 -- on top of the itbl.
796 ret_frame_sizeW :: Word
797 ret_frame_sizeW = 2
798
799 -- The extra frame we push to save/restor the CCCS when profiling
800 save_ccs_sizeW | profiling = 2
801 | otherwise = 0
802
803 -- An unlifted value gets an extra info table pushed on top
804 -- when it is returned.
805 unlifted_itbl_sizeW :: Word
806 unlifted_itbl_sizeW | isAlgCase = 0
807 | otherwise = 1
808
809 -- depth of stack after the return value has been pushed
810 d_bndr = d + ret_frame_sizeW + fromIntegral (idSizeW dflags bndr)
811
812 -- depth of stack after the extra info table for an unboxed return
813 -- has been pushed, if any. This is the stack depth at the
814 -- continuation.
815 d_alts = d_bndr + unlifted_itbl_sizeW
816
817 -- Env in which to compile the alts, not including
818 -- any vars bound by the alts themselves
819 d_bndr' = fromIntegral d_bndr - 1
820 p_alts0 = Map.insert bndr d_bndr' p
821 p_alts = case is_unboxed_tuple of
822 Just ubx_bndr -> Map.insert ubx_bndr d_bndr' p_alts0
823 Nothing -> p_alts0
824
825 bndr_ty = idType bndr
826 isAlgCase = not (isUnliftedType bndr_ty) && isNothing is_unboxed_tuple
827
828 -- given an alt, return a discr and code for it.
829 codeAlt (DEFAULT, _, (_,rhs))
830 = do rhs_code <- schemeE d_alts s p_alts rhs
831 return (NoDiscr, rhs_code)
832
833 codeAlt alt@(_, bndrs, (_,rhs))
834 -- primitive or nullary constructor alt: no need to UNPACK
835 | null real_bndrs = do
836 rhs_code <- schemeE d_alts s p_alts rhs
837 return (my_discr alt, rhs_code)
838 | any (\bndr -> case repType (idType bndr) of UbxTupleRep _ -> True; _ -> False) bndrs
839 = unboxedTupleException
840 -- algebraic alt with some binders
841 | otherwise =
842 let
843 (ptrs,nptrs) = partition (isFollowableArg.bcIdArgRep) real_bndrs
844 ptr_sizes = map (fromIntegral . idSizeW dflags) ptrs
845 nptrs_sizes = map (fromIntegral . idSizeW dflags) nptrs
846 bind_sizes = ptr_sizes ++ nptrs_sizes
847 size = sum ptr_sizes + sum nptrs_sizes
848 -- the UNPACK instruction unpacks in reverse order...
849 p' = Map.insertList
850 (zip (reverse (ptrs ++ nptrs))
851 (mkStackOffsets d_alts (reverse bind_sizes)))
852 p_alts
853 in do
854 MASSERT(isAlgCase)
855 rhs_code <- schemeE (d_alts + size) s p' rhs
856 return (my_discr alt, unitOL (UNPACK (trunc16 size)) `appOL` rhs_code)
857 where
858 real_bndrs = filterOut isTyVar bndrs
859
860 my_discr (DEFAULT, _, _) = NoDiscr {-shouldn't really happen-}
861 my_discr (DataAlt dc, _, _)
862 | isUnboxedTupleCon dc
863 = unboxedTupleException
864 | otherwise
865 = DiscrP (fromIntegral (dataConTag dc - fIRST_TAG))
866 my_discr (LitAlt l, _, _)
867 = case l of MachInt i -> DiscrI (fromInteger i)
868 MachWord w -> DiscrW (fromInteger w)
869 MachFloat r -> DiscrF (fromRational r)
870 MachDouble r -> DiscrD (fromRational r)
871 MachChar i -> DiscrI (ord i)
872 _ -> pprPanic "schemeE(AnnCase).my_discr" (ppr l)
873
874 maybe_ncons
875 | not isAlgCase = Nothing
876 | otherwise
877 = case [dc | (DataAlt dc, _, _) <- alts] of
878 [] -> Nothing
879 (dc:_) -> Just (tyConFamilySize (dataConTyCon dc))
880
881 -- the bitmap is relative to stack depth d, i.e. before the
882 -- BCO, info table and return value are pushed on.
883 -- This bit of code is v. similar to buildLivenessMask in CgBindery,
884 -- except that here we build the bitmap from the known bindings of
885 -- things that are pointers, whereas in CgBindery the code builds the
886 -- bitmap from the free slots and unboxed bindings.
887 -- (ToDo: merge?)
888 --
889 -- NOTE [7/12/2006] bug #1013, testcase ghci/should_run/ghci002.
890 -- The bitmap must cover the portion of the stack up to the sequel only.
891 -- Previously we were building a bitmap for the whole depth (d), but we
892 -- really want a bitmap up to depth (d-s). This affects compilation of
893 -- case-of-case expressions, which is the only time we can be compiling a
894 -- case expression with s /= 0.
895 bitmap_size = trunc16 $ d-s
896 bitmap_size' :: Int
897 bitmap_size' = fromIntegral bitmap_size
898 bitmap = intsToReverseBitmap dflags bitmap_size'{-size-}
899 (sort (filter (< bitmap_size') rel_slots))
900 where
901 binds = Map.toList p
902 -- NB: unboxed tuple cases bind the scrut binder to the same offset
903 -- as one of the alt binders, so we have to remove any duplicates here:
904 rel_slots = nub $ map fromIntegral $ concat (map spread binds)
905 spread (id, offset) | isFollowableArg (bcIdArgRep id) = [ rel_offset ]
906 | otherwise = []
907 where rel_offset = trunc16 $ d - fromIntegral offset - 1
908
909 alt_stuff <- mapM codeAlt alts
910 alt_final <- mkMultiBranch maybe_ncons alt_stuff
911
912 let
913 alt_bco_name = getName bndr
914 alt_bco = mkProtoBCO dflags alt_bco_name alt_final (Left alts)
915 0{-no arity-} bitmap_size bitmap True{-is alts-}
916 -- trace ("case: bndr = " ++ showSDocDebug (ppr bndr) ++ "\ndepth = " ++ show d ++ "\nenv = \n" ++ showSDocDebug (ppBCEnv p) ++
917 -- "\n bitmap = " ++ show bitmap) $ do
918
919 scrut_code <- schemeE (d + ret_frame_sizeW + save_ccs_sizeW)
920 (d + ret_frame_sizeW + save_ccs_sizeW)
921 p scrut
922 alt_bco' <- emitBc alt_bco
923 let push_alts
924 | isAlgCase = PUSH_ALTS alt_bco'
925 | otherwise = PUSH_ALTS_UNLIFTED alt_bco' (typeArgRep bndr_ty)
926 return (push_alts `consOL` scrut_code)
927
928
929 -- -----------------------------------------------------------------------------
930 -- Deal with a CCall.
931
932 -- Taggedly push the args onto the stack R->L,
933 -- deferencing ForeignObj#s and adjusting addrs to point to
934 -- payloads in Ptr/Byte arrays. Then, generate the marshalling
935 -- (machine) code for the ccall, and create bytecodes to call that and
936 -- then return in the right way.
937
938 generateCCall :: Word -> Sequel -- stack and sequel depths
939 -> BCEnv
940 -> CCallSpec -- where to call
941 -> Id -- of target, for type info
942 -> [AnnExpr' Id DVarSet] -- args (atoms)
943 -> BcM BCInstrList
944
945 generateCCall d0 s p (CCallSpec target cconv safety) fn args_r_to_l
946 = do
947 dflags <- getDynFlags
948
949 let
950 -- useful constants
951 addr_sizeW :: Word16
952 addr_sizeW = fromIntegral (argRepSizeW dflags N)
953
954 -- Get the args on the stack, with tags and suitably
955 -- dereferenced for the CCall. For each arg, return the
956 -- depth to the first word of the bits for that arg, and the
957 -- ArgRep of what was actually pushed.
958
959 pargs _ [] = return []
960 pargs d (a:az)
961 = let UnaryRep arg_ty = repType (exprType (deAnnotate' a))
962
963 in case tyConAppTyCon_maybe arg_ty of
964 -- Don't push the FO; instead push the Addr# it
965 -- contains.
966 Just t
967 | t == arrayPrimTyCon || t == mutableArrayPrimTyCon
968 -> do rest <- pargs (d + fromIntegral addr_sizeW) az
969 code <- parg_ArrayishRep (fromIntegral (arrPtrsHdrSize dflags)) d p a
970 return ((code,AddrRep):rest)
971
972 | t == smallArrayPrimTyCon || t == smallMutableArrayPrimTyCon
973 -> do rest <- pargs (d + fromIntegral addr_sizeW) az
974 code <- parg_ArrayishRep (fromIntegral (smallArrPtrsHdrSize dflags)) d p a
975 return ((code,AddrRep):rest)
976
977 | t == byteArrayPrimTyCon || t == mutableByteArrayPrimTyCon
978 -> do rest <- pargs (d + fromIntegral addr_sizeW) az
979 code <- parg_ArrayishRep (fromIntegral (arrWordsHdrSize dflags)) d p a
980 return ((code,AddrRep):rest)
981
982 -- Default case: push taggedly, but otherwise intact.
983 _
984 -> do (code_a, sz_a) <- pushAtom d p a
985 rest <- pargs (d + fromIntegral sz_a) az
986 return ((code_a, atomPrimRep a) : rest)
987
988 -- Do magic for Ptr/Byte arrays. Push a ptr to the array on
989 -- the stack but then advance it over the headers, so as to
990 -- point to the payload.
991 parg_ArrayishRep :: Word16 -> Word -> BCEnv -> AnnExpr' Id DVarSet
992 -> BcM BCInstrList
993 parg_ArrayishRep hdrSize d p a
994 = do (push_fo, _) <- pushAtom d p a
995 -- The ptr points at the header. Advance it over the
996 -- header and then pretend this is an Addr#.
997 return (push_fo `snocOL` SWIZZLE 0 hdrSize)
998
999 code_n_reps <- pargs d0 args_r_to_l
1000 let
1001 (pushs_arg, a_reps_pushed_r_to_l) = unzip code_n_reps
1002 a_reps_sizeW = fromIntegral (sum (map (primRepSizeW dflags) a_reps_pushed_r_to_l))
1003
1004 push_args = concatOL pushs_arg
1005 d_after_args = d0 + a_reps_sizeW
1006 a_reps_pushed_RAW
1007 | null a_reps_pushed_r_to_l || head a_reps_pushed_r_to_l /= VoidRep
1008 = panic "ByteCodeGen.generateCCall: missing or invalid World token?"
1009 | otherwise
1010 = reverse (tail a_reps_pushed_r_to_l)
1011
1012 -- Now: a_reps_pushed_RAW are the reps which are actually on the stack.
1013 -- push_args is the code to do that.
1014 -- d_after_args is the stack depth once the args are on.
1015
1016 -- Get the result rep.
1017 (returns_void, r_rep)
1018 = case maybe_getCCallReturnRep (idType fn) of
1019 Nothing -> (True, VoidRep)
1020 Just rr -> (False, rr)
1021 {-
1022 Because the Haskell stack grows down, the a_reps refer to
1023 lowest to highest addresses in that order. The args for the call
1024 are on the stack. Now push an unboxed Addr# indicating
1025 the C function to call. Then push a dummy placeholder for the
1026 result. Finally, emit a CCALL insn with an offset pointing to the
1027 Addr# just pushed, and a literal field holding the mallocville
1028 address of the piece of marshalling code we generate.
1029 So, just prior to the CCALL insn, the stack looks like this
1030 (growing down, as usual):
1031
1032 <arg_n>
1033 ...
1034 <arg_1>
1035 Addr# address_of_C_fn
1036 <placeholder-for-result#> (must be an unboxed type)
1037
1038 The interpreter then calls the marshall code mentioned
1039 in the CCALL insn, passing it (& <placeholder-for-result#>),
1040 that is, the addr of the topmost word in the stack.
1041 When this returns, the placeholder will have been
1042 filled in. The placeholder is slid down to the sequel
1043 depth, and we RETURN.
1044
1045 This arrangement makes it simple to do f-i-dynamic since the Addr#
1046 value is the first arg anyway.
1047
1048 The marshalling code is generated specifically for this
1049 call site, and so knows exactly the (Haskell) stack
1050 offsets of the args, fn address and placeholder. It
1051 copies the args to the C stack, calls the stacked addr,
1052 and parks the result back in the placeholder. The interpreter
1053 calls it as a normal C call, assuming it has a signature
1054 void marshall_code ( StgWord* ptr_to_top_of_stack )
1055 -}
1056 -- resolve static address
1057 maybe_static_target =
1058 case target of
1059 DynamicTarget -> Nothing
1060 StaticTarget _ _ _ False ->
1061 panic "generateCCall: unexpected FFI value import"
1062 StaticTarget _ target _ True ->
1063 Just (MachLabel target mb_size IsFunction)
1064 where
1065 mb_size
1066 | OSMinGW32 <- platformOS (targetPlatform dflags)
1067 , StdCallConv <- cconv
1068 = Just (fromIntegral a_reps_sizeW * wORD_SIZE dflags)
1069 | otherwise
1070 = Nothing
1071
1072 let
1073 is_static = isJust maybe_static_target
1074
1075 -- Get the arg reps, zapping the leading Addr# in the dynamic case
1076 a_reps -- | trace (showSDoc (ppr a_reps_pushed_RAW)) False = error "???"
1077 | is_static = a_reps_pushed_RAW
1078 | otherwise = if null a_reps_pushed_RAW
1079 then panic "ByteCodeGen.generateCCall: dyn with no args"
1080 else tail a_reps_pushed_RAW
1081
1082 -- push the Addr#
1083 (push_Addr, d_after_Addr)
1084 | Just machlabel <- maybe_static_target
1085 = (toOL [PUSH_UBX machlabel addr_sizeW],
1086 d_after_args + fromIntegral addr_sizeW)
1087 | otherwise -- is already on the stack
1088 = (nilOL, d_after_args)
1089
1090 -- Push the return placeholder. For a call returning nothing,
1091 -- this is a V (tag).
1092 r_sizeW = fromIntegral (primRepSizeW dflags r_rep)
1093 d_after_r = d_after_Addr + fromIntegral r_sizeW
1094 r_lit = mkDummyLiteral r_rep
1095 push_r = (if returns_void
1096 then nilOL
1097 else unitOL (PUSH_UBX r_lit r_sizeW))
1098
1099 -- generate the marshalling code we're going to call
1100
1101 -- Offset of the next stack frame down the stack. The CCALL
1102 -- instruction needs to describe the chunk of stack containing
1103 -- the ccall args to the GC, so it needs to know how large it
1104 -- is. See comment in Interpreter.c with the CCALL instruction.
1105 stk_offset = trunc16 $ d_after_r - s
1106
1107 conv = case cconv of
1108 CCallConv -> FFICCall
1109 StdCallConv -> FFIStdCall
1110 _ -> panic "ByteCodeGen: unexpected calling convention"
1111
1112 -- the only difference in libffi mode is that we prepare a cif
1113 -- describing the call type by calling libffi, and we attach the
1114 -- address of this to the CCALL instruction.
1115
1116
1117 let ffires = primRepToFFIType dflags r_rep
1118 ffiargs = map (primRepToFFIType dflags) a_reps
1119 hsc_env <- getHscEnv
1120 token <- ioToBc $ iservCmd hsc_env (PrepFFI conv ffiargs ffires)
1121 recordFFIBc token
1122
1123 let
1124 -- do the call
1125 do_call = unitOL (CCALL stk_offset token
1126 (fromIntegral (fromEnum (playInterruptible safety))))
1127 -- slide and return
1128 wrapup = mkSLIDE r_sizeW (d_after_r - fromIntegral r_sizeW - s)
1129 `snocOL` RETURN_UBX (toArgRep r_rep)
1130 --trace (show (arg1_offW, args_offW , (map argRepSizeW a_reps) )) $
1131 return (
1132 push_args `appOL`
1133 push_Addr `appOL` push_r `appOL` do_call `appOL` wrapup
1134 )
1135
1136 primRepToFFIType :: DynFlags -> PrimRep -> FFIType
1137 primRepToFFIType dflags r
1138 = case r of
1139 VoidRep -> FFIVoid
1140 IntRep -> signed_word
1141 WordRep -> unsigned_word
1142 Int64Rep -> FFISInt64
1143 Word64Rep -> FFIUInt64
1144 AddrRep -> FFIPointer
1145 FloatRep -> FFIFloat
1146 DoubleRep -> FFIDouble
1147 _ -> panic "primRepToFFIType"
1148 where
1149 (signed_word, unsigned_word)
1150 | wORD_SIZE dflags == 4 = (FFISInt32, FFIUInt32)
1151 | wORD_SIZE dflags == 8 = (FFISInt64, FFIUInt64)
1152 | otherwise = panic "primTyDescChar"
1153
1154 -- Make a dummy literal, to be used as a placeholder for FFI return
1155 -- values on the stack.
1156 mkDummyLiteral :: PrimRep -> Literal
1157 mkDummyLiteral pr
1158 = case pr of
1159 IntRep -> MachInt 0
1160 WordRep -> MachWord 0
1161 AddrRep -> MachNullAddr
1162 DoubleRep -> MachDouble 0
1163 FloatRep -> MachFloat 0
1164 Int64Rep -> MachInt64 0
1165 Word64Rep -> MachWord64 0
1166 _ -> panic "mkDummyLiteral"
1167
1168
1169 -- Convert (eg)
1170 -- GHC.Prim.Char# -> GHC.Prim.State# GHC.Prim.RealWorld
1171 -- -> (# GHC.Prim.State# GHC.Prim.RealWorld, GHC.Prim.Int# #)
1172 --
1173 -- to Just IntRep
1174 -- and check that an unboxed pair is returned wherein the first arg is V'd.
1175 --
1176 -- Alternatively, for call-targets returning nothing, convert
1177 --
1178 -- GHC.Prim.Char# -> GHC.Prim.State# GHC.Prim.RealWorld
1179 -- -> (# GHC.Prim.State# GHC.Prim.RealWorld #)
1180 --
1181 -- to Nothing
1182
1183 maybe_getCCallReturnRep :: Type -> Maybe PrimRep
1184 maybe_getCCallReturnRep fn_ty
1185 = let (_a_tys, r_ty) = splitFunTys (dropForAlls fn_ty)
1186 maybe_r_rep_to_go
1187 = if isSingleton r_reps then Nothing else Just (r_reps !! 1)
1188 r_reps = case repType r_ty of
1189 UbxTupleRep reps -> map typePrimRep reps
1190 UnaryRep _ -> blargh
1191 ok = ( ( r_reps `lengthIs` 2 && VoidRep == head r_reps)
1192 || r_reps == [VoidRep] )
1193 && case maybe_r_rep_to_go of
1194 Nothing -> True
1195 Just r_rep -> r_rep /= PtrRep
1196 -- if it was, it would be impossible
1197 -- to create a valid return value
1198 -- placeholder on the stack
1199
1200 blargh :: a -- Used at more than one type
1201 blargh = pprPanic "maybe_getCCallReturn: can't handle:"
1202 (pprType fn_ty)
1203 in
1204 --trace (showSDoc (ppr (a_reps, r_reps))) $
1205 if ok then maybe_r_rep_to_go else blargh
1206
1207 maybe_is_tagToEnum_call :: AnnExpr' Id DVarSet -> Maybe (AnnExpr' Id DVarSet, [Name])
1208 -- Detect and extract relevant info for the tagToEnum kludge.
1209 maybe_is_tagToEnum_call app
1210 | AnnApp (_, AnnApp (_, AnnVar v) (_, AnnType t)) arg <- app
1211 , Just TagToEnumOp <- isPrimOpId_maybe v
1212 = Just (snd arg, extract_constr_Names t)
1213 | otherwise
1214 = Nothing
1215 where
1216 extract_constr_Names ty
1217 | UnaryRep rep_ty <- repType ty
1218 , Just tyc <- tyConAppTyCon_maybe rep_ty,
1219 isDataTyCon tyc
1220 = map (getName . dataConWorkId) (tyConDataCons tyc)
1221 -- NOTE: use the worker name, not the source name of
1222 -- the DataCon. See DataCon.hs for details.
1223 | otherwise
1224 = pprPanic "maybe_is_tagToEnum_call.extract_constr_Ids" (ppr ty)
1225
1226 {- -----------------------------------------------------------------------------
1227 Note [Implementing tagToEnum#]
1228 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1229 (implement_tagToId arg names) compiles code which takes an argument
1230 'arg', (call it i), and enters the i'th closure in the supplied list
1231 as a consequence. The [Name] is a list of the constructors of this
1232 (enumeration) type.
1233
1234 The code we generate is this:
1235 push arg
1236 push bogus-word
1237
1238 TESTEQ_I 0 L1
1239 PUSH_G <lbl for first data con>
1240 JMP L_Exit
1241
1242 L1: TESTEQ_I 1 L2
1243 PUSH_G <lbl for second data con>
1244 JMP L_Exit
1245 ...etc...
1246 Ln: TESTEQ_I n L_fail
1247 PUSH_G <lbl for last data con>
1248 JMP L_Exit
1249
1250 L_fail: CASEFAIL
1251
1252 L_exit: SLIDE 1 n
1253 ENTER
1254
1255 The 'bogus-word' push is because TESTEQ_I expects the top of the stack
1256 to have an info-table, and the next word to have the value to be
1257 tested. This is very weird, but it's the way it is right now. See
1258 Interpreter.c. We don't acutally need an info-table here; we just
1259 need to have the argument to be one-from-top on the stack, hence pushing
1260 a 1-word null. See Trac #8383.
1261 -}
1262
1263
1264 implement_tagToId :: Word -> Sequel -> BCEnv
1265 -> AnnExpr' Id DVarSet -> [Name] -> BcM BCInstrList
1266 -- See Note [Implementing tagToEnum#]
1267 implement_tagToId d s p arg names
1268 = ASSERT( notNull names )
1269 do (push_arg, arg_words) <- pushAtom d p arg
1270 labels <- getLabelsBc (genericLength names)
1271 label_fail <- getLabelBc
1272 label_exit <- getLabelBc
1273 let infos = zip4 labels (tail labels ++ [label_fail])
1274 [0 ..] names
1275 steps = map (mkStep label_exit) infos
1276
1277 return (push_arg
1278 `appOL` unitOL (PUSH_UBX MachNullAddr 1)
1279 -- Push bogus word (see Note [Implementing tagToEnum#])
1280 `appOL` concatOL steps
1281 `appOL` toOL [ LABEL label_fail, CASEFAIL,
1282 LABEL label_exit ]
1283 `appOL` mkSLIDE 1 (d - s + fromIntegral arg_words + 1)
1284 -- "+1" to account for bogus word
1285 -- (see Note [Implementing tagToEnum#])
1286 `appOL` unitOL ENTER)
1287 where
1288 mkStep l_exit (my_label, next_label, n, name_for_n)
1289 = toOL [LABEL my_label,
1290 TESTEQ_I n next_label,
1291 PUSH_G name_for_n,
1292 JMP l_exit]
1293
1294
1295 -- -----------------------------------------------------------------------------
1296 -- pushAtom
1297
1298 -- Push an atom onto the stack, returning suitable code & number of
1299 -- stack words used.
1300 --
1301 -- The env p must map each variable to the highest- numbered stack
1302 -- slot for it. For example, if the stack has depth 4 and we
1303 -- tagged-ly push (v :: Int#) on it, the value will be in stack[4],
1304 -- the tag in stack[5], the stack will have depth 6, and p must map v
1305 -- to 5 and not to 4. Stack locations are numbered from zero, so a
1306 -- depth 6 stack has valid words 0 .. 5.
1307
1308 pushAtom :: Word -> BCEnv -> AnnExpr' Id DVarSet -> BcM (BCInstrList, Word16)
1309
1310 pushAtom d p e
1311 | Just e' <- bcView e
1312 = pushAtom d p e'
1313
1314 pushAtom _ _ (AnnCoercion {}) -- Coercions are zero-width things,
1315 = return (nilOL, 0) -- treated just like a variable V
1316
1317 pushAtom d p (AnnVar v)
1318 | UnaryRep rep_ty <- repType (idType v)
1319 , V <- typeArgRep rep_ty
1320 = return (nilOL, 0)
1321
1322 | isFCallId v
1323 = pprPanic "pushAtom: shouldn't get an FCallId here" (ppr v)
1324
1325 | Just primop <- isPrimOpId_maybe v
1326 = return (unitOL (PUSH_PRIMOP primop), 1)
1327
1328 | Just d_v <- lookupBCEnv_maybe v p -- v is a local variable
1329 = do dflags <- getDynFlags
1330 let sz :: Word16
1331 sz = fromIntegral (idSizeW dflags v)
1332 l = trunc16 $ d - d_v + fromIntegral sz - 2
1333 return (toOL (genericReplicate sz (PUSH_L l)), sz)
1334 -- d - d_v the number of words between the TOS
1335 -- and the 1st slot of the object
1336 --
1337 -- d - d_v - 1 the offset from the TOS of the 1st slot
1338 --
1339 -- d - d_v - 1 + sz - 1 the offset from the TOS of the last slot
1340 -- of the object.
1341 --
1342 -- Having found the last slot, we proceed to copy the right number of
1343 -- slots on to the top of the stack.
1344
1345 | otherwise -- v must be a global variable
1346 = do dflags <- getDynFlags
1347 let sz :: Word16
1348 sz = fromIntegral (idSizeW dflags v)
1349 MASSERT(sz == 1)
1350 return (unitOL (PUSH_G (getName v)), sz)
1351
1352
1353 pushAtom _ _ (AnnLit lit) = do
1354 dflags <- getDynFlags
1355 let code rep
1356 = let size_host_words = fromIntegral (argRepSizeW dflags rep)
1357 in return (unitOL (PUSH_UBX lit size_host_words),
1358 size_host_words)
1359
1360 case lit of
1361 MachLabel _ _ _ -> code N
1362 MachWord _ -> code N
1363 MachInt _ -> code N
1364 MachWord64 _ -> code L
1365 MachInt64 _ -> code L
1366 MachFloat _ -> code F
1367 MachDouble _ -> code D
1368 MachChar _ -> code N
1369 MachNullAddr -> code N
1370 MachStr _ -> code N
1371 -- No LitInteger's should be left by the time this is called.
1372 -- CorePrep should have converted them all to a real core
1373 -- representation.
1374 LitInteger {} -> panic "pushAtom: LitInteger"
1375
1376 pushAtom _ _ expr
1377 = pprPanic "ByteCodeGen.pushAtom"
1378 (pprCoreExpr (deAnnotate (undefined, expr)))
1379
1380
1381 -- -----------------------------------------------------------------------------
1382 -- Given a bunch of alts code and their discrs, do the donkey work
1383 -- of making a multiway branch using a switch tree.
1384 -- What a load of hassle!
1385
1386 mkMultiBranch :: Maybe Int -- # datacons in tycon, if alg alt
1387 -- a hint; generates better code
1388 -- Nothing is always safe
1389 -> [(Discr, BCInstrList)]
1390 -> BcM BCInstrList
1391 mkMultiBranch maybe_ncons raw_ways = do
1392 lbl_default <- getLabelBc
1393
1394 let
1395 mkTree :: [(Discr, BCInstrList)] -> Discr -> Discr -> BcM BCInstrList
1396 mkTree [] _range_lo _range_hi = return (unitOL (JMP lbl_default))
1397 -- shouldn't happen?
1398
1399 mkTree [val] range_lo range_hi
1400 | range_lo == range_hi
1401 = return (snd val)
1402 | null defaults -- Note [CASEFAIL]
1403 = do lbl <- getLabelBc
1404 return (testEQ (fst val) lbl
1405 `consOL` (snd val
1406 `appOL` (LABEL lbl `consOL` unitOL CASEFAIL)))
1407 | otherwise
1408 = return (testEQ (fst val) lbl_default `consOL` snd val)
1409
1410 -- Note [CASEFAIL] It may be that this case has no default
1411 -- branch, but the alternatives are not exhaustive - this
1412 -- happens for GADT cases for example, where the types
1413 -- prove that certain branches are impossible. We could
1414 -- just assume that the other cases won't occur, but if
1415 -- this assumption was wrong (because of a bug in GHC)
1416 -- then the result would be a segfault. So instead we
1417 -- emit an explicit test and a CASEFAIL instruction that
1418 -- causes the interpreter to barf() if it is ever
1419 -- executed.
1420
1421 mkTree vals range_lo range_hi
1422 = let n = length vals `div` 2
1423 vals_lo = take n vals
1424 vals_hi = drop n vals
1425 v_mid = fst (head vals_hi)
1426 in do
1427 label_geq <- getLabelBc
1428 code_lo <- mkTree vals_lo range_lo (dec v_mid)
1429 code_hi <- mkTree vals_hi v_mid range_hi
1430 return (testLT v_mid label_geq
1431 `consOL` (code_lo
1432 `appOL` unitOL (LABEL label_geq)
1433 `appOL` code_hi))
1434
1435 the_default
1436 = case defaults of
1437 [] -> nilOL
1438 [(_, def)] -> LABEL lbl_default `consOL` def
1439 _ -> panic "mkMultiBranch/the_default"
1440 instrs <- mkTree notd_ways init_lo init_hi
1441 return (instrs `appOL` the_default)
1442 where
1443 (defaults, not_defaults) = partition (isNoDiscr.fst) raw_ways
1444 notd_ways = sortBy (comparing fst) not_defaults
1445
1446 testLT (DiscrI i) fail_label = TESTLT_I i fail_label
1447 testLT (DiscrW i) fail_label = TESTLT_W i fail_label
1448 testLT (DiscrF i) fail_label = TESTLT_F i fail_label
1449 testLT (DiscrD i) fail_label = TESTLT_D i fail_label
1450 testLT (DiscrP i) fail_label = TESTLT_P i fail_label
1451 testLT NoDiscr _ = panic "mkMultiBranch NoDiscr"
1452
1453 testEQ (DiscrI i) fail_label = TESTEQ_I i fail_label
1454 testEQ (DiscrW i) fail_label = TESTEQ_W i fail_label
1455 testEQ (DiscrF i) fail_label = TESTEQ_F i fail_label
1456 testEQ (DiscrD i) fail_label = TESTEQ_D i fail_label
1457 testEQ (DiscrP i) fail_label = TESTEQ_P i fail_label
1458 testEQ NoDiscr _ = panic "mkMultiBranch NoDiscr"
1459
1460 -- None of these will be needed if there are no non-default alts
1461 (init_lo, init_hi)
1462 | null notd_ways
1463 = panic "mkMultiBranch: awesome foursome"
1464 | otherwise
1465 = case fst (head notd_ways) of
1466 DiscrI _ -> ( DiscrI minBound, DiscrI maxBound )
1467 DiscrW _ -> ( DiscrW minBound, DiscrW maxBound )
1468 DiscrF _ -> ( DiscrF minF, DiscrF maxF )
1469 DiscrD _ -> ( DiscrD minD, DiscrD maxD )
1470 DiscrP _ -> ( DiscrP algMinBound, DiscrP algMaxBound )
1471 NoDiscr -> panic "mkMultiBranch NoDiscr"
1472
1473 (algMinBound, algMaxBound)
1474 = case maybe_ncons of
1475 -- XXX What happens when n == 0?
1476 Just n -> (0, fromIntegral n - 1)
1477 Nothing -> (minBound, maxBound)
1478
1479 isNoDiscr NoDiscr = True
1480 isNoDiscr _ = False
1481
1482 dec (DiscrI i) = DiscrI (i-1)
1483 dec (DiscrW w) = DiscrW (w-1)
1484 dec (DiscrP i) = DiscrP (i-1)
1485 dec other = other -- not really right, but if you
1486 -- do cases on floating values, you'll get what you deserve
1487
1488 -- same snotty comment applies to the following
1489 minF, maxF :: Float
1490 minD, maxD :: Double
1491 minF = -1.0e37
1492 maxF = 1.0e37
1493 minD = -1.0e308
1494 maxD = 1.0e308
1495
1496
1497 -- -----------------------------------------------------------------------------
1498 -- Supporting junk for the compilation schemes
1499
1500 -- Describes case alts
1501 data Discr
1502 = DiscrI Int
1503 | DiscrW Word
1504 | DiscrF Float
1505 | DiscrD Double
1506 | DiscrP Word16
1507 | NoDiscr
1508 deriving (Eq, Ord)
1509
1510 instance Outputable Discr where
1511 ppr (DiscrI i) = int i
1512 ppr (DiscrW w) = text (show w)
1513 ppr (DiscrF f) = text (show f)
1514 ppr (DiscrD d) = text (show d)
1515 ppr (DiscrP i) = ppr i
1516 ppr NoDiscr = text "DEF"
1517
1518
1519 lookupBCEnv_maybe :: Id -> BCEnv -> Maybe Word
1520 lookupBCEnv_maybe = Map.lookup
1521
1522 idSizeW :: DynFlags -> Id -> Int
1523 idSizeW dflags = argRepSizeW dflags . bcIdArgRep
1524
1525 bcIdArgRep :: Id -> ArgRep
1526 bcIdArgRep = toArgRep . bcIdPrimRep
1527
1528 bcIdPrimRep :: Id -> PrimRep
1529 bcIdPrimRep = typePrimRep . bcIdUnaryType
1530
1531 isFollowableArg :: ArgRep -> Bool
1532 isFollowableArg P = True
1533 isFollowableArg _ = False
1534
1535 isVoidArg :: ArgRep -> Bool
1536 isVoidArg V = True
1537 isVoidArg _ = False
1538
1539 bcIdUnaryType :: Id -> UnaryType
1540 bcIdUnaryType x = case repType (idType x) of
1541 UnaryRep rep_ty -> rep_ty
1542 UbxTupleRep [rep_ty] -> rep_ty
1543 UbxTupleRep [rep_ty1, rep_ty2]
1544 | VoidRep <- typePrimRep rep_ty1 -> rep_ty2
1545 | VoidRep <- typePrimRep rep_ty2 -> rep_ty1
1546 _ -> pprPanic "bcIdUnaryType" (ppr x $$ ppr (idType x))
1547
1548 -- See bug #1257
1549 unboxedTupleException :: a
1550 unboxedTupleException = throwGhcException (ProgramError
1551 ("Error: bytecode compiler can't handle unboxed tuples.\n"++
1552 " Possibly due to foreign import/export decls in source.\n"++
1553 " Workaround: use -fobject-code, or compile this module to .o separately."))
1554
1555 -- | Indicate if the calling convention is supported
1556 isSupportedCConv :: CCallSpec -> Bool
1557 isSupportedCConv (CCallSpec _ cconv _) = case cconv of
1558 CCallConv -> True -- we explicitly pattern match on every
1559 StdCallConv -> True -- convention to ensure that a warning
1560 PrimCallConv -> False -- is triggered when a new one is added
1561 JavaScriptCallConv -> False
1562 CApiConv -> False
1563
1564 -- See bug #10462
1565 unsupportedCConvException :: a
1566 unsupportedCConvException = throwGhcException (ProgramError
1567 ("Error: bytecode compiler can't handle some foreign calling conventions\n"++
1568 " Workaround: use -fobject-code, or compile this module to .o separately."))
1569
1570 mkSLIDE :: Word16 -> Word -> OrdList BCInstr
1571 mkSLIDE n d
1572 -- if the amount to slide doesn't fit in a word,
1573 -- generate multiple slide instructions
1574 | d > fromIntegral limit
1575 = SLIDE n limit `consOL` mkSLIDE n (d - fromIntegral limit)
1576 | d == 0
1577 = nilOL
1578 | otherwise
1579 = if d == 0 then nilOL else unitOL (SLIDE n $ fromIntegral d)
1580 where
1581 limit :: Word16
1582 limit = maxBound
1583
1584 splitApp :: AnnExpr' Var ann -> (AnnExpr' Var ann, [AnnExpr' Var ann])
1585 -- The arguments are returned in *right-to-left* order
1586 splitApp e | Just e' <- bcView e = splitApp e'
1587 splitApp (AnnApp (_,f) (_,a)) = case splitApp f of
1588 (f', as) -> (f', a:as)
1589 splitApp e = (e, [])
1590
1591
1592 bcView :: AnnExpr' Var ann -> Maybe (AnnExpr' Var ann)
1593 -- The "bytecode view" of a term discards
1594 -- a) type abstractions
1595 -- b) type applications
1596 -- c) casts
1597 -- d) ticks (but not breakpoints)
1598 -- Type lambdas *can* occur in random expressions,
1599 -- whereas value lambdas cannot; that is why they are nuked here
1600 bcView (AnnCast (_,e) _) = Just e
1601 bcView (AnnLam v (_,e)) | isTyVar v = Just e
1602 bcView (AnnApp (_,e) (_, AnnType _)) = Just e
1603 bcView (AnnTick Breakpoint{} _) = Nothing
1604 bcView (AnnTick _other_tick (_,e)) = Just e
1605 bcView _ = Nothing
1606
1607 isVAtom :: AnnExpr' Var ann -> Bool
1608 isVAtom e | Just e' <- bcView e = isVAtom e'
1609 isVAtom (AnnVar v) = isVoidArg (bcIdArgRep v)
1610 isVAtom (AnnCoercion {}) = True
1611 isVAtom _ = False
1612
1613 atomPrimRep :: AnnExpr' Id ann -> PrimRep
1614 atomPrimRep e | Just e' <- bcView e = atomPrimRep e'
1615 atomPrimRep (AnnVar v) = bcIdPrimRep v
1616 atomPrimRep (AnnLit l) = typePrimRep (literalType l)
1617 atomPrimRep (AnnCoercion {}) = VoidRep
1618 atomPrimRep other = pprPanic "atomPrimRep" (ppr (deAnnotate (undefined,other)))
1619
1620 atomRep :: AnnExpr' Id ann -> ArgRep
1621 atomRep e = toArgRep (atomPrimRep e)
1622
1623 isPtrAtom :: AnnExpr' Id ann -> Bool
1624 isPtrAtom e = isFollowableArg (atomRep e)
1625
1626 -- Let szsw be the sizes in words of some items pushed onto the stack,
1627 -- which has initial depth d'. Return the values which the stack environment
1628 -- should map these items to.
1629 mkStackOffsets :: Word -> [Word] -> [Word]
1630 mkStackOffsets original_depth szsw
1631 = map (subtract 1) (tail (scanl (+) original_depth szsw))
1632
1633 typeArgRep :: Type -> ArgRep
1634 typeArgRep = toArgRep . typePrimRep
1635
1636 -- -----------------------------------------------------------------------------
1637 -- The bytecode generator's monad
1638
1639 data BcM_State
1640 = BcM_State
1641 { bcm_hsc_env :: HscEnv
1642 , uniqSupply :: UniqSupply -- for generating fresh variable names
1643 , thisModule :: Module -- current module (for breakpoints)
1644 , nextlabel :: Word16 -- for generating local labels
1645 , ffis :: [FFIInfo] -- ffi info blocks, to free later
1646 -- Should be free()d when it is GCd
1647 , modBreaks :: Maybe ModBreaks -- info about breakpoints
1648 , breakInfo :: IntMap CgBreakInfo
1649 }
1650
1651 newtype BcM r = BcM (BcM_State -> IO (BcM_State, r))
1652
1653 ioToBc :: IO a -> BcM a
1654 ioToBc io = BcM $ \st -> do
1655 x <- io
1656 return (st, x)
1657
1658 runBc :: HscEnv -> UniqSupply -> Module -> Maybe ModBreaks -> BcM r
1659 -> IO (BcM_State, r)
1660 runBc hsc_env us this_mod modBreaks (BcM m)
1661 = m (BcM_State hsc_env us this_mod 0 [] modBreaks IntMap.empty)
1662
1663 thenBc :: BcM a -> (a -> BcM b) -> BcM b
1664 thenBc (BcM expr) cont = BcM $ \st0 -> do
1665 (st1, q) <- expr st0
1666 let BcM k = cont q
1667 (st2, r) <- k st1
1668 return (st2, r)
1669
1670 thenBc_ :: BcM a -> BcM b -> BcM b
1671 thenBc_ (BcM expr) (BcM cont) = BcM $ \st0 -> do
1672 (st1, _) <- expr st0
1673 (st2, r) <- cont st1
1674 return (st2, r)
1675
1676 returnBc :: a -> BcM a
1677 returnBc result = BcM $ \st -> (return (st, result))
1678
1679 instance Functor BcM where
1680 fmap = liftM
1681
1682 instance Applicative BcM where
1683 pure = returnBc
1684 (<*>) = ap
1685 (*>) = thenBc_
1686
1687 instance Monad BcM where
1688 (>>=) = thenBc
1689 (>>) = (*>)
1690
1691 instance HasDynFlags BcM where
1692 getDynFlags = BcM $ \st -> return (st, hsc_dflags (bcm_hsc_env st))
1693
1694 getHscEnv :: BcM HscEnv
1695 getHscEnv = BcM $ \st -> return (st, bcm_hsc_env st)
1696
1697 emitBc :: ([FFIInfo] -> ProtoBCO Name) -> BcM (ProtoBCO Name)
1698 emitBc bco
1699 = BcM $ \st -> return (st{ffis=[]}, bco (ffis st))
1700
1701 recordFFIBc :: RemotePtr C_ffi_cif -> BcM ()
1702 recordFFIBc a
1703 = BcM $ \st -> return (st{ffis = FFIInfo a : ffis st}, ())
1704
1705 getLabelBc :: BcM Word16
1706 getLabelBc
1707 = BcM $ \st -> do let nl = nextlabel st
1708 when (nl == maxBound) $
1709 panic "getLabelBc: Ran out of labels"
1710 return (st{nextlabel = nl + 1}, nl)
1711
1712 getLabelsBc :: Word16 -> BcM [Word16]
1713 getLabelsBc n
1714 = BcM $ \st -> let ctr = nextlabel st
1715 in return (st{nextlabel = ctr+n}, [ctr .. ctr+n-1])
1716
1717 getCCArray :: BcM (Array BreakIndex (RemotePtr CostCentre))
1718 getCCArray = BcM $ \st ->
1719 let breaks = expectJust "ByteCodeGen.getCCArray" $ modBreaks st in
1720 return (st, modBreaks_ccs breaks)
1721
1722
1723 newBreakInfo :: BreakIndex -> CgBreakInfo -> BcM ()
1724 newBreakInfo ix info = BcM $ \st ->
1725 return (st{breakInfo = IntMap.insert ix info (breakInfo st)}, ())
1726
1727 newUnique :: BcM Unique
1728 newUnique = BcM $
1729 \st -> case takeUniqFromSupply (uniqSupply st) of
1730 (uniq, us) -> let newState = st { uniqSupply = us }
1731 in return (newState, uniq)
1732
1733 getCurrentModule :: BcM Module
1734 getCurrentModule = BcM $ \st -> return (st, thisModule st)
1735
1736 newId :: Type -> BcM Id
1737 newId ty = do
1738 uniq <- newUnique
1739 return $ mkSysLocal tickFS uniq ty
1740
1741 tickFS :: FastString
1742 tickFS = fsLit "ticked"