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 )
50 import CoreUnfold ( isCompulsoryUnfolding )
51 import PprCore () -- Instances
52 import CostCentre ( CostCentreStack, subsumedCCS )
53 import Name ( isLocallyDefined )
54 import OccName ( UserFS )
57 import qualified Subst
58 import Subst ( Subst, mkSubst, substEnv,
59 InScopeSet, substInScope, isInScope
62 import UniqSupply ( uniqsFromSupply, uniqFromSupply, splitUniqSupply,
66 import CmdLineOpts ( SimplifierSwitch(..), SwitchResult(..),
67 opt_PprStyle_Debug, opt_HistorySize, opt_D_dump_simpl_stats,
70 import Unique ( Unique )
71 import Maybes ( expectJust )
72 import Util ( zipWithEqual )
75 infixr 0 `thenSmpl`, `thenSmpl_`
78 %************************************************************************
80 \subsection[Simplify-types]{Type declarations}
82 %************************************************************************
85 type InBinder = CoreBndr
86 type InId = Id -- Not yet cloned
87 type InType = Type -- Ditto
88 type InBind = CoreBind
89 type InExpr = CoreExpr
93 type OutBinder = CoreBndr
94 type OutId = Id -- Cloned
95 type OutType = Type -- Cloned
96 type OutBind = CoreBind
97 type OutExpr = CoreExpr
101 type SwitchChecker = SimplifierSwitch -> SwitchResult
103 type OutExprStuff = OutStuff (InScopeSet, OutExpr)
104 type OutStuff a = ([OutBind], a)
105 -- We return something equivalent to (let b in e), but
106 -- in pieces to avoid the quadratic blowup when floating
107 -- incrementally. Comments just before simplExprB in Simplify.lhs
111 %************************************************************************
113 \subsection{Monad plumbing}
115 %************************************************************************
117 For the simplifier monad, we want to {\em thread} a unique supply and a counter.
118 (Command-line switches move around through the explicitly-passed SimplEnv.)
121 type SimplM result -- We thread the unique supply because
122 = SimplEnv -- constantly splitting it is rather expensive
125 -> (result, UniqSupply, SimplCount)
129 seChkr :: SwitchChecker,
130 seCC :: CostCentreStack, -- The enclosing CCS (when profiling)
131 seBlackList :: Id -> Bool, -- True => don't inline this Id
132 seSubst :: Subst -- The current substitution
134 -- The range of the substitution is OutType and OutExpr resp
136 -- The substitution is idempotent
137 -- It *must* be applied; things in its domain simply aren't
138 -- bound in the result.
140 -- The substitution usually maps an Id to its clone,
141 -- but if the orig defn is a let-binding, and
142 -- the RHS of the let simplifies to an atom,
143 -- we just add the binding to the substitution and elide the let.
145 -- The in-scope part of Subst includes *all* in-scope TyVars and Ids
146 -- The elements of the set may have better IdInfo than the
147 -- occurrences of in-scope Ids, and (more important) they will
148 -- have a correctly-substituted type. So we use a lookup in this
149 -- set to replace occurrences
153 initSmpl :: SwitchChecker
154 -> UniqSupply -- No init count; set to 0
155 -> VarSet -- In scope (usually empty, but useful for nested calls)
156 -> (Id -> Bool) -- Black-list function
160 initSmpl chkr us in_scope black_list m
161 = case m (emptySimplEnv chkr in_scope black_list) us zeroSimplCount of
162 (result, _, count) -> (result, count)
165 {-# INLINE thenSmpl #-}
166 {-# INLINE thenSmpl_ #-}
167 {-# INLINE returnSmpl #-}
169 returnSmpl :: a -> SimplM a
170 returnSmpl e env us sc = (e, us, sc)
172 thenSmpl :: SimplM a -> (a -> SimplM b) -> SimplM b
173 thenSmpl_ :: SimplM a -> SimplM b -> SimplM b
175 thenSmpl m k env us0 sc0
176 = case (m env us0 sc0) of
177 (m_result, us1, sc1) -> k m_result env us1 sc1
179 thenSmpl_ m k env us0 sc0
180 = case (m env us0 sc0) of
181 (_, us1, sc1) -> k env us1 sc1
186 mapSmpl :: (a -> SimplM b) -> [a] -> SimplM [b]
187 mapAndUnzipSmpl :: (a -> SimplM (b, c)) -> [a] -> SimplM ([b],[c])
189 mapSmpl f [] = returnSmpl []
191 = f x `thenSmpl` \ x' ->
192 mapSmpl f xs `thenSmpl` \ xs' ->
195 mapAndUnzipSmpl f [] = returnSmpl ([],[])
196 mapAndUnzipSmpl f (x:xs)
197 = f x `thenSmpl` \ (r1, r2) ->
198 mapAndUnzipSmpl f xs `thenSmpl` \ (rs1, rs2) ->
199 returnSmpl (r1:rs1, r2:rs2)
201 mapAccumLSmpl f acc [] = returnSmpl (acc, [])
202 mapAccumLSmpl f acc (x:xs) = f acc x `thenSmpl` \ (acc', x') ->
203 mapAccumLSmpl f acc' xs `thenSmpl` \ (acc'', xs') ->
204 returnSmpl (acc'', x':xs')
208 %************************************************************************
210 \subsection{The unique supply}
212 %************************************************************************
215 getUniqueSmpl :: SimplM Unique
216 getUniqueSmpl env us sc = case splitUniqSupply us of
217 (us1, us2) -> (uniqFromSupply us1, us2, sc)
219 getUniquesSmpl :: Int -> SimplM [Unique]
220 getUniquesSmpl n env us sc = case splitUniqSupply us of
221 (us1, us2) -> (uniqsFromSupply n us1, us2, sc)
225 %************************************************************************
227 \subsection{Counting up what we've done}
229 %************************************************************************
232 getSimplCount :: SimplM SimplCount
233 getSimplCount env us sc = (sc, us, sc)
235 tick :: Tick -> SimplM ()
236 tick t env us sc = sc' `seq` ((), us, sc')
240 freeTick :: Tick -> SimplM ()
241 -- Record a tick, but don't add to the total tick count, which is
242 -- used to decide when nothing further has happened
243 freeTick t env us sc = sc' `seq` ((), us, sc')
245 sc' = doFreeTick t sc
249 verboseSimplStats = opt_PprStyle_Debug -- For now, anyway
251 zeroSimplCount :: SimplCount
252 isZeroSimplCount :: SimplCount -> Bool
253 pprSimplCount :: SimplCount -> SDoc
254 doTick, doFreeTick :: Tick -> SimplCount -> SimplCount
255 plusSimplCount :: SimplCount -> SimplCount -> SimplCount
259 data SimplCount = VerySimplZero -- These two are used when
260 | VerySimplNonZero -- we are only interested in
264 ticks :: !Int, -- Total ticks
265 details :: !TickCounts, -- How many of each type
267 log1 :: [Tick], -- Last N events; <= opt_HistorySize
268 log2 :: [Tick] -- Last opt_HistorySize events before that
271 type TickCounts = FiniteMap Tick Int
273 zeroSimplCount -- This is where we decide whether to do
274 -- the VerySimpl version or the full-stats version
275 | opt_D_dump_simpl_stats = SimplCount {ticks = 0, details = emptyFM,
276 n_log = 0, log1 = [], log2 = []}
277 | otherwise = VerySimplZero
279 isZeroSimplCount VerySimplZero = True
280 isZeroSimplCount (SimplCount { ticks = 0 }) = True
281 isZeroSimplCount other = False
283 doFreeTick tick sc@SimplCount { details = dts }
284 = dts' `seqFM` sc { details = dts' }
286 dts' = dts `addTick` tick
287 doFreeTick tick sc = sc
289 -- Gross hack to persuade GHC 3.03 to do this important seq
290 seqFM fm x | isEmptyFM fm = x
293 doTick tick sc@SimplCount { ticks = tks, details = dts, n_log = nl, log1 = l1, log2 = l2 }
294 | nl >= opt_HistorySize = sc1 { n_log = 1, log1 = [tick], log2 = l1 }
295 | otherwise = sc1 { n_log = nl+1, log1 = tick : l1 }
297 sc1 = sc { ticks = tks+1, details = dts `addTick` tick }
299 doTick tick sc = VerySimplNonZero -- The very simple case
302 -- Don't use plusFM_C because that's lazy, and we want to
303 -- be pretty strict here!
304 addTick :: TickCounts -> Tick -> TickCounts
305 addTick fm tick = case lookupFM fm tick of
306 Nothing -> addToFM fm tick 1
307 Just n -> n1 `seq` addToFM fm tick n1
312 plusSimplCount sc1@(SimplCount { ticks = tks1, details = dts1 })
313 sc2@(SimplCount { ticks = tks2, details = dts2 })
314 = log_base { ticks = tks1 + tks2, details = plusFM_C (+) dts1 dts2 }
316 -- A hackish way of getting recent log info
317 log_base | null (log1 sc2) = sc1 -- Nothing at all in sc2
318 | null (log2 sc2) = sc2 { log2 = log1 sc1 }
321 plusSimplCount VerySimplZero VerySimplZero = VerySimplZero
322 plusSimplCount sc1 sc2 = VerySimplNonZero
324 pprSimplCount VerySimplZero = ptext SLIT("Total ticks: ZERO!")
325 pprSimplCount VerySimplNonZero = ptext SLIT("Total ticks: NON-ZERO!")
326 pprSimplCount (SimplCount { ticks = tks, details = dts, log1 = l1, log2 = l2 })
327 = vcat [ptext SLIT("Total ticks: ") <+> int tks,
329 pprTickCounts (fmToList dts),
330 if verboseSimplStats then
332 ptext SLIT("Log (most recent first)"),
333 nest 4 (vcat (map ppr l1) $$ vcat (map ppr l2))]
337 pprTickCounts :: [(Tick,Int)] -> SDoc
338 pprTickCounts [] = empty
339 pprTickCounts ((tick1,n1):ticks)
340 = vcat [int tot_n <+> text (tickString tick1),
341 pprTCDetails real_these,
345 tick1_tag = tickToTag tick1
346 (these, others) = span same_tick ticks
347 real_these = (tick1,n1):these
348 same_tick (tick2,_) = tickToTag tick2 == tick1_tag
349 tot_n = sum [n | (_,n) <- real_these]
351 pprTCDetails ticks@((tick,_):_)
352 | verboseSimplStats || isRuleFired tick
353 = nest 4 (vcat [int n <+> pprTickCts tick | (tick,n) <- ticks])
358 %************************************************************************
362 %************************************************************************
366 = PreInlineUnconditionally Id
367 | PostInlineUnconditionally Id
370 | RuleFired FAST_STRING -- Rule name
372 | LetFloatFromLet Id -- Thing floated out
373 | EtaExpansion Id -- LHS binder
374 | EtaReduction Id -- Binder on outer lambda
375 | BetaReduction Id -- Lambda binder
378 | CaseOfCase Id -- Bndr on *inner* case
379 | KnownBranch Id -- Case binder
380 | CaseMerge Id -- Binder on outer case
381 | CaseElim Id -- Case binder
382 | CaseIdentity Id -- Case binder
383 | FillInCaseDefault Id -- Case binder
386 | SimplifierDone -- Ticked at each iteration of the simplifier
388 isRuleFired (RuleFired _) = True
389 isRuleFired other = False
391 instance Outputable Tick where
392 ppr tick = text (tickString tick) <+> pprTickCts tick
394 instance Eq Tick where
395 a == b = case a `cmpTick` b of { EQ -> True; other -> False }
397 instance Ord Tick where
400 tickToTag :: Tick -> Int
401 tickToTag (PreInlineUnconditionally _) = 0
402 tickToTag (PostInlineUnconditionally _) = 1
403 tickToTag (UnfoldingDone _) = 2
404 tickToTag (RuleFired _) = 3
405 tickToTag (LetFloatFromLet _) = 4
406 tickToTag (EtaExpansion _) = 5
407 tickToTag (EtaReduction _) = 6
408 tickToTag (BetaReduction _) = 7
409 tickToTag (CaseOfCase _) = 8
410 tickToTag (KnownBranch _) = 9
411 tickToTag (CaseMerge _) = 10
412 tickToTag (CaseElim _) = 11
413 tickToTag (CaseIdentity _) = 12
414 tickToTag (FillInCaseDefault _) = 13
415 tickToTag BottomFound = 14
416 tickToTag SimplifierDone = 16
418 tickString :: Tick -> String
419 tickString (PreInlineUnconditionally _) = "PreInlineUnconditionally"
420 tickString (PostInlineUnconditionally _)= "PostInlineUnconditionally"
421 tickString (UnfoldingDone _) = "UnfoldingDone"
422 tickString (RuleFired _) = "RuleFired"
423 tickString (LetFloatFromLet _) = "LetFloatFromLet"
424 tickString (EtaExpansion _) = "EtaExpansion"
425 tickString (EtaReduction _) = "EtaReduction"
426 tickString (BetaReduction _) = "BetaReduction"
427 tickString (CaseOfCase _) = "CaseOfCase"
428 tickString (KnownBranch _) = "KnownBranch"
429 tickString (CaseMerge _) = "CaseMerge"
430 tickString (CaseElim _) = "CaseElim"
431 tickString (CaseIdentity _) = "CaseIdentity"
432 tickString (FillInCaseDefault _) = "FillInCaseDefault"
433 tickString BottomFound = "BottomFound"
434 tickString SimplifierDone = "SimplifierDone"
436 pprTickCts :: Tick -> SDoc
437 pprTickCts (PreInlineUnconditionally v) = ppr v
438 pprTickCts (PostInlineUnconditionally v)= ppr v
439 pprTickCts (UnfoldingDone v) = ppr v
440 pprTickCts (RuleFired v) = ppr v
441 pprTickCts (LetFloatFromLet v) = ppr v
442 pprTickCts (EtaExpansion v) = ppr v
443 pprTickCts (EtaReduction v) = ppr v
444 pprTickCts (BetaReduction v) = ppr v
445 pprTickCts (CaseOfCase v) = ppr v
446 pprTickCts (KnownBranch v) = ppr v
447 pprTickCts (CaseMerge v) = ppr v
448 pprTickCts (CaseElim v) = ppr v
449 pprTickCts (CaseIdentity v) = ppr v
450 pprTickCts (FillInCaseDefault v) = ppr v
451 pprTickCts other = empty
453 cmpTick :: Tick -> Tick -> Ordering
454 cmpTick a b = case (tickToTag a `compare` tickToTag b) of
456 EQ | isRuleFired a || verboseSimplStats -> cmpEqTick a b
459 -- Always distinguish RuleFired, so that the stats
460 -- can report them even in non-verbose mode
462 cmpEqTick :: Tick -> Tick -> Ordering
463 cmpEqTick (PreInlineUnconditionally a) (PreInlineUnconditionally b) = a `compare` b
464 cmpEqTick (PostInlineUnconditionally a) (PostInlineUnconditionally b) = a `compare` b
465 cmpEqTick (UnfoldingDone a) (UnfoldingDone b) = a `compare` b
466 cmpEqTick (RuleFired a) (RuleFired b) = a `compare` b
467 cmpEqTick (LetFloatFromLet a) (LetFloatFromLet b) = a `compare` b
468 cmpEqTick (EtaExpansion a) (EtaExpansion b) = a `compare` b
469 cmpEqTick (EtaReduction a) (EtaReduction b) = a `compare` b
470 cmpEqTick (BetaReduction a) (BetaReduction b) = a `compare` b
471 cmpEqTick (CaseOfCase a) (CaseOfCase b) = a `compare` b
472 cmpEqTick (KnownBranch a) (KnownBranch b) = a `compare` b
473 cmpEqTick (CaseMerge a) (CaseMerge b) = a `compare` b
474 cmpEqTick (CaseElim a) (CaseElim b) = a `compare` b
475 cmpEqTick (CaseIdentity a) (CaseIdentity b) = a `compare` b
476 cmpEqTick (FillInCaseDefault a) (FillInCaseDefault b) = a `compare` b
477 cmpEqTick other1 other2 = EQ
481 %************************************************************************
483 \subsubsection{Command-line switches}
485 %************************************************************************
488 getSwitchChecker :: SimplM SwitchChecker
489 getSwitchChecker env us sc = (seChkr env, us, sc)
491 getSimplIntSwitch :: SwitchChecker -> (Int-> SimplifierSwitch) -> Int
492 getSimplIntSwitch chkr switch
493 = expectJust "getSimplIntSwitch" (intSwitchSet chkr switch)
497 @switchOffInlining@ is used to prepare the environment for simplifying
498 the RHS of an Id that's marked with an INLINE pragma. It is going to
499 be inlined wherever they are used, and then all the inlining will take
500 effect. Meanwhile, there isn't much point in doing anything to the
501 as-yet-un-INLINEd rhs. Furthremore, it's very important to switch off
503 (a) not doing so will inline a worker straight back into its wrapper!
505 and (b) Consider the following example
510 in ...g...g...g...g...g...
512 Now, if that's the ONLY occurrence of f, it will be inlined inside g,
513 and thence copied multiple times when g is inlined.
515 Andy disagrees! Example:
516 all xs = foldr (&&) True xs
517 any p = all . map p {-# INLINE any #-}
519 Problem: any won't get deforested, and so if it's exported and
520 the importer doesn't use the inlining, (eg passes it as an arg)
521 then we won't get deforestation at all.
522 We havn't solved this problem yet!
524 We prepare the envt by simply modifying the in_scope_env, which has all the
525 unfolding info. At one point we did it by modifying the chkr so that
526 it said "EssentialUnfoldingsOnly", but that prevented legitmate, and
527 important, simplifications happening in the body of the RHS.
531 We *don't* prevent inlining from happening for identifiers
532 that are marked as IMustBeINLINEd. An example of where
533 doing this is crucial is:
535 class Bar a => Foo a where
541 If `f' needs to peer inside Foo's superclass, Bar, it refers
542 to the appropriate super class selector, which is marked as
543 must-inlineable. We don't generate any code for a superclass
544 selector, so failing to inline it in the RHS of `f' will
545 leave a reference to a non-existent id, with bad consequences.
547 ALSO NOTE that we do all this by modifing the inline-pragma,
548 not by zapping the unfolding. The latter may still be useful for
549 knowing when something is evaluated.
551 June 98 update: I've gone back to dealing with this by adding
552 the EssentialUnfoldingsOnly switch. That doesn't stop essential
553 unfoldings, nor inlineUnconditionally stuff; and the thing's going
554 to be inlined at every call site anyway. Running over the whole
555 environment seems like wild overkill.
558 switchOffInlining :: SimplM a -> SimplM a
559 switchOffInlining m env us sc
560 = m (env { seBlackList = \v -> not (isCompulsoryUnfolding (idUnfolding v)) &&
561 not (isDataConWrapId v) &&
562 ((v `isInScope` subst) || not (isLocallyDefined v))
565 -- Inside inlinings, black list anything that is in scope or imported.
566 -- except for things that must be unfolded (Compulsory)
567 -- and data con wrappers. The latter is a hack, like the one in
568 -- SimplCore.simplRules, to make wrappers inline in rule LHSs. We
569 -- may as well do the same here.
572 old_black_list = seBlackList env
576 %************************************************************************
578 \subsubsection{The ``enclosing cost-centre''}
580 %************************************************************************
583 getEnclosingCC :: SimplM CostCentreStack
584 getEnclosingCC env us sc = (seCC env, us, sc)
586 setEnclosingCC :: CostCentreStack -> SimplM a -> SimplM a
587 setEnclosingCC cc m env us sc = m (env { seCC = cc }) us sc
591 %************************************************************************
593 \subsubsection{The @SimplEnv@ type}
595 %************************************************************************
599 emptySimplEnv :: SwitchChecker -> InScopeSet -> (Id -> Bool) -> SimplEnv
601 emptySimplEnv sw_chkr in_scope black_list
602 = SimplEnv { seChkr = sw_chkr, seCC = subsumedCCS,
603 seBlackList = black_list,
604 seSubst = mkSubst in_scope emptySubstEnv }
605 -- The top level "enclosing CC" is "SUBSUMED".
607 getEnv :: SimplM SimplEnv
608 getEnv env us sc = (env, us, sc)
610 setAllExceptInScope :: SimplEnv -> SimplM a -> SimplM a
611 setAllExceptInScope new_env@(SimplEnv {seSubst = new_subst}) m
612 (SimplEnv {seSubst = old_subst}) us sc
613 = m (new_env {seSubst = Subst.setInScope new_subst (substInScope old_subst)}) us sc
615 getSubst :: SimplM Subst
616 getSubst env us sc = (seSubst env, us, sc)
618 getBlackList :: SimplM (Id -> Bool)
619 getBlackList env us sc = (seBlackList env, us, sc)
621 setSubst :: Subst -> SimplM a -> SimplM a
622 setSubst subst m env us sc = m (env {seSubst = subst}) us sc
624 getSubstEnv :: SimplM SubstEnv
625 getSubstEnv env us sc = (substEnv (seSubst env), us, sc)
627 extendInScope :: CoreBndr -> SimplM a -> SimplM a
628 extendInScope v m env@(SimplEnv {seSubst = subst}) us sc
629 = m (env {seSubst = Subst.extendInScope subst v}) us sc
631 extendInScopes :: [CoreBndr] -> SimplM a -> SimplM a
632 extendInScopes vs m env@(SimplEnv {seSubst = subst}) us sc
633 = m (env {seSubst = Subst.extendInScopes subst vs}) us sc
635 getInScope :: SimplM InScopeSet
636 getInScope env us sc = (substInScope (seSubst env), us, sc)
638 setInScope :: InScopeSet -> SimplM a -> SimplM a
639 setInScope in_scope m env@(SimplEnv {seSubst = subst}) us sc
640 = m (env {seSubst = Subst.setInScope subst in_scope}) us sc
642 modifyInScope :: CoreBndr -> CoreBndr -> SimplM a -> SimplM a
643 modifyInScope v v' m env@(SimplEnv {seSubst = subst}) us sc
644 = m (env {seSubst = Subst.modifyInScope subst v v'}) us sc
646 extendSubst :: CoreBndr -> SubstResult -> SimplM a -> SimplM a
647 extendSubst var res m env@(SimplEnv {seSubst = subst}) us sc
648 = m (env { seSubst = Subst.extendSubst subst var res }) us sc
650 extendSubstList :: [CoreBndr] -> [SubstResult] -> SimplM a -> SimplM a
651 extendSubstList vars ress m env@(SimplEnv {seSubst = subst}) us sc
652 = m (env { seSubst = Subst.extendSubstList subst vars ress }) us sc
654 setSubstEnv :: SubstEnv -> SimplM a -> SimplM a
655 setSubstEnv senv m env@(SimplEnv {seSubst = subst}) us sc
656 = m (env {seSubst = Subst.setSubstEnv subst senv}) us sc
658 zapSubstEnv :: SimplM a -> SimplM a
659 zapSubstEnv m env@(SimplEnv {seSubst = subst}) us sc
660 = m (env {seSubst = Subst.zapSubstEnv subst}) us sc
662 getSimplBinderStuff :: SimplM (Subst, UniqSupply)
663 getSimplBinderStuff (SimplEnv {seSubst = subst}) us sc
664 = ((subst, us), us, sc)
666 setSimplBinderStuff :: (Subst, UniqSupply) -> SimplM a -> SimplM a
667 setSimplBinderStuff (subst, us) m env _ sc
668 = m (env {seSubst = subst}) us sc
673 newId :: UserFS -> Type -> (Id -> SimplM a) -> SimplM a
674 -- Extends the in-scope-env too
675 newId fs ty m env@(SimplEnv {seSubst = subst}) us sc
676 = case splitUniqSupply us of
677 (us1, us2) -> m v (env {seSubst = Subst.extendInScope subst v}) us2 sc
679 v = mkSysLocal fs (uniqFromSupply us1) ty
681 newIds :: UserFS -> [Type] -> ([Id] -> SimplM a) -> SimplM a
682 newIds fs tys m env@(SimplEnv {seSubst = subst}) us sc
683 = case splitUniqSupply us of
684 (us1, us2) -> m vs (env {seSubst = Subst.extendInScopes subst vs}) us2 sc
686 vs = zipWithEqual "newIds" (mkSysLocal fs)
687 (uniqsFromSupply (length tys) us1) tys