Пример #1
0
class Block(Value):
    """
    Basic block of Operations.

        name:   Name of block (unique within function)
        parent: Function owning block
    """

    head, tail = Delegate('ops'), Delegate('ops')

    def __init__(self, name, parent=None, ops=None):
        self.name = name
        self.parent = parent
        self.ops = LinkedList(ops or [])

    def __iter__(self):
        return iter(self.ops)

    def append(self, op):
        """Append op to block"""
        self.ops.append(op)
        op.parent = self
        # self.parent.values[op.result] = op

    def extend(self, ops):
        """Extend block with ops"""
        for op in ops:
            self.append(op)

    @property
    def result(self):
        """We are a first-class value..."""
        return self.name

    @property
    def leaders(self):
        """
        Return an iterator of basic block leaders
        """
        for op in self.ops:
            if ops.is_leader(op.opcode):
                yield op
            else:
                break

    @property
    def terminator(self):
        """Block Op in block, which needs to be a terminator"""
        assert ops.is_terminator(self.ops.tail)
        return self.ops.tail

    def __repr__(self):
        return "Block(%s, %s)" % (self.name, list(self))
Пример #2
0
class Block(Value):
    """
    Basic block of Operations.

        name:   Name of block (unique within function)
        parent: Function owning block
    """

    head, tail = Delegate('ops'), Delegate('ops')

    def __init__(self, name, parent=None, ops=None):
        self.name   = name
        self.parent = parent
        self.ops = LinkedList(ops or [])

    def __iter__(self):
        return iter(self.ops)

    def append(self, op):
        """Append op to block"""
        self.ops.append(op)
        op.parent = self
        # self.parent.values[op.result] = op

    def extend(self, ops):
        """Extend block with ops"""
        for op in ops:
            self.append(op)

    @property
    def result(self):
        """We are a first-class value..."""
        return self.name

    @property
    def leaders(self):
        """
        Return an iterator of basic block leaders
        """
        for op in self.ops:
            if ops.is_leader(op.opcode):
                yield op
            else:
                break

    @property
    def terminator(self):
        """Block Op in block, which needs to be a terminator"""
        assert ops.is_terminator(self.ops.tail)
        return self.ops.tail

    def __repr__(self):
        return "Block(%s, %s)" % (self.name, list(self))
Пример #3
0
    def __init__(self, name, argnames, type, temper=None):
        self.module = None
        self.name = name
        self.type = type
        self.temp = temper or make_temper()

        self.blocks = LinkedList()
        self.blockmap = dict((block.name, block) for block in self.blocks)
        self.argnames = argnames
        self.argdict = {}

        self.uses = defaultdict(set)

        # reserve names
        for argname in argnames:
            self.temp(argname)
Пример #4
0
    def __init__(self, name, argnames, type, temper=None):
        self.module = None
        self.name = name
        self.type = type
        self.temp = temper or make_temper()

        self.blocks = LinkedList()
        self.blockmap = dict((block.name, block) for block in self.blocks)
        self.argnames = argnames
        self.argdict = {}

        self.uses = defaultdict(set)

        # reserve names
        for argname in argnames:
            self.temp(argname)
Пример #5
0
    def test_linkedlist(self):
        items = [LinkableItem(i) for i in range(5)]
        l = LinkedList(items)
        foo, bar, head, tail = map(LinkableItem, ["foo", "bar", "head", "tail"])
        five = LinkableItem(5)

        l.insert_before(foo, items[2])
        l.insert_after(bar, items[2])
        l.insert_before(head, items[0])
        l.append(five)
        l.insert_after(tail, five)
        l.remove(items[4])

        expected = ["head", 0, 1, "foo", 2, "bar", 3, 5, "tail"]
        expected = [LinkableItem(x) for x in expected]
        got = list(l)
        self.assertEqual(got, expected)
Пример #6
0
    def test_linkedlist(self):
        items = [LinkableItem(i) for i in range(5)]
        l = LinkedList(items)
        foo, bar, head, tail = map(LinkableItem,
                                   ["foo", "bar", "head", "tail"])
        five = LinkableItem(5)

        l.insert_before(foo, items[2])
        l.insert_after(bar, items[2])
        l.insert_before(head, items[0])
        l.append(five)
        l.insert_after(tail, five)
        l.remove(items[4])

        expected = ["head", 0, 1, "foo", 2, "bar", 3, 5, "tail"]
        expected = [LinkableItem(x) for x in expected]
        got = list(l)
        self.assertEqual(got, expected)
Пример #7
0
 def __init__(self, name, parent=None, ops=None):
     self.name = name
     self.parent = parent
     self.ops = LinkedList(ops or [])
Пример #8
0
 def __init__(self, name, parent=None, ops=None):
     self.name   = name
     self.parent = parent
     self.ops = LinkedList(ops or [])
Пример #9
0
class Function(Value):
    """
    Function consisting of basic blocks.

    Attributes
    ----------
    module: Module
         Module owning the function

    name:
        name of the function

    args: [FuncArg]

    argnames:
        argument names ([str])

    blocks:
        List of basic blocks in topological order

    startblock: Block
        The entry basic block

    exitblock: Block
        The last block in the list. This will only be the actual 'exit block'
        if the function is actually populated and has an exit block.

    values:  { op_name: Operation }

    uses: { Operation : [Operation] }
        Operations that refer to this operation in their 'args' list

    temp: function, name -> tempname
        allocate a temporary name
    """

    __slots__ = ('module', 'name', 'type', 'temp', 'blocks', 'blockmap',
                 'argnames', 'argdict', 'uses')

    def __init__(self, name, argnames, type, temper=None):
        self.module = None
        self.name = name
        self.type = type
        self.temp = temper or make_temper()

        self.blocks = LinkedList()
        self.blockmap = dict((block.name, block) for block in self.blocks)
        self.argnames = argnames
        self.argdict = {}

        self.uses = defaultdict(set)

        # reserve names
        for argname in argnames:
            self.temp(argname)

    @property
    def args(self):
        return [self.get_arg(argname) for argname in self.argnames]

    @property
    def startblock(self):
        return self.blocks.head

    @property
    def exitblock(self):
        return self.blocks.tail

    @property
    def ops(self):
        """Get a flat iterable of all Ops in this function"""
        return chain(*self.blocks)

    def new_block(self, label, ops=None, after=None):
        """Create a new block with name `label` and append it"""
        label = self.temp(label)
        return self.add_block(Block(label, self, ops), after)

    def add_arg(self, argname, argtype):
        self.argnames.append(argname)
        argtypes = tuple(self.type.argtypes) + (argtype,)
        self.type = types.Function(self.type.restype, argtypes,
                                   self.type.varargs)
        return self.get_arg(argname)

    def add_block(self, block, after=None):
        """Add a Block at the end, or after `after`"""
        assert block.name not in self.blockmap
        self.temp(block.name) # Make sure this name is taken

        if block.parent is None:
            block.parent = self
        else:
            assert block.parent is self

        self.blockmap[block.name] = block
        if after is None:
            self.blocks.append(block)
        else:
            self.blocks.insert_after(block, after)

        return block

    def get_block(self, label):
        return self.blockmap[label]

    def del_block(self, block):
        self.blocks.remove(block)
        del self.blockmap[block.name]

    def get_arg(self, argname):
        """Get argument as a Value"""
        if argname in self.argdict:
            return self.argdict[argname]

        idx = self.argnames.index(argname)
        type = self.type.argtypes[idx]
        arg = FuncArg(self, argname, type)
        self.argdict[argname] = arg
        return arg

    @property
    def result(self):
        """We are a first-class value..."""
        return self.name

    # ______________________________________________________________________
    # uses

    def add_op(self, op):
        """
        Register a new Op as part of the function.

        Does NOT insert the Op in any basic block
        """
        _add_args(self.uses, op, op.args)

    def reset_uses(self):
        from pykit.analysis import defuse
        self.uses = defuse.defuse(self)

    def delete_all(self, delete):
        """
        Delete all given operands, don't complain about uses from ops are that
        to be deleted. For example:

            %0 = myop(%arg0)
            %1 = add(%0, %arg1)

        delete = [%0, %1]
        """
        for op in delete:
            op.set_args([])
        for op in delete:
            op.delete()

    # ______________________________________________________________________

    def __repr__(self):
        return "Function(%s)" % self.name
Пример #10
0
class Block(Value):
    """
    Basic block of Operations.

        name:   Name of block (unique within function)
        parent: Function owning block
    """

    head, tail = Delegate('ops'), Delegate('ops')

    __slots__ = ('name', 'parent', 'ops', '_prev', '_next')

    def __init__(self, name, parent=None, ops=None):
        self.name   = name
        self.parent = parent
        self.ops = LinkedList(ops or [])
        self._prev = None
        self._next = None

    @property
    def opcodes(self):
        """Returns [opcode] for all operations in the block"""
        for op in self.ops:
            yield op.opcode

    @property
    def optypes(self):
        """Returns [type] for all operations in the block"""
        for op in self.ops:
            yield op.type

    def __iter__(self):
        return iter(self.ops)

    def append(self, op):
        """Append op to block"""
        self.ops.append(op)
        op.parent = self
        self.parent.add_op(op)

    def extend(self, ops):
        """Extend block with ops"""
        for op in ops:
            self.append(op)

    @property
    def result(self):
        """We are a first-class value..."""
        return self.name

    @property
    @listify
    def leaders(self):
        """
        Return an iterator of basic block leaders
        """
        for op in self.ops:
            if ops.is_leader(op.opcode):
                yield op
            else:
                break

    @property
    def terminator(self):
        """Block Op in block, which needs to be a terminator"""
        assert self.is_terminated(), self.ops.tail
        return self.ops.tail

    def is_terminated(self):
        """Returns whether the block is terminated"""
        return self.ops.tail and ops.is_terminator(self.ops.tail.opcode)

    def __lt__(self, other):
        return self.name < other.name

    def __repr__(self):
        return "Block(%s)" % self.name
Пример #11
0
class Function(Value):
    """
    Function consisting of basic blocks.

    Attributes
    ----------
    module: Module
         Module owning the function

    name:
        name of the function

    args: [FuncArg]

    argnames:
        argument names ([str])

    blocks:
        List of basic blocks in topological order

    startblock: Block
        The entry basic block

    exitblock: Block
        The last block in the list. This will only be the actual 'exit block'
        if the function is actually populated and has an exit block.

    values:  { op_name: Operation }

    uses: { Operation : [Operation] }
        Operations that refer to this operation in their 'args' list

    temp: function, name -> tempname
        allocate a temporary name
    """
    def __init__(self, name, argnames, type, temper=None):
        self.module = None
        self.name = name
        self.type = type
        self.temp = temper or make_temper()

        self.blocks = LinkedList()
        self.blockmap = dict((block.name, block) for block in self.blocks)
        self.argnames = argnames
        self.argdict = {}

        self.uses = defaultdict(set)

        # reserve names
        for argname in argnames:
            self.temp(argname)

    @property
    def args(self):
        return [self.get_arg(argname) for argname in self.argnames]

    @property
    def startblock(self):
        return self.blocks.head

    @property
    def exitblock(self):
        return self.blocks.tail

    @property
    def ops(self):
        """Get a flat iterable of all Ops in this function"""
        return chain(*self.blocks)

    def new_block(self, label, ops=None, after=None):
        """Create a new block with name `label` and append it"""
        assert label not in self.blockmap, label
        label = self.temp(label)
        return self.add_block(Block(label, self, ops), after)

    def add_block(self, block, after=None):
        """Add a Block at the end, or after `after`"""
        if block.parent is None:
            block.parent = self
        else:
            assert block.parent is self

        self.blockmap[block.name] = block
        if after is None:
            self.blocks.append(block)
        else:
            self.blocks.insert_after(block, after)

        return block

    def get_block(self, label):
        return self.blockmap[label]

    def del_block(self, block):
        self.blocks.remove(block)
        del self.blockmap[block.name]

    def get_arg(self, argname):
        """Get argument as a Value"""
        if argname in self.argdict:
            return self.argdict[argname]

        idx = self.argnames.index(argname)
        type = self.type.argtypes[idx]
        arg = FuncArg(self, argname, type)
        self.argdict[argname] = arg
        return arg

    @property
    def result(self):
        """We are a first-class value..."""
        return self.name

    # ______________________________________________________________________
    # uses

    def add_op(self, op):
        """
        Register a new Op as part of the function.

        Does NOT insert the Op in any basic block
        """
        _add_args(self.uses, op, op.args)

    def reset_uses(self):
        from pykit.analysis import defuse
        self.uses = defuse.defuse(self)

    # ______________________________________________________________________

    def __repr__(self):
        return "FunctionGraph(%s)" % self.blocks
Пример #12
0
class Block(Value):
    """
    Basic block of Operations.

        name:   Name of block (unique within function)
        parent: Function owning block
    """

    head, tail = Delegate('ops'), Delegate('ops')
    _prev, _next = None, None  # LinkedList

    def __init__(self, name, parent=None, ops=None):
        self.name = name
        self.parent = parent
        self.ops = LinkedList(ops or [])

    @property
    def opcodes(self):
        """Returns [opcode] for all operations in the block"""
        for op in self.ops:
            yield op.opcode

    @property
    def optypes(self):
        """Returns [type] for all operations in the block"""
        for op in self.ops:
            yield op.type

    def __iter__(self):
        return iter(self.ops)

    def append(self, op):
        """Append op to block"""
        self.ops.append(op)
        op.parent = self
        self.parent.add_op(op)

    def extend(self, ops):
        """Extend block with ops"""
        for op in ops:
            self.append(op)

    @property
    def result(self):
        """We are a first-class value..."""
        return self.name

    @property
    @listify
    def leaders(self):
        """
        Return an iterator of basic block leaders
        """
        for op in self.ops:
            if ops.is_leader(op.opcode):
                yield op
            else:
                break

    @property
    def terminator(self):
        """Block Op in block, which needs to be a terminator"""
        assert self.is_terminated(), self.ops.tail
        return self.ops.tail

    def is_terminated(self):
        """Returns whether the block is terminated"""
        return self.ops.tail and ops.is_terminator(self.ops.tail.opcode)

    def __lt__(self, other):
        return self.name < other.name

    def __repr__(self):
        return "Block(%s)" % self.name
Пример #13
0
    def test_linkedlist(self):
        items = map(LinkableItem, range(5))
        l = LinkedList(items)
        foo, bar, head, tail = map(LinkableItem, ["foo", "bar", "head", "tail"])
        five = LinkableItem(5)

        l.insert_before(foo, items[2])
        l.insert_after(bar, items[2])
        l.insert_before(head, items[0])
        l.append(five)
        l.insert_after(tail, five)
        l.remove(items[4])

        expected = ["head", 0, 1, "foo", 2, "bar", 3, 5, "tail"]
        self.assertEqual(list(l), list(map(LinkableItem, expected)))