Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
GHC
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Iterations
Merge Requests
0
Merge Requests
0
Requirements
Requirements
List
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Package Registry
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issue
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Alex D
GHC
Commits
2059de7c
Commit
2059de7c
authored
Jun 22, 1999
by
simonpj
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[project @ 1999-06-22 16:30:53 by simonpj]
Add common sub-expression
parent
c34d93da
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
184 additions
and
0 deletions
+184
-0
ghc/compiler/simplCore/CSE.lhs
ghc/compiler/simplCore/CSE.lhs
+184
-0
No files found.
ghc/compiler/simplCore/CSE.lhs
0 → 100644
View file @
2059de7c
%
% (c) The AQUA Project, Glasgow University, 1993-1998
%
\section{Common subexpression}
\begin{code}
module CSE (
cseProgram
) where
#include "HsVersions.h"
import CmdLineOpts ( opt_D_dump_cse, opt_D_verbose_core2core )
import Id ( Id, idType )
import CoreUtils ( hashExpr, cheapEqExpr, exprIsBig )
import Const ( Con(..) )
import DataCon ( isUnboxedTupleCon )
import Type ( splitTyConApp_maybe )
import CoreSyn
import VarEnv
import CoreLint ( beginPass, endPass )
import Outputable
import Util ( mapAccumL )
import UniqFM
\end{code}
Simple common sub-expression
When we see
x1 = C a b
x2 = C x1 b
we build up a reverse mapping: C a b -> x1
C x1 b -> x2
and apply that to the rest of the program.
When we then see
y1 = C a b
y2 = C y1 b
we replace the C a b with x1. But then we *dont* want to
add x1 -> y to the mapping. Rather, we want the reverse, y -> x1
so that a subsequent binding
z = C y b
will get transformed to C x1 b, and then to x2.
So we carry an extra var->var mapping which we apply before looking up in the
reverse mapping.
IMPORTANT NOTE
~~~~~~~~~~~~~~
This pass relies on the no-shadowing invariant, so it must run
immediately after the simplifier.
For example, consider
f = \x -> let y = x+x in
h = \x -> x+x
in ...
Here we must *not* do CSE on the x+x!
%************************************************************************
%* *
\section{Common subexpression}
%* *
%************************************************************************
\begin{code}
cseProgram :: [CoreBind] -> IO [CoreBind]
cseProgram binds
= do {
beginPass "Common sub-expression";
let { binds' = cseBinds emptyCSEnv binds };
endPass "Common sub-expression"
(opt_D_dump_cse || opt_D_verbose_core2core)
binds'
}
cseBinds :: CSEnv -> [CoreBind] -> [CoreBind]
cseBinds env [] = []
cseBinds env (b:bs) = (b':bs')
where
(env1, b') = cseBind env b
bs' = cseBinds env1 bs
cseBind :: CSEnv -> CoreBind -> (CSEnv, CoreBind)
cseBind env (NonRec b e) = let (env', (_,e')) = do_one env (b, e)
in (env', NonRec b e')
cseBind env (Rec pairs) = let (env', pairs') = mapAccumL do_one env pairs
in (env', Rec pairs')
do_one env (id, rhs) = case lookupCSEnv env rhs' of
Just other_id -> (extendSubst env id other_id, (id, Var other_id))
Nothing -> (addCSEnvItem env id rhs', (id, rhs'))
where
rhs' = cseExpr env rhs
tryForCSE :: CSEnv -> CoreExpr -> CoreExpr
tryForCSE env (Type t) = Type t
tryForCSE env expr = case lookupCSEnv env expr' of
Just id -> Var id
Nothing -> expr'
where
expr' = cseExpr env expr
cseExpr :: CSEnv -> CoreExpr -> CoreExpr
cseExpr env (Var v) = Var (lookupSubst env v)
cseExpr env (App f (Type t)) = App (cseExpr env f) (Type t)
cseExpr env (App f a) = App (cseExpr env f) (tryForCSE env a)
cseExpr env expr@(Con con args) = case lookupCSEnv env expr of
Just id -> Var id
Nothing -> Con con [tryForCSE env arg | arg <- args]
cseExpr env (Note n e) = Note n (cseExpr env e)
cseExpr env (Lam b e) = Lam b (cseExpr env e)
cseExpr env (Let bind e) = let (env1, bind') = cseBind env bind
in Let bind' (cseExpr env1 e)
cseExpr env (Type t) = Type t
cseExpr env (Case scrut bndr alts) = Case (tryForCSE env scrut) bndr (cseAlts env bndr alts)
cseAlts env bndr alts
= map cse_alt alts
where
arg_tys = case splitTyConApp_maybe (idType bndr) of
Just (_, arg_tys) -> map Type arg_tys
other -> pprPanic "cseAlts" (ppr bndr)
cse_alt (con, args, rhs)
| ok_for_cse con = (con, args, cseExpr (extendCSEnv env bndr (Con con (arg_tys ++ (map varToCoreExpr args)))) rhs)
| otherwise = (con, args, cseExpr env rhs)
ok_for_cse DEFAULT = False
ok_for_cse (Literal l) = True
ok_for_cse (DataCon dc) = not (isUnboxedTupleCon dc)
-- Unboxed tuples aren't shared
\end{code}
%************************************************************************
%* *
\section{The CSE envt}
%* *
%************************************************************************
\begin{code}
data CSEnv = CS (UniqFM [(Id, CoreExpr)]) -- The expr in the range has already been CSE'd
(IdEnv Id) -- Simple substitution
emptyCSEnv = CS emptyUFM emptyVarEnv
lookupCSEnv :: CSEnv -> CoreExpr -> Maybe Id
lookupCSEnv (CS cs _) expr
= case lookupUFM cs (hashExpr expr) of
Nothing -> Nothing
Just pairs -> lookup_list pairs expr
lookup_list :: [(Id,CoreExpr)] -> CoreExpr -> Maybe Id
lookup_list [] expr = Nothing
lookup_list ((x,e):es) expr | cheapEqExpr e expr = Just x
| otherwise = lookup_list es expr
addCSEnvItem env id expr | exprIsBig expr = env
| otherwise = extendCSEnv env id expr
extendCSEnv (CS cs sub) id expr
= CS (addToUFM_C combine cs hash [(id, expr)]) sub
where
hash = hashExpr expr
combine old new = WARN( length result > 4, text "extendCSEnv: long list:" <+> ppr result )
result
where
result = new ++ old
lookupSubst (CS _ sub) x = case lookupVarEnv sub x of
Just y -> y
Nothing -> x
extendSubst (CS cs sub) x y = CS cs (extendVarEnv sub x y)
\end{code}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment