3 -- Copyright (c) [2001..2002] Manuel M T Chakravarty & Gabriele Keller
5 -- Auxiliary routines for NDP-related Core transformations.
7 --- DESCRIPTION ---------------------------------------------------------------
9 -- This module exports all functions to access and alter the `Type' data
10 -- structure from modules `Type' and `CoreExpr' from `CoreSyn'. As it is part
11 -- of the NDP flattening component, the functions provide access to all the
12 -- fields that are important for the flattening and lifting transformation.
14 --- DOCU ----------------------------------------------------------------------
16 -- Language: Haskell 98
18 --- TODO ----------------------------------------------------------------------
21 {-# OPTIONS_GHC -w #-}
22 -- The above warning supression flag is a temporary kludge.
23 -- While working on this module you are encouraged to remove it and fix
24 -- any warnings in the module. See
25 -- http://hackage.haskell.org/trac/ghc/wiki/WorkingConventions#Warnings
30 -- type inspection functions
32 tupleTyArgs, -- :: Type -> [Type]
33 funTyArgs, -- :: Type -> (Type, Type)
34 parrElemTy, -- :: Type -> Type
36 -- Core generation functions
38 mkTuple, -- :: [Type] -> [CoreExpr] -> CoreExpr
39 mkInt, -- :: CoreExpr -> CoreExpr
43 isDefault, -- :: CoreAlt -> Bool
44 isLit, -- :: [CoreAlt] -> Bool
45 isSimpleExpr, -- :: CoreExpr -> Bool
47 -- re-exported functions
49 mkPArrTy, -- :: Type -> Type
59 import Outputable (Outputable(ppr), pprPanic)
60 import BasicTypes (Boxity(..))
61 import Type (Type, splitTyConApp_maybe, splitFunTy)
62 import TyCon (isTupleTyCon)
63 import TysWiredIn (parrTyCon, unitDataConId, tupleCon, intDataCon, mkPArrTy,
65 import CoreSyn (CoreExpr, CoreAlt, Expr(..), AltCon(..),
67 import PprCore ( {- instances -} )
69 import VarEnv (IdEnv, delVarEnv, delVarEnvList, lookupVarEnv)
71 -- friends: don't import any to avoid cyclic imports
75 -- type inspection functions
76 -- -------------------------
78 -- determines the argument types of a tuple type (EXPORTED)
80 tupleTyArgs :: Type -> [Type]
82 case splitTyConApp_maybe ty of
83 Just (tyCon, argTys) | isTupleTyCon tyCon -> argTys
85 pprPanic "NDPCoreUtils.tupleTyArgs: wrong type: " (ppr ty)
87 -- determines the argument and result type of a function type (EXPORTED)
89 funTyArgs :: Type -> (Type, Type)
90 funTyArgs = splitFunTy
92 -- for a type of the form `[:t:]', yield `t' (EXPORTED)
94 -- * if the type has any other form, a fatal error occurs
96 parrElemTy :: Type -> Type
98 case splitTyConApp_maybe ty of
99 Just (tyCon, [argTy]) | tyCon == parrTyCon -> argTy
101 pprPanic "NDPCoreUtils.parrElemTy: wrong type: " (ppr ty)
104 -- Core generation functions
105 -- -------------------------
107 -- make a tuple construction expression from a list of argument types and
108 -- argument values (EXPORTED)
110 -- * the two lists need to be of the same length
112 mkTuple :: [Type] -> [CoreExpr] -> CoreExpr
113 mkTuple [] [] = Var unitDataConId
115 mkTuple ts es | length ts == length es =
116 mkConApp (tupleCon Boxed (length es)) (map Type ts ++ es)
118 panic "NDPCoreUtils.mkTuple: mismatch between number of types and exprs!"
120 -- make a boxed integer from an unboxed one (EXPORTED)
122 mkInt :: CoreExpr -> CoreExpr
123 mkInt e = mkConApp intDataCon [e]
129 -- checks whether a given case alternative is a default alternative (EXPORTED)
131 isDefault :: CoreAlt -> Bool
132 isDefault (DEFAULT, _, _) = True
135 -- check whether a list of case alternatives in belongs to a case over a
136 -- literal type (EXPORTED)
138 isLit :: [CoreAlt] -> Bool
139 isLit ((DEFAULT, _, _ ):alts) = isLit alts
140 isLit ((LitAlt _, _, _):_ ) = True
143 -- FIXME: this function should get a more expressive name and maybe also a
144 -- more detailed return type (depends on how the analysis goes)
145 isSimpleExpr:: CoreExpr -> Bool
154 substIdEnv:: IdEnv Id -> CoreExpr -> CoreExpr
155 substIdEnv env e@(Lit _) = e
156 substIdEnv env e@(Var id) =
157 case (lookupVarEnv env id) of
160 substIdEnv env (App e arg) =
161 App (substIdEnv env e) (substIdEnv env arg)
162 substIdEnv env (Lam b expr) =
163 Lam b (substIdEnv (delVarEnv env b) expr)
164 substIdEnv env (Let (NonRec b expr1) expr2) =
165 Let (NonRec b (substIdEnv env expr1))
166 (substIdEnv (delVarEnv env b) expr2)
167 substIdEnv env (Let (Rec bnds) expr) =
169 newEnv = delVarEnvList env (map fst bnds)
170 newExpr = substIdEnv newEnv expr
171 substBnd (b,e) = (b, substIdEnv newEnv e)
172 in Let (Rec (map substBnd bnds)) newExpr
173 substIdEnv env (Case expr b ty alts) =
174 Case (substIdEnv newEnv expr) b ty (map substAlt alts)
176 newEnv = delVarEnv env b
177 substAlt (c, bnds, expr) =
178 (c, bnds, substIdEnv (delVarEnvList env bnds) expr)
179 substIdEnv env (Note n expr) =
180 Note n (substIdEnv env expr)
181 substIdEnv env (Cast e co) = Cast (substIdEnv env e) co
182 substIdEnv env e@(Type t) = e