X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=NormalizeTools.hs;h=0508b38162aab5381bf025e62b6679f8f901573a;hb=758998d6ef18ab5124c65518781c358d76d229ab;hp=14e3faca07543f497da404cd8e5cb317c7e6d099;hpb=cccb87b1cdff39f45148b525bd8e426b6bf667ad;p=matthijs%2Fmaster-project%2Fc%CE%BBash.git diff --git a/NormalizeTools.hs b/NormalizeTools.hs index 14e3fac..0508b38 100644 --- a/NormalizeTools.hs +++ b/NormalizeTools.hs @@ -7,6 +7,7 @@ module NormalizeTools where import Debug.Trace import qualified List import qualified Data.Monoid as Monoid +import qualified Data.Either as Either import qualified Control.Arrow as Arrow import qualified Control.Monad as Monad import qualified Control.Monad.Trans.State as State @@ -14,6 +15,7 @@ import qualified Control.Monad.Trans.Writer as Writer import qualified "transformers" Control.Monad.Trans as Trans import qualified Data.Map as Map import Data.Accessor +import Data.Accessor.MonadState as MonadState -- GHC API import CoreSyn @@ -28,10 +30,14 @@ import qualified IdInfo import qualified CoreUtils import qualified CoreSubst import qualified VarSet +import qualified HscTypes import Outputable ( showSDoc, ppr, nest ) -- Local imports import NormalizeTypes +import Pretty +import VHDLTypes +import qualified VHDLTools -- Create a new internal var with the given name and type. A Unique is -- appended to the given name, to ensure uniqueness (not strictly neccesary, @@ -119,6 +125,11 @@ subeverywhere trans (App a b) = do b' <- trans b return $ App a' b' +subeverywhere trans (Let (NonRec b bexpr) expr) = do + bexpr' <- trans bexpr + expr' <- trans expr + return $ Let (NonRec b bexpr') expr' + subeverywhere trans (Let (Rec binds) expr) = do expr' <- trans expr binds' <- mapM transbind binds @@ -142,26 +153,33 @@ subeverywhere trans (Case scrut b t alts) = do transalt (con, binders, expr) = do expr' <- trans expr return (con, binders, expr') - -subeverywhere trans expr = return expr +subeverywhere trans (Var x) = return $ Var x +subeverywhere trans (Lit x) = return $ Lit x +subeverywhere trans (Type x) = return $ Type x + +subeverywhere trans (Cast expr ty) = do + expr' <- trans expr + return $ Cast expr' ty + +subeverywhere trans expr = error $ "\nNormalizeTools.subeverywhere: Unsupported expression: " ++ show expr --- Apply the given transformation to all expressions, except for every first --- argument of an application. -notapplied :: (String, Transform) -> Transform -notapplied trans = applyboth (subnotapplied trans) trans +-- Apply the given transformation to all expressions, except for direct +-- arguments of an application +notappargs :: (String, Transform) -> Transform +notappargs trans = applyboth (subnotappargs trans) trans -- Apply the given transformation to all (direct and indirect) subexpressions --- (but not the expression itself), except for the first argument of an --- applicfirst argument of an application -subnotapplied :: (String, Transform) -> Transform -subnotapplied trans (App a b) = do - a' <- subnotapplied trans a - b' <- notapplied trans b +-- (but not the expression itself), except for direct arguments of an +-- application +subnotappargs :: (String, Transform) -> Transform +subnotappargs trans (App a b) = do + a' <- subnotappargs trans a + b' <- subnotappargs trans b return $ App a' b' -- Let subeverywhere handle all other expressions -subnotapplied trans expr = subeverywhere (notapplied trans) expr +subnotappargs trans expr = subeverywhere (notappargs trans) expr -- Runs each of the transforms repeatedly inside the State monad. dotransforms :: [Transform] -> CoreExpr -> TransformSession CoreExpr @@ -170,14 +188,23 @@ dotransforms transs expr = do if Monoid.getAny changed then dotransforms transs expr' else return expr' -- Inline all let bindings that satisfy the given condition -inlinebind :: ((CoreBndr, CoreExpr) -> Bool) -> Transform -inlinebind condition (Let (Rec binds) expr) | not $ null replace = - change newexpr +inlinebind :: ((CoreBndr, CoreExpr) -> TransformMonad Bool) -> Transform +inlinebind condition expr@(Let (Rec binds) res) = do + -- Find all bindings that adhere to the condition + res_eithers <- mapM docond binds + case Either.partitionEithers res_eithers of + -- No replaces? No change + ([], _) -> return expr + (replace, others) -> do + -- Substitute the to be replaced binders with their expression + let newexpr = substitute replace (Let (Rec others) res) + change newexpr where - -- Find all simple bindings - (replace, others) = List.partition condition binds - -- Substitute the to be replaced binders with their expression - newexpr = substitute replace (Let (Rec others) expr) + docond :: (CoreBndr, CoreExpr) -> TransformMonad (Either (CoreBndr, CoreExpr) (CoreBndr, CoreExpr)) + docond b = do + res <- condition b + return $ case res of True -> Left b; False -> Right b + -- Leave all other expressions unchanged inlinebind _ expr = return expr @@ -221,6 +248,13 @@ substitute ((b, e):subss) expr = substitute subss' expr' -- Run a given TransformSession. Used mostly to setup the right calls and -- an initial state. -runTransformSession :: UniqSupply.UniqSupply -> TransformSession a -> a -runTransformSession uniqSupply session = State.evalState session initState - where initState = TransformState uniqSupply Map.empty VarSet.emptyVarSet +runTransformSession :: HscTypes.HscEnv -> UniqSupply.UniqSupply -> TransformSession a -> a +runTransformSession env uniqSupply session = State.evalState session emptyTransformState + where + emptyTypeState = TypeState Map.empty [] Map.empty Map.empty env + emptyTransformState = TransformState uniqSupply Map.empty VarSet.emptyVarSet emptyTypeState + +-- Is the given expression representable at runtime, based on the type? +isRepr :: CoreSyn.CoreExpr -> TransformMonad Bool +isRepr (Type ty) = return False +isRepr expr = Trans.lift $ MonadState.lift tsType $ VHDLTools.isReprType (CoreUtils.exprType expr)