def test_redundant_ops_time_complexity(self):
        """
        Test the graph pass doesn't re-run right away after detecting a redundant pattern,
        in order to keep time complexity low.

        In this example, a program with 26 ops is first traversed, and 5 relu ops are removed.
        At the time of second traversal, there are only 21 remaining ops.
        As the result, the total ops of visited is 26 + 21 = 47.
        """

        @mb.program(input_specs=[mb.TensorSpec(shape=(2, 3, 5))])
        def prog(x):
            x = mb.cos(x=x)
            for i in range(5):
                x1 = mb.relu(x=x)
                x2 = mb.relu(x=x)
                z = mb.add(x=x1, y=x2)
                z = mb.add(x=z, y=x2)
                x = mb.sin(x=x)
            return x

        graph_pass = remove_redundant_ops()
        graph_pass.apply(prog)

        assert get_op_types_in_program(prog) == ["cos"] + ["relu", "add", "add", "sin"] * 5
        assert graph_pass._num_of_visited_ops == 47

        Test the graph pass doesn't re-run right away after detecting a redundant pattern,
        in order to keep time complexity low.

        In this example, a program with 26 ops is first traversed, and 5 relu ops are removed.
        At the time of second traversal, there are only 21 remaining ops.
        As the result, the total ops of visited is 26 + 21 = 47.
        
coremltools/converters/mil/mil/passes/tests/test_cleanup_passes.py