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,
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 -- Defined both with and without debugging
256 zeroSimplCount :: SimplCount
257 isZeroSimplCount :: SimplCount -> Bool
258 pprSimplCount :: SimplCount -> SDoc
259 doTick, doFreeTick :: Tick -> SimplCount -> SimplCount
260 plusSimplCount :: SimplCount -> SimplCount -> SimplCount
265 ----------------------------------------------------------
267 ----------------------------------------------------------
268 type SimplCount = Int
272 isZeroSimplCount n = n==0
274 doTick t n = n+1 -- Very basic when not debugging
275 doFreeTick t n = n -- Don't count leaf visits
277 pprSimplCount n = ptext SLIT("Total ticks:") <+> int n
279 plusSimplCount n m = n+m
282 ----------------------------------------------------------
284 ----------------------------------------------------------
286 data SimplCount = SimplCount {
287 ticks :: !Int, -- Total ticks
288 details :: !TickCounts, -- How many of each type
290 log1 :: [Tick], -- Last N events; <= opt_HistorySize
291 log2 :: [Tick] -- Last opt_HistorySize events before that
294 type TickCounts = FiniteMap Tick Int
296 zeroSimplCount = SimplCount {ticks = 0, details = emptyFM,
297 n_log = 0, log1 = [], log2 = []}
299 isZeroSimplCount sc = ticks sc == 0
301 doFreeTick tick sc@SimplCount { details = dts }
302 = dts' `seqFM` sc { details = dts' }
304 dts' = dts `addTick` tick
306 -- Gross hack to persuade GHC 3.03 to do this important seq
307 seqFM fm x | isEmptyFM fm = x
310 doTick tick sc@SimplCount { ticks = tks, details = dts, n_log = nl, log1 = l1, log2 = l2 }
311 | nl >= opt_HistorySize = sc1 { n_log = 1, log1 = [tick], log2 = l1 }
312 | otherwise = sc1 { n_log = nl+1, log1 = tick : l1 }
314 sc1 = sc { ticks = tks+1, details = dts `addTick` tick }
316 -- Don't use plusFM_C because that's lazy, and we want to
317 -- be pretty strict here!
318 addTick :: TickCounts -> Tick -> TickCounts
319 addTick fm tick = case lookupFM fm tick of
320 Nothing -> addToFM fm tick 1
321 Just n -> n1 `seq` addToFM fm tick n1
325 plusSimplCount sc1@(SimplCount { ticks = tks1, details = dts1 })
326 sc2@(SimplCount { ticks = tks2, details = dts2 })
327 = log_base { ticks = tks1 + tks2, details = plusFM_C (+) dts1 dts2 }
329 -- A hackish way of getting recent log info
330 log_base | null (log1 sc2) = sc1 -- Nothing at all in sc2
331 | null (log2 sc2) = sc2 { log2 = log1 sc1 }
335 pprSimplCount (SimplCount { ticks = tks, details = dts, log1 = l1, log2 = l2 })
336 = vcat [ptext SLIT("Total ticks: ") <+> int tks,
338 pprTickCounts (fmToList dts),
339 if verboseSimplStats then
341 ptext SLIT("Log (most recent first)"),
342 nest 4 (vcat (map ppr l1) $$ vcat (map ppr l2))]
346 pprTickCounts :: [(Tick,Int)] -> SDoc
347 pprTickCounts [] = empty
348 pprTickCounts ((tick1,n1):ticks)
349 = vcat [int tot_n <+> text (tickString tick1),
350 pprTCDetails real_these,
354 tick1_tag = tickToTag tick1
355 (these, others) = span same_tick ticks
356 real_these = (tick1,n1):these
357 same_tick (tick2,_) = tickToTag tick2 == tick1_tag
358 tot_n = sum [n | (_,n) <- real_these]
360 pprTCDetails ticks@((tick,_):_)
361 | verboseSimplStats || isRuleFired tick
362 = nest 4 (vcat [int n <+> pprTickCts tick | (tick,n) <- ticks])
368 %************************************************************************
372 %************************************************************************
376 = PreInlineUnconditionally Id
377 | PostInlineUnconditionally Id
380 | RuleFired FAST_STRING -- Rule name
382 | LetFloatFromLet Id -- Thing floated out
383 | EtaExpansion Id -- LHS binder
384 | EtaReduction Id -- Binder on outer lambda
385 | BetaReduction Id -- Lambda binder
388 | CaseOfCase Id -- Bndr on *inner* case
389 | KnownBranch Id -- Case binder
390 | CaseMerge Id -- Binder on outer case
391 | CaseElim Id -- Case binder
392 | CaseIdentity Id -- Case binder
393 | FillInCaseDefault Id -- Case binder
396 | SimplifierDone -- Ticked at each iteration of the simplifier
398 isRuleFired (RuleFired _) = True
399 isRuleFired other = False
401 instance Outputable Tick where
402 ppr tick = text (tickString tick) <+> pprTickCts tick
404 instance Eq Tick where
405 a == b = case a `cmpTick` b of { EQ -> True; other -> False }
407 instance Ord Tick where
410 tickToTag :: Tick -> Int
411 tickToTag (PreInlineUnconditionally _) = 0
412 tickToTag (PostInlineUnconditionally _) = 1
413 tickToTag (UnfoldingDone _) = 2
414 tickToTag (RuleFired _) = 3
415 tickToTag (LetFloatFromLet _) = 4
416 tickToTag (EtaExpansion _) = 5
417 tickToTag (EtaReduction _) = 6
418 tickToTag (BetaReduction _) = 7
419 tickToTag (CaseOfCase _) = 8
420 tickToTag (KnownBranch _) = 9
421 tickToTag (CaseMerge _) = 10
422 tickToTag (CaseElim _) = 11
423 tickToTag (CaseIdentity _) = 12
424 tickToTag (FillInCaseDefault _) = 13
425 tickToTag BottomFound = 14
426 tickToTag SimplifierDone = 16
428 tickString :: Tick -> String
429 tickString (PreInlineUnconditionally _) = "PreInlineUnconditionally"
430 tickString (PostInlineUnconditionally _)= "PostInlineUnconditionally"
431 tickString (UnfoldingDone _) = "UnfoldingDone"
432 tickString (RuleFired _) = "RuleFired"
433 tickString (LetFloatFromLet _) = "LetFloatFromLet"
434 tickString (EtaExpansion _) = "EtaExpansion"
435 tickString (EtaReduction _) = "EtaReduction"
436 tickString (BetaReduction _) = "BetaReduction"
437 tickString (CaseOfCase _) = "CaseOfCase"
438 tickString (KnownBranch _) = "KnownBranch"
439 tickString (CaseMerge _) = "CaseMerge"
440 tickString (CaseElim _) = "CaseElim"
441 tickString (CaseIdentity _) = "CaseIdentity"
442 tickString (FillInCaseDefault _) = "FillInCaseDefault"
443 tickString BottomFound = "BottomFound"
444 tickString SimplifierDone = "SimplifierDone"
446 pprTickCts :: Tick -> SDoc
447 pprTickCts (PreInlineUnconditionally v) = ppr v
448 pprTickCts (PostInlineUnconditionally v)= ppr v
449 pprTickCts (UnfoldingDone v) = ppr v
450 pprTickCts (RuleFired v) = ppr v
451 pprTickCts (LetFloatFromLet v) = ppr v
452 pprTickCts (EtaExpansion v) = ppr v
453 pprTickCts (EtaReduction v) = ppr v
454 pprTickCts (BetaReduction v) = ppr v
455 pprTickCts (CaseOfCase v) = ppr v
456 pprTickCts (KnownBranch v) = ppr v
457 pprTickCts (CaseMerge v) = ppr v
458 pprTickCts (CaseElim v) = ppr v
459 pprTickCts (CaseIdentity v) = ppr v
460 pprTickCts (FillInCaseDefault v) = ppr v
461 pprTickCts other = empty
463 cmpTick :: Tick -> Tick -> Ordering
464 cmpTick a b = case (tickToTag a `compare` tickToTag b) of
466 EQ | isRuleFired a || verboseSimplStats -> cmpEqTick a b
469 -- Always distinguish RuleFired, so that the stats
470 -- can report them even in non-verbose mode
472 cmpEqTick :: Tick -> Tick -> Ordering
473 cmpEqTick (PreInlineUnconditionally a) (PreInlineUnconditionally b) = a `compare` b
474 cmpEqTick (PostInlineUnconditionally a) (PostInlineUnconditionally b) = a `compare` b
475 cmpEqTick (UnfoldingDone a) (UnfoldingDone b) = a `compare` b
476 cmpEqTick (RuleFired a) (RuleFired b) = a `compare` b
477 cmpEqTick (LetFloatFromLet a) (LetFloatFromLet b) = a `compare` b
478 cmpEqTick (EtaExpansion a) (EtaExpansion b) = a `compare` b
479 cmpEqTick (EtaReduction a) (EtaReduction b) = a `compare` b
480 cmpEqTick (BetaReduction a) (BetaReduction b) = a `compare` b
481 cmpEqTick (CaseOfCase a) (CaseOfCase b) = a `compare` b
482 cmpEqTick (KnownBranch a) (KnownBranch b) = a `compare` b
483 cmpEqTick (CaseMerge a) (CaseMerge b) = a `compare` b
484 cmpEqTick (CaseElim a) (CaseElim b) = a `compare` b
485 cmpEqTick (CaseIdentity a) (CaseIdentity b) = a `compare` b
486 cmpEqTick (FillInCaseDefault a) (FillInCaseDefault b) = a `compare` b
487 cmpEqTick other1 other2 = EQ
491 %************************************************************************
493 \subsubsection{Command-line switches}
495 %************************************************************************
498 getSwitchChecker :: SimplM SwitchChecker
499 getSwitchChecker env us sc = (seChkr env, us, sc)
501 getSimplIntSwitch :: SwitchChecker -> (Int-> SimplifierSwitch) -> Int
502 getSimplIntSwitch chkr switch
503 = expectJust "getSimplIntSwitch" (intSwitchSet chkr switch)
507 @switchOffInlining@ is used to prepare the environment for simplifying
508 the RHS of an Id that's marked with an INLINE pragma. It is going to
509 be inlined wherever they are used, and then all the inlining will take
510 effect. Meanwhile, there isn't much point in doing anything to the
511 as-yet-un-INLINEd rhs. Furthremore, it's very important to switch off
513 (a) not doing so will inline a worker straight back into its wrapper!
515 and (b) Consider the following example
520 in ...g...g...g...g...g...
522 Now, if that's the ONLY occurrence of f, it will be inlined inside g,
523 and thence copied multiple times when g is inlined.
525 Andy disagrees! Example:
526 all xs = foldr (&&) True xs
527 any p = all . map p {-# INLINE any #-}
529 Problem: any won't get deforested, and so if it's exported and
530 the importer doesn't use the inlining, (eg passes it as an arg)
531 then we won't get deforestation at all.
532 We havn't solved this problem yet!
534 We prepare the envt by simply modifying the in_scope_env, which has all the
535 unfolding info. At one point we did it by modifying the chkr so that
536 it said "EssentialUnfoldingsOnly", but that prevented legitmate, and
537 important, simplifications happening in the body of the RHS.
541 We *don't* prevent inlining from happening for identifiers
542 that are marked as IMustBeINLINEd. An example of where
543 doing this is crucial is:
545 class Bar a => Foo a where
551 If `f' needs to peer inside Foo's superclass, Bar, it refers
552 to the appropriate super class selector, which is marked as
553 must-inlineable. We don't generate any code for a superclass
554 selector, so failing to inline it in the RHS of `f' will
555 leave a reference to a non-existent id, with bad consequences.
557 ALSO NOTE that we do all this by modifing the inline-pragma,
558 not by zapping the unfolding. The latter may still be useful for
559 knowing when something is evaluated.
561 June 98 update: I've gone back to dealing with this by adding
562 the EssentialUnfoldingsOnly switch. That doesn't stop essential
563 unfoldings, nor inlineUnconditionally stuff; and the thing's going
564 to be inlined at every call site anyway. Running over the whole
565 environment seems like wild overkill.
568 switchOffInlining :: SimplM a -> SimplM a
569 switchOffInlining m env us sc
570 = m (env { seBlackList = \v -> not (isCompulsoryUnfolding (idUnfolding v)) &&
571 not (isDataConWrapId v) &&
572 ((v `isInScope` subst) || not (isLocallyDefined v))
575 -- Inside inlinings, black list anything that is in scope or imported.
576 -- except for things that must be unfolded (Compulsory)
577 -- and data con wrappers. The latter is a hack, like the one in
578 -- SimplCore.simplRules, to make wrappers inline in rule LHSs. We
579 -- may as well do the same here.
582 old_black_list = seBlackList env
586 %************************************************************************
588 \subsubsection{The ``enclosing cost-centre''}
590 %************************************************************************
593 getEnclosingCC :: SimplM CostCentreStack
594 getEnclosingCC env us sc = (seCC env, us, sc)
596 setEnclosingCC :: CostCentreStack -> SimplM a -> SimplM a
597 setEnclosingCC cc m env us sc = m (env { seCC = cc }) us sc
601 %************************************************************************
603 \subsubsection{The @SimplEnv@ type}
605 %************************************************************************
609 emptySimplEnv :: SwitchChecker -> InScopeSet -> (Id -> Bool) -> SimplEnv
611 emptySimplEnv sw_chkr in_scope black_list
612 = SimplEnv { seChkr = sw_chkr, seCC = subsumedCCS,
613 seBlackList = black_list,
614 seSubst = mkSubst in_scope emptySubstEnv }
615 -- The top level "enclosing CC" is "SUBSUMED".
617 getEnv :: SimplM SimplEnv
618 getEnv env us sc = (env, us, sc)
620 setAllExceptInScope :: SimplEnv -> SimplM a -> SimplM a
621 setAllExceptInScope new_env@(SimplEnv {seSubst = new_subst}) m
622 (SimplEnv {seSubst = old_subst}) us sc
623 = m (new_env {seSubst = Subst.setInScope new_subst (substInScope old_subst)}) us sc
625 getSubst :: SimplM Subst
626 getSubst env us sc = (seSubst env, us, sc)
628 getBlackList :: SimplM (Id -> Bool)
629 getBlackList env us sc = (seBlackList env, us, sc)
631 setSubst :: Subst -> SimplM a -> SimplM a
632 setSubst subst m env us sc = m (env {seSubst = subst}) us sc
634 getSubstEnv :: SimplM SubstEnv
635 getSubstEnv env us sc = (substEnv (seSubst env), us, sc)
637 extendInScope :: CoreBndr -> SimplM a -> SimplM a
638 extendInScope v m env@(SimplEnv {seSubst = subst}) us sc
639 = m (env {seSubst = Subst.extendInScope subst v}) us sc
641 extendInScopes :: [CoreBndr] -> SimplM a -> SimplM a
642 extendInScopes vs m env@(SimplEnv {seSubst = subst}) us sc
643 = m (env {seSubst = Subst.extendInScopes subst vs}) us sc
645 getInScope :: SimplM InScopeSet
646 getInScope env us sc = (substInScope (seSubst env), us, sc)
648 setInScope :: InScopeSet -> SimplM a -> SimplM a
649 setInScope in_scope m env@(SimplEnv {seSubst = subst}) us sc
650 = m (env {seSubst = Subst.setInScope subst in_scope}) us sc
652 modifyInScope :: CoreBndr -> CoreBndr -> SimplM a -> SimplM a
653 modifyInScope v v' m env@(SimplEnv {seSubst = subst}) us sc
654 = m (env {seSubst = Subst.modifyInScope subst v v'}) us sc
656 extendSubst :: CoreBndr -> SubstResult -> SimplM a -> SimplM a
657 extendSubst var res m env@(SimplEnv {seSubst = subst}) us sc
658 = m (env { seSubst = Subst.extendSubst subst var res }) us sc
660 extendSubstList :: [CoreBndr] -> [SubstResult] -> SimplM a -> SimplM a
661 extendSubstList vars ress m env@(SimplEnv {seSubst = subst}) us sc
662 = m (env { seSubst = Subst.extendSubstList subst vars ress }) us sc
664 setSubstEnv :: SubstEnv -> SimplM a -> SimplM a
665 setSubstEnv senv m env@(SimplEnv {seSubst = subst}) us sc
666 = m (env {seSubst = Subst.setSubstEnv subst senv}) us sc
668 zapSubstEnv :: SimplM a -> SimplM a
669 zapSubstEnv m env@(SimplEnv {seSubst = subst}) us sc
670 = m (env {seSubst = Subst.zapSubstEnv subst}) us sc
672 getSimplBinderStuff :: SimplM (Subst, UniqSupply)
673 getSimplBinderStuff (SimplEnv {seSubst = subst}) us sc
674 = ((subst, us), us, sc)
676 setSimplBinderStuff :: (Subst, UniqSupply) -> SimplM a -> SimplM a
677 setSimplBinderStuff (subst, us) m env _ sc
678 = m (env {seSubst = subst}) us sc
683 newId :: Type -> (Id -> SimplM a) -> SimplM a
684 -- Extends the in-scope-env too
685 newId ty m env@(SimplEnv {seSubst = subst}) us sc
686 = case splitUniqSupply us of
687 (us1, us2) -> m v (env {seSubst = Subst.extendInScope subst v}) us2 sc
689 v = mkSysLocal SLIT("s") (uniqFromSupply us1) ty
691 newIds :: [Type] -> ([Id] -> SimplM a) -> SimplM a
692 newIds tys m env@(SimplEnv {seSubst = subst}) us sc
693 = case splitUniqSupply us of
694 (us1, us2) -> m vs (env {seSubst = Subst.extendInScopes subst vs}) us2 sc
696 vs = zipWithEqual "newIds" (mkSysLocal SLIT("s"))
697 (uniqsFromSupply (length tys) us1) tys