| 1 | % |
|---|
| 2 | % (c) The University of Glasgow, 1994-2006 |
|---|
| 3 | % |
|---|
| 4 | |
|---|
| 5 | Core pass to saturate constructors and PrimOps |
|---|
| 6 | |
|---|
| 7 | \begin{code} |
|---|
| 8 | {-# LANGUAGE BangPatterns #-} |
|---|
| 9 | {-# OPTIONS -fno-warn-tabs #-} |
|---|
| 10 | -- The above warning supression flag is a temporary kludge. |
|---|
| 11 | -- While working on this module you are encouraged to remove it and |
|---|
| 12 | -- detab the module (please do the detabbing in a separate patch). See |
|---|
| 13 | -- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces |
|---|
| 14 | -- for details |
|---|
| 15 | |
|---|
| 16 | module CorePrep ( |
|---|
| 17 | corePrepPgm, corePrepExpr |
|---|
| 18 | ) where |
|---|
| 19 | |
|---|
| 20 | #include "HsVersions.h" |
|---|
| 21 | |
|---|
| 22 | import PrelNames |
|---|
| 23 | import CoreUtils |
|---|
| 24 | import CoreArity |
|---|
| 25 | import CoreFVs |
|---|
| 26 | import CoreMonad ( endPass, CoreToDo(..) ) |
|---|
| 27 | import CoreSyn |
|---|
| 28 | import CoreSubst |
|---|
| 29 | import MkCore hiding( FloatBind(..) ) -- We use our own FloatBind here |
|---|
| 30 | import Type |
|---|
| 31 | import Literal |
|---|
| 32 | import Coercion |
|---|
| 33 | import TyCon |
|---|
| 34 | import Demand |
|---|
| 35 | import Var |
|---|
| 36 | import VarSet |
|---|
| 37 | import VarEnv |
|---|
| 38 | import Id |
|---|
| 39 | import IdInfo |
|---|
| 40 | import TysWiredIn |
|---|
| 41 | import DataCon |
|---|
| 42 | import PrimOp |
|---|
| 43 | import BasicTypes |
|---|
| 44 | import UniqSupply |
|---|
| 45 | import Maybes |
|---|
| 46 | import OrdList |
|---|
| 47 | import ErrUtils |
|---|
| 48 | import DynFlags |
|---|
| 49 | import Util |
|---|
| 50 | import Pair |
|---|
| 51 | import Outputable |
|---|
| 52 | import MonadUtils |
|---|
| 53 | import FastString |
|---|
| 54 | import Config |
|---|
| 55 | import Data.Bits |
|---|
| 56 | import Data.List ( mapAccumL ) |
|---|
| 57 | import Control.Monad |
|---|
| 58 | \end{code} |
|---|
| 59 | |
|---|
| 60 | -- --------------------------------------------------------------------------- |
|---|
| 61 | -- Overview |
|---|
| 62 | -- --------------------------------------------------------------------------- |
|---|
| 63 | |
|---|
| 64 | The goal of this pass is to prepare for code generation. |
|---|
| 65 | |
|---|
| 66 | 1. Saturate constructor and primop applications. |
|---|
| 67 | |
|---|
| 68 | 2. Convert to A-normal form; that is, function arguments |
|---|
| 69 | are always variables. |
|---|
| 70 | |
|---|
| 71 | * Use case for strict arguments: |
|---|
| 72 | f E ==> case E of x -> f x |
|---|
| 73 | (where f is strict) |
|---|
| 74 | |
|---|
| 75 | * Use let for non-trivial lazy arguments |
|---|
| 76 | f E ==> let x = E in f x |
|---|
| 77 | (were f is lazy and x is non-trivial) |
|---|
| 78 | |
|---|
| 79 | 3. Similarly, convert any unboxed lets into cases. |
|---|
| 80 | [I'm experimenting with leaving 'ok-for-speculation' |
|---|
| 81 | rhss in let-form right up to this point.] |
|---|
| 82 | |
|---|
| 83 | 4. Ensure that *value* lambdas only occur as the RHS of a binding |
|---|
| 84 | (The code generator can't deal with anything else.) |
|---|
| 85 | Type lambdas are ok, however, because the code gen discards them. |
|---|
| 86 | |
|---|
| 87 | 5. [Not any more; nuked Jun 2002] Do the seq/par munging. |
|---|
| 88 | |
|---|
| 89 | 6. Clone all local Ids. |
|---|
| 90 | This means that all such Ids are unique, rather than the |
|---|
| 91 | weaker guarantee of no clashes which the simplifier provides. |
|---|
| 92 | And that is what the code generator needs. |
|---|
| 93 | |
|---|
| 94 | We don't clone TyVars or CoVars. The code gen doesn't need that, |
|---|
| 95 | and doing so would be tiresome because then we'd need |
|---|
| 96 | to substitute in types and coercions. |
|---|
| 97 | |
|---|
| 98 | 7. Give each dynamic CCall occurrence a fresh unique; this is |
|---|
| 99 | rather like the cloning step above. |
|---|
| 100 | |
|---|
| 101 | 8. Inject bindings for the "implicit" Ids: |
|---|
| 102 | * Constructor wrappers |
|---|
| 103 | * Constructor workers |
|---|
| 104 | We want curried definitions for all of these in case they |
|---|
| 105 | aren't inlined by some caller. |
|---|
| 106 | |
|---|
| 107 | 9. Replace (lazy e) by e. See Note [lazyId magic] in MkId.lhs |
|---|
| 108 | |
|---|
| 109 | 10. Convert (LitInteger i mkInteger) into the core representation |
|---|
| 110 | for the Integer i. Normally this uses the mkInteger Id, but if |
|---|
| 111 | we are using the integer-gmp implementation then there is a |
|---|
| 112 | special case where we use the S# constructor for Integers that |
|---|
| 113 | are in the range of Int. |
|---|
| 114 | |
|---|
| 115 | This is all done modulo type applications and abstractions, so that |
|---|
| 116 | when type erasure is done for conversion to STG, we don't end up with |
|---|
| 117 | any trivial or useless bindings. |
|---|
| 118 | |
|---|
| 119 | |
|---|
| 120 | Invariants |
|---|
| 121 | ~~~~~~~~~~ |
|---|
| 122 | Here is the syntax of the Core produced by CorePrep: |
|---|
| 123 | |
|---|
| 124 | Trivial expressions |
|---|
| 125 | triv ::= lit | var |
|---|
| 126 | | triv ty | /\a. triv |
|---|
| 127 | | truv co | /\c. triv | triv |> co |
|---|
| 128 | |
|---|
| 129 | Applications |
|---|
| 130 | app ::= lit | var | app triv | app ty | app co | app |> co |
|---|
| 131 | |
|---|
| 132 | Expressions |
|---|
| 133 | body ::= app |
|---|
| 134 | | let(rec) x = rhs in body -- Boxed only |
|---|
| 135 | | case body of pat -> body |
|---|
| 136 | | /\a. body | /\c. body |
|---|
| 137 | | body |> co |
|---|
| 138 | |
|---|
| 139 | Right hand sides (only place where value lambdas can occur) |
|---|
| 140 | rhs ::= /\a.rhs | \x.rhs | body |
|---|
| 141 | |
|---|
| 142 | We define a synonym for each of these non-terminals. Functions |
|---|
| 143 | with the corresponding name produce a result in that syntax. |
|---|
| 144 | |
|---|
| 145 | \begin{code} |
|---|
| 146 | type CpeTriv = CoreExpr -- Non-terminal 'triv' |
|---|
| 147 | type CpeApp = CoreExpr -- Non-terminal 'app' |
|---|
| 148 | type CpeBody = CoreExpr -- Non-terminal 'body' |
|---|
| 149 | type CpeRhs = CoreExpr -- Non-terminal 'rhs' |
|---|
| 150 | \end{code} |
|---|
| 151 | |
|---|
| 152 | %************************************************************************ |
|---|
| 153 | %* * |
|---|
| 154 | Top level stuff |
|---|
| 155 | %* * |
|---|
| 156 | %************************************************************************ |
|---|
| 157 | |
|---|
| 158 | \begin{code} |
|---|
| 159 | corePrepPgm :: DynFlags -> CoreProgram -> [TyCon] -> IO CoreProgram |
|---|
| 160 | corePrepPgm dflags binds data_tycons = do |
|---|
| 161 | showPass dflags "CorePrep" |
|---|
| 162 | us <- mkSplitUniqSupply 's' |
|---|
| 163 | |
|---|
| 164 | let implicit_binds = mkDataConWorkers data_tycons |
|---|
| 165 | -- NB: we must feed mkImplicitBinds through corePrep too |
|---|
| 166 | -- so that they are suitably cloned and eta-expanded |
|---|
| 167 | |
|---|
| 168 | binds_out = initUs_ us $ do |
|---|
| 169 | floats1 <- corePrepTopBinds binds |
|---|
| 170 | floats2 <- corePrepTopBinds implicit_binds |
|---|
| 171 | return (deFloatTop (floats1 `appendFloats` floats2)) |
|---|
| 172 | |
|---|
| 173 | endPass dflags CorePrep binds_out [] |
|---|
| 174 | return binds_out |
|---|
| 175 | |
|---|
| 176 | corePrepExpr :: DynFlags -> CoreExpr -> IO CoreExpr |
|---|
| 177 | corePrepExpr dflags expr = do |
|---|
| 178 | showPass dflags "CorePrep" |
|---|
| 179 | us <- mkSplitUniqSupply 's' |
|---|
| 180 | let new_expr = initUs_ us (cpeBodyNF emptyCorePrepEnv expr) |
|---|
| 181 | dumpIfSet_dyn dflags Opt_D_dump_prep "CorePrep" (ppr new_expr) |
|---|
| 182 | return new_expr |
|---|
| 183 | |
|---|
| 184 | corePrepTopBinds :: [CoreBind] -> UniqSM Floats |
|---|
| 185 | -- Note [Floating out of top level bindings] |
|---|
| 186 | corePrepTopBinds binds |
|---|
| 187 | = go emptyCorePrepEnv binds |
|---|
| 188 | where |
|---|
| 189 | go _ [] = return emptyFloats |
|---|
| 190 | go env (bind : binds) = do (env', bind') <- cpeBind TopLevel env bind |
|---|
| 191 | binds' <- go env' binds |
|---|
| 192 | return (bind' `appendFloats` binds') |
|---|
| 193 | |
|---|
| 194 | mkDataConWorkers :: [TyCon] -> [CoreBind] |
|---|
| 195 | -- See Note [Data constructor workers] |
|---|
| 196 | mkDataConWorkers data_tycons |
|---|
| 197 | = [ NonRec id (Var id) -- The ice is thin here, but it works |
|---|
| 198 | | tycon <- data_tycons, -- CorePrep will eta-expand it |
|---|
| 199 | data_con <- tyConDataCons tycon, |
|---|
| 200 | let id = dataConWorkId data_con ] |
|---|
| 201 | \end{code} |
|---|
| 202 | |
|---|
| 203 | Note [Floating out of top level bindings] |
|---|
| 204 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 205 | NB: we do need to float out of top-level bindings |
|---|
| 206 | Consider x = length [True,False] |
|---|
| 207 | We want to get |
|---|
| 208 | s1 = False : [] |
|---|
| 209 | s2 = True : s1 |
|---|
| 210 | x = length s2 |
|---|
| 211 | |
|---|
| 212 | We return a *list* of bindings, because we may start with |
|---|
| 213 | x* = f (g y) |
|---|
| 214 | where x is demanded, in which case we want to finish with |
|---|
| 215 | a = g y |
|---|
| 216 | x* = f a |
|---|
| 217 | And then x will actually end up case-bound |
|---|
| 218 | |
|---|
| 219 | Note [CafInfo and floating] |
|---|
| 220 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 221 | What happens when we try to float bindings to the top level? At this |
|---|
| 222 | point all the CafInfo is supposed to be correct, and we must make certain |
|---|
| 223 | that is true of the new top-level bindings. There are two cases |
|---|
| 224 | to consider |
|---|
| 225 | |
|---|
| 226 | a) The top-level binding is marked asCafRefs. In that case we are |
|---|
| 227 | basically fine. The floated bindings had better all be lazy lets, |
|---|
| 228 | so they can float to top level, but they'll all have HasCafRefs |
|---|
| 229 | (the default) which is safe. |
|---|
| 230 | |
|---|
| 231 | b) The top-level binding is marked NoCafRefs. This really happens |
|---|
| 232 | Example. CoreTidy produces |
|---|
| 233 | $fApplicativeSTM [NoCafRefs] = D:Alternative retry# ...blah... |
|---|
| 234 | Now CorePrep has to eta-expand to |
|---|
| 235 | $fApplicativeSTM = let sat = \xy. retry x y |
|---|
| 236 | in D:Alternative sat ...blah... |
|---|
| 237 | So what we *want* is |
|---|
| 238 | sat [NoCafRefs] = \xy. retry x y |
|---|
| 239 | $fApplicativeSTM [NoCafRefs] = D:Alternative sat ...blah... |
|---|
| 240 | |
|---|
| 241 | So, gruesomely, we must set the NoCafRefs flag on the sat bindings, |
|---|
| 242 | *and* substutite the modified 'sat' into the old RHS. |
|---|
| 243 | |
|---|
| 244 | It should be the case that 'sat' is itself [NoCafRefs] (a value, no |
|---|
| 245 | cafs) else the original top-level binding would not itself have been |
|---|
| 246 | marked [NoCafRefs]. The DEBUG check in CoreToStg for |
|---|
| 247 | consistentCafInfo will find this. |
|---|
| 248 | |
|---|
| 249 | This is all very gruesome and horrible. It would be better to figure |
|---|
| 250 | out CafInfo later, after CorePrep. We'll do that in due course. |
|---|
| 251 | Meanwhile this horrible hack works. |
|---|
| 252 | |
|---|
| 253 | |
|---|
| 254 | Note [Data constructor workers] |
|---|
| 255 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 256 | Create any necessary "implicit" bindings for data con workers. We |
|---|
| 257 | create the rather strange (non-recursive!) binding |
|---|
| 258 | |
|---|
| 259 | $wC = \x y -> $wC x y |
|---|
| 260 | |
|---|
| 261 | i.e. a curried constructor that allocates. This means that we can |
|---|
| 262 | treat the worker for a constructor like any other function in the rest |
|---|
| 263 | of the compiler. The point here is that CoreToStg will generate a |
|---|
| 264 | StgConApp for the RHS, rather than a call to the worker (which would |
|---|
| 265 | give a loop). As Lennart says: the ice is thin here, but it works. |
|---|
| 266 | |
|---|
| 267 | Hmm. Should we create bindings for dictionary constructors? They are |
|---|
| 268 | always fully applied, and the bindings are just there to support |
|---|
| 269 | partial applications. But it's easier to let them through. |
|---|
| 270 | |
|---|
| 271 | |
|---|
| 272 | Note [Dead code in CorePrep] |
|---|
| 273 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 274 | Imagine that we got an input program like this: |
|---|
| 275 | |
|---|
| 276 | f :: Show b => Int -> (Int, b -> Maybe Int -> Int) |
|---|
| 277 | f x = (g True (Just x) + g () (Just x), g) |
|---|
| 278 | where |
|---|
| 279 | g :: Show a => a -> Maybe Int -> Int |
|---|
| 280 | g _ Nothing = x |
|---|
| 281 | g y (Just z) = if z > 100 then g y (Just (z + length (show y))) else g y unknown |
|---|
| 282 | |
|---|
| 283 | After specialisation and SpecConstr, we would get something like this: |
|---|
| 284 | |
|---|
| 285 | f :: Show b => Int -> (Int, b -> Maybe Int -> Int) |
|---|
| 286 | f x = (g$Bool_True_Just x + g$Unit_Unit_Just x, g) |
|---|
| 287 | where |
|---|
| 288 | {-# RULES g $dBool = g$Bool |
|---|
| 289 | g $dUnit = g$Unit #-} |
|---|
| 290 | g = ... |
|---|
| 291 | {-# RULES forall x. g$Bool True (Just x) = g$Bool_True_Just x #-} |
|---|
| 292 | g$Bool = ... |
|---|
| 293 | {-# RULES forall x. g$Unit () (Just x) = g$Unit_Unit_Just x #-} |
|---|
| 294 | g$Unit = ... |
|---|
| 295 | g$Bool_True_Just = ... |
|---|
| 296 | g$Unit_Unit_Just = ... |
|---|
| 297 | |
|---|
| 298 | Note that the g$Bool and g$Unit functions are actually dead code: they |
|---|
| 299 | are only kept alive by the occurrence analyser because they are |
|---|
| 300 | referred to by the rules of g, which is being kept alive by the fact |
|---|
| 301 | that it is used (unspecialised) in the returned pair. |
|---|
| 302 | |
|---|
| 303 | However, at the CorePrep stage there is no way that the rules for g |
|---|
| 304 | will ever fire, and it really seems like a shame to produce an output |
|---|
| 305 | program that goes to the trouble of allocating a closure for the |
|---|
| 306 | unreachable g$Bool and g$Unit functions. |
|---|
| 307 | |
|---|
| 308 | The way we fix this is to: |
|---|
| 309 | * In cloneBndr, drop all unfoldings/rules |
|---|
| 310 | * In deFloatTop, run a simple dead code analyser on each top-level RHS to drop |
|---|
| 311 | the dead local bindings. (we used to run the occurrence analyser to do |
|---|
| 312 | this job, but the occurrence analyser sometimes introduces new let |
|---|
| 313 | bindings for case binders, which lead to the bug in #5433, hence we |
|---|
| 314 | now have a special-purpose dead code analyser). |
|---|
| 315 | |
|---|
| 316 | The reason we don't just OccAnal the whole output of CorePrep is that |
|---|
| 317 | the tidier ensures that all top-level binders are GlobalIds, so they |
|---|
| 318 | don't show up in the free variables any longer. So if you run the |
|---|
| 319 | occurrence analyser on the output of CoreTidy (or later) you e.g. turn |
|---|
| 320 | this program: |
|---|
| 321 | |
|---|
| 322 | Rec { |
|---|
| 323 | f = ... f ... |
|---|
| 324 | } |
|---|
| 325 | |
|---|
| 326 | Into this one: |
|---|
| 327 | |
|---|
| 328 | f = ... f ... |
|---|
| 329 | |
|---|
| 330 | (Since f is not considered to be free in its own RHS.) |
|---|
| 331 | |
|---|
| 332 | |
|---|
| 333 | %************************************************************************ |
|---|
| 334 | %* * |
|---|
| 335 | The main code |
|---|
| 336 | %* * |
|---|
| 337 | %************************************************************************ |
|---|
| 338 | |
|---|
| 339 | \begin{code} |
|---|
| 340 | cpeBind :: TopLevelFlag |
|---|
| 341 | -> CorePrepEnv -> CoreBind |
|---|
| 342 | -> UniqSM (CorePrepEnv, Floats) |
|---|
| 343 | cpeBind top_lvl env (NonRec bndr rhs) |
|---|
| 344 | = do { (_, bndr1) <- cpCloneBndr env bndr |
|---|
| 345 | ; let is_strict = isStrictDmd (idDemandInfo bndr) |
|---|
| 346 | is_unlifted = isUnLiftedType (idType bndr) |
|---|
| 347 | ; (floats, bndr2, rhs2) <- cpePair top_lvl NonRecursive |
|---|
| 348 | (is_strict || is_unlifted) |
|---|
| 349 | env bndr1 rhs |
|---|
| 350 | ; let new_float = mkFloat is_strict is_unlifted bndr2 rhs2 |
|---|
| 351 | |
|---|
| 352 | -- We want bndr'' in the envt, because it records |
|---|
| 353 | -- the evaluated-ness of the binder |
|---|
| 354 | ; return (extendCorePrepEnv env bndr bndr2, |
|---|
| 355 | addFloat floats new_float) } |
|---|
| 356 | |
|---|
| 357 | cpeBind top_lvl env (Rec pairs) |
|---|
| 358 | = do { let (bndrs,rhss) = unzip pairs |
|---|
| 359 | ; (env', bndrs1) <- cpCloneBndrs env (map fst pairs) |
|---|
| 360 | ; stuff <- zipWithM (cpePair top_lvl Recursive False env') bndrs1 rhss |
|---|
| 361 | |
|---|
| 362 | ; let (floats_s, bndrs2, rhss2) = unzip3 stuff |
|---|
| 363 | all_pairs = foldrOL add_float (bndrs2 `zip` rhss2) |
|---|
| 364 | (concatFloats floats_s) |
|---|
| 365 | ; return (extendCorePrepEnvList env (bndrs `zip` bndrs2), |
|---|
| 366 | unitFloat (FloatLet (Rec all_pairs))) } |
|---|
| 367 | where |
|---|
| 368 | -- Flatten all the floats, and the currrent |
|---|
| 369 | -- group into a single giant Rec |
|---|
| 370 | add_float (FloatLet (NonRec b r)) prs2 = (b,r) : prs2 |
|---|
| 371 | add_float (FloatLet (Rec prs1)) prs2 = prs1 ++ prs2 |
|---|
| 372 | add_float b _ = pprPanic "cpeBind" (ppr b) |
|---|
| 373 | |
|---|
| 374 | --------------- |
|---|
| 375 | cpePair :: TopLevelFlag -> RecFlag -> RhsDemand |
|---|
| 376 | -> CorePrepEnv -> Id -> CoreExpr |
|---|
| 377 | -> UniqSM (Floats, Id, CpeRhs) |
|---|
| 378 | -- Used for all bindings |
|---|
| 379 | cpePair top_lvl is_rec is_strict_or_unlifted env bndr rhs |
|---|
| 380 | = do { (floats1, rhs1) <- cpeRhsE env rhs |
|---|
| 381 | |
|---|
| 382 | -- See if we are allowed to float this stuff out of the RHS |
|---|
| 383 | ; (floats2, rhs2) <- float_from_rhs floats1 rhs1 |
|---|
| 384 | |
|---|
| 385 | -- Make the arity match up |
|---|
| 386 | ; (floats3, rhs') |
|---|
| 387 | <- if manifestArity rhs1 <= arity |
|---|
| 388 | then return (floats2, cpeEtaExpand arity rhs2) |
|---|
| 389 | else WARN(True, text "CorePrep: silly extra arguments:" <+> ppr bndr) |
|---|
| 390 | -- Note [Silly extra arguments] |
|---|
| 391 | (do { v <- newVar (idType bndr) |
|---|
| 392 | ; let float = mkFloat False False v rhs2 |
|---|
| 393 | ; return ( addFloat floats2 float |
|---|
| 394 | , cpeEtaExpand arity (Var v)) }) |
|---|
| 395 | |
|---|
| 396 | -- Record if the binder is evaluated |
|---|
| 397 | -- and otherwise trim off the unfolding altogether |
|---|
| 398 | -- It's not used by the code generator; getting rid of it reduces |
|---|
| 399 | -- heap usage and, since we may be changing uniques, we'd have |
|---|
| 400 | -- to substitute to keep it right |
|---|
| 401 | ; let bndr' | exprIsHNF rhs' = bndr `setIdUnfolding` evaldUnfolding |
|---|
| 402 | | otherwise = bndr `setIdUnfolding` noUnfolding |
|---|
| 403 | |
|---|
| 404 | ; return (floats3, bndr', rhs') } |
|---|
| 405 | where |
|---|
| 406 | arity = idArity bndr -- We must match this arity |
|---|
| 407 | |
|---|
| 408 | --------------------- |
|---|
| 409 | float_from_rhs floats rhs |
|---|
| 410 | | isEmptyFloats floats = return (emptyFloats, rhs) |
|---|
| 411 | | isTopLevel top_lvl = float_top floats rhs |
|---|
| 412 | | otherwise = float_nested floats rhs |
|---|
| 413 | |
|---|
| 414 | --------------------- |
|---|
| 415 | float_nested floats rhs |
|---|
| 416 | | wantFloatNested is_rec is_strict_or_unlifted floats rhs |
|---|
| 417 | = return (floats, rhs) |
|---|
| 418 | | otherwise = dont_float floats rhs |
|---|
| 419 | |
|---|
| 420 | --------------------- |
|---|
| 421 | float_top floats rhs -- Urhgh! See Note [CafInfo and floating] |
|---|
| 422 | | mayHaveCafRefs (idCafInfo bndr) |
|---|
| 423 | , allLazyTop floats |
|---|
| 424 | = return (floats, rhs) |
|---|
| 425 | |
|---|
| 426 | -- So the top-level binding is marked NoCafRefs |
|---|
| 427 | | Just (floats', rhs') <- canFloatFromNoCaf floats rhs |
|---|
| 428 | = return (floats', rhs') |
|---|
| 429 | |
|---|
| 430 | | otherwise |
|---|
| 431 | = dont_float floats rhs |
|---|
| 432 | |
|---|
| 433 | --------------------- |
|---|
| 434 | dont_float floats rhs |
|---|
| 435 | -- Non-empty floats, but do not want to float from rhs |
|---|
| 436 | -- So wrap the rhs in the floats |
|---|
| 437 | -- But: rhs1 might have lambdas, and we can't |
|---|
| 438 | -- put them inside a wrapBinds |
|---|
| 439 | = do { body <- rhsToBodyNF rhs |
|---|
| 440 | ; return (emptyFloats, wrapBinds floats body) } |
|---|
| 441 | |
|---|
| 442 | {- Note [Silly extra arguments] |
|---|
| 443 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 444 | Suppose we had this |
|---|
| 445 | f{arity=1} = \x\y. e |
|---|
| 446 | We *must* match the arity on the Id, so we have to generate |
|---|
| 447 | f' = \x\y. e |
|---|
| 448 | f = \x. f' x |
|---|
| 449 | |
|---|
| 450 | It's a bizarre case: why is the arity on the Id wrong? Reason |
|---|
| 451 | (in the days of __inline_me__): |
|---|
| 452 | f{arity=0} = __inline_me__ (let v = expensive in \xy. e) |
|---|
| 453 | When InlineMe notes go away this won't happen any more. But |
|---|
| 454 | it seems good for CorePrep to be robust. |
|---|
| 455 | -} |
|---|
| 456 | |
|---|
| 457 | -- --------------------------------------------------------------------------- |
|---|
| 458 | -- CpeRhs: produces a result satisfying CpeRhs |
|---|
| 459 | -- --------------------------------------------------------------------------- |
|---|
| 460 | |
|---|
| 461 | cpeRhsE :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeRhs) |
|---|
| 462 | -- If |
|---|
| 463 | -- e ===> (bs, e') |
|---|
| 464 | -- then |
|---|
| 465 | -- e = let bs in e' (semantically, that is!) |
|---|
| 466 | -- |
|---|
| 467 | -- For example |
|---|
| 468 | -- f (g x) ===> ([v = g x], f v) |
|---|
| 469 | |
|---|
| 470 | cpeRhsE _env expr@(Type {}) = return (emptyFloats, expr) |
|---|
| 471 | cpeRhsE _env expr@(Coercion {}) = return (emptyFloats, expr) |
|---|
| 472 | cpeRhsE env (Lit (LitInteger i mk_integer)) |
|---|
| 473 | = cpeRhsE env (cvtLitInteger i mk_integer) |
|---|
| 474 | cpeRhsE _env expr@(Lit {}) = return (emptyFloats, expr) |
|---|
| 475 | cpeRhsE env expr@(Var {}) = cpeApp env expr |
|---|
| 476 | |
|---|
| 477 | cpeRhsE env (Var f `App` _ `App` arg) |
|---|
| 478 | | f `hasKey` lazyIdKey -- Replace (lazy a) by a |
|---|
| 479 | = cpeRhsE env arg -- See Note [lazyId magic] in MkId |
|---|
| 480 | |
|---|
| 481 | cpeRhsE env expr@(App {}) = cpeApp env expr |
|---|
| 482 | |
|---|
| 483 | cpeRhsE env (Let bind expr) |
|---|
| 484 | = do { (env', new_binds) <- cpeBind NotTopLevel env bind |
|---|
| 485 | ; (floats, body) <- cpeRhsE env' expr |
|---|
| 486 | ; return (new_binds `appendFloats` floats, body) } |
|---|
| 487 | |
|---|
| 488 | cpeRhsE env (Tick tickish expr) |
|---|
| 489 | | ignoreTickish tickish |
|---|
| 490 | = cpeRhsE env expr |
|---|
| 491 | | otherwise -- Just SCCs actually |
|---|
| 492 | = do { body <- cpeBodyNF env expr |
|---|
| 493 | ; return (emptyFloats, Tick tickish' body) } |
|---|
| 494 | where |
|---|
| 495 | tickish' | Breakpoint n fvs <- tickish |
|---|
| 496 | = Breakpoint n (map (lookupCorePrepEnv env) fvs) |
|---|
| 497 | | otherwise |
|---|
| 498 | = tickish |
|---|
| 499 | |
|---|
| 500 | cpeRhsE env (Cast expr co) |
|---|
| 501 | = do { (floats, expr') <- cpeRhsE env expr |
|---|
| 502 | ; return (floats, Cast expr' co) } |
|---|
| 503 | |
|---|
| 504 | cpeRhsE env expr@(Lam {}) |
|---|
| 505 | = do { let (bndrs,body) = collectBinders expr |
|---|
| 506 | ; (env', bndrs') <- cpCloneBndrs env bndrs |
|---|
| 507 | ; body' <- cpeBodyNF env' body |
|---|
| 508 | ; return (emptyFloats, mkLams bndrs' body') } |
|---|
| 509 | |
|---|
| 510 | cpeRhsE env (Case scrut bndr ty alts) |
|---|
| 511 | = do { (floats, scrut') <- cpeBody env scrut |
|---|
| 512 | ; let bndr1 = bndr `setIdUnfolding` evaldUnfolding |
|---|
| 513 | -- Record that the case binder is evaluated in the alternatives |
|---|
| 514 | ; (env', bndr2) <- cpCloneBndr env bndr1 |
|---|
| 515 | ; alts' <- mapM (sat_alt env') alts |
|---|
| 516 | ; return (floats, Case scrut' bndr2 ty alts') } |
|---|
| 517 | where |
|---|
| 518 | sat_alt env (con, bs, rhs) |
|---|
| 519 | = do { (env2, bs') <- cpCloneBndrs env bs |
|---|
| 520 | ; rhs' <- cpeBodyNF env2 rhs |
|---|
| 521 | ; return (con, bs', rhs') } |
|---|
| 522 | |
|---|
| 523 | cvtLitInteger :: Integer -> Id -> CoreExpr |
|---|
| 524 | -- Here we convert a literal Integer to the low-level |
|---|
| 525 | -- represenation. Exactly how we do this depends on the |
|---|
| 526 | -- library that implements Integer. If it's GMP we |
|---|
| 527 | -- use the S# data constructor for small literals. |
|---|
| 528 | -- See Note [Integer literals] in Literal |
|---|
| 529 | cvtLitInteger i mk_integer |
|---|
| 530 | | cIntegerLibraryType == IntegerGMP |
|---|
| 531 | , inIntRange i -- Special case for small integers in GMP |
|---|
| 532 | = mkConApp integerGmpSDataCon [Lit (mkMachInt i)] |
|---|
| 533 | |
|---|
| 534 | | otherwise |
|---|
| 535 | = mkApps (Var mk_integer) [isNonNegative, ints] |
|---|
| 536 | where isNonNegative = if i < 0 then mkConApp falseDataCon [] |
|---|
| 537 | else mkConApp trueDataCon [] |
|---|
| 538 | ints = mkListExpr intTy (f (abs i)) |
|---|
| 539 | f 0 = [] |
|---|
| 540 | f x = let low = x .&. mask |
|---|
| 541 | high = x `shiftR` bits |
|---|
| 542 | in mkConApp intDataCon [Lit (mkMachInt low)] : f high |
|---|
| 543 | bits = 31 |
|---|
| 544 | mask = 2 ^ bits - 1 |
|---|
| 545 | |
|---|
| 546 | -- --------------------------------------------------------------------------- |
|---|
| 547 | -- CpeBody: produces a result satisfying CpeBody |
|---|
| 548 | -- --------------------------------------------------------------------------- |
|---|
| 549 | |
|---|
| 550 | cpeBodyNF :: CorePrepEnv -> CoreExpr -> UniqSM CpeBody |
|---|
| 551 | cpeBodyNF env expr |
|---|
| 552 | = do { (floats, body) <- cpeBody env expr |
|---|
| 553 | ; return (wrapBinds floats body) } |
|---|
| 554 | |
|---|
| 555 | -------- |
|---|
| 556 | cpeBody :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeBody) |
|---|
| 557 | cpeBody env expr |
|---|
| 558 | = do { (floats1, rhs) <- cpeRhsE env expr |
|---|
| 559 | ; (floats2, body) <- rhsToBody rhs |
|---|
| 560 | ; return (floats1 `appendFloats` floats2, body) } |
|---|
| 561 | |
|---|
| 562 | -------- |
|---|
| 563 | rhsToBodyNF :: CpeRhs -> UniqSM CpeBody |
|---|
| 564 | rhsToBodyNF rhs = do { (floats,body) <- rhsToBody rhs |
|---|
| 565 | ; return (wrapBinds floats body) } |
|---|
| 566 | |
|---|
| 567 | -------- |
|---|
| 568 | rhsToBody :: CpeRhs -> UniqSM (Floats, CpeBody) |
|---|
| 569 | -- Remove top level lambdas by let-binding |
|---|
| 570 | |
|---|
| 571 | rhsToBody (Tick t expr) |
|---|
| 572 | | not (tickishScoped t) -- we can only float out of non-scoped annotations |
|---|
| 573 | = do { (floats, expr') <- rhsToBody expr |
|---|
| 574 | ; return (floats, Tick t expr') } |
|---|
| 575 | |
|---|
| 576 | rhsToBody (Cast e co) |
|---|
| 577 | -- You can get things like |
|---|
| 578 | -- case e of { p -> coerce t (\s -> ...) } |
|---|
| 579 | = do { (floats, e') <- rhsToBody e |
|---|
| 580 | ; return (floats, Cast e' co) } |
|---|
| 581 | |
|---|
| 582 | rhsToBody expr@(Lam {}) |
|---|
| 583 | | Just no_lam_result <- tryEtaReducePrep bndrs body |
|---|
| 584 | = return (emptyFloats, no_lam_result) |
|---|
| 585 | | all isTyVar bndrs -- Type lambdas are ok |
|---|
| 586 | = return (emptyFloats, expr) |
|---|
| 587 | | otherwise -- Some value lambdas |
|---|
| 588 | = do { fn <- newVar (exprType expr) |
|---|
| 589 | ; let rhs = cpeEtaExpand (exprArity expr) expr |
|---|
| 590 | float = FloatLet (NonRec fn rhs) |
|---|
| 591 | ; return (unitFloat float, Var fn) } |
|---|
| 592 | where |
|---|
| 593 | (bndrs,body) = collectBinders expr |
|---|
| 594 | |
|---|
| 595 | rhsToBody expr = return (emptyFloats, expr) |
|---|
| 596 | |
|---|
| 597 | |
|---|
| 598 | |
|---|
| 599 | -- --------------------------------------------------------------------------- |
|---|
| 600 | -- CpeApp: produces a result satisfying CpeApp |
|---|
| 601 | -- --------------------------------------------------------------------------- |
|---|
| 602 | |
|---|
| 603 | cpeApp :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeRhs) |
|---|
| 604 | -- May return a CpeRhs because of saturating primops |
|---|
| 605 | cpeApp env expr |
|---|
| 606 | = do { (app, (head,depth), _, floats, ss) <- collect_args expr 0 |
|---|
| 607 | ; MASSERT(null ss) -- make sure we used all the strictness info |
|---|
| 608 | |
|---|
| 609 | -- Now deal with the function |
|---|
| 610 | ; case head of |
|---|
| 611 | Var fn_id -> do { sat_app <- maybeSaturate fn_id app depth |
|---|
| 612 | ; return (floats, sat_app) } |
|---|
| 613 | _other -> return (floats, app) } |
|---|
| 614 | |
|---|
| 615 | where |
|---|
| 616 | -- Deconstruct and rebuild the application, floating any non-atomic |
|---|
| 617 | -- arguments to the outside. We collect the type of the expression, |
|---|
| 618 | -- the head of the application, and the number of actual value arguments, |
|---|
| 619 | -- all of which are used to possibly saturate this application if it |
|---|
| 620 | -- has a constructor or primop at the head. |
|---|
| 621 | |
|---|
| 622 | collect_args |
|---|
| 623 | :: CoreExpr |
|---|
| 624 | -> Int -- Current app depth |
|---|
| 625 | -> UniqSM (CpeApp, -- The rebuilt expression |
|---|
| 626 | (CoreExpr,Int), -- The head of the application, |
|---|
| 627 | -- and no. of args it was applied to |
|---|
| 628 | Type, -- Type of the whole expr |
|---|
| 629 | Floats, -- Any floats we pulled out |
|---|
| 630 | [Demand]) -- Remaining argument demands |
|---|
| 631 | |
|---|
| 632 | collect_args (App fun arg@(Type arg_ty)) depth |
|---|
| 633 | = do { (fun',hd,fun_ty,floats,ss) <- collect_args fun depth |
|---|
| 634 | ; return (App fun' arg, hd, applyTy fun_ty arg_ty, floats, ss) } |
|---|
| 635 | |
|---|
| 636 | collect_args (App fun arg@(Coercion arg_co)) depth |
|---|
| 637 | = do { (fun',hd,fun_ty,floats,ss) <- collect_args fun depth |
|---|
| 638 | ; return (App fun' arg, hd, applyCo fun_ty arg_co, floats, ss) } |
|---|
| 639 | |
|---|
| 640 | collect_args (App fun arg) depth |
|---|
| 641 | = do { (fun',hd,fun_ty,floats,ss) <- collect_args fun (depth+1) |
|---|
| 642 | ; let |
|---|
| 643 | (ss1, ss_rest) = case ss of |
|---|
| 644 | (ss1:ss_rest) -> (ss1, ss_rest) |
|---|
| 645 | [] -> (lazyDmd, []) |
|---|
| 646 | (arg_ty, res_ty) = expectJust "cpeBody:collect_args" $ |
|---|
| 647 | splitFunTy_maybe fun_ty |
|---|
| 648 | |
|---|
| 649 | ; (fs, arg') <- cpeArg env (isStrictDmd ss1) arg arg_ty |
|---|
| 650 | ; return (App fun' arg', hd, res_ty, fs `appendFloats` floats, ss_rest) } |
|---|
| 651 | |
|---|
| 652 | collect_args (Var v) depth |
|---|
| 653 | = do { v1 <- fiddleCCall v |
|---|
| 654 | ; let v2 = lookupCorePrepEnv env v1 |
|---|
| 655 | ; return (Var v2, (Var v2, depth), idType v2, emptyFloats, stricts) } |
|---|
| 656 | where |
|---|
| 657 | stricts = case idStrictness v of |
|---|
| 658 | StrictSig (DmdType _ demands _) |
|---|
| 659 | | listLengthCmp demands depth /= GT -> demands |
|---|
| 660 | -- length demands <= depth |
|---|
| 661 | | otherwise -> [] |
|---|
| 662 | -- If depth < length demands, then we have too few args to |
|---|
| 663 | -- satisfy strictness info so we have to ignore all the |
|---|
| 664 | -- strictness info, e.g. + (error "urk") |
|---|
| 665 | -- Here, we can't evaluate the arg strictly, because this |
|---|
| 666 | -- partial application might be seq'd |
|---|
| 667 | |
|---|
| 668 | collect_args (Cast fun co) depth |
|---|
| 669 | = do { let Pair _ty1 ty2 = coercionKind co |
|---|
| 670 | ; (fun', hd, _, floats, ss) <- collect_args fun depth |
|---|
| 671 | ; return (Cast fun' co, hd, ty2, floats, ss) } |
|---|
| 672 | |
|---|
| 673 | collect_args (Tick tickish fun) depth |
|---|
| 674 | | ignoreTickish tickish -- Drop these notes altogether |
|---|
| 675 | = collect_args fun depth -- They aren't used by the code generator |
|---|
| 676 | |
|---|
| 677 | -- N-variable fun, better let-bind it |
|---|
| 678 | collect_args fun depth |
|---|
| 679 | = do { (fun_floats, fun') <- cpeArg env True fun ty |
|---|
| 680 | -- The True says that it's sure to be evaluated, |
|---|
| 681 | -- so we'll end up case-binding it |
|---|
| 682 | ; return (fun', (fun', depth), ty, fun_floats, []) } |
|---|
| 683 | where |
|---|
| 684 | ty = exprType fun |
|---|
| 685 | |
|---|
| 686 | -- --------------------------------------------------------------------------- |
|---|
| 687 | -- CpeArg: produces a result satisfying CpeArg |
|---|
| 688 | -- --------------------------------------------------------------------------- |
|---|
| 689 | |
|---|
| 690 | -- This is where we arrange that a non-trivial argument is let-bound |
|---|
| 691 | cpeArg :: CorePrepEnv -> RhsDemand -> CoreArg -> Type |
|---|
| 692 | -> UniqSM (Floats, CpeTriv) |
|---|
| 693 | cpeArg env is_strict arg arg_ty |
|---|
| 694 | = do { (floats1, arg1) <- cpeRhsE env arg -- arg1 can be a lambda |
|---|
| 695 | ; (floats2, arg2) <- if want_float floats1 arg1 |
|---|
| 696 | then return (floats1, arg1) |
|---|
| 697 | else do { body1 <- rhsToBodyNF arg1 |
|---|
| 698 | ; return (emptyFloats, wrapBinds floats1 body1) } |
|---|
| 699 | -- Else case: arg1 might have lambdas, and we can't |
|---|
| 700 | -- put them inside a wrapBinds |
|---|
| 701 | |
|---|
| 702 | ; if cpe_ExprIsTrivial arg2 -- Do not eta expand a trivial argument |
|---|
| 703 | then return (floats2, arg2) |
|---|
| 704 | else do |
|---|
| 705 | { v <- newVar arg_ty |
|---|
| 706 | ; let arg3 = cpeEtaExpand (exprArity arg2) arg2 |
|---|
| 707 | arg_float = mkFloat is_strict is_unlifted v arg3 |
|---|
| 708 | ; return (addFloat floats2 arg_float, varToCoreExpr v) } } |
|---|
| 709 | where |
|---|
| 710 | is_unlifted = isUnLiftedType arg_ty |
|---|
| 711 | want_float = wantFloatNested NonRecursive (is_strict || is_unlifted) |
|---|
| 712 | \end{code} |
|---|
| 713 | |
|---|
| 714 | Note [Floating unlifted arguments] |
|---|
| 715 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 716 | Consider C (let v* = expensive in v) |
|---|
| 717 | |
|---|
| 718 | where the "*" indicates "will be demanded". Usually v will have been |
|---|
| 719 | inlined by now, but let's suppose it hasn't (see Trac #2756). Then we |
|---|
| 720 | do *not* want to get |
|---|
| 721 | |
|---|
| 722 | let v* = expensive in C v |
|---|
| 723 | |
|---|
| 724 | because that has different strictness. Hence the use of 'allLazy'. |
|---|
| 725 | (NB: the let v* turns into a FloatCase, in mkLocalNonRec.) |
|---|
| 726 | |
|---|
| 727 | |
|---|
| 728 | ------------------------------------------------------------------------------ |
|---|
| 729 | -- Building the saturated syntax |
|---|
| 730 | -- --------------------------------------------------------------------------- |
|---|
| 731 | |
|---|
| 732 | maybeSaturate deals with saturating primops and constructors |
|---|
| 733 | The type is the type of the entire application |
|---|
| 734 | |
|---|
| 735 | \begin{code} |
|---|
| 736 | maybeSaturate :: Id -> CpeApp -> Int -> UniqSM CpeRhs |
|---|
| 737 | maybeSaturate fn expr n_args |
|---|
| 738 | | Just DataToTagOp <- isPrimOpId_maybe fn -- DataToTag must have an evaluated arg |
|---|
| 739 | -- A gruesome special case |
|---|
| 740 | = saturateDataToTag sat_expr |
|---|
| 741 | |
|---|
| 742 | | hasNoBinding fn -- There's no binding |
|---|
| 743 | = return sat_expr |
|---|
| 744 | |
|---|
| 745 | | otherwise |
|---|
| 746 | = return expr |
|---|
| 747 | where |
|---|
| 748 | fn_arity = idArity fn |
|---|
| 749 | excess_arity = fn_arity - n_args |
|---|
| 750 | sat_expr = cpeEtaExpand excess_arity expr |
|---|
| 751 | |
|---|
| 752 | ------------- |
|---|
| 753 | saturateDataToTag :: CpeApp -> UniqSM CpeApp |
|---|
| 754 | -- See Note [dataToTag magic] |
|---|
| 755 | saturateDataToTag sat_expr |
|---|
| 756 | = do { let (eta_bndrs, eta_body) = collectBinders sat_expr |
|---|
| 757 | ; eta_body' <- eval_data2tag_arg eta_body |
|---|
| 758 | ; return (mkLams eta_bndrs eta_body') } |
|---|
| 759 | where |
|---|
| 760 | eval_data2tag_arg :: CpeApp -> UniqSM CpeBody |
|---|
| 761 | eval_data2tag_arg app@(fun `App` arg) |
|---|
| 762 | | exprIsHNF arg -- Includes nullary constructors |
|---|
| 763 | = return app -- The arg is evaluated |
|---|
| 764 | | otherwise -- Arg not evaluated, so evaluate it |
|---|
| 765 | = do { arg_id <- newVar (exprType arg) |
|---|
| 766 | ; let arg_id1 = setIdUnfolding arg_id evaldUnfolding |
|---|
| 767 | ; return (Case arg arg_id1 (exprType app) |
|---|
| 768 | [(DEFAULT, [], fun `App` Var arg_id1)]) } |
|---|
| 769 | |
|---|
| 770 | eval_data2tag_arg (Tick t app) -- Scc notes can appear |
|---|
| 771 | = do { app' <- eval_data2tag_arg app |
|---|
| 772 | ; return (Tick t app') } |
|---|
| 773 | |
|---|
| 774 | eval_data2tag_arg other -- Should not happen |
|---|
| 775 | = pprPanic "eval_data2tag" (ppr other) |
|---|
| 776 | \end{code} |
|---|
| 777 | |
|---|
| 778 | Note [dataToTag magic] |
|---|
| 779 | ~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 780 | Horrid: we must ensure that the arg of data2TagOp is evaluated |
|---|
| 781 | (data2tag x) --> (case x of y -> data2tag y) |
|---|
| 782 | (yuk yuk) take into account the lambdas we've now introduced |
|---|
| 783 | |
|---|
| 784 | How might it not be evaluated? Well, we might have floated it out |
|---|
| 785 | of the scope of a `seq`, or dropped the `seq` altogether. |
|---|
| 786 | |
|---|
| 787 | |
|---|
| 788 | %************************************************************************ |
|---|
| 789 | %* * |
|---|
| 790 | Simple CoreSyn operations |
|---|
| 791 | %* * |
|---|
| 792 | %************************************************************************ |
|---|
| 793 | |
|---|
| 794 | \begin{code} |
|---|
| 795 | -- we don't ignore any Tickishes at the moment. |
|---|
| 796 | ignoreTickish :: Tickish Id -> Bool |
|---|
| 797 | ignoreTickish _ = False |
|---|
| 798 | |
|---|
| 799 | cpe_ExprIsTrivial :: CoreExpr -> Bool |
|---|
| 800 | -- Version that doesn't consider an scc annotation to be trivial. |
|---|
| 801 | cpe_ExprIsTrivial (Var _) = True |
|---|
| 802 | cpe_ExprIsTrivial (Type _) = True |
|---|
| 803 | cpe_ExprIsTrivial (Coercion _) = True |
|---|
| 804 | cpe_ExprIsTrivial (Lit _) = True |
|---|
| 805 | cpe_ExprIsTrivial (App e arg) = isTypeArg arg && cpe_ExprIsTrivial e |
|---|
| 806 | cpe_ExprIsTrivial (Tick t e) = not (tickishIsCode t) && cpe_ExprIsTrivial e |
|---|
| 807 | cpe_ExprIsTrivial (Cast e _) = cpe_ExprIsTrivial e |
|---|
| 808 | cpe_ExprIsTrivial (Lam b body) | isTyVar b = cpe_ExprIsTrivial body |
|---|
| 809 | cpe_ExprIsTrivial _ = False |
|---|
| 810 | \end{code} |
|---|
| 811 | |
|---|
| 812 | -- ----------------------------------------------------------------------------- |
|---|
| 813 | -- Eta reduction |
|---|
| 814 | -- ----------------------------------------------------------------------------- |
|---|
| 815 | |
|---|
| 816 | Note [Eta expansion] |
|---|
| 817 | ~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 818 | Eta expand to match the arity claimed by the binder Remember, |
|---|
| 819 | CorePrep must not change arity |
|---|
| 820 | |
|---|
| 821 | Eta expansion might not have happened already, because it is done by |
|---|
| 822 | the simplifier only when there at least one lambda already. |
|---|
| 823 | |
|---|
| 824 | NB1:we could refrain when the RHS is trivial (which can happen |
|---|
| 825 | for exported things). This would reduce the amount of code |
|---|
| 826 | generated (a little) and make things a little words for |
|---|
| 827 | code compiled without -O. The case in point is data constructor |
|---|
| 828 | wrappers. |
|---|
| 829 | |
|---|
| 830 | NB2: we have to be careful that the result of etaExpand doesn't |
|---|
| 831 | invalidate any of the assumptions that CorePrep is attempting |
|---|
| 832 | to establish. One possible cause is eta expanding inside of |
|---|
| 833 | an SCC note - we're now careful in etaExpand to make sure the |
|---|
| 834 | SCC is pushed inside any new lambdas that are generated. |
|---|
| 835 | |
|---|
| 836 | Note [Eta expansion and the CorePrep invariants] |
|---|
| 837 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 838 | It turns out to be much much easier to do eta expansion |
|---|
| 839 | *after* the main CorePrep stuff. But that places constraints |
|---|
| 840 | on the eta expander: given a CpeRhs, it must return a CpeRhs. |
|---|
| 841 | |
|---|
| 842 | For example here is what we do not want: |
|---|
| 843 | f = /\a -> g (h 3) -- h has arity 2 |
|---|
| 844 | After ANFing we get |
|---|
| 845 | f = /\a -> let s = h 3 in g s |
|---|
| 846 | and now we do NOT want eta expansion to give |
|---|
| 847 | f = /\a -> \ y -> (let s = h 3 in g s) y |
|---|
| 848 | |
|---|
| 849 | Instead CoreArity.etaExpand gives |
|---|
| 850 | f = /\a -> \y -> let s = h 3 in g s y |
|---|
| 851 | |
|---|
| 852 | \begin{code} |
|---|
| 853 | cpeEtaExpand :: Arity -> CpeRhs -> CpeRhs |
|---|
| 854 | cpeEtaExpand arity expr |
|---|
| 855 | | arity == 0 = expr |
|---|
| 856 | | otherwise = etaExpand arity expr |
|---|
| 857 | \end{code} |
|---|
| 858 | |
|---|
| 859 | -- ----------------------------------------------------------------------------- |
|---|
| 860 | -- Eta reduction |
|---|
| 861 | -- ----------------------------------------------------------------------------- |
|---|
| 862 | |
|---|
| 863 | Why try eta reduction? Hasn't the simplifier already done eta? |
|---|
| 864 | But the simplifier only eta reduces if that leaves something |
|---|
| 865 | trivial (like f, or f Int). But for deLam it would be enough to |
|---|
| 866 | get to a partial application: |
|---|
| 867 | case x of { p -> \xs. map f xs } |
|---|
| 868 | ==> case x of { p -> map f } |
|---|
| 869 | |
|---|
| 870 | \begin{code} |
|---|
| 871 | tryEtaReducePrep :: [CoreBndr] -> CoreExpr -> Maybe CoreExpr |
|---|
| 872 | tryEtaReducePrep bndrs expr@(App _ _) |
|---|
| 873 | | ok_to_eta_reduce f |
|---|
| 874 | , n_remaining >= 0 |
|---|
| 875 | , and (zipWith ok bndrs last_args) |
|---|
| 876 | , not (any (`elemVarSet` fvs_remaining) bndrs) |
|---|
| 877 | , exprIsHNF remaining_expr -- Don't turn value into a non-value |
|---|
| 878 | -- else the behaviour with 'seq' changes |
|---|
| 879 | = Just remaining_expr |
|---|
| 880 | where |
|---|
| 881 | (f, args) = collectArgs expr |
|---|
| 882 | remaining_expr = mkApps f remaining_args |
|---|
| 883 | fvs_remaining = exprFreeVars remaining_expr |
|---|
| 884 | (remaining_args, last_args) = splitAt n_remaining args |
|---|
| 885 | n_remaining = length args - length bndrs |
|---|
| 886 | |
|---|
| 887 | ok bndr (Var arg) = bndr == arg |
|---|
| 888 | ok _ _ = False |
|---|
| 889 | |
|---|
| 890 | -- We can't eta reduce something which must be saturated. |
|---|
| 891 | ok_to_eta_reduce (Var f) = not (hasNoBinding f) |
|---|
| 892 | ok_to_eta_reduce _ = False -- Safe. ToDo: generalise |
|---|
| 893 | |
|---|
| 894 | tryEtaReducePrep bndrs (Let bind@(NonRec _ r) body) |
|---|
| 895 | | not (any (`elemVarSet` fvs) bndrs) |
|---|
| 896 | = case tryEtaReducePrep bndrs body of |
|---|
| 897 | Just e -> Just (Let bind e) |
|---|
| 898 | Nothing -> Nothing |
|---|
| 899 | where |
|---|
| 900 | fvs = exprFreeVars r |
|---|
| 901 | |
|---|
| 902 | tryEtaReducePrep _ _ = Nothing |
|---|
| 903 | \end{code} |
|---|
| 904 | |
|---|
| 905 | |
|---|
| 906 | -- ----------------------------------------------------------------------------- |
|---|
| 907 | -- Demands |
|---|
| 908 | -- ----------------------------------------------------------------------------- |
|---|
| 909 | |
|---|
| 910 | \begin{code} |
|---|
| 911 | type RhsDemand = Bool -- True => used strictly; hence not top-level, non-recursive |
|---|
| 912 | \end{code} |
|---|
| 913 | |
|---|
| 914 | %************************************************************************ |
|---|
| 915 | %* * |
|---|
| 916 | Floats |
|---|
| 917 | %* * |
|---|
| 918 | %************************************************************************ |
|---|
| 919 | |
|---|
| 920 | \begin{code} |
|---|
| 921 | data FloatingBind |
|---|
| 922 | = FloatLet CoreBind -- Rhs of bindings are CpeRhss |
|---|
| 923 | -- They are always of lifted type; |
|---|
| 924 | -- unlifted ones are done with FloatCase |
|---|
| 925 | |
|---|
| 926 | | FloatCase |
|---|
| 927 | Id CpeBody |
|---|
| 928 | Bool -- The bool indicates "ok-for-speculation" |
|---|
| 929 | |
|---|
| 930 | data Floats = Floats OkToSpec (OrdList FloatingBind) |
|---|
| 931 | |
|---|
| 932 | instance Outputable FloatingBind where |
|---|
| 933 | ppr (FloatLet b) = ppr b |
|---|
| 934 | ppr (FloatCase b r ok) = brackets (ppr ok) <+> ppr b <+> equals <+> ppr r |
|---|
| 935 | |
|---|
| 936 | instance Outputable Floats where |
|---|
| 937 | ppr (Floats flag fs) = ptext (sLit "Floats") <> brackets (ppr flag) <+> |
|---|
| 938 | braces (vcat (map ppr (fromOL fs))) |
|---|
| 939 | |
|---|
| 940 | instance Outputable OkToSpec where |
|---|
| 941 | ppr OkToSpec = ptext (sLit "OkToSpec") |
|---|
| 942 | ppr IfUnboxedOk = ptext (sLit "IfUnboxedOk") |
|---|
| 943 | ppr NotOkToSpec = ptext (sLit "NotOkToSpec") |
|---|
| 944 | |
|---|
| 945 | -- Can we float these binds out of the rhs of a let? We cache this decision |
|---|
| 946 | -- to avoid having to recompute it in a non-linear way when there are |
|---|
| 947 | -- deeply nested lets. |
|---|
| 948 | data OkToSpec |
|---|
| 949 | = OkToSpec -- Lazy bindings of lifted type |
|---|
| 950 | | IfUnboxedOk -- A mixture of lazy lifted bindings and n |
|---|
| 951 | -- ok-to-speculate unlifted bindings |
|---|
| 952 | | NotOkToSpec -- Some not-ok-to-speculate unlifted bindings |
|---|
| 953 | |
|---|
| 954 | mkFloat :: Bool -> Bool -> Id -> CpeRhs -> FloatingBind |
|---|
| 955 | mkFloat is_strict is_unlifted bndr rhs |
|---|
| 956 | | use_case = FloatCase bndr rhs (exprOkForSpeculation rhs) |
|---|
| 957 | | otherwise = FloatLet (NonRec bndr rhs) |
|---|
| 958 | where |
|---|
| 959 | use_case = is_unlifted || is_strict && not (exprIsHNF rhs) |
|---|
| 960 | -- Don't make a case for a value binding, |
|---|
| 961 | -- even if it's strict. Otherwise we get |
|---|
| 962 | -- case (\x -> e) of ...! |
|---|
| 963 | |
|---|
| 964 | emptyFloats :: Floats |
|---|
| 965 | emptyFloats = Floats OkToSpec nilOL |
|---|
| 966 | |
|---|
| 967 | isEmptyFloats :: Floats -> Bool |
|---|
| 968 | isEmptyFloats (Floats _ bs) = isNilOL bs |
|---|
| 969 | |
|---|
| 970 | wrapBinds :: Floats -> CpeBody -> CpeBody |
|---|
| 971 | wrapBinds (Floats _ binds) body |
|---|
| 972 | = foldrOL mk_bind body binds |
|---|
| 973 | where |
|---|
| 974 | mk_bind (FloatCase bndr rhs _) body = Case rhs bndr (exprType body) [(DEFAULT, [], body)] |
|---|
| 975 | mk_bind (FloatLet bind) body = Let bind body |
|---|
| 976 | |
|---|
| 977 | addFloat :: Floats -> FloatingBind -> Floats |
|---|
| 978 | addFloat (Floats ok_to_spec floats) new_float |
|---|
| 979 | = Floats (combine ok_to_spec (check new_float)) (floats `snocOL` new_float) |
|---|
| 980 | where |
|---|
| 981 | check (FloatLet _) = OkToSpec |
|---|
| 982 | check (FloatCase _ _ ok_for_spec) |
|---|
| 983 | | ok_for_spec = IfUnboxedOk |
|---|
| 984 | | otherwise = NotOkToSpec |
|---|
| 985 | -- The ok-for-speculation flag says that it's safe to |
|---|
| 986 | -- float this Case out of a let, and thereby do it more eagerly |
|---|
| 987 | -- We need the top-level flag because it's never ok to float |
|---|
| 988 | -- an unboxed binding to the top level |
|---|
| 989 | |
|---|
| 990 | unitFloat :: FloatingBind -> Floats |
|---|
| 991 | unitFloat = addFloat emptyFloats |
|---|
| 992 | |
|---|
| 993 | appendFloats :: Floats -> Floats -> Floats |
|---|
| 994 | appendFloats (Floats spec1 floats1) (Floats spec2 floats2) |
|---|
| 995 | = Floats (combine spec1 spec2) (floats1 `appOL` floats2) |
|---|
| 996 | |
|---|
| 997 | concatFloats :: [Floats] -> OrdList FloatingBind |
|---|
| 998 | concatFloats = foldr (\ (Floats _ bs1) bs2 -> appOL bs1 bs2) nilOL |
|---|
| 999 | |
|---|
| 1000 | combine :: OkToSpec -> OkToSpec -> OkToSpec |
|---|
| 1001 | combine NotOkToSpec _ = NotOkToSpec |
|---|
| 1002 | combine _ NotOkToSpec = NotOkToSpec |
|---|
| 1003 | combine IfUnboxedOk _ = IfUnboxedOk |
|---|
| 1004 | combine _ IfUnboxedOk = IfUnboxedOk |
|---|
| 1005 | combine _ _ = OkToSpec |
|---|
| 1006 | |
|---|
| 1007 | deFloatTop :: Floats -> [CoreBind] |
|---|
| 1008 | -- For top level only; we don't expect any FloatCases |
|---|
| 1009 | deFloatTop (Floats _ floats) |
|---|
| 1010 | = foldrOL get [] floats |
|---|
| 1011 | where |
|---|
| 1012 | get (FloatLet b) bs = occurAnalyseRHSs b : bs |
|---|
| 1013 | get b _ = pprPanic "corePrepPgm" (ppr b) |
|---|
| 1014 | |
|---|
| 1015 | -- See Note [Dead code in CorePrep] |
|---|
| 1016 | occurAnalyseRHSs (NonRec x e) = NonRec x (fst (dropDeadCode e)) |
|---|
| 1017 | occurAnalyseRHSs (Rec xes) = Rec [ (x, fst (dropDeadCode e)) |
|---|
| 1018 | | (x, e) <- xes] |
|---|
| 1019 | |
|---|
| 1020 | --------------------------------------------------------------------------- |
|---|
| 1021 | -- Simple dead-code analyser, see Note [Dead code in CorePrep] |
|---|
| 1022 | |
|---|
| 1023 | dropDeadCode :: CoreExpr -> (CoreExpr, VarSet) |
|---|
| 1024 | dropDeadCode (Var v) |
|---|
| 1025 | = (Var v, if isLocalId v then unitVarSet v else emptyVarSet) |
|---|
| 1026 | dropDeadCode (App fun arg) |
|---|
| 1027 | = (App fun' arg', fun_fvs `unionVarSet` arg_fvs) |
|---|
| 1028 | where !(fun', fun_fvs) = dropDeadCode fun |
|---|
| 1029 | !(arg', arg_fvs) = dropDeadCode arg |
|---|
| 1030 | dropDeadCode (Lam v e) |
|---|
| 1031 | = (Lam v e', delVarSet fvs v) |
|---|
| 1032 | where !(e', fvs) = dropDeadCode e |
|---|
| 1033 | dropDeadCode (Let (NonRec v rhs) body) |
|---|
| 1034 | | v `elemVarSet` body_fvs |
|---|
| 1035 | = (Let (NonRec v rhs') body', rhs_fvs `unionVarSet` (body_fvs `delVarSet` v)) |
|---|
| 1036 | | otherwise |
|---|
| 1037 | = (body', body_fvs) -- drop the dead let bind! |
|---|
| 1038 | where !(body', body_fvs) = dropDeadCode body |
|---|
| 1039 | !(rhs', rhs_fvs) = dropDeadCode rhs |
|---|
| 1040 | dropDeadCode (Let (Rec prs) body) |
|---|
| 1041 | | any (`elemVarSet` all_fvs) bndrs |
|---|
| 1042 | -- approximation: strictly speaking we should do SCC analysis here, |
|---|
| 1043 | -- but for simplicity we just look to see whether any of the binders |
|---|
| 1044 | -- is used and drop the entire group if all are unused. |
|---|
| 1045 | = (Let (Rec (zip bndrs rhss')) body', all_fvs `delVarSetList` bndrs) |
|---|
| 1046 | | otherwise |
|---|
| 1047 | = (body', body_fvs) -- drop the dead let bind! |
|---|
| 1048 | where !(body', body_fvs) = dropDeadCode body |
|---|
| 1049 | !(bndrs, rhss) = unzip prs |
|---|
| 1050 | !(rhss', rhs_fvss) = unzip (map dropDeadCode rhss) |
|---|
| 1051 | all_fvs = unionVarSets (body_fvs : rhs_fvss) |
|---|
| 1052 | |
|---|
| 1053 | dropDeadCode (Case scrut bndr t alts) |
|---|
| 1054 | = (Case scrut' bndr t alts', scrut_fvs `unionVarSet` alts_fvs) |
|---|
| 1055 | where !(scrut', scrut_fvs) = dropDeadCode scrut |
|---|
| 1056 | !(alts', alts_fvs) = dropDeadCodeAlts alts |
|---|
| 1057 | dropDeadCode (Cast e c) |
|---|
| 1058 | = (Cast e' c, fvs) |
|---|
| 1059 | where !(e', fvs) = dropDeadCode e |
|---|
| 1060 | dropDeadCode (Tick t e) |
|---|
| 1061 | = (Tick t e', fvs') |
|---|
| 1062 | where !(e', fvs) = dropDeadCode e |
|---|
| 1063 | fvs' | Breakpoint _ xs <- t = fvs `unionVarSet` mkVarSet xs |
|---|
| 1064 | | otherwise = fvs |
|---|
| 1065 | dropDeadCode e = (e, emptyVarSet) -- Lit, Type, Coercion |
|---|
| 1066 | |
|---|
| 1067 | dropDeadCodeAlts :: [CoreAlt] -> ([CoreAlt], VarSet) |
|---|
| 1068 | dropDeadCodeAlts alts = (alts', unionVarSets fvss) |
|---|
| 1069 | where !(alts', fvss) = unzip (map do_alt alts) |
|---|
| 1070 | do_alt (c, vs, e) = ((c,vs,e'), fvs `delVarSetList` vs) |
|---|
| 1071 | where !(e', fvs) = dropDeadCode e |
|---|
| 1072 | |
|---|
| 1073 | ------------------------------------------- |
|---|
| 1074 | canFloatFromNoCaf :: Floats -> CpeRhs -> Maybe (Floats, CpeRhs) |
|---|
| 1075 | -- Note [CafInfo and floating] |
|---|
| 1076 | canFloatFromNoCaf (Floats ok_to_spec fs) rhs |
|---|
| 1077 | | OkToSpec <- ok_to_spec -- Worth trying |
|---|
| 1078 | , Just (subst, fs') <- go (emptySubst, nilOL) (fromOL fs) |
|---|
| 1079 | = Just (Floats OkToSpec fs', subst_expr subst rhs) |
|---|
| 1080 | | otherwise |
|---|
| 1081 | = Nothing |
|---|
| 1082 | where |
|---|
| 1083 | subst_expr = substExpr (text "CorePrep") |
|---|
| 1084 | |
|---|
| 1085 | go :: (Subst, OrdList FloatingBind) -> [FloatingBind] |
|---|
| 1086 | -> Maybe (Subst, OrdList FloatingBind) |
|---|
| 1087 | |
|---|
| 1088 | go (subst, fbs_out) [] = Just (subst, fbs_out) |
|---|
| 1089 | |
|---|
| 1090 | go (subst, fbs_out) (FloatLet (NonRec b r) : fbs_in) |
|---|
| 1091 | | rhs_ok r |
|---|
| 1092 | = go (subst', fbs_out `snocOL` new_fb) fbs_in |
|---|
| 1093 | where |
|---|
| 1094 | (subst', b') = set_nocaf_bndr subst b |
|---|
| 1095 | new_fb = FloatLet (NonRec b' (subst_expr subst r)) |
|---|
| 1096 | |
|---|
| 1097 | go (subst, fbs_out) (FloatLet (Rec prs) : fbs_in) |
|---|
| 1098 | | all rhs_ok rs |
|---|
| 1099 | = go (subst', fbs_out `snocOL` new_fb) fbs_in |
|---|
| 1100 | where |
|---|
| 1101 | (bs,rs) = unzip prs |
|---|
| 1102 | (subst', bs') = mapAccumL set_nocaf_bndr subst bs |
|---|
| 1103 | rs' = map (subst_expr subst') rs |
|---|
| 1104 | new_fb = FloatLet (Rec (bs' `zip` rs')) |
|---|
| 1105 | |
|---|
| 1106 | go _ _ = Nothing -- Encountered a caffy binding |
|---|
| 1107 | |
|---|
| 1108 | ------------ |
|---|
| 1109 | set_nocaf_bndr subst bndr |
|---|
| 1110 | = (extendIdSubst subst bndr (Var bndr'), bndr') |
|---|
| 1111 | where |
|---|
| 1112 | bndr' = bndr `setIdCafInfo` NoCafRefs |
|---|
| 1113 | |
|---|
| 1114 | ------------ |
|---|
| 1115 | rhs_ok :: CoreExpr -> Bool |
|---|
| 1116 | -- We can only float to top level from a NoCaf thing if |
|---|
| 1117 | -- the new binding is static. However it can't mention |
|---|
| 1118 | -- any non-static things or it would *already* be Caffy |
|---|
| 1119 | rhs_ok = rhsIsStatic (\_ -> False) |
|---|
| 1120 | |
|---|
| 1121 | wantFloatNested :: RecFlag -> Bool -> Floats -> CpeRhs -> Bool |
|---|
| 1122 | wantFloatNested is_rec strict_or_unlifted floats rhs |
|---|
| 1123 | = isEmptyFloats floats |
|---|
| 1124 | || strict_or_unlifted |
|---|
| 1125 | || (allLazyNested is_rec floats && exprIsHNF rhs) |
|---|
| 1126 | -- Why the test for allLazyNested? |
|---|
| 1127 | -- v = f (x `divInt#` y) |
|---|
| 1128 | -- we don't want to float the case, even if f has arity 2, |
|---|
| 1129 | -- because floating the case would make it evaluated too early |
|---|
| 1130 | |
|---|
| 1131 | allLazyTop :: Floats -> Bool |
|---|
| 1132 | allLazyTop (Floats OkToSpec _) = True |
|---|
| 1133 | allLazyTop _ = False |
|---|
| 1134 | |
|---|
| 1135 | allLazyNested :: RecFlag -> Floats -> Bool |
|---|
| 1136 | allLazyNested _ (Floats OkToSpec _) = True |
|---|
| 1137 | allLazyNested _ (Floats NotOkToSpec _) = False |
|---|
| 1138 | allLazyNested is_rec (Floats IfUnboxedOk _) = isNonRec is_rec |
|---|
| 1139 | \end{code} |
|---|
| 1140 | |
|---|
| 1141 | |
|---|
| 1142 | %************************************************************************ |
|---|
| 1143 | %* * |
|---|
| 1144 | Cloning |
|---|
| 1145 | %* * |
|---|
| 1146 | %************************************************************************ |
|---|
| 1147 | |
|---|
| 1148 | \begin{code} |
|---|
| 1149 | -- --------------------------------------------------------------------------- |
|---|
| 1150 | -- The environment |
|---|
| 1151 | -- --------------------------------------------------------------------------- |
|---|
| 1152 | |
|---|
| 1153 | data CorePrepEnv = CPE (IdEnv Id) -- Clone local Ids |
|---|
| 1154 | |
|---|
| 1155 | emptyCorePrepEnv :: CorePrepEnv |
|---|
| 1156 | emptyCorePrepEnv = CPE emptyVarEnv |
|---|
| 1157 | |
|---|
| 1158 | extendCorePrepEnv :: CorePrepEnv -> Id -> Id -> CorePrepEnv |
|---|
| 1159 | extendCorePrepEnv (CPE env) id id' = CPE (extendVarEnv env id id') |
|---|
| 1160 | |
|---|
| 1161 | extendCorePrepEnvList :: CorePrepEnv -> [(Id,Id)] -> CorePrepEnv |
|---|
| 1162 | extendCorePrepEnvList (CPE env) prs = CPE (extendVarEnvList env prs) |
|---|
| 1163 | |
|---|
| 1164 | lookupCorePrepEnv :: CorePrepEnv -> Id -> Id |
|---|
| 1165 | lookupCorePrepEnv (CPE env) id |
|---|
| 1166 | = case lookupVarEnv env id of |
|---|
| 1167 | Nothing -> id |
|---|
| 1168 | Just id' -> id' |
|---|
| 1169 | |
|---|
| 1170 | ------------------------------------------------------------------------------ |
|---|
| 1171 | -- Cloning binders |
|---|
| 1172 | -- --------------------------------------------------------------------------- |
|---|
| 1173 | |
|---|
| 1174 | cpCloneBndrs :: CorePrepEnv -> [Var] -> UniqSM (CorePrepEnv, [Var]) |
|---|
| 1175 | cpCloneBndrs env bs = mapAccumLM cpCloneBndr env bs |
|---|
| 1176 | |
|---|
| 1177 | cpCloneBndr :: CorePrepEnv -> Var -> UniqSM (CorePrepEnv, Var) |
|---|
| 1178 | cpCloneBndr env bndr |
|---|
| 1179 | | isLocalId bndr, not (isCoVar bndr) |
|---|
| 1180 | = do bndr' <- setVarUnique bndr <$> getUniqueM |
|---|
| 1181 | |
|---|
| 1182 | -- We are going to OccAnal soon, so drop (now-useless) rules/unfoldings |
|---|
| 1183 | -- so that we can drop more stuff as dead code. |
|---|
| 1184 | -- See also Note [Dead code in CorePrep] |
|---|
| 1185 | let bndr'' = bndr' `setIdUnfolding` noUnfolding |
|---|
| 1186 | `setIdSpecialisation` emptySpecInfo |
|---|
| 1187 | return (extendCorePrepEnv env bndr bndr'', bndr'') |
|---|
| 1188 | |
|---|
| 1189 | | otherwise -- Top level things, which we don't want |
|---|
| 1190 | -- to clone, have become GlobalIds by now |
|---|
| 1191 | -- And we don't clone tyvars, or coercion variables |
|---|
| 1192 | = return (env, bndr) |
|---|
| 1193 | |
|---|
| 1194 | |
|---|
| 1195 | ------------------------------------------------------------------------------ |
|---|
| 1196 | -- Cloning ccall Ids; each must have a unique name, |
|---|
| 1197 | -- to give the code generator a handle to hang it on |
|---|
| 1198 | -- --------------------------------------------------------------------------- |
|---|
| 1199 | |
|---|
| 1200 | fiddleCCall :: Id -> UniqSM Id |
|---|
| 1201 | fiddleCCall id |
|---|
| 1202 | | isFCallId id = (id `setVarUnique`) <$> getUniqueM |
|---|
| 1203 | | otherwise = return id |
|---|
| 1204 | |
|---|
| 1205 | ------------------------------------------------------------------------------ |
|---|
| 1206 | -- Generating new binders |
|---|
| 1207 | -- --------------------------------------------------------------------------- |
|---|
| 1208 | |
|---|
| 1209 | newVar :: Type -> UniqSM Id |
|---|
| 1210 | newVar ty |
|---|
| 1211 | = seqType ty `seq` do |
|---|
| 1212 | uniq <- getUniqueM |
|---|
| 1213 | return (mkSysLocal (fsLit "sat") uniq ty) |
|---|
| 1214 | \end{code} |
|---|