{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}

-- | Perform copy propagation.  This is done by invoking the
-- simplifier with no rules, so hoisting and dead-code elimination may
-- also take place.
module Futhark.Transform.CopyPropagate
  ( copyPropagateInProg,
    copyPropagateInStms,
    copyPropagateInFun,
  )
where

import qualified Futhark.Analysis.SymbolTable as ST
import Futhark.IR
import Futhark.MonadFreshNames
import Futhark.Optimise.Simplify
import Futhark.Optimise.Simplify.Lore (Wise)
import Futhark.Pass

-- | Run copy propagation on an entire program.
copyPropagateInProg ::
  SimplifiableLore lore =>
  SimpleOps lore ->
  Prog lore ->
  PassM (Prog lore)
copyPropagateInProg :: forall lore.
SimplifiableLore lore =>
SimpleOps lore -> Prog lore -> PassM (Prog lore)
copyPropagateInProg SimpleOps lore
simpl = SimpleOps lore
-> RuleBook (Wise lore)
-> HoistBlockers lore
-> Prog lore
-> PassM (Prog lore)
forall lore.
SimplifiableLore lore =>
SimpleOps lore
-> RuleBook (Wise lore)
-> HoistBlockers lore
-> Prog lore
-> PassM (Prog lore)
simplifyProg SimpleOps lore
simpl RuleBook (Wise lore)
forall a. Monoid a => a
mempty HoistBlockers lore
forall lore. HoistBlockers lore
neverHoist

-- | Run copy propagation on some statements.
copyPropagateInStms ::
  (MonadFreshNames m, SimplifiableLore lore) =>
  SimpleOps lore ->
  Scope lore ->
  Stms lore ->
  m (ST.SymbolTable (Wise lore), Stms lore)
copyPropagateInStms :: forall (m :: * -> *) lore.
(MonadFreshNames m, SimplifiableLore lore) =>
SimpleOps lore
-> Scope lore
-> Stms lore
-> m (SymbolTable (Wise lore), Stms lore)
copyPropagateInStms SimpleOps lore
simpl = SimpleOps lore
-> RuleBook (Wise lore)
-> HoistBlockers lore
-> Scope lore
-> Stms lore
-> m (SymbolTable (Wise lore), Stms lore)
forall (m :: * -> *) lore.
(MonadFreshNames m, SimplifiableLore lore) =>
SimpleOps lore
-> RuleBook (Wise lore)
-> HoistBlockers lore
-> Scope lore
-> Stms lore
-> m (SymbolTable (Wise lore), Stms lore)
simplifyStms SimpleOps lore
simpl RuleBook (Wise lore)
forall a. Monoid a => a
mempty HoistBlockers lore
forall lore. HoistBlockers lore
neverHoist

-- | Run copy propagation on a function.
copyPropagateInFun ::
  (MonadFreshNames m, SimplifiableLore lore) =>
  SimpleOps lore ->
  ST.SymbolTable (Wise lore) ->
  FunDef lore ->
  m (FunDef lore)
copyPropagateInFun :: forall (m :: * -> *) lore.
(MonadFreshNames m, SimplifiableLore lore) =>
SimpleOps lore
-> SymbolTable (Wise lore) -> FunDef lore -> m (FunDef lore)
copyPropagateInFun SimpleOps lore
simpl = SimpleOps lore
-> RuleBook (Wise lore)
-> HoistBlockers lore
-> SymbolTable (Wise lore)
-> FunDef lore
-> m (FunDef lore)
forall (m :: * -> *) lore.
(MonadFreshNames m, SimplifiableLore lore) =>
SimpleOps lore
-> RuleBook (Wise lore)
-> HoistBlockers lore
-> SymbolTable (Wise lore)
-> FunDef lore
-> m (FunDef lore)
simplifyFun SimpleOps lore
simpl RuleBook (Wise lore)
forall a. Monoid a => a
mempty HoistBlockers lore
forall lore. HoistBlockers lore
neverHoist