예제 #1
0
def intervals(graph):
    '''
    Compute the intervals of the graph
    Returns
        interval_graph: a graph of the intervals of G
        interv_heads: a dict of (header node, interval)
    '''
    interval_graph = Graph()  # graph of intervals
    heads = set([graph.get_entry()])  # set of header nodes
    interv_heads = {}  # interv_heads[i] = interval of header i
    processed = dict([(i, False) for i in graph])
    edges = {}

    while heads:
        head = heads.pop()

        if not processed[head]:
            processed[head] = True
            interv_heads[head] = Interval(head)

            # Check if if there is a node which has all its predecessor in the
            # current interval. If there is, add that node to the interval and
            # repeat until all the possible nodes have been added.
            change = True
            while change:
                change = False
                for node in graph.get_rpo()[1:]:
                    if all(p in interv_heads[head] for p in graph.preds(node)):
                        change |= interv_heads[head].add_node(node)

            # At this stage, a node which is not in the interval, but has one
            # of its predecessor in it, is the header of another interval. So
            # we add all such nodes to the header list.
            for node in graph:
                if node not in interv_heads[head] and node not in heads:
                    if any(p in interv_heads[head] for p in graph.preds(node)):
                        edges.setdefault(interv_heads[head], []).append(node)
                        heads.add(node)

            interval_graph.add_node(interv_heads[head])
            interv_heads[head].compute_end(graph)

    # Edges is a mapping of 'Interval -> [header nodes of interval successors]'
    for interval, heads in edges.items():
        for head in heads:
            interval_graph.add_edge(interval, interv_heads[head])

    interval_graph.set_entry(graph.get_entry().interval)
    graph_exit = graph.get_exit()
    if graph_exit:
        interval_graph.set_exit(graph_exit.interval)

    return interval_graph, interv_heads
def intervals(graph):
    '''
    Compute the intervals of the graph
    Returns
        interval_graph: a graph of the intervals of G
        interv_heads: a dict of (header node, interval)
    '''
    interval_graph = Graph()  # graph of intervals
    heads = set([graph.get_entry()])  # set of header nodes
    interv_heads = {}  # interv_heads[i] = interval of header i
    processed = dict([(i, False) for i in graph])
    edges = {}

    while heads:
        head = heads.pop()

        if not processed[head]:
            processed[head] = True
            interv_heads[head] = Interval(head)

            # Check if if there is a node which has all its predecessor in the
            # current interval. If there is, add that node to the interval and
            # repeat until all the possible nodes have been added.
            change = True
            while change:
                change = False
                for node in graph.get_rpo()[1:]:
                    if all(p in interv_heads[head] for p in graph.preds(node)):
                        change |= interv_heads[head].add_node(node)

            # At this stage, a node which is not in the interval, but has one
            # of its predecessor in it, is the header of another interval. So
            # we add all such nodes to the header list.
            for node in graph:
                if node not in interv_heads[head] and node not in heads:
                    if any(p in interv_heads[head] for p in graph.preds(node)):
                        edges.setdefault(interv_heads[head], []).append(node)
                        heads.add(node)

            interval_graph.add_node(interv_heads[head])
            interv_heads[head].compute_end(graph)

    # Edges is a mapping of 'Interval -> [header nodes of interval successors]'
    for interval, heads in edges.items():
        for head in heads:
            interval_graph.add_edge(interval, interv_heads[head])

    interval_graph.set_entry(graph.get_entry().interval)
    graph_exit = graph.get_exit()
    if graph_exit:
        interval_graph.set_exit(graph_exit.interval)

    return interval_graph, interv_heads