{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ConstraintKinds #-}
module Futhark.Optimise.Simplify
( simplifyProg
, simplifySomething
, simplifyFun
, simplifyLambda
, simplifyStms
, Engine.SimpleOps (..)
, Engine.SimpleM
, Engine.SimplifyOp
, Engine.bindableSimpleOps
, Engine.noExtraHoistBlockers
, Engine.SimplifiableLore
, Engine.HoistBlockers
, RuleBook
)
where
import Futhark.Representation.AST
import Futhark.MonadFreshNames
import qualified Futhark.Optimise.Simplify.Engine as Engine
import qualified Futhark.Analysis.SymbolTable as ST
import Futhark.Optimise.Simplify.Rule
import Futhark.Optimise.Simplify.Lore
import Futhark.Pass
simplifyProg :: Engine.SimplifiableLore lore =>
Engine.SimpleOps lore
-> RuleBook (Engine.Wise lore)
-> Engine.HoistBlockers lore
-> Prog lore
-> PassM (Prog lore)
simplifyProg simpl rules blockers =
intraproceduralTransformation $ simplifyFun simpl rules blockers
simplifySomething :: (MonadFreshNames m, HasScope lore m,
Engine.SimplifiableLore lore) =>
(a -> Engine.SimpleM lore b)
-> (b -> a)
-> Engine.SimpleOps lore
-> RuleBook (Wise lore)
-> Engine.HoistBlockers lore
-> a
-> m a
simplifySomething f g simpl rules blockers x = do
scope <- askScope
let f' x' = Engine.localVtable (ST.fromScope (addScopeWisdom scope)<>) $ f x'
loopUntilConvergence env simpl f' g x
where env = Engine.emptyEnv rules blockers
simplifyFun :: (MonadFreshNames m, Engine.SimplifiableLore lore) =>
Engine.SimpleOps lore
-> RuleBook (Engine.Wise lore)
-> Engine.HoistBlockers lore
-> FunDef lore
-> m (FunDef lore)
simplifyFun simpl rules blockers =
loopUntilConvergence env simpl Engine.simplifyFun removeFunDefWisdom
where env = Engine.emptyEnv rules blockers
simplifyLambda :: (MonadFreshNames m, HasScope lore m, Engine.SimplifiableLore lore) =>
Engine.SimpleOps lore
-> RuleBook (Engine.Wise lore)
-> Engine.HoistBlockers lore
-> Lambda lore -> [Maybe VName]
-> m (Lambda lore)
simplifyLambda simpl rules blockers orig_lam args =
simplifySomething f removeLambdaWisdom simpl rules blockers orig_lam
where f lam' = Engine.simplifyLambdaNoHoisting lam' args
simplifyStms :: (MonadFreshNames m, HasScope lore m, Engine.SimplifiableLore lore) =>
Engine.SimpleOps lore
-> RuleBook (Engine.Wise lore)
-> Engine.HoistBlockers lore
-> Stms lore
-> m (Stms lore)
simplifyStms = simplifySomething f g
where f stms = fmap snd $ Engine.simplifyStms stms $ return ((), mempty)
g = fmap removeStmWisdom
loopUntilConvergence :: (MonadFreshNames m, Engine.SimplifiableLore lore) =>
Engine.Env lore
-> Engine.SimpleOps lore
-> (a -> Engine.SimpleM lore b)
-> (b -> a)
-> a
-> m a
loopUntilConvergence env simpl f g x = do
(x', changed) <- modifyNameSource $ Engine.runSimpleM (f x) simpl env
if changed then loopUntilConvergence env simpl f g (g x') else return $ g x'