@@ -22,6 +22,11 @@ import Transformations.ExtendedSyntax.Util
2222 TODO:
2323 Is the as-pattern elimination handled by LLVM?
2424 We will figure this out after implementing the LLVM codegen for as-patterns.
25+
26+ NOTE:
27+ Anamorphisms don't let us to "skip" bindings. We circumvent this issue by replacing the binding with a block.
28+ This will essentially skip the bind, since SBlockF is simply projected into SBlock. These extra (possibly nested)
29+ blocks will be removed in the cata part of the hylo.
2530-}
2631
2732-- (k,v) ~ the variable k has the original value v
@@ -32,7 +37,7 @@ type Aliases = Map Name Name
3237type Env = (OriginalValues , Aliases )
3338
3439copyPropagation :: Exp -> Exp
35- copyPropagation e = skipRhsBlocks $ hylo folder builder (mempty , e) where
40+ copyPropagation e = hylo rmBlocks builder (mempty , e) where
3641
3742 builder :: (Env , Exp ) -> ExpF (Env , Exp )
3843 builder (env@ (origVals, aliases), exp ) = let e = substVarRefExp aliases $ exp in case e of
@@ -41,9 +46,9 @@ copyPropagation e = skipRhsBlocks $ hylo folder builder (mempty, e) where
4146 | origVar <- getAlias valVar aliases
4247 -> let aliases' = Map. insert patVar origVar aliases
4348 newEnv = (origVals, aliases')
44- in SBlockF (newEnv, rightExp) -- no skip in builder
49+ in SBlockF (newEnv, rightExp)
4550
46- -- left unit law
51+ -- rename lhs variables with their original aliases
4752 EBind (SReturn val) bpat@ (VarPat patVar) rightExp
4853 | isn't _Lit val
4954 , valWithOrigVars <- substNamesVal aliases val
@@ -60,9 +65,10 @@ copyPropagation e = skipRhsBlocks $ hylo folder builder (mempty, e) where
6065 , patTag == valTag
6166 -> let aliases' = aliases <> (Map. fromList $ zip (patVar: patArgs) (origVar: valArgs))
6267 newEnv = (origVals, aliases')
63- in SBlockF (newEnv, rightExp) -- no skip in builder
68+ in SBlockF (newEnv, rightExp)
6469
65- -- left unit law + eliminate redundant rebinds
70+ -- rename lhs variables with their original aliases
71+ -- and eliminate redudant rebinds
6672 EBind (SReturn val) (AsPat patVar asPat) rightExp
6773 | isn't _Lit val
6874 , valWithOrigVars <- substNamesVal aliases val
@@ -74,25 +80,19 @@ copyPropagation e = skipRhsBlocks $ hylo folder builder (mempty, e) where
7480 newEnv = (origVals', aliases')
7581 in (newEnv,) <$> project (EBind (SReturn val) (VarPat patVar) rightExp)
7682
77- _ -> (env,) <$> project e
78-
79- genBind :: (Val , BPat ) -> Exp -> Exp
80- genBind (val, bpat) exp = EBind (SReturn val) bpat exp
81-
82- -- NOTE: This cleans up the left-over produced by the above transformation.
83- folder :: ExpF Exp -> Exp
84- folder = \ case
85- -- <patVal> @ <var> <- pure <retVal>
86- -- where retVal is a basic value (lit or unit)
87- EBindF (SReturn retVal) (AsPat var patVal) rightExp
83+ -- simplifying as-patterns matching against the same basic value they bind
84+ EBind (SReturn retVal) (AsPat var patVal) rightExp
8885 | isBasicValue retVal
8986 , retVal == patVal
90- -> EBind (SReturn retVal) (VarPat var) rightExp
87+ -> (env,) <$> project ( EBind (SReturn retVal) (VarPat var) rightExp)
9188
92- exp -> embed exp
89+ _ -> (env,) <$> project e
9390
94- skipRhsBlocks :: Exp -> Exp
95- skipRhsBlocks exp = flip cata exp $ \ case
91+ -- NOTE: This cleans up the left-over produced by the above transformation.
92+ -- It removes nested blocks, and blocks appearing on the left-hand side of a
93+ -- binding. These are always safe to remove.
94+ rmBlocks :: ExpF Exp -> Exp
95+ rmBlocks = \ case
9696 EBindF lhs bpat (SBlock rhs) -> EBind lhs bpat rhs
9797 SBlockF exp @ SBlock {} -> exp
9898 exp -> embed exp
0 commit comments