def _check_vars_visibility_in_block(
        self, visible_vars_from_outer_block: Optional[Set[Var]] = None
    ):
        """
        This utils does a one pass program-wise checking of vars visibility.
        That is, each input of an op, should appear before the op in the sequantial order.

        For the debug purpose, if you want to pinpoint the operation which caused the
        invalid program state, please set DEBUG=True, and it will be captured by the ``is_var_visible_in_block`` utils.
        """
        if visible_vars_from_outer_block is None:
            visible_vars_from_outer_block = set()
        block_inputs = list(self.inputs.values()) if isinstance(self, Function) else self.inputs
        visible_vars_in_block = set(block_inputs)

        for op in self.operations:
            for b in op.blocks:
                b._check_vars_visibility_in_block(
                    visible_vars_from_outer_block=visible_vars_from_outer_block.union(
                        visible_vars_in_block
                    )
                )
            for val in op.get_flattened_inputs():
                if (
                    val not in self._internal_vars
                    and val not in visible_vars_in_block
                    and val not in visible_vars_from_outer_block
                ):
                    raise ValueError(f"Var {val} not visible in the block {self.name}.")
            for out_var in op.outputs:
                visible_vars_in_block.add(out_var)

        This utils does a one pass program-wise checking of vars visibility.
        That is, each input of an op, should appear before the op in the sequantial order.

        For the debug purpose, if you want to pinpoint the operation which caused the
        invalid program state, please set DEBUG=True, and it will be captured by the ``is_var_visible_in_block`` utils.
        
coremltools/converters/mil/mil/block.py