ByteCodeGen.hs 72.6 KB
Newer Older
1
{-# LANGUAGE CPP, MagicHash, RecordWildCards, BangPatterns #-}
2
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3
{-# OPTIONS_GHC -fprof-auto-top #-}
4
5
6
7
8
--
--  (c) The University of Glasgow 2002-2006
--

-- | ByteCodeGen: Generate bytecode from Core
9
module ByteCodeGen ( UnlinkedBCO, byteCodeGen, coreExprToBCOs ) where
10
11
12

#include "HsVersions.h"

13
14
import GhcPrelude

15
import ByteCodeInstr
16
import ByteCodeAsm
17
import ByteCodeTypes
18

19
20
21
22
import GHCi
import GHCi.FFI
import GHCi.RemoteTypes
import BasicTypes
ian@well-typed.com's avatar
ian@well-typed.com committed
23
import DynFlags
24
import Outputable
ian@well-typed.com's avatar
ian@well-typed.com committed
25
import Platform
26
import Name
27
import MkId
28
import Id
29
30
31
import ForeignCall
import HscTypes
import CoreUtils
32
import CoreSyn
33
34
35
36
37
import PprCore
import Literal
import PrimOp
import CoreFVs
import Type
38
import RepType
39
import Kind            ( isLiftedTypeKind )
40
41
import DataCon
import TyCon
42
import Util
43
44
45
46
47
48
import VarSet
import TysPrim
import ErrUtils
import Unique
import FastString
import Panic
49
import StgCmmClosure    ( NonVoid(..), fromNonVoid, nonVoidIds )
Simon Marlow's avatar
Simon Marlow committed
50
import StgCmmLayout
51
import SMRep hiding (WordOff, ByteOff, wordsToBytes)
52
import Bitmap
53
import OrdList
54
import Maybes
55
import VarEnv
56

Ian Lynagh's avatar
Ian Lynagh committed
57
import Data.List
58
import Foreign
Ian Lynagh's avatar
Ian Lynagh committed
59
import Control.Monad
Ian Lynagh's avatar
Ian Lynagh committed
60
import Data.Char
61

62
import UniqSupply
63
import Module
64
import Control.Arrow ( second )
65

66
import Control.Exception
67
import Data.Array
68
import Data.ByteString (ByteString)
69
import Data.Map (Map)
70
import Data.IntMap (IntMap)
71
import qualified Data.Map as Map
72
import qualified Data.IntMap as IntMap
73
import qualified FiniteMap as Map
74
import Data.Ord
75
import GHC.Stack.CCS
76
import Data.Either ( partitionEithers )
77

78
-- -----------------------------------------------------------------------------
79
-- Generating byte code for a complete module
80

81
byteCodeGen :: HscEnv
82
            -> Module
83
            -> CoreProgram
84
            -> [TyCon]
85
            -> Maybe ModBreaks
86
            -> IO CompiledByteCode
87
byteCodeGen hsc_env this_mod binds tycs mb_modBreaks
88
89
90
   = withTiming (pure dflags)
                (text "ByteCodeGen"<+>brackets (ppr this_mod))
                (const ()) $ do
91
92
        -- Split top-level binds into strings and others.
        -- See Note [generating code for top-level string literal bindings].
93
        let (strings, flatBinds) = partitionEithers $ do
94
                (bndr, rhs) <- flattenBinds binds
95
96
                return $ case exprIsTickedString_maybe rhs of
                    Just str -> Left (bndr, str)
97
98
                    _ -> Right (bndr, simpleFreeVars rhs)
        stringPtrs <- allocateTopStrings hsc_env strings
99

100
        us <- mkSplitUniqSupply 'y'
101
        (BcM_State{..}, proto_bcos) <-
102
           runBc hsc_env us this_mod mb_modBreaks (mkVarEnv stringPtrs) $
103
             mapM schemeTopBind flatBinds
104

105
        when (notNull ffis)
106
107
             (panic "ByteCodeGen.byteCodeGen: missing final emitBc?")

108
        dumpIfSet_dyn dflags Opt_D_dump_BCOs
109
           "Proto-BCOs" (vcat (intersperse (char ' ') (map ppr proto_bcos)))
110

111
        cbc <- assembleBCOs hsc_env proto_bcos tycs (map snd stringPtrs)
112
113
114
          (case modBreaks of
             Nothing -> Nothing
             Just mb -> Just mb{ modBreaks_breakInfo = breakInfo })
115
116
117
118
119
120
121
122
123
124
125

        -- Squash space leaks in the CompiledByteCode.  This is really
        -- important, because when loading a set of modules into GHCi
        -- we don't touch the CompiledByteCode until the end when we
        -- do linking.  Forcing out the thunks here reduces space
        -- usage by more than 50% when loading a large number of
        -- modules.
        evaluate (seqCompiledByteCode cbc)

        return cbc

126
  where dflags = hsc_dflags hsc_env
127

128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
allocateTopStrings
  :: HscEnv
  -> [(Id, ByteString)]
  -> IO [(Var, RemotePtr ())]
allocateTopStrings hsc_env topStrings = do
  let !(bndrs, strings) = unzip topStrings
  ptrs <- iservCmd hsc_env $ MallocStrings strings
  return $ zip bndrs ptrs

{-
Note [generating code for top-level string literal bindings]

Here is a summary on how the byte code generator deals with top-level string
literals:

143
1. Top-level string literal bindings are separated from the rest of the module.
144
145
146
147
148
149
150

2. The strings are allocated via iservCmd, in allocateTopStrings

3. The mapping from binders to allocated strings (topStrings) are maintained in
   BcM and used when generating code for variable references.
-}

151
152
-- -----------------------------------------------------------------------------
-- Generating byte code for an expression
153

154
-- Returns: the root BCO for this expression
155
coreExprToBCOs :: HscEnv
156
               -> Module
157
               -> CoreExpr
158
               -> IO UnlinkedBCO
159
coreExprToBCOs hsc_env this_mod expr
160
161
162
 = withTiming (pure dflags)
              (text "ByteCodeGen"<+>brackets (ppr this_mod))
              (const ()) $ do
163
164
      -- create a totally bogus name for the top-level BCO; this
      -- should be harmless, since it's never used for anything
Ian Lynagh's avatar
Ian Lynagh committed
165
      let invented_name  = mkSystemVarName (mkPseudoUniqueE 0) (fsLit "ExprTopLevel")
166
          invented_id    = Id.mkLocalId invented_name (panic "invented_id's type")
167

168
169
170
      -- the uniques are needed to generate fresh variables when we introduce new
      -- let bindings for ticked expressions
      us <- mkSplitUniqSupply 'y'
171
172
      (BcM_State _dflags _us _this_mod _final_ctr mallocd _ _ _, proto_bco)
         <- runBc hsc_env us this_mod Nothing emptyVarEnv $
173
              schemeTopBind (invented_id, simpleFreeVars expr)
174

sof's avatar
sof committed
175
      when (notNull mallocd)
176
177
           (panic "ByteCodeGen.coreExprToBCOs: missing final emitBc?")

178
      dumpIfSet_dyn dflags Opt_D_dump_BCOs "Proto-BCOs" (ppr proto_bco)
179

180
      assembleOneBCO hsc_env proto_bco
181
  where dflags = hsc_dflags hsc_env
182

183
-- The regular freeVars function gives more information than is useful to
Gabor Greif's avatar
Gabor Greif committed
184
-- us here. simpleFreeVars does the impedance matching.
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
simpleFreeVars :: CoreExpr -> AnnExpr Id DVarSet
simpleFreeVars = go . freeVars
  where
    go :: AnnExpr Id FVAnn -> AnnExpr Id DVarSet
    go (ann, e) = (freeVarsOfAnn ann, go' e)

    go' :: AnnExpr' Id FVAnn -> AnnExpr' Id DVarSet
    go' (AnnVar id)                  = AnnVar id
    go' (AnnLit lit)                 = AnnLit lit
    go' (AnnLam bndr body)           = AnnLam bndr (go body)
    go' (AnnApp fun arg)             = AnnApp (go fun) (go arg)
    go' (AnnCase scrut bndr ty alts) = AnnCase (go scrut) bndr ty (map go_alt alts)
    go' (AnnLet bind body)           = AnnLet (go_bind bind) (go body)
    go' (AnnCast expr (ann, co))     = AnnCast (go expr) (freeVarsOfAnn ann, co)
    go' (AnnTick tick body)          = AnnTick tick (go body)
    go' (AnnType ty)                 = AnnType ty
    go' (AnnCoercion co)             = AnnCoercion co

    go_alt (con, args, expr) = (con, args, go expr)

    go_bind (AnnNonRec bndr rhs) = AnnNonRec bndr (go rhs)
    go_bind (AnnRec pairs)       = AnnRec (map (second go) pairs)

208
209
-- -----------------------------------------------------------------------------
-- Compilation schema for the bytecode generator
210
211
212

type BCInstrList = OrdList BCInstr

213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
newtype ByteOff = ByteOff Int
    deriving (Enum, Eq, Integral, Num, Ord, Real)

newtype WordOff = WordOff Int
    deriving (Enum, Eq, Integral, Num, Ord, Real)

wordsToBytes :: DynFlags -> WordOff -> ByteOff
wordsToBytes dflags = fromIntegral . (* wORD_SIZE dflags) . fromIntegral

-- Used when we know we have a whole number of words
bytesToWords :: DynFlags -> ByteOff -> WordOff
bytesToWords dflags (ByteOff bytes) =
    let (q, r) = bytes `quotRem` (wORD_SIZE dflags)
    in if r == 0
           then fromIntegral q
           else panic $ "ByteCodeGen.bytesToWords: bytes=" ++ show bytes

wordSize :: DynFlags -> ByteOff
wordSize dflags = ByteOff (wORD_SIZE dflags)

type Sequel = ByteOff -- back off to this depth before ENTER

type StackDepth = ByteOff
236

237
238
-- | Maps Ids to their stack depth. This allows us to avoid having to mess with
-- it after each push/pop.
239
type BCEnv = Map Id StackDepth -- To find vars on the stack
240

Ian Lynagh's avatar
Ian Lynagh committed
241
{-
242
243
244
ppBCEnv :: BCEnv -> SDoc
ppBCEnv p
   = text "begin-env"
245
     $$ nest 4 (vcat (map pp_one (sortBy cmp_snd (Map.toList p))))
246
247
     $$ text "end-env"
     where
Simon Marlow's avatar
Simon Marlow committed
248
        pp_one (var, offset) = int offset <> colon <+> ppr var <+> ppr (bcIdArgRep var)
249
        cmp_snd x y = compare (snd x) (snd y)
Ian Lynagh's avatar
Ian Lynagh committed
250
-}
251

252
253
-- Create a BCO and do a spot of peephole optimisation on the insns
-- at the same time.
254
mkProtoBCO
255
256
   :: DynFlags
   -> name
257
   -> BCInstrList
258
   -> Either  [AnnAlt Id DVarSet] (AnnExpr Id DVarSet)
259
   -> Int
260
   -> Word16
261
   -> [StgWord]
262
   -> Bool      -- True <=> is a return point, rather than a function
263
   -> [FFIInfo]
264
   -> ProtoBCO name
265
mkProtoBCO dflags nm instrs_ordlist origin arity bitmap_size bitmap is_ret ffis
266
   = ProtoBCO {
267
        protoBCOName = nm,
268
        protoBCOInstrs = maybe_with_stack_check,
269
270
271
272
        protoBCOBitmap = bitmap,
        protoBCOBitmapSize = bitmap_size,
        protoBCOArity = arity,
        protoBCOExpr = origin,
273
        protoBCOFFIs = ffis
274
      }
275
     where
276
277
278
279
        -- Overestimate the stack usage (in words) of this BCO,
        -- and if >= iNTERP_STACK_CHECK_THRESH, add an explicit
        -- stack check.  (The interpreter always does a stack check
        -- for iNTERP_STACK_CHECK_THRESH words at the start of each
Thomas Schilling's avatar
Thomas Schilling committed
280
        -- BCO anyway, so we only need to add an explicit one in the
281
282
        -- (hopefully rare) cases when the (overestimated) stack use
        -- exceeds iNTERP_STACK_CHECK_THRESH.
283
        maybe_with_stack_check
284
           | is_ret && stack_usage < fromIntegral (aP_STACK_SPLIM dflags) = peep_d
285
286
287
                -- don't do stack checks at return points,
                -- everything is aggregated up to the top BCO
                -- (which must be a function).
288
289
                -- That is, unless the stack usage is >= AP_STACK_SPLIM,
                -- see bug #1466.
290
           | stack_usage >= fromIntegral iNTERP_STACK_CHECK_THRESH
291
           = STKCHECK stack_usage : peep_d
292
           | otherwise
293
294
           = peep_d     -- the supposedly common case

295
        -- We assume that this sum doesn't wrap
296
        stack_usage = sum (map bciStackUse peep_d)
297
298
299
300

        -- Merge local pushes
        peep_d = peep (fromOL instrs_ordlist)

301
302
303
        peep (PUSH_L off1 : PUSH_L off2 : PUSH_L off3 : rest)
           = PUSH_LLL off1 (off2-1) (off3-2) : peep rest
        peep (PUSH_L off1 : PUSH_L off2 : rest)
304
           = PUSH_LL off1 (off2-1) : peep rest
305
306
307
308
309
        peep (i:rest)
           = i : peep rest
        peep []
           = []

Simon Marlow's avatar
Simon Marlow committed
310
argBits :: DynFlags -> [ArgRep] -> [Bool]
311
312
argBits _      [] = []
argBits dflags (rep : args)
Simon Marlow's avatar
Simon Marlow committed
313
314
  | isFollowableArg rep  = False : argBits dflags args
  | otherwise = take (argRepSizeW dflags rep) (repeat True) ++ argBits dflags args
315

316
317
318
319
320
-- -----------------------------------------------------------------------------
-- schemeTopBind

-- Compile code for the right-hand side of a top-level binding

321
schemeTopBind :: (Id, AnnExpr Id DVarSet) -> BcM (ProtoBCO Name)
322
schemeTopBind (id, rhs)
323
  | Just data_con <- isDataConWorkId_maybe id,
324
    isNullaryRepDataCon data_con = do
325
    dflags <- getDynFlags
326
327
328
329
330
331
332
        -- Special case for the worker of a nullary data con.
        -- It'll look like this:        Nil = /\a -> Nil a
        -- If we feed it into schemeR, we'll get
        --      Nil = Nil
        -- because mkConAppCode treats nullary constructor applications
        -- by just re-using the single top-level definition.  So
        -- for the worker itself, we must allocate it directly.
333
    -- ioToBc (putStrLn $ "top level BCO")
334
    emitBc (mkProtoBCO dflags (getName id) (toOL [PACK data_con 0, ENTER])
335
                       (Right rhs) 0 0 [{-no bitmap-}] False{-not alts-})
336
337
338
339

  | otherwise
  = schemeR [{- No free variables -}] (id, rhs)

340

341
342
-- -----------------------------------------------------------------------------
-- schemeR
343

344
345
346
347
348
-- Compile code for a right-hand side, to give a BCO that,
-- when executed with the free variables and arguments on top of the stack,
-- will return with a pointer to the result on top of the stack, after
-- removing the free variables and arguments.
--
349
350
-- Park the resulting BCO in the monad.  Also requires the
-- variable to which this value was bound, so as to give the
351
-- resulting BCO a name.
352

353
354
355
schemeR :: [Id]                 -- Free vars of the RHS, ordered as they
                                -- will appear in the thunk.  Empty for
                                -- top-level things, which have no free vars.
356
        -> (Id, AnnExpr Id DVarSet)
357
        -> BcM (ProtoBCO Name)
358
schemeR fvs (nm, rhs)
359
{-
360
361
   | trace (showSDoc (
              (char ' '
362
               $$ (ppr.filter (not.isTyVar).dVarSetElems.fst) rhs
363
364
365
366
367
               $$ pprCoreExpr (deAnnotate rhs)
               $$ char ' '
              ))) False
   = undefined
   | otherwise
368
-}
369
   = schemeR_wrk fvs nm rhs (collect rhs)
370

371
collect :: AnnExpr Id DVarSet -> ([Var], AnnExpr' Id DVarSet)
372
373
374
collect (_, e) = go [] e
  where
    go xs e | Just e' <- bcView e = go xs e'
375
    go xs (AnnLam x (_,e))
Richard Eisenberg's avatar
Richard Eisenberg committed
376
      | typePrimRep (idType x) `lengthExceeds` 1
377
      = multiValException
378
379
380
      | otherwise
      = go (x:xs) e
    go xs not_lambda = (reverse xs, not_lambda)
381

382
383
384
385
386
387
schemeR_wrk
    :: [Id]
    -> Id
    -> AnnExpr Id DVarSet
    -> ([Var], AnnExpr' Var DVarSet)
    -> BcM (ProtoBCO Name)
388
schemeR_wrk fvs nm original_body (args, body)
389
390
391
   = do
     dflags <- getDynFlags
     let
392
393
394
395
396
         all_args  = reverse args ++ fvs
         arity     = length all_args
         -- all_args are the args in reverse order.  We're compiling a function
         -- \fv1..fvn x1..xn -> e
         -- i.e. the fvs come first
397

398
399
400
401
402
         -- Stack arguments always take a whole number of words, we never pack
         -- them unlike constructor fields.
         szsb_args = map (wordsToBytes dflags . idSizeW dflags) all_args
         sum_szsb_args  = sum szsb_args
         p_init    = Map.fromList (zip all_args (mkStackOffsets 0 szsb_args))
403

404
         -- make the arg bitmap
Simon Marlow's avatar
Simon Marlow committed
405
         bits = argBits dflags (reverse (map bcIdArgRep all_args))
406
         bitmap_size = genericLength bits
407
         bitmap = mkBitmap dflags bits
408
     body_code <- schemeER_wrk sum_szsb_args p_init body
409

410
     emitBc (mkProtoBCO dflags (getName nm) body_code (Right original_body)
411
                 arity bitmap_size bitmap False{-not alts-})
412

413
-- introduce break instructions for ticked expressions
414
schemeER_wrk :: StackDepth -> BCEnv -> AnnExpr' Id DVarSet -> BcM BCInstrList
415
schemeER_wrk d p rhs
416
  | AnnTick (Breakpoint tick_no fvs) (_annot, newRhs) <- rhs
417
  = do  code <- schemeE d 0 p newRhs
418
        cc_arr <- getCCArray
419
        this_mod <- moduleName <$> getCurrentModule
420
421
        dflags <- getDynFlags
        let idOffSets = getVarOffSets dflags d p fvs
422
423
424
        let breakInfo = CgBreakInfo
                        { cgb_vars = idOffSets
                        , cgb_resty = exprType (deAnnotate' newRhs)
425
                        }
426
        newBreakInfo tick_no breakInfo
427
428
429
        dflags <- getDynFlags
        let cc | interpreterProfiled dflags = cc_arr ! tick_no
               | otherwise = toRemotePtr nullPtr
430
        let breakInstr = BRK_FUN (fromIntegral tick_no) (getUnique this_mod) cc
431
        return $ breakInstr `consOL` code
432
   | otherwise = schemeE d 0 p rhs
433

434
435
getVarOffSets :: DynFlags -> StackDepth -> BCEnv -> [Id] -> [(Id, Word16)]
getVarOffSets dflags depth env = catMaybes . map getOffSet
436
437
  where
    getOffSet id = case lookupBCEnv_maybe id env of
438
        Nothing     -> Nothing
439
440
        Just offset ->
            -- michalt: I'm not entirely sure why we need the stack
Gabor Greif's avatar
Gabor Greif committed
441
            -- adjustment by 2 here. I initially thought that there's
442
443
            -- something off with getIdValFromApStack (the only user of this
            -- value), but it looks ok to me. My current hypothesis is that
Gabor Greif's avatar
Gabor Greif committed
444
            -- this "adjustment" is needed due to stack manipulation for
445
446
            -- BRK_FUN in Interpreter.c In any case, this is used only when
            -- we trigger a breakpoint.
447
448
449
            let !var_depth_ws =
                    trunc16W $ bytesToWords dflags (depth - offset) + 2
            in Just (id, var_depth_ws)
pcapriotti's avatar
pcapriotti committed
450

451
452
truncIntegral16 :: Integral a => a -> Word16
truncIntegral16 w
pcapriotti's avatar
pcapriotti committed
453
454
455
456
    | w > fromIntegral (maxBound :: Word16)
    = panic "stack depth overflow"
    | otherwise
    = fromIntegral w
457

458
459
460
trunc16B :: ByteOff -> Word16
trunc16B = truncIntegral16

461
462
463
trunc16W :: WordOff -> Word16
trunc16W = truncIntegral16

464
fvsToEnv :: BCEnv -> DVarSet -> [Id]
465
466
467
468
469
470
471
472
-- Takes the free variables of a right-hand side, and
-- delivers an ordered list of the local variables that will
-- be captured in the thunk for the RHS
-- The BCEnv argument tells which variables are in the local
-- environment: these are the ones that should be captured
--
-- The code that constructs the thunk, and the code that executes
-- it, have to agree about this layout
473
fvsToEnv p fvs = [v | v <- dVarSetElems fvs,
474
475
                      isId v,           -- Could be a type variable
                      v `Map.member` p]
476

477
478
-- -----------------------------------------------------------------------------
-- schemeE
479

480
481
482
483
484
485
486
returnUnboxedAtom
    :: StackDepth
    -> Sequel
    -> BCEnv
    -> AnnExpr' Id DVarSet
    -> ArgRep
    -> BcM BCInstrList
487
488
-- Returning an unlifted value.
-- Heave it on the stack, SLIDE, and RETURN.
489
490
491
492
493
494
returnUnboxedAtom d s p e e_rep = do
    dflags <- getDynFlags
    (push, szb) <- pushAtom d p e
    return (push                                 -- value onto stack
           `appOL`  mkSlideB dflags szb (d - s)  -- clear to sequel
           `snocOL` RETURN_UBX e_rep)            -- go
495

496
497
-- Compile code to apply the given expression to the remaining args
-- on the stack, returning a HNF.
498
499
schemeE
    :: StackDepth -> Sequel -> BCEnv -> AnnExpr' Id DVarSet -> BcM BCInstrList
500
501
502
503
schemeE d s p e
   | Just e' <- bcView e
   = schemeE d s p e'

504
-- Delegate tail-calls to schemeT.
505
schemeE d s p e@(AnnApp _ _) = schemeT d s p e
506

Simon Marlow's avatar
Simon Marlow committed
507
508
schemeE d s p e@(AnnLit lit)     = returnUnboxedAtom d s p e (typeArgRep (literalType lit))
schemeE d s p e@(AnnCoercion {}) = returnUnboxedAtom d s p e V
509

510
schemeE d s p e@(AnnVar v)
511
    | isUnliftedType (idType v) = returnUnboxedAtom d s p e (bcIdArgRep v)
512
    | otherwise                 = schemeT d s p e
513

514
515
schemeE d s p (AnnLet (AnnNonRec x (_,rhs)) (_,body))
   | (AnnVar v, args_r_to_l) <- splitApp rhs,
516
     Just data_con <- isDataConWorkId_maybe v,
517
     dataConRepArity data_con == length args_r_to_l
518
   = do -- Special case for a non-recursive let whose RHS is a
Gabor Greif's avatar
Gabor Greif committed
519
        -- saturated constructor application.
520
        -- Just allocate the constructor and carry on
521
        alloc_code <- mkConAppCode d s p data_con args_r_to_l
522
523
        dflags <- getDynFlags
        let !d2 = d + wordSize dflags
524
        body_code <- schemeE d2 s (Map.insert x d2 p) body
525
        return (alloc_code `appOL` body_code)
526
527
528

-- General case for let.  Generates correct, if inefficient, code in
-- all situations.
529
530
531
schemeE d s p (AnnLet binds (_,body)) = do
     dflags <- getDynFlags
     let (xs,rhss) = case binds of AnnNonRec x rhs  -> ([x],[rhs])
532
                                   AnnRec xs_n_rhss -> unzip xs_n_rhss
533
         n_binds = genericLength xs
534

535
         fvss  = map (fvsToEnv p' . fst) rhss
536

sof's avatar
sof committed
537
         -- Sizes of free vars
538
539
         size_w = trunc16W . idSizeW dflags
         sizes = map (\rhs_fvs -> sum (map size_w rhs_fvs)) fvss
540

541
542
         -- the arity of each rhs
         arities = map (genericLength . fst . collect) rhss
543
544

         -- This p', d' defn is safe because all the items being pushed
545
         -- are ptrs, so all have size 1 word.  d' and p' reflect the stack
546
547
         -- after the closures have been allocated in the heap (but not
         -- filled in), and pointers to them parked on the stack.
548
549
550
551
         offsets = mkStackOffsets d (genericReplicate n_binds (wordSize dflags))
         p' = Map.insertList (zipE xs offsets) p
         d' = d + wordsToBytes dflags n_binds
         zipE = zipEqual "schemeE"
552
553

         -- ToDo: don't build thunks for things with no free variables
554
555
556
557
558
559
560
561
         build_thunk
             :: StackDepth
             -> [Id]
             -> Word16
             -> ProtoBCO Name
             -> Word16
             -> Word16
             -> BcM BCInstrList
Ian Lynagh's avatar
Ian Lynagh committed
562
         build_thunk _ [] size bco off arity
563
            = return (PUSH_BCO bco `consOL` unitOL (mkap (off+size) size))
564
565
566
           where
                mkap | arity == 0 = MKAP
                     | otherwise  = MKPAP
567
         build_thunk dd (fv:fvs) size bco off arity = do
568
569
570
              (push_code, pushed_szb) <- pushAtom dd p' (AnnVar fv)
              more_push_code <-
                  build_thunk (dd + pushed_szb) fvs size bco off arity
571
              return (push_code `appOL` more_push_code)
572

573
         alloc_code = toOL (zipWith mkAlloc sizes arities)
574
           where mkAlloc sz 0
575
576
                    | is_tick     = ALLOC_AP_NOUPD sz
                    | otherwise   = ALLOC_AP sz
577
                 mkAlloc sz arity = ALLOC_PAP arity sz
578

579
         is_tick = case binds of
580
581
582
                     AnnNonRec id _ -> occNameFS (getOccName id) == tickFS
                     _other -> False

583
584
585
         compile_bind d' fvs x rhs size arity off = do
                bco <- schemeR fvs (x,rhs)
                build_thunk d' fvs size bco off arity
586

587
         compile_binds =
588
            [ compile_bind d' fvs x rhs size arity (trunc16W n)
589
590
591
            | (fvs, x, rhs, size, arity, n) <-
                zip6 fvss xs rhss sizes arities [n_binds, n_binds-1 .. 1]
            ]
592
     body_code <- schemeE d' s p' body
593
     thunk_codes <- sequence compile_binds
594
     return (alloc_code `appOL` concatOL thunk_codes `appOL` body_code)
595

596
-- Introduce a let binding for a ticked case expression. This rule
597
598
599
600
601
-- *should* only fire when the expression was not already let-bound
-- (the code gen for let bindings should take care of that).  Todo: we
-- call exprFreeVars on a deAnnotated expression, this may not be the
-- best way to calculate the free vars but it seemed like the least
-- intrusive thing to do
602
schemeE d s p exp@(AnnTick (Breakpoint _id _fvs) _rhs)
603
604
605
606
607
608
609
610
   | isLiftedTypeKind (typeKind ty)
   = do   id <- newId ty
          -- Todo: is emptyVarSet correct on the next line?
          let letExp = AnnLet (AnnNonRec id (fvs, exp)) (emptyDVarSet, AnnVar id)
          schemeE d s p letExp

   | otherwise
   = do   -- If the result type is not definitely lifted, then we must generate
611
          --   let f = \s . tick<n> e
612
613
614
615
          --   in  f realWorld#
          -- When we stop at the breakpoint, _result will have an unlifted
          -- type and hence won't be bound in the environment, but the
          -- breakpoint will otherwise work fine.
616
617
618
619
620
621
622
623
624
625
          --
          -- NB (Trac #12007) this /also/ applies for if (ty :: TYPE r), where
          --    r :: RuntimeRep is a variable. This can happen in the
          --    continuations for a pattern-synonym matcher
          --    match = /\(r::RuntimeRep) /\(a::TYPE r).
          --            \(k :: Int -> a) \(v::T).
          --            case v of MkV n -> k n
          -- Here (k n) :: a :: Type r, so we don't know if it's lifted
          -- or not; but that should be fine provided we add that void arg.

626
627
          id <- newId (mkFunTy realWorldStatePrimTy ty)
          st <- newId realWorldStatePrimTy
628
629
630
          let letExp = AnnLet (AnnNonRec id (fvs, AnnLam st (emptyDVarSet, exp)))
                              (emptyDVarSet, (AnnApp (emptyDVarSet, AnnVar id)
                                                    (emptyDVarSet, AnnVar realWorldPrimId)))
631
          schemeE d s p letExp
632
633
634
635
636

   where
     exp' = deAnnotate' exp
     fvs  = exprFreeVarsDSet exp'
     ty   = exprType exp'
637

638
639
640
-- ignore other kinds of tick
schemeE d s p (AnnTick _ (_, rhs)) = schemeE d s p rhs

641
642
643
schemeE d s p (AnnCase (_,scrut) _ _ []) = schemeE d s p scrut
        -- no alts: scrut is guaranteed to diverge

644
schemeE d s p (AnnCase scrut bndr _ [(DataAlt dc, [bind1, bind2], rhs)])
645
   | isUnboxedTupleCon dc -- handles pairs with one void argument (e.g. state token)
646
        -- Convert
Simon Marlow's avatar
Simon Marlow committed
647
        --      case .... of x { (# V'd-thing, a #) -> ... }
648
649
        -- to
        --      case .... of a { DEFAULT -> ... }
Gabor Greif's avatar
Gabor Greif committed
650
        -- because the return convention for both are identical.
651
652
653
        --
        -- Note that it does not matter losing the void-rep thing from the
        -- envt (it won't be bound now) because we never look such things up.
Richard Eisenberg's avatar
Richard Eisenberg committed
654
655
   , Just res <- case (typePrimRep (idType bind1), typePrimRep (idType bind2)) of
                   ([], [_])
656
                     -> Just $ doCase d s p scrut bind2 [(DEFAULT, [], rhs)] (Just bndr)
Richard Eisenberg's avatar
Richard Eisenberg committed
657
                   ([_], [])
658
                     -> Just $ doCase d s p scrut bind1 [(DEFAULT, [], rhs)] (Just bndr)
Richard Eisenberg's avatar
Richard Eisenberg committed
659
                   _ -> Nothing
660
661
662
   = res

schemeE d s p (AnnCase scrut bndr _ [(DataAlt dc, [bind1], rhs)])
663
   | isUnboxedTupleCon dc
664
   , typePrimRep (idType bndr) `lengthAtMost` 1 -- handles unit tuples
665
666
667
668
   = doCase d s p scrut bind1 [(DEFAULT, [], rhs)] (Just bndr)

schemeE d s p (AnnCase scrut bndr _ alt@[(DEFAULT, [], _)])
   | isUnboxedTupleType (idType bndr)
Richard Eisenberg's avatar
Richard Eisenberg committed
669
670
671
672
   , Just ty <- case typePrimRep (idType bndr) of
       [_]  -> Just (unwrapType (idType bndr))
       []   -> Just voidPrimTy
       _    -> Nothing
673
674
675
       -- handles any pattern with a single non-void binder; in particular I/O
       -- monad returns (# RealWorld#, a #)
   = doCase d s p scrut (bndr `setIdType` ty) alt (Just bndr)
676

677
schemeE d s p (AnnCase scrut bndr _ alts)
678
   = doCase d s p scrut bndr alts Nothing{-not an unboxed tuple-}
679

Ian Lynagh's avatar
Ian Lynagh committed
680
schemeE _ _ _ expr
681
   = pprPanic "ByteCodeGen.schemeE: unhandled case"
Ian Lynagh's avatar
Ian Lynagh committed
682
               (pprCoreExpr (deAnnotate' expr))
683

684
{-
685
686
   Ticked Expressions
   ------------------
687

688
  The idea is that the "breakpoint<n,fvs> E" is really just an annotation on
689
  the code. When we find such a thing, we pull out the useful information,
690
  and then compile the code as if it was just the expression E.
691
692
693

-}

694
695
696
697
698
-- Compile code to do a tail call.  Specifically, push the fn,
-- slide the on-stack app back down to the sequel depth,
-- and enter.  Four cases:
--
-- 0.  (Nasty hack).
699
--     An application "GHC.Prim.tagToEnum# <type> unboxed-int".
700
701
--     The int will be on the stack.  Generate a code sequence
--     to convert it to the relevant constructor, SLIDE and ENTER.
702
--
703
-- 1.  The fn denotes a ccall.  Defer to generateCCall.
704
--
Simon Marlow's avatar
Simon Marlow committed
705
-- 2.  (Another nasty hack).  Spot (# a::V, b #) and treat
706
--     it simply as  b  -- since the representations are identical
Simon Marlow's avatar
Simon Marlow committed
707
--     (the V takes up zero stack space).  Also, spot
708
--     (# b #) and treat it as  b.
709
--
710
-- 3.  Application of a constructor, by defn saturated.
711
--     Split the args into ptrs and non-ptrs, and push the nonptrs,
712
713
--     then the ptrs, and then do PACK and RETURN.
--
714
-- 4.  Otherwise, it must be a function call.  Push the args
715
--     right to left, SLIDE and ENTER.
716

717
schemeT :: StackDepth   -- Stack depth
718
719
        -> Sequel       -- Sequel depth
        -> BCEnv        -- stack env
720
        -> AnnExpr' Id DVarSet
721
        -> BcM BCInstrList
722

723
schemeT d s p app
724

725
   -- Case 0
726
727
   | Just (arg, constr_names) <- maybe_is_tagToEnum_call app
   = implement_tagToId d s p arg constr_names
728

729
   -- Case 1
730
   | Just (CCall ccall_spec) <- isFCallId_maybe fn
731
732
733
734
   = if isSupportedCConv ccall_spec
      then generateCCall d s p ccall_spec fn args_r_to_l
      else unsupportedCConvException

735

736
   -- Case 2: Constructor application
737
738
   | Just con <- maybe_saturated_dcon
   , isUnboxedTupleCon con
739
   = case args_r_to_l of
Simon Marlow's avatar
Simon Marlow committed
740
        [arg1,arg2] | isVAtom arg1 ->
741
                  unboxedTupleReturn d s p arg2
Simon Marlow's avatar
Simon Marlow committed
742
        [arg1,arg2] | isVAtom arg2 ->
743
                  unboxedTupleReturn d s p arg1
744
        _other -> multiValException
745
746

   -- Case 3: Ordinary data constructor
747
   | Just con <- maybe_saturated_dcon
748
   = do alloc_con <- mkConAppCode d s p con args_r_to_l
749
        dflags <- getDynFlags
750
        return (alloc_con         `appOL`
751
                mkSlideW 1 (bytesToWords dflags $ d - s) `snocOL`
752
                ENTER)
753

754
   -- Case 4: Tail call of function
755
   | otherwise
756
   = doTailCall d s p fn args_r_to_l
757

758
   where
759
760
761
        -- Extract the args (R->L) and fn
        -- The function will necessarily be a variable,
        -- because we are compiling a tail call
762
      (AnnVar fn, args_r_to_l) = splitApp app
763

764
      -- Only consider this to be a constructor application iff it is
765
      -- saturated.  Otherwise, we'll call the constructor wrapper.
766
      n_args = length args_r_to_l
767
768
769
770
      maybe_saturated_dcon
        = case isDataConWorkId_maybe fn of
                Just con | dataConRepArity con == n_args -> Just con
                _ -> Nothing
771

772
-- -----------------------------------------------------------------------------
773
-- Generate code to build a constructor application,
774
775
-- leaving it on top of the stack

776
777
778
779
780
781
782
mkConAppCode
    :: StackDepth
    -> Sequel
    -> BCEnv
    -> DataCon                  -- The data constructor
    -> [AnnExpr' Id DVarSet]    -- Args, in *reverse* order
    -> BcM BCInstrList
783
mkConAppCode _ _ _ con []       -- Nullary constructor
784
  = ASSERT( isNullaryRepDataCon con )
785
    return (unitOL (PUSH_G (getName (dataConWorkId con))))
786
787
        -- Instead of doing a PACK, which would allocate a fresh
        -- copy of this constructor, use the single shared version.
788

789
790
791
792
793
mkConAppCode orig_d _ p con args_r_to_l =
    ASSERT( args_r_to_l `lengthIs` dataConRepArity con ) app_code
  where
    app_code = do
        dflags <- getDynFlags
794

795
796
797
798
799
800
801
802
        -- The args are initially in reverse order, but mkVirtHeapOffsets
        -- expects them to be left-to-right.
        let non_voids =
                [ NonVoid (prim_rep, arg)
                | arg <- reverse args_r_to_l
                , let prim_rep = atomPrimRep arg
                , not (isVoidRep prim_rep)
                ]
803
            (_, _, args_offsets) =
Simon Marlow's avatar
Simon Marlow committed
804
                mkVirtHeapOffsetsWithPadding dflags StdHeader non_voids
805

806
807
            do_pushery !d (arg : args) = do
                (push, arg_bytes) <- case arg of
Michal Terepeta's avatar
Michal Terepeta committed
808
                    (Padding l _) -> return $! pushPadding l
809
                    (FieldOff a _) -> pushConstrAtom d p (fromNonVoid a)
810
811
812
813
814
815
816
817
                more_push_code <- do_pushery (d + arg_bytes) args
                return (push `appOL` more_push_code)
            do_pushery !d [] = do
                let !n_arg_words = trunc16W $ bytesToWords dflags (d - orig_d)
                return (unitOL (PACK con n_arg_words))

        -- Push on the stack in the reverse order.
        do_pushery orig_d (reverse args_offsets)
818

819
820
821
822
823
824
825
826
827

-- -----------------------------------------------------------------------------
-- Returning an unboxed tuple with one non-void component (the only
-- case we can handle).
--
-- Remember, we don't want to *evaluate* the component that is being
-- returned, even if it is a pointed type.  We always just return.

unboxedTupleReturn
828
    :: StackDepth -> Sequel -> BCEnv -> AnnExpr' Id DVarSet -> BcM BCInstrList
829
unboxedTupleReturn d s p arg = returnUnboxedAtom d s p arg (atomRep arg)
830
831
832
833
834

-- -----------------------------------------------------------------------------
-- Generate code for a tail-call

doTailCall
835
836
837
838
839
840
841
    :: StackDepth
    -> Sequel
    -> BCEnv
    -> Id
    -> [AnnExpr' Id DVarSet]
    -> BcM BCInstrList
doTailCall init_d s p fn args = do_pushes init_d args (map atomRep args)
842
  where
843
  do_pushes !d [] reps = do
844
        ASSERT( null reps ) return ()
845
        (push_fn, sz) <- pushAtom d p (AnnVar fn)
846
847
848
849
850
        dflags <- getDynFlags
        ASSERT( sz == wordSize dflags ) return ()
        let slide = mkSlideB dflags (d - init_d + wordSize dflags) (init_d - s)
        return (push_fn `appOL` (slide `appOL` unitOL ENTER))
  do_pushes !d args reps = do
851
      let (push_apply, n, rest_of_reps) = findPushSeq reps
852
          (these_args, rest_of_args) = splitAt n args
853
      (next_d, push_code) <- push_seq d these_args
854
855
      dflags <- getDynFlags
      instrs <- do_pushes (next_d + wordSize dflags) rest_of_args rest_of_reps
856
      --                          ^^^ for the PUSH_APPLY_ instruction
Simon Marlow's avatar