view python/interferencegraph.py @ 278:9fca39eebe50

First implementation of regalloc with coalsesc
author Windel Bouwman
date Sun, 29 Sep 2013 14:08:15 +0200
parents 046017431c6a
children 2ccd57b1d78c
line wrap: on
line source

import graph


class InterferenceGraphNode(graph.Node):
    def __init__(self, g, varname):
        super().__init__(g)
        self.temps = [varname]
        self.moves = set()

    def __repr__(self):
        return 'IGN<{}>'.format(self.temps)


class InterferenceGraph(graph.Graph):
    """
        Interference graph.
    """
    def __init__(self, flowgraph):
        """ 
            Create a new interference graph from a flowgraph 
        """
        super().__init__()
        # Calculate liveness in CFG:
        ###
        # Liveness:
        #  in[n] = use[n] UNION (out[n] - def[n])
        #  out[n] = for s in n.succ in union in[s]
        ###
        for n in flowgraph.nodes:
            n.live_in = set()
            n.live_out = set()

        # Dataflow fixed point iteration:
        change = True
        while change:
            change = False
            for n in flowgraph.nodes:
                _in = n.live_in
                _out = n.live_out
                n.live_in = n.uses | (n.live_out - n.defs)
                if n.Succ:
                    n.live_out = set.union(*(s.live_in for s in n.Succ))
                else:
                    n.live_out = set()
                change = change or (_in != n.live_in) or (_out != n.live_out)

        # Construct interference graph:
        for n in flowgraph.nodes:
            for tmp in n.live_out:
                n1 = self.getNode(tmp)
                for tmp2 in (n.live_out - {tmp}):
                    n2 = self.getNode(tmp2)
                    self.addEdge(n1, n2)

    def getNode(self, tmp):
        # Linear search
        # TODO: can be improved for speed!
        for n in self.nodes:
            if tmp in n.temps:
                return n
        n = InterferenceGraphNode(self, tmp)
        self.addNode(n)
        return n

    def Combine(self, n, m):
        """ Combine n and m into n """
        n.temps.extend(m.temps)
        n.moves.update(m.moves)
        for t in m.Adjecent:
            self.addEdge(n, t)
        self.delNode(m)