[project @ 1999-03-02 18:31:51 by sof]
[ghc-hetmet.git] / ghc / compiler / simplCore / SimplCore.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 %
4 \section[SimplCore]{Driver for simplifying @Core@ programs}
5
6 \begin{code}
7 module SimplCore ( core2core ) where
8
9 #include "HsVersions.h"
10
11 import CmdLineOpts      ( CoreToDo(..), SimplifierSwitch(..), 
12                           SwitchResult, switchIsOn,
13                           opt_D_dump_occur_anal,
14                           opt_D_dump_simpl_iterations,
15                           opt_D_simplifier_stats,
16                           opt_D_dump_simpl,
17                           opt_D_verbose_core2core,
18                           opt_D_dump_occur_anal
19                         )
20 import CoreLint         ( beginPass, endPass )
21 import CoreSyn
22 import PprCore          ( pprCoreBindings )
23 import OccurAnal        ( occurAnalyseBinds )
24 import CoreUtils        ( exprIsTrivial, coreExprType )
25 import Simplify         ( simplBind )
26 import SimplUtils       ( etaCoreExpr, findDefault )
27 import SimplMonad
28 import CoreUnfold
29 import Const            ( Con(..), Literal(..), literalType, mkMachInt )
30 import ErrUtils         ( dumpIfSet )
31 import FloatIn          ( floatInwards )
32 import FloatOut         ( floatOutwards )
33 import Id               ( Id, mkSysLocal, mkUserId, isBottomingId,
34                           idType, setIdType, idName, idInfo, idDetails
35                         )
36 import IdInfo           ( InlinePragInfo(..), specInfo, setSpecInfo,
37                           inlinePragInfo, setInlinePragInfo,
38                           setUnfoldingInfo
39                         )
40 import VarEnv
41 import VarSet
42 import Module           ( Module )
43 import Name             ( mkLocalName, tidyOccName, tidyTopName, initTidyOccEnv, isExported,
44                           NamedThing(..), OccName
45                         )
46 import TyCon            ( TyCon, isDataTyCon )
47 import PrimOp           ( PrimOp(..) )
48 import PrelInfo         ( unpackCStringId, unpackCString2Id, addr2IntegerId )
49 import Type             ( Type, splitAlgTyConApp_maybe, 
50                           isUnLiftedType,
51                           tidyType, tidyTypes, tidyTopType, tidyTyVar, tidyTyVars,
52                           Type
53                         )
54 import Class            ( Class, classSelIds )
55 import TysWiredIn       ( smallIntegerDataCon, isIntegerTy )
56 import LiberateCase     ( liberateCase )
57 import SAT              ( doStaticArgs )
58 import Specialise       ( specProgram)
59 import SpecEnv          ( specEnvToList, specEnvFromList )
60 import StrictAnal       ( saWwTopBinds )
61 import Var              ( TyVar, mkId )
62 import Unique           ( Unique, Uniquable(..),
63                           ratioTyConKey, mkUnique, incrUnique, initTidyUniques
64                         )
65 import UniqSupply       ( UniqSupply, splitUniqSupply, uniqFromSupply )
66 import Constants        ( tARGET_MIN_INT, tARGET_MAX_INT )
67 import Util             ( mapAccumL )
68 import SrcLoc           ( noSrcLoc )
69 import Bag
70 import Maybes
71 import IO               ( hPutStr, stderr )
72 import Outputable
73
74 import Ratio            ( numerator, denominator )
75 \end{code}
76
77 \begin{code}
78 core2core :: [CoreToDo]         -- Spec of what core-to-core passes to do
79           -> Module             -- Module name (profiling only)
80           -> [Class]            -- Local classes
81           -> UniqSupply         -- A name supply
82           -> [CoreBind]         -- Input
83           -> IO [CoreBind]      -- Result
84
85 core2core core_todos module_name classes us binds
86   = do
87         let (us1, us2) = splitUniqSupply us
88
89         -- Do the main business
90         processed_binds <- doCorePasses us1 binds core_todos
91
92         -- Do the post-simplification business
93         post_simpl_binds <- doPostSimplification us2 processed_binds
94
95         -- Do the final tidy-up
96         final_binds <- tidyCorePgm module_name classes post_simpl_binds
97
98         -- Return results
99         return final_binds
100
101 doCorePasses us binds []
102   = return binds
103
104 doCorePasses us binds (to_do : to_dos) 
105   = do
106         let (us1, us2) =  splitUniqSupply us
107         binds1         <- doCorePass us1 binds to_do
108         doCorePasses us2 binds1 to_dos
109
110 doCorePass us binds (CoreDoSimplify sw_chkr) = _scc_ "Simplify"       simplifyPgm sw_chkr us binds
111 doCorePass us binds CoreLiberateCase         = _scc_ "LiberateCase"   liberateCase binds
112 doCorePass us binds CoreDoFloatInwards       = _scc_ "FloatInwards"   floatInwards binds
113 doCorePass us binds CoreDoFullLaziness       = _scc_ "CoreFloating"   floatOutwards us binds
114 doCorePass us binds CoreDoStaticArgs         = _scc_ "CoreStaticArgs" doStaticArgs us binds
115 doCorePass us binds CoreDoStrictness         = _scc_ "CoreStranal"    saWwTopBinds us binds
116 doCorePass us binds CoreDoSpecialising       = _scc_ "Specialise"     specProgram us binds
117 \end{code}
118
119
120 %************************************************************************
121 %*                                                                      *
122 \subsection{The driver for the simplifier}
123 %*                                                                      *
124 %************************************************************************
125
126 \begin{code}
127 simplifyPgm :: (SimplifierSwitch -> SwitchResult)
128             -> UniqSupply
129             -> [CoreBind]               -- Input
130             -> IO [CoreBind]            -- New bindings
131
132 simplifyPgm sw_chkr us binds
133   = do {
134         beginPass "Simplify";
135
136         (termination_msg, it_count, counts, binds') <- iteration us 1 zeroSimplCount binds;
137
138         dumpIfSet opt_D_simplifier_stats "Simplifier statistics"
139                   (vcat [text termination_msg <+> text "after" <+> ppr it_count <+> text "iterations",
140                          text "",
141                          pprSimplCount counts]);
142
143         endPass "Simplify" 
144                 (opt_D_verbose_core2core && not opt_D_dump_simpl_iterations)
145                 binds'
146     }
147   where
148     max_iterations      = getSimplIntSwitch sw_chkr MaxSimplifierIterations
149     simpl_switch_is_on  = switchIsOn sw_chkr
150
151     core_iter_dump binds | opt_D_verbose_core2core = pprCoreBindings binds
152                          | otherwise               = empty
153
154     iteration us iteration_no counts binds
155       = do {
156                 -- Occurrence analysis
157            let { tagged_binds = _scc_ "OccAnal" occurAnalyseBinds simpl_switch_is_on binds };
158            dumpIfSet opt_D_dump_occur_anal "Occurrence analysis"
159                      (pprCoreBindings tagged_binds);
160
161                 -- Simplify
162            let { (binds', counts') = initSmpl sw_chkr us1 (simplTopBinds tagged_binds);
163                  all_counts        = counts `plusSimplCount` counts'
164                } ;
165
166                 -- Stop if nothing happened; don't dump output
167            if isZeroSimplCount counts' then
168                 return ("Simplifier reached fixed point", iteration_no, all_counts, binds')
169            else do {
170
171                 -- Dump the result of this iteration
172            dumpIfSet opt_D_dump_simpl_iterations
173                      ("Simplifier iteration " ++ show iteration_no 
174                       ++ " out of " ++ show max_iterations)
175                      (vcat[pprSimplCount counts',
176                            text "",
177                            core_iter_dump binds']) ;
178
179                 -- Stop if we've run out of iterations
180            if iteration_no == max_iterations then
181                 do {
182                     if  max_iterations > 1 then
183                             hPutStr stderr ("NOTE: Simplifier still going after " ++ 
184                                     show max_iterations ++ 
185                                     " iterations; bailing out.\n")
186                     else return ();
187
188                     return ("Simplifier baled out", iteration_no, all_counts, binds')
189                 }
190
191                 -- Else loop
192            else iteration us2 (iteration_no + 1) all_counts binds'
193         }  }
194       where
195           (us1, us2) = splitUniqSupply us
196
197
198 simplTopBinds binds = go binds          `thenSmpl` \ (binds', _) ->
199                       returnSmpl binds'
200                     where
201                       go []              = returnSmpl ([], ())
202                       go (bind1 : binds) = simplBind bind1 (go binds)
203 \end{code}
204
205
206 %************************************************************************
207 %*                                                                      *
208 \subsection{Tidying core}
209 %*                                                                      *
210 %************************************************************************
211
212 Several tasks are done by @tidyCorePgm@
213
214 1.  Make certain top-level bindings into Globals. The point is that 
215     Global things get externally-visible labels at code generation
216     time
217
218
219 2. Give all binders a nice print-name.  Their uniques aren't changed;
220    rather we give them lexically unique occ-names, so that we can
221    safely print the OccNae only in the interface file.  [Bad idea to
222    change the uniques, because the code generator makes global labels
223    from the uniques for local thunks etc.]
224
225
226 \begin{code}
227 tidyCorePgm :: Module -> [Class] -> [CoreBind] -> IO [CoreBind]
228 tidyCorePgm mod local_classes binds_in
229   = do
230         beginPass "Tidy Core"
231         let (_, binds_out) = mapAccumL (tidyBind (Just mod)) init_tidy_env binds_in
232         endPass "Tidy Core" (opt_D_dump_simpl || opt_D_verbose_core2core) binds_out
233   where
234         -- Make sure to avoid the names of class operations
235         -- They don't have top-level bindings, so we won't see them
236         -- in binds_in; so we must initialise the tidy_env appropriately
237         --
238         -- We also make sure to avoid any exported binders.  Consider
239         --      f{-u1-} = 1     -- Local decl
240         --      ...
241         --      f{-u2-} = 2     -- Exported decl
242         --
243         -- The second exported decl must 'get' the name 'f', so we
244         -- have to put 'f' in the avoids list before we get to the first
245         -- decl.  Name.tidyName then does a no-op on exported binders.
246     init_tidy_env = (initTidyOccEnv avoids, emptyVarEnv)
247     avoids        = [getOccName sel_id | cls <- local_classes,
248                                          sel_id <- classSelIds cls]
249                     ++
250                     [getOccName bndr | bind <- binds_in,
251                                        bndr <- bindersOf bind,
252                                        isExported bndr]
253
254 tidyBind :: Maybe Module                -- (Just m) for top level, Nothing for nested
255          -> TidyEnv
256          -> CoreBind
257          -> (TidyEnv, CoreBind)
258 tidyBind maybe_mod env (NonRec bndr rhs)
259   = let
260         (env', bndr') = tidyBndr maybe_mod env bndr
261         rhs'          = tidyExpr env rhs
262     in
263     (env', NonRec bndr' rhs')
264
265 tidyBind maybe_mod env (Rec pairs)
266   = let
267         -- We use env' when tidying the rhss
268         -- When tidying the binder itself we may tidy it's
269         -- specialisations; if any of these mention other binders
270         -- in the group we should really feed env' to them too;
271         -- but that seems (a) unlikely and (b) a bit tiresome.
272         -- So I left it out for now
273
274         (bndrs, rhss)  = unzip pairs
275         (env', bndrs') = mapAccumL (tidyBndr maybe_mod) env bndrs
276         rhss'          = map (tidyExpr env') rhss
277   in
278   (env', Rec (zip bndrs' rhss'))
279
280 tidyExpr env (Type ty)       = Type (tidyType env ty)
281 tidyExpr env (Con con args)  = Con con (map (tidyExpr env) args)
282 tidyExpr env (App f a)       = App (tidyExpr env f) (tidyExpr env a)
283 tidyExpr env (Note n e)      = Note (tidyNote env n) (tidyExpr env e)
284
285 tidyExpr env (Let b e)       = Let b' (tidyExpr env' e)
286                              where
287                                (env', b') = tidyBind Nothing env b
288
289 tidyExpr env (Case e b alts) = Case (tidyExpr env e) b' (map (tidyAlt env') alts)
290                              where
291                                (env', b') = tidyNestedBndr env b
292
293 tidyExpr env (Var v)         = case lookupVarEnv var_env v of
294                                   Just v' -> Var v'
295                                   Nothing -> Var v
296                              where
297                                (_, var_env) = env
298
299 tidyExpr env (Lam b e)       = Lam b' (tidyExpr env' e)
300                              where
301                                (env', b') = tidyNestedBndr env b
302
303 tidyAlt env (con, vs, rhs)   = (con, vs', tidyExpr env' rhs)
304                              where
305                                (env', vs') = mapAccumL tidyNestedBndr env vs
306
307 tidyNote env (Coerce t1 t2)  = Coerce (tidyType env t1) (tidyType env t2)
308
309 tidyNote env note            = note
310 \end{code}
311
312 \begin{code}
313 tidyBndr (Just mod) env id  = tidyTopBndr mod env id
314 tidyBndr Nothing    env var = tidyNestedBndr  env var
315
316 tidyNestedBndr env tyvar
317   | isTyVar tyvar
318   = tidyTyVar env tyvar
319
320 tidyNestedBndr env@(tidy_env, var_env) id
321   =     -- Non-top-level variables
322     let 
323         -- Give the Id a fresh print-name, *and* rename its type
324         -- The SrcLoc isn't important now, though we could extract it from the Id
325         name'             = mkLocalName (getUnique id) occ' noSrcLoc
326         (tidy_env', occ') = tidyOccName tidy_env (getOccName id)
327         ty'               = tidyType env (idType id)
328         id'               = mkUserId name' ty'
329                         -- NB: This throws away the IdInfo of the Id, which we
330                         -- no longer need.  That means we don't need to
331                         -- run over it with env, nor renumber it.
332         var_env'          = extendVarEnv var_env id id'
333     in
334     ((tidy_env', var_env'), id')
335
336 tidyTopBndr mod env@(tidy_env, var_env) id
337   =     -- Top level variables
338     let
339         (tidy_env', name') = tidyTopName mod tidy_env (idName id)
340         ty'                = tidyTopType (idType id)
341         idinfo'            = tidyIdInfo env (idInfo id)
342         id'                = mkId name' ty' (idDetails id) idinfo'
343         var_env'           = extendVarEnv var_env id id'
344     in
345     ((tidy_env', var_env'), id')
346
347 -- tidyIdInfo does these things:
348 --      a) tidy the specialisation info (if any)
349 --      b) zap a complicated ICanSafelyBeINLINEd pragma,
350 --      c) zap the unfolding
351 -- The latter two are to avoid space leaks
352
353 tidyIdInfo env info
354   = info3
355   where
356     spec_items = specEnvToList (specInfo info)
357     spec_env'  = specEnvFromList (map tidy_item spec_items)
358     info1 | null spec_items = info 
359           | otherwise       = spec_env' `setSpecInfo` info
360                 
361     info2 = case inlinePragInfo info of
362                 ICanSafelyBeINLINEd _ _ -> NoInlinePragInfo `setInlinePragInfo` info1
363                 other                   -> info1
364
365     info3 = noUnfolding `setUnfoldingInfo` info2
366
367     tidy_item (tyvars, tys, rhs)
368         = (tyvars', tidyTypes env' tys, tidyExpr env' rhs)
369         where
370           (env', tyvars') = tidyTyVars env tyvars
371 \end{code}
372
373
374
375 %************************************************************************
376 %*                                                                      *
377 \subsection{PostSimplification}
378 %*                                                                      *
379 %************************************************************************
380
381 Several tasks are performed by the post-simplification pass
382
383 1.  Make the representation of NoRep literals explicit, and
384     float their bindings to the top level.  We only do the floating
385     part for NoRep lits inside a lambda (else no gain).  We need to
386     take care with      let x = "foo" in e
387     that we don't end up with a silly binding
388                         let x = y in e
389     with a floated "foo".  What a bore.
390     
391 2.  *Mangle* cases involving par# in the discriminant.  The unfolding
392     for par in PrelConc.lhs include case expressions with integer
393     results solely to fool the strictness analyzer, the simplifier,
394     and anyone else who might want to fool with the evaluation order.
395     At this point in the compiler our evaluation order is safe.
396     Therefore, we convert expressions of the form:
397
398         case par# e of
399           0# -> rhs
400           _  -> parError#
401     ==>
402         case par# e of
403           _ -> rhs
404
405     fork# isn't handled like this - it's an explicit IO operation now.
406     The reason is that fork# returns a ThreadId#, which gets in the
407     way of the above scheme.  And anyway, IO is the only guaranteed
408     way to enforce ordering  --SDM.
409
410 3.  Mangle cases involving seq# in the discriminant.  Up to this
411     point, seq# will appear like this:
412
413           case seq# e of
414                 0# -> seqError#
415                 _  -> ...
416
417     where the 0# branch is purely to bamboozle the strictness analyser
418     (see case 4 above).  This code comes from an unfolding for 'seq'
419     in Prelude.hs.  We translate this into
420
421           case e of
422                 _ -> ...
423
424     Now that the evaluation order is safe.
425
426 4. Do eta reduction for lambda abstractions appearing in:
427         - the RHS of case alternatives
428         - the body of a let
429
430    These will otherwise turn into local bindings during Core->STG;
431    better to nuke them if possible.  (In general the simplifier does
432    eta expansion not eta reduction, up to this point.  It does eta
433    on the RHSs of bindings but not the RHSs of case alternatives and
434    let bodies)
435
436
437 ------------------- NOT DONE ANY MORE ------------------------
438 [March 98] Indirections are now elimianted by the occurrence analyser
439 1.  Eliminate indirections.  The point here is to transform
440         x_local = E
441         x_exported = x_local
442     ==>
443         x_exported = E
444
445 [Dec 98] [Not now done because there is no penalty in the code
446           generator for using the former form]
447 2.  Convert
448         case x of {...; x' -> ...x'...}
449     ==>
450         case x of {...; _  -> ...x... }
451     See notes in SimplCase.lhs, near simplDefault for the reasoning here.
452 --------------------------------------------------------------
453
454 Special case
455 ~~~~~~~~~~~~
456
457 NOT ENABLED AT THE MOMENT (because the floated Ids are global-ish
458 things, and we need local Ids for non-floated stuff):
459
460   Don't float stuff out of a binder that's marked as a bottoming Id.
461   Reason: it doesn't do any good, and creates more CAFs that increase
462   the size of SRTs.
463
464 eg.
465
466         f = error "string"
467
468 is translated to
469
470         f' = unpackCString# "string"
471         f = error f'
472
473 hence f' and f become CAFs.  Instead, the special case for
474 tidyTopBinding below makes sure this comes out as
475
476         f = let f' = unpackCString# "string" in error f'
477
478 and we can safely ignore f as a CAF, since it can only ever be entered once.
479
480
481
482 \begin{code}
483 doPostSimplification :: UniqSupply -> [CoreBind] -> IO [CoreBind]
484 doPostSimplification us binds_in
485   = do
486         beginPass "Post-simplification pass"
487         let binds_out = initPM us (postSimplTopBinds binds_in)
488         endPass "Post-simplification pass" opt_D_verbose_core2core binds_out
489
490 postSimplTopBinds :: [CoreBind] -> PostM [CoreBind]
491 postSimplTopBinds binds
492   = mapPM postSimplTopBind binds        `thenPM` \ binds' ->
493     returnPM (bagToList (unionManyBags binds'))
494
495 postSimplTopBind :: CoreBind -> PostM (Bag CoreBind)
496 postSimplTopBind (NonRec bndr rhs)
497   | isBottomingId bndr          -- Don't lift out floats for bottoming Ids
498                                 -- See notes above
499   = getFloatsPM (postSimplExpr rhs)     `thenPM` \ (rhs', floats) ->
500     returnPM (unitBag (NonRec bndr (foldrBag Let rhs' floats)))
501
502 postSimplTopBind bind
503   = getFloatsPM (postSimplBind bind)    `thenPM` \ (bind', floats) ->
504     returnPM (floats `snocBag` bind')
505
506 postSimplBind (NonRec bndr rhs)
507   = postSimplExpr rhs           `thenPM` \ rhs' ->
508     returnPM (NonRec bndr rhs')
509
510 postSimplBind (Rec pairs)
511   = mapPM postSimplExpr rhss    `thenPM` \ rhss' ->
512     returnPM (Rec (bndrs `zip` rhss'))
513   where
514     (bndrs, rhss) = unzip pairs
515 \end{code}
516
517
518 Expressions
519 ~~~~~~~~~~~
520 \begin{code}
521 postSimplExpr (Var v)   = returnPM (Var v)
522 postSimplExpr (Type ty) = returnPM (Type ty)
523
524 postSimplExpr (App fun arg)
525   = postSimplExpr fun   `thenPM` \ fun' ->
526     postSimplExpr arg   `thenPM` \ arg' ->
527     returnPM (App fun' arg')
528
529 postSimplExpr (Con (Literal lit) args)
530   = ASSERT( null args )
531     litToRep lit        `thenPM` \ (lit_ty, lit_expr) ->
532     getInsideLambda     `thenPM` \ in_lam ->
533     if in_lam && not (exprIsTrivial lit_expr) then
534         -- It must have been a no-rep literal with a
535         -- non-trivial representation; and we're inside a lambda;
536         -- so float it to the top
537         addTopFloat lit_ty lit_expr     `thenPM` \ v ->
538         returnPM (Var v)
539     else
540         returnPM lit_expr
541
542 postSimplExpr (Con con args)
543   = mapPM postSimplExpr args    `thenPM` \ args' ->
544     returnPM (Con con args')
545
546 postSimplExpr (Lam bndr body)
547   = insideLambda bndr           $
548     postSimplExpr body          `thenPM` \ body' ->
549     returnPM (Lam bndr body')
550
551 postSimplExpr (Let bind body)
552   = postSimplBind bind          `thenPM` \ bind' ->
553     postSimplExprEta body       `thenPM` \ body' ->
554     returnPM (Let bind' body')
555
556 postSimplExpr (Note note body)
557   = postSimplExprEta body       `thenPM` \ body' ->
558     returnPM (Note note body')
559
560 -- seq#: see notes above.
561 -- NB: seq# :: forall a. a -> Int#
562 postSimplExpr (Case scrut@(Con (PrimOp SeqOp) [Type ty, e]) bndr alts)
563   = postSimplExpr e                     `thenPM` \ e' ->
564     let 
565         -- The old binder can't have been used, so we
566         -- can gaily re-use it (yuk!)
567         new_bndr = setIdType bndr ty
568     in
569     postSimplExprEta default_rhs        `thenPM` \ rhs' ->
570     returnPM (Case e' new_bndr [(DEFAULT,[],rhs')])
571   where
572     (other_alts, maybe_default)  = findDefault alts
573     Just default_rhs             = maybe_default
574
575 -- par#: see notes above.
576 postSimplExpr (Case scrut@(Con (PrimOp op) args) bndr alts)
577   | funnyParallelOp op && maybeToBool maybe_default
578   = postSimplExpr scrut                 `thenPM` \ scrut' ->
579     postSimplExprEta default_rhs        `thenPM` \ rhs' ->
580     returnPM (Case scrut' bndr [(DEFAULT,[],rhs')])
581   where
582     (other_alts, maybe_default)  = findDefault alts
583     Just default_rhs             = maybe_default
584
585 postSimplExpr (Case scrut case_bndr alts)
586   = postSimplExpr scrut                 `thenPM` \ scrut' ->
587     mapPM ps_alt alts                   `thenPM` \ alts' ->
588     returnPM (Case scrut' case_bndr alts')
589   where
590     ps_alt (con,bndrs,rhs) = postSimplExprEta rhs       `thenPM` \ rhs' ->
591                              returnPM (con, bndrs, rhs')
592
593 postSimplExprEta e = postSimplExpr e    `thenPM` \ e' ->
594                      returnPM (etaCoreExpr e')
595 \end{code}
596
597 \begin{code}
598 funnyParallelOp ParOp  = True
599 funnyParallelOp _      = False
600 \end{code}  
601
602
603 %************************************************************************
604 %*                                                                      *
605 \subsection[coreToStg-lits]{Converting literals}
606 %*                                                                      *
607 %************************************************************************
608
609 Literals: the NoRep kind need to be de-no-rep'd.
610 We always replace them with a simple variable, and float a suitable
611 binding out to the top level.
612
613 \begin{code}
614 litToRep :: Literal -> PostM (Type, CoreExpr)
615
616 litToRep (NoRepStr s ty)
617   = returnPM (ty, rhs)
618   where
619     rhs = if (any is_NUL (_UNPK_ s))
620
621           then   -- Must cater for NULs in literal string
622                 mkApps (Var unpackCString2Id)
623                        [mkLit (MachStr s),
624                         mkLit (mkMachInt (toInteger (_LENGTH_ s)))]
625
626           else  -- No NULs in the string
627                 App (Var unpackCStringId) (mkLit (MachStr s))
628
629     is_NUL c = c == '\0'
630 \end{code}
631
632 If an Integer is small enough (Haskell implementations must support
633 Ints in the range $[-2^29+1, 2^29-1]$), wrap it up in @int2Integer@;
634 otherwise, wrap with @addr2Integer@.
635
636 \begin{code}
637 litToRep (NoRepInteger i integer_ty)
638   = returnPM (integer_ty, rhs)
639   where
640     rhs | i > tARGET_MIN_INT &&         -- Small enough, so start from an Int
641           i < tARGET_MAX_INT
642         = Con (DataCon smallIntegerDataCon) [Con (Literal (mkMachInt i)) []]
643   
644         | otherwise                     -- Big, so start from a string
645         = App (Var addr2IntegerId) (Con (Literal (MachStr (_PK_ (show i)))) [])
646
647
648 litToRep (NoRepRational r rational_ty)
649   = postSimplExpr (mkLit (NoRepInteger (numerator   r) integer_ty))     `thenPM` \ num_arg ->
650     postSimplExpr (mkLit (NoRepInteger (denominator r) integer_ty))     `thenPM` \ denom_arg ->
651     returnPM (rational_ty, mkConApp ratio_data_con [Type integer_ty, num_arg, denom_arg])
652   where
653     (ratio_data_con, integer_ty)
654       = case (splitAlgTyConApp_maybe rational_ty) of
655           Just (tycon, [i_ty], [con])
656             -> ASSERT(isIntegerTy i_ty && getUnique tycon == ratioTyConKey)
657                (con, i_ty)
658
659           _ -> (panic "ratio_data_con", panic "integer_ty")
660
661 litToRep other_lit = returnPM (literalType other_lit, mkLit other_lit)
662 \end{code}
663
664
665 %************************************************************************
666 %*                                                                      *
667 \subsection{The monad}
668 %*                                                                      *
669 %************************************************************************
670
671 \begin{code}
672 type PostM a =  Bool                            -- True <=> inside a *value* lambda
673              -> (UniqSupply, Bag CoreBind)      -- Unique supply and Floats in 
674              -> (a, (UniqSupply, Bag CoreBind))
675
676 initPM :: UniqSupply -> PostM a -> a
677 initPM us m
678   = case m False {- not inside lambda -} (us, emptyBag) of 
679         (result, _) -> result
680
681 returnPM v in_lam usf = (v, usf)
682 thenPM m k in_lam usf = case m in_lam usf of
683                                   (r, usf') -> k r in_lam usf'
684
685 mapPM f []     = returnPM []
686 mapPM f (x:xs) = f x            `thenPM` \ r ->
687                  mapPM f xs     `thenPM` \ rs ->
688                  returnPM (r:rs)
689
690 insideLambda :: CoreBndr -> PostM a -> PostM a
691 insideLambda bndr m in_lam usf | isId bndr = m True   usf
692                                | otherwise = m in_lam usf
693
694 getInsideLambda :: PostM Bool
695 getInsideLambda in_lam usf = (in_lam, usf)
696
697 getFloatsPM :: PostM a -> PostM (a, Bag CoreBind)
698 getFloatsPM m in_lam (us, floats)
699   = let
700         (a, (us', floats')) = m in_lam (us, emptyBag)
701     in
702     ((a, floats'), (us', floats))
703
704 addTopFloat :: Type -> CoreExpr -> PostM Id
705 addTopFloat lit_ty lit_rhs in_lam (us, floats)
706   = let
707         (us1, us2) = splitUniqSupply us
708         uniq       = uniqFromSupply us1
709         lit_id     = mkSysLocal SLIT("lf") uniq lit_ty
710     in
711     (lit_id, (us2, floats `snocBag` NonRec lit_id lit_rhs))
712 \end{code}
713
714