def cache_expressions(node):
    # Count the occurance of each expression
    counts = defaultdict(int)
    def count_func(pattern, node):
        name = node_name(node)
        if isinstance(name, tuple) and "Operator" in name[0]:
            counts[name] += 1
    tile(node, [Pattern()], count_func)

    # Replace all the expressions with count > 1 with
    # a cached version
    state = {"last_id": 0}
    replacements = {}
    def repl_func(pattern, node):
        # Check for a cached node
        name = node_name(node)
        if name and name in counts and counts[name] > 1:
            if name in replacements:
                return replacements[name]
            else:
                cache_node = ast.CachedNode(node, state["last_id"])
                replacements[name] = cache_node
                state["last_id"] += 1
                return cache_node

    tile(node, [Pattern()], repl_func)
    return node
Modifies the AST tree in place to reduce the duplicated computations.
dataset/ETHPy150Open armon/pypred/pypred/cache.py/cache_expressions