{-# 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.Rep (Wise)
import Futhark.Pass

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

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

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