    -- | 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 Futhark.Analysis.SymbolTable qualified 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 :: forall rep.
    SimplifiableRep rep =>
    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 {k} (rep :: k). HoistBlockers rep
    neverHoist

    -- | Run copy propagation on some statements.
    copyPropagateInStms ::
      (MonadFreshNames m, SimplifiableRep rep) =>
      SimpleOps rep ->
      Scope rep ->
      Stms rep ->
      m (Stms rep)
    copyPropagateInStms :: forall (m :: * -> *) rep.
    (MonadFreshNames m, SimplifiableRep rep) =>
    SimpleOps rep -> Scope rep -> Stms rep -> m (Stms rep)
    copyPropagateInStms SimpleOps rep
    simpl = SimpleOps rep
    -> RuleBook (Wise rep)
    -> HoistBlockers rep
    -> Scope rep
    -> Stms rep
    -> m (Stms rep)
    forall (m :: * -> *) rep.
    (MonadFreshNames m, SimplifiableRep rep) =>
    SimpleOps rep
    -> RuleBook (Wise rep)
    -> HoistBlockers rep
    -> Scope rep
    -> Stms rep
    -> m (Stms rep)
    simplifyStms SimpleOps rep
    simpl RuleBook (Wise rep)
    forall a. Monoid a => a
    mempty HoistBlockers rep
    forall {k} (rep :: k). 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 :: forall (m :: * -> *) rep.
    (MonadFreshNames m, SimplifiableRep rep) =>
    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 {k} (rep :: k). HoistBlockers rep
    neverHoist