1-- | This module optimizes code in the simplified-JavaScript intermediate representation. 2-- 3-- The following optimizations are supported: 4-- 5-- * Collapsing nested blocks 6-- 7-- * Tail call elimination 8-- 9-- * Inlining of (>>=) and ret for the Eff monad 10-- 11-- * Removal of unnecessary thunks 12-- 13-- * Eta conversion 14-- 15-- * Inlining variables 16-- 17-- * Inline Prelude.($), Prelude.(#), Prelude.(++), Prelude.(!!) 18-- 19-- * Inlining primitive JavaScript operators 20module Language.PureScript.CoreImp.Optimizer (optimize) where 21 22import Prelude.Compat 23 24import Control.Monad.Supply.Class (MonadSupply) 25import Language.PureScript.CoreImp.AST 26import Language.PureScript.CoreImp.Optimizer.Blocks 27import Language.PureScript.CoreImp.Optimizer.Common 28import Language.PureScript.CoreImp.Optimizer.Inliner 29import Language.PureScript.CoreImp.Optimizer.MagicDo 30import Language.PureScript.CoreImp.Optimizer.TCO 31import Language.PureScript.CoreImp.Optimizer.Unused 32 33-- | Apply a series of optimizer passes to simplified JavaScript code 34optimize :: MonadSupply m => AST -> m AST 35optimize js = do 36 js' <- untilFixedPoint (inlineFnComposition . inlineUnsafeCoerce . inlineUnsafePartial . tidyUp . applyAll 37 [ inlineCommonValues 38 , inlineCommonOperators 39 ]) js 40 untilFixedPoint (return . tidyUp) . tco . inlineST 41 =<< untilFixedPoint (return . magicDoST) 42 =<< untilFixedPoint (return . magicDoEff) 43 =<< untilFixedPoint (return . magicDoEffect) js' 44 where 45 tidyUp :: AST -> AST 46 tidyUp = applyAll 47 [ collapseNestedBlocks 48 , collapseNestedIfs 49 , removeCodeAfterReturnStatements 50 , removeUndefinedApp 51 , unThunk 52 , etaConvert 53 , evaluateIifes 54 , inlineVariables 55 ] 56 57untilFixedPoint :: (Monad m, Eq a) => (a -> m a) -> a -> m a 58untilFixedPoint f = go 59 where 60 go a = do 61 a' <- f a 62 if a' == a then return a' else go a' 63