3 -- Copyright (c) [2001..2002] Manuel M T Chakravarty & Gabriele Keller
5 -- Vectorisation and lifting
7 --- DESCRIPTION ---------------------------------------------------------------
9 -- This module implements the vectorisation and function lifting
10 -- transformations of the flattening transformation.
12 --- DOCU ----------------------------------------------------------------------
14 -- Language: Haskell 98 with C preprocessor
17 -- the transformation on types has five purposes:
19 -- 1) for each type definition, derive the lifted version of this type
21 -- 2) change the type annotations of functions & variables acc. to rep.
23 -- 3) derive the type of a lifted function
26 -- this is the most fuzzy and complicated part. For each lifted
27 -- sumtype we need to generate function to access and combine the
30 -- NOTE: the type information of variables and data constructors is *not*
31 -- changed to reflect it's representation. This has to be solved
32 -- somehow (???, FIXME) using type indexed types
35 -- is very naive at the moment. One of the most striking inefficiencies is
36 -- application vect (app e1 e2) -> app (fst (vect e1) (vect e2)) if e1 is a
37 -- lambda abstraction. The vectorisation produces a pair consisting of the
38 -- original and the lifted function, but the lifted version is discarded.
39 -- I'm also not sure how much of this would be thrown out by the simplifier
46 --- TODO ----------------------------------------------------------------------
48 -- * look closer into the definition of type definition (TypeThing or so)
56 import Monad (liftM, foldM)
59 import CmdLineOpts (opt_Flatten)
61 import ErrUtils (dumpIfSet_dyn)
62 import UniqSupply (UniqSupply, mkSplitUniqSupply)
63 import CmdLineOpts (DynFlag(..), DynFlags)
64 import Literal (Literal, literalType)
65 import Var (Var(..),TyVar)
66 import DataCon (DataCon, dataConTag)
67 import TypeRep (Type(..))
68 import Type (isTypeKind)
69 import HscTypes (HomeSymbolTable, PersistentCompilerState, ModDetails(..))
70 import CoreFVs (exprFreeVars)
71 import CoreSyn (Expr(..), Bind(..), Alt(..), AltCon(..), Note(..),
72 CoreBndr, CoreExpr, CoreBind, CoreAlt, mkLams, mkLets,
74 import PprCore (pprCoreExpr)
75 import CoreLint (showPass, endPass)
77 import CoreUtils (exprType, applyTypeToArg, mkPiType)
78 import VarEnv (IdEnv, mkVarEnv, zipVarEnv, extendVarEnv)
79 import TysWiredIn (mkTupleTy)
80 import BasicTypes (Boxity(..))
81 import Outputable (showSDoc, Outputable(..))
85 import NDPCoreUtils (tupleTyArgs, funTyArgs, parrElemTy, isDefault,
86 isLit, mkPArrTy, mkTuple, isSimpleExpr, boolTy, substIdEnv)
87 import FlattenMonad (Flatten, runFlatten, mkBind, extendContext, packContext,
88 liftVar, liftConst, intersectWithContext, mk'fst,
89 mk'lengthP, mk'replicateP, mk'mapP, mk'bpermuteDftP,
90 mk'indexOfP,mk'eq,mk'neq)
92 -- FIXME: fro debugging - remove this
96 #include "HsVersions.h"
99 -- toplevel transformation
100 -- -----------------------
102 -- entry point to the flattening transformation for the compiler driver when
103 -- compiling a complete module (EXPORTED)
106 -> PersistentCompilerState
108 -> ModDetails -- the module to be flattened
110 flatten dflags pcs hst modDetails@(ModDetails {md_binds = binds})
111 | not opt_Flatten = return modDetails -- skip without -fflatten
114 us <- mkSplitUniqSupply 'l' -- 'l' as in fLattening
116 -- announce vectorisation
118 showPass dflags "Flattening [first phase: vectorisation]"
120 -- vectorise all toplevel bindings
122 let binds' = runFlatten pcs hst us $ vectoriseTopLevelBinds binds
124 -- and dump the result if requested
126 endPass dflags "Flattening [first phase: vectorisation]"
127 Opt_D_dump_vect binds'
128 return $ modDetails {md_binds = binds'}
130 -- entry point to the flattening transformation for the compiler driver when
131 -- compiling a single expression in interactive mode (EXPORTED)
133 flattenExpr :: DynFlags
134 -> PersistentCompilerState
136 -> CoreExpr -- the expression to be flattened
138 flattenExpr dflags pcs hst expr
139 | not opt_Flatten = return expr -- skip without -fflatten
142 us <- mkSplitUniqSupply 'l' -- 'l' as in fLattening
144 -- announce vectorisation
146 showPass dflags "Flattening [first phase: vectorisation]"
148 -- vectorise the expression
150 let expr' = fst . runFlatten pcs hst us $ vectorise expr
152 -- and dump the result if requested
154 dumpIfSet_dyn dflags Opt_D_dump_vect "Vectorised expression"
159 -- vectorisation of bindings and expressions
160 -- -----------------------------------------
163 vectoriseTopLevelBinds:: [CoreBind] -> Flatten [CoreBind]
164 vectoriseTopLevelBinds binds =
166 vbinds <- mapM vectoriseBind binds
167 return (adjustTypeBinds vbinds)
169 adjustTypeBinds:: [CoreBind] -> [CoreBind]
170 adjustTypeBinds vbinds =
172 ids = concat (map extIds vbinds)
173 idEnv = zipVarEnv ids ids
174 in map (substIdEnvBind idEnv) vbinds
176 -- FIXME replace by 'bindersOf'
177 extIds (NonRec b expr) = [b]
178 extIds (Rec bnds) = map fst bnds
179 substIdEnvBind idEnv (NonRec b expr) = NonRec b (substIdEnv idEnv expr)
180 substIdEnvBind idEnv (Rec bnds)
181 = Rec (map (\ (b,e) -> (b, (substIdEnv idEnv e))) bnds)
183 -- vectorise a single core binder
185 vectoriseBind :: CoreBind -> Flatten CoreBind
186 vectoriseBind (NonRec b expr) =
187 liftM (NonRec b) $ liftM fst $ vectorise expr
188 vectoriseBind (Rec bindings) =
189 liftM Rec $ mapM vectoriseOne bindings
191 vectoriseOne (b, expr) =
193 (vexpr, ty) <- vectorise expr
194 return (b{varType = ty}, vexpr)
197 -- Searches for function definitions and creates a lifted version for
199 -- We have only two interesting cases:
200 -- 1) function application (ex1) (ex2)
201 -- vectorise both subexpressions. The function will end up becoming a
202 -- pair (orig. fun, lifted fun), choose first component (in many cases,
203 -- this is pretty inefficient, since the lifted version is generated
204 -- although it is clear that it won't be used
206 -- 2) lambda abstraction
207 -- any function has to exist in two forms: it's original form and it's
208 -- lifted form. Therefore, every lambda abstraction is transformed into
209 -- a pair of functions: the original function and its lifted variant
212 -- FIXME: currently, I use 'exprType' all over the place - this is terribly
213 -- inefficient. It should be suffiecient to change 'vectorise' and 'lift' to
214 -- return the type of the result expression as well.
216 vectorise:: CoreExpr -> Flatten (CoreExpr, Type)
219 let varTy = varType id
220 let vecTy = vectoriseTy varTy
221 return ((Var id{varType = vecTy}), vecTy)
223 vectorise (Lit lit) =
224 return ((Lit lit), literalType lit)
227 vectorise e@(App expr t@(Type _)) =
229 (vexpr, vexprTy) <- vectorise expr
230 return ((App vexpr t), applyTypeToArg vexprTy t)
232 vectorise (App (Lam b expr) arg) =
234 (varg, argTy) <- vectorise arg
235 (vexpr, vexprTy) <- vectorise expr
236 let vb = b{varType = argTy}
237 return ((App (Lam vb vexpr) varg),
238 applyTypeToArg (mkPiType vb vexprTy) varg)
240 -- if vexpr expects a type as first argument
241 -- application stays just as it is
243 vectorise (App expr arg) =
245 (vexpr, vexprTy) <- vectorise expr
246 (varg, vargTy) <- vectorise arg
248 if (isPolyType vexprTy)
250 let resTy = applyTypeToArg vexprTy varg
251 return (App vexpr varg, resTy)
253 let [t1, t2] = tupleTyArgs vexprTy
254 vexpr' <- mk'fst t1 t2 vexpr
255 let resTy = applyTypeToArg t1 varg
256 return ((App vexpr' varg), resTy) -- apply the first component of
257 -- the vectorized function
261 (ForAllTy _ _) -> True
262 (NoteTy _ nt) -> isPolyType nt
266 vectorise e@(Lam b expr)
267 | isTypeKind (varType b) =
269 (vexpr, vexprTy) <- vectorise expr -- don't vectorise 'b'!
270 return ((Lam b vexpr), mkPiType b vexprTy)
273 (vexpr, vexprTy) <- vectorise expr
274 let vb = b{varType = vectoriseTy (varType b)}
275 let ve = Lam vb vexpr
276 (lexpr, lexprTy) <- lift e
277 let veTy = mkPiType vb vexprTy
278 return $ (mkTuple [veTy, lexprTy] [ve, lexpr],
279 mkTupleTy Boxed 2 [veTy, lexprTy])
281 vectorise (Let bind body) =
283 vbind <- vectoriseBind bind
284 (vbody, vbodyTy) <- vectorise body
285 return ((Let vbind vbody), vbodyTy)
287 vectorise (Case expr b alts) =
289 (vexpr, vexprTy) <- vectorise expr
290 valts <- mapM vectorise' alts
291 return (Case vexpr b{varType = vexprTy} (map fst valts), snd (head valts))
292 where vectorise' (con, bs, expr) =
294 (vexpr, vexprTy) <- vectorise expr
295 return ((con, bs, vexpr), vexprTy) -- FIXME: change type of con
300 vectorise (Note note expr) =
302 (vexpr, vexprTy) <- vectorise expr -- FIXME: is this ok or does it
303 return ((Note note vexpr), vexprTy) -- change the validity of note?
305 vectorise e@(Type t) =
306 return (e, t) -- FIXME: panic instead of 't'???
310 myShowTy (TyVarTy _) = "TyVar "
311 myShowTy (AppTy t1 t2) =
312 "AppTy (" ++ (myShowTy t1) ++ ", " ++ (myShowTy t2) ++ ")"
313 myShowTy (TyConApp _ t) =
314 "TyConApp TC (" ++ (myShowTy t) ++ ")"
317 vectoriseTy :: Type -> Type
318 vectoriseTy t@(TyVarTy v) = t
319 vectoriseTy t@(AppTy t1 t2) =
320 AppTy (vectoriseTy t1) (vectoriseTy t2)
321 vectoriseTy t@(TyConApp tc ts) =
322 TyConApp tc (map vectoriseTy ts)
323 vectoriseTy t@(FunTy t1 t2) =
324 mkTupleTy Boxed 2 [(FunTy (vectoriseTy t1) (vectoriseTy t2)),
326 vectoriseTy t@(ForAllTy v ty) =
327 ForAllTy v (vectoriseTy ty)
328 vectoriseTy t@(NoteTy note ty) = -- FIXME: is the note still valid after
329 NoteTy note (vectoriseTy ty) -- this or should we just throw it away
333 -- liftTy: wrap the type in an array but be careful with function types
334 -- on the *top level* (is this sufficient???)
336 liftTy:: Type -> Type
337 liftTy (FunTy t1 t2) = FunTy (liftTy t1) (liftTy t2)
338 liftTy (ForAllTy tv t) = ForAllTy tv (liftTy t)
339 liftTy (NoteTy n t) = NoteTy n $ liftTy t
340 liftTy t = mkPArrTy t
349 -- liftBinderType: Converts a type 'a' stored in the binder to the
350 -- representation of '[:a:]' will therefore call liftType
352 -- lift type, don't change name (incl unique) nor IdInfo. IdInfo looks ok,
353 -- but I'm not entirely sure about some fields (e.g., strictness info)
354 liftBinderType:: CoreBndr -> Flatten CoreBndr
355 liftBinderType bndr = return $ bndr {varType = liftTy (varType bndr)}
357 -- lift: lifts an expression (a -> [:a:])
358 -- If the expression is a simple expression, it is treated like a constant
360 -- If the body of a lambda expression is a simple expression, it is
361 -- transformed into a mapP
362 lift:: CoreExpr -> Flatten (CoreExpr, Type)
363 lift cExpr@(Var id) =
365 lVar@(Var lId) <- liftVar id
366 return (lVar, varType lId)
368 lift cExpr@(Lit lit) =
370 lLit <- liftConst cExpr
371 return (lLit, exprType lLit)
375 | isSimpleExpr expr = liftSimpleFun b expr
376 | isTypeKind (varType b) =
378 (lexpr, lexprTy) <- lift expr -- don't lift b!
379 return (Lam b lexpr, mkPiType b lexprTy)
382 lb <- liftBinderType b
383 (lexpr, lexprTy) <- extendContext [lb] (lift expr)
384 return ((Lam lb lexpr) , mkPiType lb lexprTy)
386 lift (App expr1 expr2) =
388 (lexpr1, lexpr1Ty) <- lift expr1
389 (lexpr2, _) <- lift expr2
390 return ((App lexpr1 lexpr2), applyTypeToArg lexpr1Ty lexpr2)
393 lift (Let (NonRec b expr1) expr2)
394 |isSimpleExpr expr2 =
396 (lexpr1, _) <- lift expr1
397 (lexpr2, lexpr2Ty) <- liftSimpleFun b expr2
398 let (t1, t2) = funTyArgs lexpr2Ty
399 liftM (\x -> (x, liftTy t2)) $ mk'mapP t1 t2 lexpr2 lexpr1
403 (lexpr1, _) <- lift expr1
404 lb <- liftBinderType b
405 (lexpr2, lexpr2Ty) <- extendContext [lb] (lift expr1)
406 return ((Let (NonRec lb lexpr1) lexpr2), lexpr2Ty)
408 lift (Let (Rec binds) expr2) =
410 let (bndVars, exprs) = unzip binds
411 lBndVars <- mapM liftBinderType bndVars
412 lexprs <- extendContext bndVars (mapM lift exprs)
413 (lexpr2, lexpr2Ty) <- extendContext bndVars (lift expr2)
414 return ((Let (Rec (zip lBndVars (map fst lexprs))) lexpr2), lexpr2Ty)
417 -- Assumption: alternatives can either be literals or data construtors.
418 -- Due to type restrictions, I don't think it is possible
419 -- that they are mixed.
420 -- The handling of literals and data constructors is completely
424 -- let b = expr in alts
426 -- I think I read somewhere that the default case (if present) is stored
427 -- in the head of the list. Assume for now this is true, have to check
430 -- (2) data constructors
432 -- FIXME: optimisation: first, filter out all simple expression and
433 -- loop (mapP & filter) over all the corresponding values in a single
436 -- (1) splitAlts:: [Alt CoreBndr] -> ([Alt CoreBndr],[Alt CoreBndr])
437 -- simple alts reg alts
438 -- (2) if simpleAlts = [] then (just as before)
439 -- if regAlts = [] then (the whole thing is just a loop)
440 -- otherwise (a) compute index vector for simpleAlts (for def permute
443 lift cExpr@(Case expr b alts) =
445 (lExpr, _) <- lift expr
446 lb <- liftBinderType b -- lift alt-expression
447 lalts <- if isLit alts
448 then extendContext [lb] (liftCaseLit b alts)
449 else extendContext [lb] (liftCaseDataCon b alts)
450 letWrapper lExpr b lalts
452 lift (Note (Coerce t1 t2) expr) =
454 (lexpr, t) <- lift expr
456 return ((Note (Coerce lt1 (liftTy t2)) lexpr), lt1)
458 lift (Note note expr) =
460 (lexpr, t) <- lift expr
461 return ((Note note lexpr), t)
463 lift e@(Type t) = return (e, t)
466 -- auxilliary functions for lifting of case statements
469 liftCaseDataCon:: CoreBndr -> [Alt CoreBndr] ->
470 Flatten (([CoreBind], [CoreBind], [CoreBind]))
471 liftCaseDataCon b [] =
473 liftCaseDataCon b alls@(alt:alts)
476 (i, e, defAltBndrs) <- liftCaseDataConDefault b alt alts
477 (is, es, altBndrs) <- liftCaseDataCon' b alts
478 return (i:is, e:es, defAltBndrs ++ altBndrs)
480 liftCaseDataCon' b alls
482 liftCaseDataCon':: CoreBndr -> [Alt CoreBndr] ->
483 Flatten ([CoreBind], [CoreBind], [CoreBind])
484 liftCaseDataCon' _ [] =
489 liftCaseDataCon' b ((DataAlt dcon, bnds, expr): alts) =
491 (permBnd, exprBnd, packBnd) <- liftSingleDataCon b dcon bnds expr
492 (permBnds, exprBnds, packBnds) <- liftCaseDataCon' b alts
493 return (permBnd:permBnds, exprBnd:exprBnds, packBnd ++ packBnds)
496 -- FIXME: is is really necessary to return the binding to the permutation
497 -- array in the data constructor case, as the representation already
498 -- contains the extended flag vector
499 liftSingleDataCon:: CoreBndr -> DataCon -> [CoreBndr] -> CoreExpr ->
500 Flatten (CoreBind, CoreBind, [CoreBind])
501 liftSingleDataCon b dcon bnds expr =
503 let dconId = dataConTag dcon
504 indexExpr <- mkIndexOfExprDCon (varType b) b dconId
505 (bb, bbind) <- mkBind FSLIT("is") indexExpr
506 lbnds <- mapM liftBinderType bnds
507 ((lExpr, _), bnds') <- packContext bb (extendContext lbnds (lift expr))
508 (_, vbind) <- mkBind FSLIT("r") lExpr
509 return (bbind, vbind, bnds')
511 -- FIXME: clean this up. the datacon and the literal case are so
512 -- similar that it would be easy to use the same function here
513 -- instead of duplicating all the code.
515 liftCaseDataConDefault:: CoreBndr -> (Alt CoreBndr) -> [Alt CoreBndr]
516 -> Flatten (CoreBind, CoreBind, [CoreBind])
517 liftCaseDataConDefault b (_, _, def) alts =
519 let dconIds = map (\(DataAlt d, _, _) -> dataConTag d) alts
520 indexExpr <- mkIndexOfExprDConDft (varType b) b dconIds
521 (bb, bbind) <- mkBind FSLIT("is") indexExpr
522 ((lDef, _), bnds) <- packContext bb (lift def)
523 (_, vbind) <- mkBind FSLIT("r") lDef
524 return (bbind, vbind, bnds)
526 -- liftCaseLit: checks if we have a default case and handles it
528 liftCaseLit:: CoreBndr -> [Alt CoreBndr] ->
529 Flatten ([CoreBind], [CoreBind], [CoreBind])
531 return ([], [], []) --FIXME: a case with no cases at all???
532 liftCaseLit b alls@(alt:alts)
535 (i, e, defAltBndrs) <- liftCaseLitDefault b alt alts
536 (is, es, altBndrs) <- liftCaseLit' b alts
537 return (i:is, e:es, defAltBndrs ++ altBndrs)
542 -- liftCaseLitDefault: looks at all the other alternatives which
543 -- contain a literal and filters all those elements from the
544 -- array which do not match any of the literals in the other
546 liftCaseLitDefault:: CoreBndr -> (Alt CoreBndr) -> [Alt CoreBndr]
547 -> Flatten (CoreBind, CoreBind, [CoreBind])
548 liftCaseLitDefault b (_, _, def) alts =
550 let lits = map (\(LitAlt l, _, _) -> l) alts
551 indexExpr <- mkIndexOfExprDft (varType b) b lits
552 (bb, bbind) <- mkBind FSLIT("is") indexExpr
553 ((lDef, _), bnds) <- packContext bb (lift def)
554 (_, vbind) <- mkBind FSLIT("r") lDef
555 return (bbind, vbind, bnds)
558 -- Assumption: in case of Lit, the list of binders of the alt is empty.
561 -- a list of all vars bound to the expr in the body of the alternative
562 -- a list of (var, expr) pairs, where var has to be bound to expr
564 liftCaseLit':: CoreBndr -> [Alt CoreBndr] ->
565 Flatten ([CoreBind], [CoreBind], [CoreBind])
569 liftCaseLit' b ((LitAlt lit, [], expr):alts) =
571 (permBnd, exprBnd, packBnd) <- liftSingleCaseLit b lit expr
572 (permBnds, exprBnds, packBnds) <- liftCaseLit' b alts
573 return (permBnd:permBnds, exprBnd:exprBnds, packBnd ++ packBnds)
575 -- lift a single alternative of the form: case b of lit -> expr.
577 -- It returns the bindings:
578 -- (a) let b' = indexOfP (mapP (\x -> x == lit) b)
580 -- (b) lift expr in the packed context. Returns lexpr and the
581 -- list of binds (bnds) that describe the packed arrays
583 -- (c) create new var v' to bind lexpr to
585 -- (d) return (b' = indexOf...., v' = lexpr, bnds)
586 liftSingleCaseLit:: CoreBndr -> Literal -> CoreExpr ->
587 Flatten (CoreBind, CoreBind, [CoreBind])
588 liftSingleCaseLit b lit expr =
590 indexExpr <- mkIndexOfExpr (varType b) b lit -- (a)
591 (bb, bbind) <- mkBind FSLIT("is") indexExpr
592 ((lExpr, t), bnds) <- packContext bb (lift expr) -- (b)
593 (_, vbind) <- mkBind FSLIT("r") lExpr
594 return (bbind, vbind, bnds)
596 -- letWrapper lExpr b ([indexbnd_i], [exprbnd_i], [pckbnd_ij])
599 -- let index_bnd_1 in
602 -- let exprbnd_1 in ....
604 -- let nvar = replicate dummy (length <current context>)
605 -- nvar1 = bpermuteDftP index_bnd_1 ...
607 -- in bpermuteDftP index_bnd_n nvar_(n-1)
609 letWrapper:: CoreExpr -> CoreBndr ->([CoreBind], [CoreBind], [CoreBind]) ->
610 Flatten (CoreExpr, Type)
611 letWrapper lExpr b (indBnds, exprBnds, pckBnds) =
613 (defBpBnds, ty) <- dftbpBinders indBnds exprBnds
614 let resExpr = getExprOfBind (head defBpBnds)
615 return ((mkLets (indBnds ++ pckBnds ++ exprBnds ++ defBpBnds) resExpr), ty)
617 -- dftbpBinders: return the list of binders necessary to construct the overall
618 -- result from the subresults computed in the different branches of the case
619 -- statement. The binding which contains the final result is in the *head*
620 -- of the result list.
622 -- dftbpBinders [ind_i = ...] [expr_i = ...] = [dn = ..., d_n-1 = .., d1 = ...]
624 -- let def = replicate (length of context) undefined
625 -- d1 = bpermuteDftP dft e1 i1
628 dftbpBinders:: [CoreBind] -> [CoreBind] -> Flatten ([CoreBind], Type)
629 dftbpBinders indexBnds exprBnds =
631 let expr = getExprOfBind (head exprBnds)
632 defVecExpr <- createDftArrayBind expr
633 ((b, bnds), t) <- dftbpBinders' indexBnds exprBnds defVecExpr
636 dftbpBinders' :: [CoreBind]
639 -> Flatten ((CoreBind, [CoreBind]), Type)
640 dftbpBinders' [] [] cBnd =
641 return ((cBnd, []), panic "dftbpBinders: undefined type")
642 dftbpBinders' (i:is) (e:es) cBind =
644 let iVar = getVarOfBind i
645 let eVar = getVarOfBind e
646 let cVar = getVarOfBind cBind
647 let ty = varType eVar
648 newBnd <- mkDftBackpermute ty iVar eVar cVar
649 ((fBnd, restBnds), _) <- dftbpBinders' is es newBnd
650 return ((fBnd, (newBnd:restBnds)), liftTy ty)
652 dftbpBinders' _ _ _ =
653 panic "Flattening.dftbpBinders: index and expression binder lists \
654 \have different length!"
656 getExprOfBind:: CoreBind -> CoreExpr
657 getExprOfBind (NonRec _ expr) = expr
659 getVarOfBind:: CoreBind -> Var
660 getVarOfBind (NonRec b _) = b
664 -- Optimised Transformation
665 -- =========================
669 -- if variables x_1 to x_i occur in the context *and* free in expr
671 -- (liftSimpleExpression expr) => mapP (\ (x1,..xn) -> expr) (x1,..xn)
673 liftSimpleFun:: CoreBndr -> CoreExpr -> Flatten (CoreExpr, Type)
674 liftSimpleFun b expr =
676 bndVars <- collectBoundVars expr
677 let bndVars' = b:bndVars
678 bndVarsTuple = mkTuple (map varType bndVars') (map Var bndVars')
679 lamExpr = mkLams (b:bndVars) expr -- FIXME: should be tuple
681 let (t1, t2) = funTyArgs . exprType $ lamExpr
682 mapExpr <- mk'mapP t1 t2 lamExpr bndVarsTuple
683 let lexpr = mkApps mapExpr [bndVarsTuple]
684 return (lexpr, undefined) -- FIXME!!!!!
687 collectBoundVars:: CoreExpr -> Flatten [CoreBndr]
688 collectBoundVars expr =
689 intersectWithContext (exprFreeVars expr)
692 -- auxilliary routines
693 -- -------------------
695 -- mkIndexOfExpr b lit ->
696 -- indexOf (mapP (\x -> x == lit) b) b
698 mkIndexOfExpr:: Type -> CoreBndr -> Literal -> Flatten CoreExpr
699 mkIndexOfExpr varType b lit =
701 eqExpr <- mk'eq varType (Var b) (Lit lit)
702 let lambdaExpr = (Lam b eqExpr)
703 mk'indexOfP varType lambdaExpr (Var b)
705 -- there is FlattenMonad.mk'indexOfP as well as
706 -- CoreSyn.mkApps and CoreSyn.mkLam, all of which should help here
708 -- for case-distinction over data constructors:
712 -- dconId = dataConTag dcon
713 -- the call "mkIndexOfExprDCon b dconId" computes the core expression for
714 -- indexOfP (\x -> x == dconId) b)
716 mkIndexOfExprDCon::Type -> CoreBndr -> Int -> Flatten CoreExpr
717 mkIndexOfExprDCon varType b dId =
719 let intExpr = mkIntLitInt dId
720 eqExpr <- mk'eq varType (Var b) intExpr
721 let lambdaExpr = (Lam b intExpr)
722 mk'indexOfP varType lambdaExpr (Var b)
726 -- there is FlattenMonad.mk'indexOfP as well as
727 -- CoreSyn.mkApps and CoreSyn.mkLam, all of which should help here
729 -- mk'IndexOfExprDConDft b dconIds : Generates the index expression for the
730 -- default case. "dconIds" is a list of all the data constructor idents which
731 -- are covered by the other cases.
732 -- indexOfP (\x -> x != dconId_1 && ....) b)
734 mkIndexOfExprDConDft:: Type -> CoreBndr -> [Int] -> Flatten CoreExpr
735 mkIndexOfExprDConDft varType b dId =
737 let intExprs = map mkIntLitInt dId
738 bExpr <- foldM (mk'neq varType) (head intExprs) (tail intExprs)
739 let lambdaExpr = (Lam b bExpr)
740 mk'indexOfP varType (Var b) bExpr
743 -- mkIndexOfExprDef b [lit1, lit2,...] ->
744 -- indexOf (\x -> not (x == lit1 || x == lit2 ....) b
745 mkIndexOfExprDft:: Type -> CoreBndr -> [Literal] -> Flatten CoreExpr
746 mkIndexOfExprDft varType b lits =
748 let litExprs = map (\l-> Lit l) lits
749 bExpr <- foldM (mk'neq varType) (head litExprs) (tail litExprs)
750 let lambdaExpr = (Lam b bExpr)
751 mk'indexOfP varType bExpr (Var b)
754 -- create a back-permute binder
756 -- * `mkDftBackpermute ty indexArrayVar srcArrayVar dftArrayVar' creates a
757 -- Core binding of the form
759 -- x = bpermuteDftP indexArrayVar srcArrayVar dftArrayVar
761 -- where `x' is a new local variable
763 mkDftBackpermute :: Type -> Var -> Var -> Var -> Flatten CoreBind
764 mkDftBackpermute ty idx src dft =
766 rhs <- mk'bpermuteDftP ty (Var idx) (Var src) (Var dft)
767 liftM snd $ mkBind FSLIT("dbp") rhs
769 -- create a dummy array with elements of the given type, which can be used as
770 -- default array for the combination of the subresults of the lifted case
773 createDftArrayBind :: CoreExpr -> Flatten CoreBind
774 createDftArrayBind e =
775 panic "Flattening.createDftArrayBind: not implemented yet"
778 let ty = parrElemTy . exprType $ expr
780 rhs <- mk'replicateP ty len err??
781 lift snd $ mkBind FSLIT("dft") rhs
782 FIXME: nicht so einfach; man kann kein "error"-Wert nehmen, denn der w"urde
783 beim bpermuteDftP sofort evaluiert, aber es ist auch schwer m"oglich einen
784 generischen Wert f"ur jeden beliebigen Typ zu erfinden.
790 -- show functions (the pretty print functions sometimes don't
791 -- show it the way I want....
793 -- shows just the structure
794 showCoreExpr (Var _ ) = "Var "
795 showCoreExpr (Lit _) = "Lit "
796 showCoreExpr (App e1 e2) =
797 "(App \n " ++ (showCoreExpr e1) ++ "\n " ++ (showCoreExpr e2) ++ ") "
798 showCoreExpr (Lam b e) =
799 "Lam b " ++ (showCoreExpr e)
800 showCoreExpr (Let bnds expr) =
801 "Let \n" ++ (showBinds bnds) ++ "in " ++ (showCoreExpr expr)
802 where showBinds (NonRec b e) = showBind (b,e)
803 showBinds (Rec bnds) = concat (map showBind bnds)
804 showBind (b,e) = " b = " ++ (showCoreExpr e)++ "\n"
805 showCoreExpr (Case ex b alts) =
806 "Case b = " ++ (showCoreExpr ex) ++ " of \n" ++ (showAlts alts)
807 where showAlts _ = ""
808 showCoreExpr (Note _ ex) = "Note n " ++ (showCoreExpr ex)
809 showCoreExpr (Type t) = "Type"