def apply_pipeline(prog: Program, pass_pipeline: PassPipeline):
        """Apply a pass pipeline to a program, which modifies the program in-place."""
        if pass_pipeline is None:
            raise ValueError("The pass_pipeline cannot be None.")

        pass_pipeline.validate()
        prog.validate()

        logger.debug(f"Program before {pass_pipeline} pipeline:\n{prog}")
        for pass_name in tqdm(
            pass_pipeline.passes,
            desc=f"Running MIL {pass_pipeline} pipeline",
            unit=" passes",
        ):
            logger.debug(f'Performing pass: "{pass_name}"')
            pass_options = pass_pipeline.get_options(pass_name)
            if pass_options is not None:
                logger.debug(
                    f"The graph pass options for {pass_name} is set to {pass_options}. "
                    f"It will change the pass behavior. Make sure the option is intended."
                )
            if pass_name.startswith("experimental::"):
                logger.warning(
                    f"The graph pass {pass_name} is under experimental development, "
                    f"and the API could be changed in the future."
                )
            graph_pass = PASS_REGISTRY[pass_name]
            graph_pass.set_options(pass_options)

            try:
                graph_pass(prog)
            except Exception as e:
                logger.error(
                    f"\n\nERROR - '{pass_name}' graph pass produces the following error:\n"
                )
                raise e  # re-raise exception

            # After dead code elimination, we should check if the program misses any essential scope info
            check_essential_scope = pass_name == "common::dead_code_elimination"
            prog.validate(check_essential_scope=check_essential_scope)
        logger.debug(f"Program after {pass_pipeline} pipeline:\n{prog}")
Apply a pass pipeline to a program, which modifies the program in-place.
coremltools/converters/mil/mil/passes/pass_pipeline.py