Skip to content

Commit ef24839

Browse files
authored
Merge branch '32-extended-syntax' into 32-trf-copy-propagation-2
2 parents d16029a + d307058 commit ef24839

File tree

5 files changed

+730
-0
lines changed

5 files changed

+730
-0
lines changed

grin/grin.cabal

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ library
147147
Transformations.ExtendedSyntax.MangleNames
148148
Transformations.ExtendedSyntax.StaticSingleAssignment
149149
Transformations.ExtendedSyntax.Optimising.CopyPropagation
150+
Transformations.ExtendedSyntax.Optimising.CSE
150151
Transformations.ExtendedSyntax.Optimising.EvaluatedCaseElimination
151152
Transformations.ExtendedSyntax.Optimising.TrivialCaseElimination
152153

@@ -301,6 +302,7 @@ test-suite grin-test
301302
Transformations.ExtendedSyntax.MangleNamesSpec
302303
Transformations.ExtendedSyntax.StaticSingleAssignmentSpec
303304
Transformations.ExtendedSyntax.Optimising.CopyPropagationSpec
305+
Transformations.ExtendedSyntax.Optimising.CSESpec
304306
Transformations.ExtendedSyntax.Optimising.EvaluatedCaseEliminationSpec
305307
Transformations.ExtendedSyntax.Optimising.TrivialCaseEliminationSpec
306308

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
{-# LANGUAGE LambdaCase, TupleSections, ViewPatterns #-}
2+
module Transformations.ExtendedSyntax.Optimising.CSE where
3+
4+
-- HINT: common sub-expression elimination
5+
6+
import Data.Map.Strict (Map)
7+
import qualified Data.Map.Strict as Map
8+
import Data.Functor.Foldable as Foldable
9+
10+
import Text.Printf
11+
12+
import Lens.Micro ((^.))
13+
import Lens.Micro.Extra (isn't)
14+
15+
import Grin.ExtendedSyntax.Grin
16+
import Grin.ExtendedSyntax.TypeEnv
17+
import Grin.ExtendedSyntax.EffectMap
18+
import Transformations.ExtendedSyntax.Util
19+
20+
21+
type Env = (Map SimpleExp SimpleExp)
22+
23+
-- TODO: track if function parameters with location type can be updated in the called function to improve CSE
24+
25+
{- TODO: remove skipUnit, it does nothing with the new syntax (SDVE will get rid of the unused unit-binds)
26+
TODO: CSE could be taught to remember pattern binds:
27+
(CInt k1)@n0 <- pure (CInt k0)
28+
n1 <- pure (CInt k0)
29+
n2 <- pure (CInt k1)
30+
31+
could be transformed to:
32+
33+
(CInt k1)@n0 <- pure (CInt k0)
34+
n1 <- pure n0
35+
n2 <- pure n0
36+
-}
37+
commonSubExpressionElimination :: TypeEnv -> EffectMap -> Exp -> Exp
38+
commonSubExpressionElimination typeEnv effMap e = hylo skipUnit builder (mempty, e) where
39+
40+
builder :: (Env, Exp) -> ExpF (Env, Exp)
41+
builder (env, subst env -> exp) = case exp of
42+
EBind leftExp bPat rightExp -> EBindF (env, leftExp) bPat (newEnv, rightExp) where
43+
newEnv = case leftExp of
44+
-- HINT: also save fetch (the inverse operation) for store and update
45+
SUpdate ptr var -> Map.insert (SFetch ptr) (SReturn (Var var)) env
46+
SStore var
47+
-- TODO: AsPat
48+
| VarPat ptr <- bPat -> Map.insert (SFetch ptr) (SReturn (Var var)) extEnvKeepOld
49+
-- HINT: location parameters might be updated in the called function, so forget their content
50+
SApp defName args -> foldr
51+
Map.delete
52+
(if (hasTrueSideEffect defName effMap) then env else extEnvKeepOld)
53+
[SFetch var | var <- args, isLocation var]
54+
SReturn val | isn't _Var val -> extEnvKeepOld
55+
SFetch{} -> extEnvKeepOld
56+
_ -> env
57+
58+
extEnvKeepOld = Map.insertWith (\new old -> old) leftExp (SReturn . Var $ bPat ^. _BPatVar) env
59+
60+
-- TODO: Investigate this. Will the fetched variable, and the variable to be updated with
61+
-- always have the same name? If not, will copy propagation solve it?
62+
SUpdate ptr var | Just (SReturn (Var fetchedVar)) <- Map.lookup (SFetch ptr) env
63+
, fetchedVar == var
64+
-> SReturnF Unit
65+
66+
ECase scrut alts -> ECaseF scrut [(altEnv env scrut cpat, alt) | alt@(Alt cpat _altName _) <- alts]
67+
68+
_ -> (env,) <$> project exp
69+
70+
isLocation :: Name -> Bool
71+
isLocation name = case variableType typeEnv name of
72+
T_SimpleType T_Location{} -> True
73+
_ -> False
74+
75+
altEnv :: Env -> Name -> CPat -> Env
76+
altEnv env scrut cpat = case cpat of
77+
NodePat tag args -> env -- When we use scrutinee variable already HPT will include all the
78+
-- possible values, instead of the matching one. As result it will
79+
-- overapproximate the values more than needed.
80+
81+
-- NOTE: We could extend the env with [ SReturn (ConstTagNode tag args) -> SReturn val ]
82+
-- HPT would _not_ overapproximate the possible type of the variable,
83+
-- since it restricts the scrutinee to the alternative's domain
84+
LitPat lit -> Map.insertWith (\new old -> old) (SReturn (Lit lit)) (SReturn (Var scrut)) env
85+
DefaultPat -> env
86+

grin/src/Transformations/Optimising/CSE.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ commonSubExpressionElimination typeEnv effMap e = hylo skipUnit builder (mempty,
5555
NodePat tag args -> env -- When we use scrutinee variable already HPT will include all the
5656
-- possible values, instead of the matching one. As result it will
5757
-- overapproximate the values more than needed.
58+
59+
-- NOTE: We could extend the env with [ SReturn (ConstTagNode tag args) -> SReturn val ]
60+
-- HPT would _not_ overapproximate the possible type of the variable,
61+
-- since it restricts the scrutinee to the alternative's domain
5862
LitPat lit -> Map.insertWith (\new old -> old) (SReturn (Lit lit)) (SReturn val) env
5963
TagPat tag -> Map.insertWith (\new old -> old) (SReturn (ValTag tag)) (SReturn val) env
6064
DefaultPat -> env

0 commit comments

Comments
 (0)