@@ -8,31 +8,29 @@ import Data.Text (Text)
8
8
import Language.PureScript.CoreImp.AST
9
9
import Language.PureScript.CoreImp.Optimizer.Blocks
10
10
import Language.PureScript.CoreImp.Optimizer.Common hiding (isDict )
11
- import Language.PureScript.CoreImp.Optimizer.Inliner hiding ( inlineUnsafeCoerce , inlineUnsafePartial )
11
+ import Language.PureScript.CoreImp.Optimizer.Inliner ( etaConvert , evaluateIifes , inlineVariables , unThunk )
12
12
import Language.PureScript.CoreImp.Optimizer.Unused
13
- import Language.PureScript.PSString (PSString , decodeString )
14
13
15
14
import CodeGen.IL.Common (unusedName )
15
+ import CodeGen.IL.Optimizer.Inliner
16
+ import CodeGen.IL.Optimizer.MagicDo
16
17
import CodeGen.IL.Optimizer.TCO
17
18
18
19
import qualified Language.PureScript.Constants as C
19
20
20
-
21
- -- | Apply a series of optimizer passes to simplified C++ code
21
+ -- | Apply a series of optimizer passes to simplified IL code
22
22
optimize :: MonadSupply m => AST -> AST -> m AST
23
- -- optimize = untilFixedPoint $ return . inlineUnsafeCoerce . inlineUnsafePartial . tidyUp . tco
24
23
optimize mn il = do
25
- il' <- untilFixedPoint (return . inlineApply . inlineUnsafeCoerce . inlineUnsafePartial . tidyUp) il
26
- untilFixedPoint (return . tidyUp) . tco mn
27
- =<< untilFixedPoint (return . magicDo')
28
- =<< untilFixedPoint (return . magicDo) il'
29
-
30
-
24
+ il' <- untilFixedPoint (inlineFnComposition . inlineUnsafeCoerce . inlineUnsafePartial . tidyUp) il
25
+ untilFixedPoint (return . ignoreUnusedResults . inlineCommonValues . inlineCommonOperators . tidyUp) . tco mn . inlineST
26
+ =<< untilFixedPoint (return . magicDoST)
27
+ =<< untilFixedPoint (return . magicDoEff)
28
+ =<< untilFixedPoint (return . magicDoEffect) il'
31
29
where
32
30
tidyUp :: AST -> AST
33
31
tidyUp = applyAll
34
32
[ collapseNestedBlocks
35
- -- , collapseNestedIfs
33
+ , collapseNestedIfs
36
34
, collapseIfChecks
37
35
, removeCodeAfterReturnStatements
38
36
, unThunk
@@ -48,34 +46,6 @@ untilFixedPoint f = go
48
46
a' <- f a
49
47
if a' == a then return a' else go a'
50
48
51
- -- | Overridden from CoreImp
52
-
53
- inlineUnsafePartial :: AST -> AST
54
- inlineUnsafePartial = everywhereTopDown convert where
55
- convert (App ss (Indexer _ (Var _ unsafePartial) (Var _ partialUnsafe)) [ comp ])
56
- | unsafePartial == C. unsafePartial && partialUnsafe == C. partialUnsafe
57
- -- Apply to undefined here, the application should be optimized away
58
- -- if it is safe to do so
59
- = App ss comp [ Var ss C. undefined ]
60
- convert other = other
61
-
62
- inlineUnsafeCoerce :: AST -> AST
63
- inlineUnsafeCoerce = everywhereTopDown convert where
64
- convert (App _ (Indexer _ (Var _ unsafeCoerceFn) (Var _ unsafeCoerce)) [ comp ])
65
- | unsafeCoerceFn == C. unsafeCoerceFn && unsafeCoerce == C. unsafeCoerce
66
- = comp
67
- convert other = other
68
-
69
- inlineApply :: AST -> AST
70
- inlineApply = everywhereTopDown convert where
71
- convert (App ss (App _ (Indexer _ (Var _ apply) (Var _ dataFunction)) [ f ]) [ arg ])
72
- | apply == C. apply && dataFunction == C. dataFunction
73
- = App ss f [ arg ]
74
- convert (App ss (App _ (Indexer _ (Var _ applyFlipped) (Var _ dataFunction)) [ arg ]) [ f ])
75
- | applyFlipped == C. applyFlipped && dataFunction == C. dataFunction
76
- = App ss f [ arg ]
77
- convert other = other
78
-
79
49
collapseIfChecks :: AST -> AST
80
50
collapseIfChecks = everywhere collapse where
81
51
collapse :: AST -> AST
@@ -84,57 +54,14 @@ collapseIfChecks = everywhere collapse where
84
54
| prop == " otherwise" && val == " Data_Boolean" = exprs
85
55
collapse exprs = exprs
86
56
87
- magicDo :: AST -> AST
88
- magicDo = magicDo'' C. eff C. effDictionaries
89
-
90
- magicDo' :: AST -> AST
91
- magicDo' = magicDo'' C. effect C. effectDictionaries
92
-
93
- magicDo'' :: Text -> C. EffectDictionaries -> AST -> AST
94
- magicDo'' effectModule C. EffectDictionaries {.. } = everywhereTopDown convert
57
+ ignoreUnusedResults :: AST -> AST
58
+ ignoreUnusedResults = everywhere $ removeFromBlock go
95
59
where
96
- -- Desugar monomorphic calls to >>= and return for the Eff monad
97
- convert :: AST -> AST
98
- -- Desugar pure
99
- convert (App _ (App _ pure' [val]) [] ) | isPure pure' = val
100
- -- Desugar discard
101
- convert (App _ (App _ bind [m]) [Function s1 Nothing [unused] (Block s2 il)]) | isDiscard bind && unused == unusedName =
102
- Function s1 Nothing [] $ Block s2 (App s2 m [] : map applyReturns il )
103
- -- Desugar bind
104
- convert (App _ (App _ bind [m]) [Function s1 Nothing [arg] (Block s2 il)]) | isBind bind =
105
- Function s1 Nothing [] $ Block s2 (VariableIntroduction s2 arg (Just (App s2 m [] )) : map applyReturns il)
106
- -- Inline double applications
107
- convert (App _ (App s1 (Function s2 Nothing [] (Block ss body)) [] ) [] ) =
108
- App s1 (Function s2 Nothing [] (Block ss (applyReturns `fmap` body))) []
109
- convert other = other
110
-
111
- -- Check if an expression represents a monomorphic call to >>= for the Eff monad
112
- isBind (App _ fn [dict]) | isDict (effectModule, edBindDict) dict && isBindPoly fn = True
113
- isBind _ = False
114
- -- Check if an expression represents a call to @discard@
115
- isDiscard (App _ (App _ fn [dict1]) [dict2])
116
- | isDict (C. controlBind, C. discardUnitDictionary) dict1 &&
117
- isDict (effectModule, edBindDict) dict2 &&
118
- isDiscardPoly fn = True
119
- isDiscard _ = False
120
- -- Check if an expression represents a monomorphic call to pure or return for the Eff applicative
121
- isPure (App _ fn [dict]) | isDict (effectModule, edApplicativeDict) dict && isPurePoly fn = True
122
- isPure _ = False
123
- -- Check if an expression represents the polymorphic >>= function
124
- isBindPoly = isDict (C. controlBind, C. bind)
125
- -- Check if an expression represents the polymorphic pure function
126
- isPurePoly = isDict (C. controlApplicative, C. pure')
127
- -- Check if an expression represents the polymorphic discard function
128
- isDiscardPoly = isDict (C. controlBind, C. discard)
129
-
130
-
131
- applyReturns :: AST -> AST
132
- applyReturns (Return ss ret) = Return ss (App ss ret [] )
133
- applyReturns (Block ss ils) = Block ss (map applyReturns ils)
134
- applyReturns (IfElse ss cond t f) = IfElse ss cond (applyReturns t) (applyReturns `fmap` f)
135
- applyReturns other = other
136
-
137
- isDict :: (Text , PSString ) -> AST -> Bool
138
- isDict (moduleName, dictName) (Indexer _ (Var _ x) (Var _ y)) =
139
- Just x == decodeString dictName && y == moduleName
140
- isDict _ _ = False
60
+ go :: [AST ] -> [AST ]
61
+ go [] = []
62
+ go (VariableIntroduction ss var (Just s) : sts)
63
+ | not $ any (everything (||) (isUsed var)) sts = sts'
64
+ where
65
+ sts' | App {} <- s = s : (go sts)
66
+ | otherwise = go sts
67
+ go (s: sts) = s : go sts
0 commit comments