use crate::{
    core::{
        compile_passes::{
            circuit_pass::CircuitPass,
            DeadCodeEliminator,
            DeadGateEliminator,
            Optimizer,
            BUILD_FN_SEQ,
        },
        ir::IntermediateRepresentation,
    },
    AsyncMPCCircuit,
};

pub struct Compiler;

impl Compiler {
    /// Common SubExpression Elimination and Dead Code Elimination
    fn dead_code_elimination(old_ir: IntermediateRepresentation) -> IntermediateRepresentation {
        DeadCodeEliminator::eliminate(old_ir)
    }

    /// Performs optimizations and
    /// returns an intermediate representation that can be converted into a circuit.
    pub fn optimize_into_circuitable(
        mut ir: IntermediateRepresentation,
    ) -> IntermediateRepresentation {
        for build_fn in BUILD_FN_SEQ {
            // Optimizing.
            ir = Optimizer::optimize(ir);
            // Eliminating dead code.
            ir = Self::dead_code_elimination(ir);
            // Building.
            ir = build_fn(ir);
        }

        // Another round of DCE
        Self::dead_code_elimination(ir)
    }
    pub fn improve_async_mpc_circuit(circuit: AsyncMPCCircuit) -> AsyncMPCCircuit {
        DeadGateEliminator::make_and_run(circuit)
    }
}
