Skip to content

Commit 4950a26

Browse files
committed
ES: refactored CopyPropagation into monadic style
1 parent 4e5070c commit 4950a26

File tree

1 file changed

+64
-54
lines changed

1 file changed

+64
-54
lines changed

grin/src/Transformations/ExtendedSyntax/Optimising/CopyPropagation.hs

Lines changed: 64 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
{-# LANGUAGE LambdaCase, TupleSections, ViewPatterns #-}
22
module Transformations.ExtendedSyntax.Optimising.CopyPropagation where
33

4+
import Control.Monad.State
5+
46
import Data.Map.Strict (Map)
57
import qualified Data.Map.Strict as Map
68
import Data.Functor.Foldable as Foldable
@@ -37,65 +39,73 @@ type Aliases = Map Name Name
3739
type Env = (OriginalValues, Aliases)
3840

3941
copyPropagation :: Exp -> Exp
40-
copyPropagation e = hylo rmBlocks builder (mempty, e) where
41-
42-
builder :: (Env, Exp) -> ExpF (Env, Exp)
43-
builder (env@(origVals, aliases), exp) = let e = substVarRefExp aliases $ exp in case e of
44-
-- left unit law
45-
EBind (SReturn (Var valVar)) (VarPat patVar) rightExp
46-
| origVar <- getAlias valVar aliases
47-
-> let aliases' = Map.insert patVar origVar aliases
48-
newEnv = (origVals, aliases')
49-
in SBlockF (newEnv, rightExp)
50-
51-
-- rename lhs variables with their original aliases
52-
EBind (SReturn val) bpat@(VarPat patVar) rightExp
53-
| isn't _Lit val
54-
, valWithOrigVars <- substNamesVal aliases val
55-
-> let origVals' = Map.insert patVar valWithOrigVars origVals
56-
newEnv = (origVals', aliases)
57-
in (newEnv,) <$> project (EBind (SReturn valWithOrigVars) bpat rightExp)
58-
59-
-- left unit law + eliminate redundant rebinds
60-
EBind (SReturn (Var valVar)) (AsPat patVar asPat) rightExp
61-
| origVar <- getAlias valVar aliases
62-
, origVal <- getOrigVal origVar origVals
63-
, ConstTagNode patTag patArgs <- asPat
64-
, ConstTagNode valTag valArgs <- origVal
65-
, patTag == valTag
66-
-> let aliases' = aliases <> (Map.fromList $ zip (patVar:patArgs) (origVar:valArgs))
67-
newEnv = (origVals, aliases')
68-
in SBlockF (newEnv, rightExp)
69-
70-
-- rename lhs variables with their original aliases
71-
-- and eliminate redudant rebinds
72-
EBind (SReturn val) (AsPat patVar asPat) rightExp
73-
| isn't _Lit val
74-
, valWithOrigVars <- substNamesVal aliases val
75-
, ConstTagNode patTag patArgs <- asPat
76-
, ConstTagNode valTag valArgs <- valWithOrigVars
77-
, patTag == valTag
78-
-> let origVals' = Map.insert patVar valWithOrigVars origVals
79-
aliases' = aliases <> (Map.fromList $ zip patArgs valArgs)
80-
newEnv = (origVals', aliases')
81-
in (newEnv,) <$> project (EBind (SReturn val) (VarPat patVar) rightExp)
82-
83-
-- simplifying as-patterns matching against the same basic value they bind
84-
EBind (SReturn retVal) (AsPat var patVal) rightExp
85-
| isBasicValue retVal
86-
, retVal == patVal
87-
-> (env,) <$> project (EBind (SReturn retVal) (VarPat var) rightExp)
88-
89-
_ -> (env,) <$> project e
42+
copyPropagation = flip evalState mempty . hyloM rmBlocks builder where
43+
44+
builder :: Exp -> State Env (ExpF Exp)
45+
builder exp = do
46+
(origVals, aliases) <- get
47+
let exp' = substVarRefExp aliases $ exp
48+
49+
case exp' of
50+
-- left unit law
51+
EBind (SReturn (Var valVar)) (VarPat patVar) rightExp
52+
| origVar <- getAlias valVar aliases -> do
53+
let aliases' = Map.insert patVar origVar aliases
54+
newEnv = (origVals, aliases')
55+
put newEnv
56+
pure $ SBlockF rightExp
57+
58+
-- rename lhs variables with their original aliases
59+
EBind (SReturn val) bpat@(VarPat patVar) rightExp
60+
| isn't _Lit val
61+
, valWithOrigVars <- substNamesVal aliases val -> do
62+
let origVals' = Map.insert patVar valWithOrigVars origVals
63+
newEnv = (origVals', aliases)
64+
put newEnv
65+
pure $ project $ EBind (SReturn valWithOrigVars) bpat rightExp
66+
67+
-- left unit law + eliminate redundant rebinds
68+
EBind (SReturn (Var valVar)) (AsPat patVar asPat) rightExp
69+
| origVar <- getAlias valVar aliases
70+
, origVal <- getOrigVal origVar origVals
71+
, ConstTagNode patTag patArgs <- asPat
72+
, ConstTagNode valTag valArgs <- origVal
73+
, patTag == valTag -> do
74+
let aliases' = aliases <> (Map.fromList $ zip (patVar:patArgs) (origVar:valArgs))
75+
newEnv = (origVals, aliases')
76+
put newEnv
77+
pure $ SBlockF rightExp
78+
79+
-- rename lhs variables with their original aliases
80+
-- and eliminate redudant rebinds
81+
EBind (SReturn val) (AsPat patVar asPat) rightExp
82+
| isn't _Lit val
83+
, valWithOrigVars <- substNamesVal aliases val
84+
, ConstTagNode patTag patArgs <- asPat
85+
, ConstTagNode valTag valArgs <- valWithOrigVars
86+
, patTag == valTag -> do
87+
let origVals' = Map.insert patVar valWithOrigVars origVals
88+
aliases' = aliases <> (Map.fromList $ zip patArgs valArgs)
89+
newEnv = (origVals', aliases')
90+
put newEnv
91+
pure $ project $ EBind (SReturn val) (VarPat patVar) rightExp
92+
93+
-- simplifying as-patterns matching against the same basic value they bind
94+
EBind (SReturn retVal) (AsPat var patVal) rightExp
95+
| isBasicValue retVal
96+
, retVal == patVal -> do
97+
pure $ project $ EBind (SReturn retVal) (VarPat var) rightExp
98+
99+
_ -> pure $ project exp'
90100

91101
-- NOTE: This cleans up the left-over produced by the above transformation.
92102
-- It removes nested blocks, and blocks appearing on the left-hand side of a
93103
-- binding. These are always safe to remove.
94-
rmBlocks :: ExpF Exp -> Exp
104+
rmBlocks :: ExpF Exp -> State Env Exp
95105
rmBlocks = \case
96-
EBindF lhs bpat (SBlock rhs) -> EBind lhs bpat rhs
97-
SBlockF exp@SBlock{} -> exp
98-
exp -> embed exp
106+
EBindF lhs bpat (SBlock rhs) -> pure $ EBind lhs bpat rhs
107+
SBlockF exp@SBlock{} -> pure $ exp
108+
exp -> pure $ embed exp
99109

100110
getAlias :: Name -> Aliases -> Name
101111
getAlias var aliases = Map.findWithDefault var var aliases

0 commit comments

Comments
 (0)