{-# LANGUAGE TemplateHaskell #-}

module UntypedPlutusCore.Optimize.Opts
  ( OptimizeOpts (..)
  , ooApplyToCase
  , ooHoistPolyBuiltins
  , ooMaxSimplifierIterations
  , ooMaxCseIterations
  , ooCseWhichSubterms
  , ooInlineHints
  , ooConservativeOpts
  , ooInlineConstants
  , ooInlineUnconditionalGrowth
  , ooInlineCallsiteGrowth
  , ooPreserveLogging
  , ooCertifiedOptsOnly
  , defaultOptimizeOpts
  , CseWhichSubterms (..)
  ) where

import Control.Lens.TH (makeLenses)
import Data.Default.Class

import PlutusCore.Annotation (InlineHints (..))
import PlutusCore.AstSize
import PlutusCore.Pretty
import Prettyprinter (viaShow)

-- | Which subterms should be considered as candidates for CSE?
data CseWhichSubterms = AllSubterms | ExcludeWorkFree
  deriving stock (Int -> CseWhichSubterms -> ShowS
[CseWhichSubterms] -> ShowS
CseWhichSubterms -> String
(Int -> CseWhichSubterms -> ShowS)
-> (CseWhichSubterms -> String)
-> ([CseWhichSubterms] -> ShowS)
-> Show CseWhichSubterms
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CseWhichSubterms -> ShowS
showsPrec :: Int -> CseWhichSubterms -> ShowS
$cshow :: CseWhichSubterms -> String
show :: CseWhichSubterms -> String
$cshowList :: [CseWhichSubterms] -> ShowS
showList :: [CseWhichSubterms] -> ShowS
Show, ReadPrec [CseWhichSubterms]
ReadPrec CseWhichSubterms
Int -> ReadS CseWhichSubterms
ReadS [CseWhichSubterms]
(Int -> ReadS CseWhichSubterms)
-> ReadS [CseWhichSubterms]
-> ReadPrec CseWhichSubterms
-> ReadPrec [CseWhichSubterms]
-> Read CseWhichSubterms
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS CseWhichSubterms
readsPrec :: Int -> ReadS CseWhichSubterms
$creadList :: ReadS [CseWhichSubterms]
readList :: ReadS [CseWhichSubterms]
$creadPrec :: ReadPrec CseWhichSubterms
readPrec :: ReadPrec CseWhichSubterms
$creadListPrec :: ReadPrec [CseWhichSubterms]
readListPrec :: ReadPrec [CseWhichSubterms]
Read)

instance Pretty CseWhichSubterms where
  pretty :: forall ann. CseWhichSubterms -> Doc ann
pretty = CseWhichSubterms -> Doc ann
forall a ann. Show a => a -> Doc ann
viaShow

data OptimizeOpts name a = OptimizeOpts
  { forall name a. OptimizeOpts name a -> Int
_ooMaxSimplifierIterations :: Int
  , forall name a. OptimizeOpts name a -> Int
_ooMaxCseIterations :: Int
  , forall name a. OptimizeOpts name a -> CseWhichSubterms
_ooCseWhichSubterms :: CseWhichSubterms
  , forall name a. OptimizeOpts name a -> Bool
_ooConservativeOpts :: Bool
  , forall name a. OptimizeOpts name a -> InlineHints name a
_ooInlineHints :: InlineHints name a
  , forall name a. OptimizeOpts name a -> Bool
_ooInlineConstants :: Bool
  , forall name a. OptimizeOpts name a -> AstSize
_ooInlineUnconditionalGrowth :: AstSize
  , forall name a. OptimizeOpts name a -> AstSize
_ooInlineCallsiteGrowth :: AstSize
  , forall name a. OptimizeOpts name a -> Bool
_ooPreserveLogging :: Bool
  , forall name a. OptimizeOpts name a -> Bool
_ooApplyToCase :: Bool
  , forall name a. OptimizeOpts name a -> Bool
_ooHoistPolyBuiltins :: Bool
  , forall name a. OptimizeOpts name a -> Bool
_ooCertifiedOptsOnly :: Bool
  }
  deriving stock (Int -> OptimizeOpts name a -> ShowS
[OptimizeOpts name a] -> ShowS
OptimizeOpts name a -> String
(Int -> OptimizeOpts name a -> ShowS)
-> (OptimizeOpts name a -> String)
-> ([OptimizeOpts name a] -> ShowS)
-> Show (OptimizeOpts name a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall name a. Int -> OptimizeOpts name a -> ShowS
forall name a. [OptimizeOpts name a] -> ShowS
forall name a. OptimizeOpts name a -> String
$cshowsPrec :: forall name a. Int -> OptimizeOpts name a -> ShowS
showsPrec :: Int -> OptimizeOpts name a -> ShowS
$cshow :: forall name a. OptimizeOpts name a -> String
show :: OptimizeOpts name a -> String
$cshowList :: forall name a. [OptimizeOpts name a] -> ShowS
showList :: [OptimizeOpts name a] -> ShowS
Show)

$(makeLenses ''OptimizeOpts)

defaultOptimizeOpts :: OptimizeOpts name a
defaultOptimizeOpts :: forall name a. OptimizeOpts name a
defaultOptimizeOpts =
  OptimizeOpts
    { _ooMaxSimplifierIterations :: Int
_ooMaxSimplifierIterations = Int
12
    , _ooMaxCseIterations :: Int
_ooMaxCseIterations = Int
4
    , _ooCseWhichSubterms :: CseWhichSubterms
_ooCseWhichSubterms = CseWhichSubterms
ExcludeWorkFree
    , _ooConservativeOpts :: Bool
_ooConservativeOpts = Bool
False
    , _ooInlineHints :: InlineHints name a
_ooInlineHints = InlineHints name a
forall a. Default a => a
def
    , _ooInlineConstants :: Bool
_ooInlineConstants = Bool
True
    , _ooInlineUnconditionalGrowth :: AstSize
_ooInlineUnconditionalGrowth = AstSize
1
    , _ooInlineCallsiteGrowth :: AstSize
_ooInlineCallsiteGrowth = AstSize
5
    , _ooPreserveLogging :: Bool
_ooPreserveLogging = Bool
True
    , _ooApplyToCase :: Bool
_ooApplyToCase = Bool
True
    , _ooHoistPolyBuiltins :: Bool
_ooHoistPolyBuiltins = Bool
True
    , _ooCertifiedOptsOnly :: Bool
_ooCertifiedOptsOnly = Bool
False
    }