2 % (c) The AQUA Project, Glasgow University, 1993-1998
4 \section[SimplMonad]{The simplifier Monad}
8 InId, InBind, InExpr, InAlt, InArg, InType, InBinder,
9 OutId, OutBind, OutExpr, OutAlt, OutArg, OutType, OutBinder,
10 OutExprStuff, OutStuff,
14 initSmpl, returnSmpl, thenSmpl, thenSmpl_,
15 mapSmpl, mapAndUnzipSmpl, mapAccumLSmpl,
17 -- The inlining black-list
21 getUniqueSmpl, getUniquesSmpl,
27 getSimplCount, zeroSimplCount, pprSimplCount,
28 plusSimplCount, isZeroSimplCount,
31 SwitchChecker, getSwitchChecker, getSimplIntSwitch,
34 getEnclosingCC, setEnclosingCC,
37 getEnv, setAllExceptInScope,
39 getSubstEnv, extendSubst, extendSubstList,
40 getInScope, setInScope, extendInScope, extendInScopes, modifyInScope,
41 setSubstEnv, zapSubstEnv,
42 getSimplBinderStuff, setSimplBinderStuff,
46 #include "HsVersions.h"
48 import Id ( Id, mkSysLocal, idUnfolding, isDataConWrapId )
49 import IdInfo ( InlinePragInfo(..) )
50 import Demand ( Demand )
52 import CoreUnfold ( isCompulsoryUnfolding, isEvaldUnfolding )
53 import PprCore () -- Instances
54 import Rules ( RuleBase )
55 import CostCentre ( CostCentreStack, subsumedCCS )
56 import Name ( isLocallyDefined )
60 import qualified Subst
61 import Subst ( Subst, emptySubst, mkSubst,
63 InScopeSet, substInScope, isInScope
65 import Type ( Type, TyVarSubst, applyTy )
66 import UniqSupply ( uniqsFromSupply, uniqFromSupply, splitUniqSupply,
70 import CmdLineOpts ( SimplifierSwitch(..), SwitchResult(..),
71 opt_PprStyle_Debug, opt_HistorySize, opt_D_dump_simpl_stats,
74 import Unique ( Unique )
75 import Maybes ( expectJust )
76 import Util ( zipWithEqual )
79 infixr 0 `thenSmpl`, `thenSmpl_`
82 %************************************************************************
84 \subsection[Simplify-types]{Type declarations}
86 %************************************************************************
89 type InBinder = CoreBndr
90 type InId = Id -- Not yet cloned
91 type InType = Type -- Ditto
92 type InBind = CoreBind
93 type InExpr = CoreExpr
97 type OutBinder = CoreBndr
98 type OutId = Id -- Cloned
99 type OutType = Type -- Cloned
100 type OutBind = CoreBind
101 type OutExpr = CoreExpr
102 type OutAlt = CoreAlt
103 type OutArg = CoreArg
105 type SwitchChecker = SimplifierSwitch -> SwitchResult
107 type OutExprStuff = OutStuff (InScopeSet, OutExpr)
108 type OutStuff a = ([OutBind], a)
109 -- We return something equivalent to (let b in e), but
110 -- in pieces to avoid the quadratic blowup when floating
111 -- incrementally. Comments just before simplExprB in Simplify.lhs
115 %************************************************************************
117 \subsection{Monad plumbing}
119 %************************************************************************
121 For the simplifier monad, we want to {\em thread} a unique supply and a counter.
122 (Command-line switches move around through the explicitly-passed SimplEnv.)
125 type SimplM result -- We thread the unique supply because
126 = SimplEnv -- constantly splitting it is rather expensive
129 -> (result, UniqSupply, SimplCount)
133 seChkr :: SwitchChecker,
134 seCC :: CostCentreStack, -- The enclosing CCS (when profiling)
135 seBlackList :: Id -> Bool, -- True => don't inline this Id
136 seSubst :: Subst -- The current substitution
138 -- The range of the substitution is OutType and OutExpr resp
140 -- The substitution is idempotent
141 -- It *must* be applied; things in its domain simply aren't
142 -- bound in the result.
144 -- The substitution usually maps an Id to its clone,
145 -- but if the orig defn is a let-binding, and
146 -- the RHS of the let simplifies to an atom,
147 -- we just add the binding to the substitution and elide the let.
149 -- The in-scope part of Subst includes *all* in-scope TyVars and Ids
150 -- The elements of the set may have better IdInfo than the
151 -- occurrences of in-scope Ids, and (more important) they will
152 -- have a correctly-substituted type. So we use a lookup in this
153 -- set to replace occurrences
157 initSmpl :: SwitchChecker
158 -> UniqSupply -- No init count; set to 0
159 -> VarSet -- In scope (usually empty, but useful for nested calls)
160 -> (Id -> Bool) -- Black-list function
164 initSmpl chkr us in_scope black_list m
165 = case m (emptySimplEnv chkr in_scope black_list) us zeroSimplCount of
166 (result, _, count) -> (result, count)
169 {-# INLINE thenSmpl #-}
170 {-# INLINE thenSmpl_ #-}
171 {-# INLINE returnSmpl #-}
173 returnSmpl :: a -> SimplM a
174 returnSmpl e env us sc = (e, us, sc)
176 thenSmpl :: SimplM a -> (a -> SimplM b) -> SimplM b
177 thenSmpl_ :: SimplM a -> SimplM b -> SimplM b
179 thenSmpl m k env us0 sc0
180 = case (m env us0 sc0) of
181 (m_result, us1, sc1) -> k m_result env us1 sc1
183 thenSmpl_ m k env us0 sc0
184 = case (m env us0 sc0) of
185 (_, us1, sc1) -> k env us1 sc1
190 mapSmpl :: (a -> SimplM b) -> [a] -> SimplM [b]
191 mapAndUnzipSmpl :: (a -> SimplM (b, c)) -> [a] -> SimplM ([b],[c])
193 mapSmpl f [] = returnSmpl []
195 = f x `thenSmpl` \ x' ->
196 mapSmpl f xs `thenSmpl` \ xs' ->
199 mapAndUnzipSmpl f [] = returnSmpl ([],[])
200 mapAndUnzipSmpl f (x:xs)
201 = f x `thenSmpl` \ (r1, r2) ->
202 mapAndUnzipSmpl f xs `thenSmpl` \ (rs1, rs2) ->
203 returnSmpl (r1:rs1, r2:rs2)
205 mapAccumLSmpl f acc [] = returnSmpl (acc, [])
206 mapAccumLSmpl f acc (x:xs) = f acc x `thenSmpl` \ (acc', x') ->
207 mapAccumLSmpl f acc' xs `thenSmpl` \ (acc'', xs') ->
208 returnSmpl (acc'', x':xs')
212 %************************************************************************
214 \subsection{The unique supply}
216 %************************************************************************
219 getUniqueSmpl :: SimplM Unique
220 getUniqueSmpl env us sc = case splitUniqSupply us of
221 (us1, us2) -> (uniqFromSupply us1, us2, sc)
223 getUniquesSmpl :: Int -> SimplM [Unique]
224 getUniquesSmpl n env us sc = case splitUniqSupply us of
225 (us1, us2) -> (uniqsFromSupply n us1, us2, sc)
229 %************************************************************************
231 \subsection{Counting up what we've done}
233 %************************************************************************
236 getSimplCount :: SimplM SimplCount
237 getSimplCount env us sc = (sc, us, sc)
239 tick :: Tick -> SimplM ()
240 tick t env us sc = sc' `seq` ((), us, sc')
244 freeTick :: Tick -> SimplM ()
245 -- Record a tick, but don't add to the total tick count, which is
246 -- used to decide when nothing further has happened
247 freeTick t env us sc = sc' `seq` ((), us, sc')
249 sc' = doFreeTick t sc
253 verboseSimplStats = opt_PprStyle_Debug -- For now, anyway
255 zeroSimplCount :: SimplCount
256 isZeroSimplCount :: SimplCount -> Bool
257 pprSimplCount :: SimplCount -> SDoc
258 doTick, doFreeTick :: Tick -> SimplCount -> SimplCount
259 plusSimplCount :: SimplCount -> SimplCount -> SimplCount
263 data SimplCount = VerySimplZero -- These two are used when
264 | VerySimplNonZero -- we are only interested in
268 ticks :: !Int, -- Total ticks
269 details :: !TickCounts, -- How many of each type
271 log1 :: [Tick], -- Last N events; <= opt_HistorySize
272 log2 :: [Tick] -- Last opt_HistorySize events before that
275 type TickCounts = FiniteMap Tick Int
277 zeroSimplCount -- This is where we decide whether to do
278 -- the VerySimpl version or the full-stats version
279 | opt_D_dump_simpl_stats = SimplCount {ticks = 0, details = emptyFM,
280 n_log = 0, log1 = [], log2 = []}
281 | otherwise = VerySimplZero
283 isZeroSimplCount VerySimplZero = True
284 isZeroSimplCount (SimplCount { ticks = 0 }) = True
285 isZeroSimplCount other = False
287 doFreeTick tick sc@SimplCount { details = dts }
288 = dts' `seqFM` sc { details = dts' }
290 dts' = dts `addTick` tick
291 doFreeTick tick sc = sc
293 -- Gross hack to persuade GHC 3.03 to do this important seq
294 seqFM fm x | isEmptyFM fm = x
297 doTick tick sc@SimplCount { ticks = tks, details = dts, n_log = nl, log1 = l1, log2 = l2 }
298 | nl >= opt_HistorySize = sc1 { n_log = 1, log1 = [tick], log2 = l1 }
299 | otherwise = sc1 { n_log = nl+1, log1 = tick : l1 }
301 sc1 = sc { ticks = tks+1, details = dts `addTick` tick }
303 doTick tick sc = VerySimplNonZero -- The very simple case
306 -- Don't use plusFM_C because that's lazy, and we want to
307 -- be pretty strict here!
308 addTick :: TickCounts -> Tick -> TickCounts
309 addTick fm tick = case lookupFM fm tick of
310 Nothing -> addToFM fm tick 1
311 Just n -> n1 `seq` addToFM fm tick n1
316 plusSimplCount sc1@(SimplCount { ticks = tks1, details = dts1 })
317 sc2@(SimplCount { ticks = tks2, details = dts2 })
318 = log_base { ticks = tks1 + tks2, details = plusFM_C (+) dts1 dts2 }
320 -- A hackish way of getting recent log info
321 log_base | null (log1 sc2) = sc1 -- Nothing at all in sc2
322 | null (log2 sc2) = sc2 { log2 = log1 sc1 }
325 plusSimplCount VerySimplZero VerySimplZero = VerySimplZero
326 plusSimplCount sc1 sc2 = VerySimplNonZero
328 pprSimplCount VerySimplZero = ptext SLIT("Total ticks: ZERO!")
329 pprSimplCount VerySimplNonZero = ptext SLIT("Total ticks: NON-ZERO!")
330 pprSimplCount (SimplCount { ticks = tks, details = dts, log1 = l1, log2 = l2 })
331 = vcat [ptext SLIT("Total ticks: ") <+> int tks,
333 pprTickCounts (fmToList dts),
334 if verboseSimplStats then
336 ptext SLIT("Log (most recent first)"),
337 nest 4 (vcat (map ppr l1) $$ vcat (map ppr l2))]
341 pprTickCounts :: [(Tick,Int)] -> SDoc
342 pprTickCounts [] = empty
343 pprTickCounts ((tick1,n1):ticks)
344 = vcat [int tot_n <+> text (tickString tick1),
345 pprTCDetails real_these,
349 tick1_tag = tickToTag tick1
350 (these, others) = span same_tick ticks
351 real_these = (tick1,n1):these
352 same_tick (tick2,_) = tickToTag tick2 == tick1_tag
353 tot_n = sum [n | (_,n) <- real_these]
355 pprTCDetails ticks@((tick,_):_)
356 | verboseSimplStats || isRuleFired tick
357 = nest 4 (vcat [int n <+> pprTickCts tick | (tick,n) <- ticks])
362 %************************************************************************
366 %************************************************************************
370 = PreInlineUnconditionally Id
371 | PostInlineUnconditionally Id
374 | RuleFired FAST_STRING -- Rule name
376 | LetFloatFromLet Id -- Thing floated out
377 | EtaExpansion Id -- LHS binder
378 | EtaReduction Id -- Binder on outer lambda
379 | BetaReduction Id -- Lambda binder
382 | CaseOfCase Id -- Bndr on *inner* case
383 | KnownBranch Id -- Case binder
384 | CaseMerge Id -- Binder on outer case
385 | CaseElim Id -- Case binder
386 | CaseIdentity Id -- Case binder
387 | FillInCaseDefault Id -- Case binder
390 | SimplifierDone -- Ticked at each iteration of the simplifier
392 isRuleFired (RuleFired _) = True
393 isRuleFired other = False
395 instance Outputable Tick where
396 ppr tick = text (tickString tick) <+> pprTickCts tick
398 instance Eq Tick where
399 a == b = case a `cmpTick` b of { EQ -> True; other -> False }
401 instance Ord Tick where
404 tickToTag :: Tick -> Int
405 tickToTag (PreInlineUnconditionally _) = 0
406 tickToTag (PostInlineUnconditionally _) = 1
407 tickToTag (UnfoldingDone _) = 2
408 tickToTag (RuleFired _) = 3
409 tickToTag (LetFloatFromLet _) = 4
410 tickToTag (EtaExpansion _) = 5
411 tickToTag (EtaReduction _) = 6
412 tickToTag (BetaReduction _) = 7
413 tickToTag (CaseOfCase _) = 8
414 tickToTag (KnownBranch _) = 9
415 tickToTag (CaseMerge _) = 10
416 tickToTag (CaseElim _) = 11
417 tickToTag (CaseIdentity _) = 12
418 tickToTag (FillInCaseDefault _) = 13
419 tickToTag BottomFound = 14
420 tickToTag SimplifierDone = 16
422 tickString :: Tick -> String
423 tickString (PreInlineUnconditionally _) = "PreInlineUnconditionally"
424 tickString (PostInlineUnconditionally _)= "PostInlineUnconditionally"
425 tickString (UnfoldingDone _) = "UnfoldingDone"
426 tickString (RuleFired _) = "RuleFired"
427 tickString (LetFloatFromLet _) = "LetFloatFromLet"
428 tickString (EtaExpansion _) = "EtaExpansion"
429 tickString (EtaReduction _) = "EtaReduction"
430 tickString (BetaReduction _) = "BetaReduction"
431 tickString (CaseOfCase _) = "CaseOfCase"
432 tickString (KnownBranch _) = "KnownBranch"
433 tickString (CaseMerge _) = "CaseMerge"
434 tickString (CaseElim _) = "CaseElim"
435 tickString (CaseIdentity _) = "CaseIdentity"
436 tickString (FillInCaseDefault _) = "FillInCaseDefault"
437 tickString BottomFound = "BottomFound"
438 tickString SimplifierDone = "SimplifierDone"
440 pprTickCts :: Tick -> SDoc
441 pprTickCts (PreInlineUnconditionally v) = ppr v
442 pprTickCts (PostInlineUnconditionally v)= ppr v
443 pprTickCts (UnfoldingDone v) = ppr v
444 pprTickCts (RuleFired v) = ppr v
445 pprTickCts (LetFloatFromLet v) = ppr v
446 pprTickCts (EtaExpansion v) = ppr v
447 pprTickCts (EtaReduction v) = ppr v
448 pprTickCts (BetaReduction v) = ppr v
449 pprTickCts (CaseOfCase v) = ppr v
450 pprTickCts (KnownBranch v) = ppr v
451 pprTickCts (CaseMerge v) = ppr v
452 pprTickCts (CaseElim v) = ppr v
453 pprTickCts (CaseIdentity v) = ppr v
454 pprTickCts (FillInCaseDefault v) = ppr v
455 pprTickCts other = empty
457 cmpTick :: Tick -> Tick -> Ordering
458 cmpTick a b = case (tickToTag a `compare` tickToTag b) of
460 EQ | isRuleFired a || verboseSimplStats -> cmpEqTick a b
463 -- Always distinguish RuleFired, so that the stats
464 -- can report them even in non-verbose mode
466 cmpEqTick :: Tick -> Tick -> Ordering
467 cmpEqTick (PreInlineUnconditionally a) (PreInlineUnconditionally b) = a `compare` b
468 cmpEqTick (PostInlineUnconditionally a) (PostInlineUnconditionally b) = a `compare` b
469 cmpEqTick (UnfoldingDone a) (UnfoldingDone b) = a `compare` b
470 cmpEqTick (RuleFired a) (RuleFired b) = a `compare` b
471 cmpEqTick (LetFloatFromLet a) (LetFloatFromLet b) = a `compare` b
472 cmpEqTick (EtaExpansion a) (EtaExpansion b) = a `compare` b
473 cmpEqTick (EtaReduction a) (EtaReduction b) = a `compare` b
474 cmpEqTick (BetaReduction a) (BetaReduction b) = a `compare` b
475 cmpEqTick (CaseOfCase a) (CaseOfCase b) = a `compare` b
476 cmpEqTick (KnownBranch a) (KnownBranch b) = a `compare` b
477 cmpEqTick (CaseMerge a) (CaseMerge b) = a `compare` b
478 cmpEqTick (CaseElim a) (CaseElim b) = a `compare` b
479 cmpEqTick (CaseIdentity a) (CaseIdentity b) = a `compare` b
480 cmpEqTick (FillInCaseDefault a) (FillInCaseDefault b) = a `compare` b
481 cmpEqTick other1 other2 = EQ
485 %************************************************************************
487 \subsubsection{Command-line switches}
489 %************************************************************************
492 getSwitchChecker :: SimplM SwitchChecker
493 getSwitchChecker env us sc = (seChkr env, us, sc)
495 getSimplIntSwitch :: SwitchChecker -> (Int-> SimplifierSwitch) -> Int
496 getSimplIntSwitch chkr switch
497 = expectJust "getSimplIntSwitch" (intSwitchSet chkr switch)
501 @switchOffInlining@ is used to prepare the environment for simplifying
502 the RHS of an Id that's marked with an INLINE pragma. It is going to
503 be inlined wherever they are used, and then all the inlining will take
504 effect. Meanwhile, there isn't much point in doing anything to the
505 as-yet-un-INLINEd rhs. Furthremore, it's very important to switch off
507 (a) not doing so will inline a worker straight back into its wrapper!
509 and (b) Consider the following example
514 in ...g...g...g...g...g...
516 Now, if that's the ONLY occurrence of f, it will be inlined inside g,
517 and thence copied multiple times when g is inlined.
519 Andy disagrees! Example:
520 all xs = foldr (&&) True xs
521 any p = all . map p {-# INLINE any #-}
523 Problem: any won't get deforested, and so if it's exported and
524 the importer doesn't use the inlining, (eg passes it as an arg)
525 then we won't get deforestation at all.
526 We havn't solved this problem yet!
528 We prepare the envt by simply modifying the in_scope_env, which has all the
529 unfolding info. At one point we did it by modifying the chkr so that
530 it said "EssentialUnfoldingsOnly", but that prevented legitmate, and
531 important, simplifications happening in the body of the RHS.
535 We *don't* prevent inlining from happening for identifiers
536 that are marked as IMustBeINLINEd. An example of where
537 doing this is crucial is:
539 class Bar a => Foo a where
545 If `f' needs to peer inside Foo's superclass, Bar, it refers
546 to the appropriate super class selector, which is marked as
547 must-inlineable. We don't generate any code for a superclass
548 selector, so failing to inline it in the RHS of `f' will
549 leave a reference to a non-existent id, with bad consequences.
551 ALSO NOTE that we do all this by modifing the inline-pragma,
552 not by zapping the unfolding. The latter may still be useful for
553 knowing when something is evaluated.
555 June 98 update: I've gone back to dealing with this by adding
556 the EssentialUnfoldingsOnly switch. That doesn't stop essential
557 unfoldings, nor inlineUnconditionally stuff; and the thing's going
558 to be inlined at every call site anyway. Running over the whole
559 environment seems like wild overkill.
562 switchOffInlining :: SimplM a -> SimplM a
563 switchOffInlining m env us sc
564 = m (env { seBlackList = \v -> not (isCompulsoryUnfolding (idUnfolding v)) &&
565 not (isDataConWrapId v) &&
566 ((v `isInScope` subst) || not (isLocallyDefined v))
569 -- Inside inlinings, black list anything that is in scope or imported.
570 -- except for things that must be unfolded (Compulsory)
571 -- and data con wrappers. The latter is a hack, like the one in
572 -- SimplCore.simplRules, to make wrappers inline in rule LHSs. We
573 -- may as well do the same here.
576 old_black_list = seBlackList env
580 %************************************************************************
582 \subsubsection{The ``enclosing cost-centre''}
584 %************************************************************************
587 getEnclosingCC :: SimplM CostCentreStack
588 getEnclosingCC env us sc = (seCC env, us, sc)
590 setEnclosingCC :: CostCentreStack -> SimplM a -> SimplM a
591 setEnclosingCC cc m env us sc = m (env { seCC = cc }) us sc
595 %************************************************************************
597 \subsubsection{The @SimplEnv@ type}
599 %************************************************************************
603 emptySimplEnv :: SwitchChecker -> InScopeSet -> (Id -> Bool) -> SimplEnv
605 emptySimplEnv sw_chkr in_scope black_list
606 = SimplEnv { seChkr = sw_chkr, seCC = subsumedCCS,
607 seBlackList = black_list,
608 seSubst = mkSubst in_scope emptySubstEnv }
609 -- The top level "enclosing CC" is "SUBSUMED".
611 getEnv :: SimplM SimplEnv
612 getEnv env us sc = (env, us, sc)
614 setAllExceptInScope :: SimplEnv -> SimplM a -> SimplM a
615 setAllExceptInScope new_env@(SimplEnv {seSubst = new_subst}) m
616 (SimplEnv {seSubst = old_subst}) us sc
617 = m (new_env {seSubst = Subst.setInScope new_subst (substInScope old_subst)}) us sc
619 getSubst :: SimplM Subst
620 getSubst env us sc = (seSubst env, us, sc)
622 getBlackList :: SimplM (Id -> Bool)
623 getBlackList env us sc = (seBlackList env, us, sc)
625 setSubst :: Subst -> SimplM a -> SimplM a
626 setSubst subst m env us sc = m (env {seSubst = subst}) us sc
628 getSubstEnv :: SimplM SubstEnv
629 getSubstEnv env us sc = (substEnv (seSubst env), us, sc)
631 extendInScope :: CoreBndr -> SimplM a -> SimplM a
632 extendInScope v m env@(SimplEnv {seSubst = subst}) us sc
633 = m (env {seSubst = Subst.extendInScope subst v}) us sc
635 extendInScopes :: [CoreBndr] -> SimplM a -> SimplM a
636 extendInScopes vs m env@(SimplEnv {seSubst = subst}) us sc
637 = m (env {seSubst = Subst.extendInScopes subst vs}) us sc
639 getInScope :: SimplM InScopeSet
640 getInScope env us sc = (substInScope (seSubst env), us, sc)
642 setInScope :: InScopeSet -> SimplM a -> SimplM a
643 setInScope in_scope m env@(SimplEnv {seSubst = subst}) us sc
644 = m (env {seSubst = Subst.setInScope subst in_scope}) us sc
646 modifyInScope :: CoreBndr -> CoreBndr -> SimplM a -> SimplM a
647 modifyInScope v v' m env@(SimplEnv {seSubst = subst}) us sc
648 = m (env {seSubst = Subst.modifyInScope subst v v'}) us sc
650 extendSubst :: CoreBndr -> SubstResult -> SimplM a -> SimplM a
651 extendSubst var res m env@(SimplEnv {seSubst = subst}) us sc
652 = m (env { seSubst = Subst.extendSubst subst var res }) us sc
654 extendSubstList :: [CoreBndr] -> [SubstResult] -> SimplM a -> SimplM a
655 extendSubstList vars ress m env@(SimplEnv {seSubst = subst}) us sc
656 = m (env { seSubst = Subst.extendSubstList subst vars ress }) us sc
658 setSubstEnv :: SubstEnv -> SimplM a -> SimplM a
659 setSubstEnv senv m env@(SimplEnv {seSubst = subst}) us sc
660 = m (env {seSubst = Subst.setSubstEnv subst senv}) us sc
662 zapSubstEnv :: SimplM a -> SimplM a
663 zapSubstEnv m env@(SimplEnv {seSubst = subst}) us sc
664 = m (env {seSubst = Subst.zapSubstEnv subst}) us sc
666 getSimplBinderStuff :: SimplM (Subst, UniqSupply)
667 getSimplBinderStuff (SimplEnv {seSubst = subst}) us sc
668 = ((subst, us), us, sc)
670 setSimplBinderStuff :: (Subst, UniqSupply) -> SimplM a -> SimplM a
671 setSimplBinderStuff (subst, us) m env _ sc
672 = m (env {seSubst = subst}) us sc
677 newId :: Type -> (Id -> SimplM a) -> SimplM a
678 -- Extends the in-scope-env too
679 newId ty m env@(SimplEnv {seSubst = subst}) us sc
680 = case splitUniqSupply us of
681 (us1, us2) -> m v (env {seSubst = Subst.extendInScope subst v}) us2 sc
683 v = mkSysLocal SLIT("s") (uniqFromSupply us1) ty
685 newIds :: [Type] -> ([Id] -> SimplM a) -> SimplM a
686 newIds tys m env@(SimplEnv {seSubst = subst}) us sc
687 = case splitUniqSupply us of
688 (us1, us2) -> m vs (env {seSubst = Subst.extendInScopes subst vs}) us2 sc
690 vs = zipWithEqual "newIds" (mkSysLocal SLIT("s"))
691 (uniqsFromSupply (length tys) us1) tys