예제 #1
0
def test_set_inputs_property():
    in0 = Constant(0)
    in1 = Constant(1)
    value = Apply([in0], Graph())
    value.inputs = [in1]
    assert in0.uses == set()
    assert in1.uses == {(value, 0)}
예제 #2
0
def test_set_inputs(index):
    in0 = Constant(0)
    in1 = Constant(1)
    value = Apply([in0], Graph())
    value.inputs[index] = in1
    assert value.inputs[0] is in1
    assert in0.uses == set()
    assert in1.uses == {(value, 0)}
예제 #3
0
def test_slice_inputs():
    in0 = Constant(0)
    in1 = Constant(1)
    value = Apply([in0, in1], Graph())
    assert value.inputs[:] == [in0, in1]
    with pytest.raises(ValueError):
        del value.inputs[:]
    with pytest.raises(ValueError):
        value.inputs[:] = [in0]
예제 #4
0
def test_toposort2():
    g0 = Graph()
    g0.output = Constant(33)
    g1 = Graph()
    in0 = Constant(g0)
    in1 = Constant(1)
    v1 = Apply([in0, in1], g1)
    v2 = Apply([in0, v1, in1], g1)
    g1.output = v2

    order = list(toposort(g1.return_))
    _check_toposort(order, g1.return_, succ_incoming)
예제 #5
0
def test_graph():
    """Construct a small graph.

    Note that this graph is strictly speaking nonsensical, because it doesn't
    use any actual primitive operations.
    """
    g = Graph()
    x = Parameter(g)
    assert x.value is PARAMETER
    one = Constant(1)
    add = Constant('add')
    return_ = Constant('return')
    value = Apply([add, x, one], g)
    return_ = Apply([return_, value], g)
    g.return_ = return_
    g.parameters.append(x)
예제 #6
0
 def process_Subscript(self, block: 'Block',
                       node: ast.Subscript) -> ANFNode:
     """Process subscripts: `x[y]`."""
     op = self.environment.map(operator.getitem)
     value = self.process_node(block, node.value)
     slice = self.process_node(block, node.slice)
     return Apply([op, value, slice], block.graph)
예제 #7
0
 def process_Compare(self, block: 'Block', node: ast.Compare) -> ANFNode:
     """Process comparison operators: `a == b`, `a > b`, etc."""
     ops = [self._resolve_ast_type(op) for op in node.ops]
     assert len(ops) == 1
     left = self.process_node(block, node.left)
     right = self.process_node(block, node.comparators[0])
     return Apply([ops[0], left, right], block.graph)
예제 #8
0
def test_dfs_graphs():
    g0 = Graph()
    in0 = Constant(g0)
    in1 = Constant(1)
    g0.return_ = in1
    value = Apply([in0], Graph())
    assert set(dfs(value)) == {value, in0}
    assert set(dfs(value, follow_graph=True)) == {value, in0, in1}
예제 #9
0
def test_del_inputs(index):
    in0 = Constant(0)
    in1 = Constant(1)
    value = Apply([in0, in1], Graph())
    del value.inputs[index]
    assert in0.uses == set()
    assert in1.uses == {(value, 0)}
    assert value.inputs[0] is in1
예제 #10
0
def test_insert_inputs(index):
    in0 = Constant(0)
    in1 = Constant(1)
    value = Apply([in1], Graph())
    value.inputs.insert(index, in0)
    assert value.inputs[0] is in0
    assert value.inputs[1] is in1
    assert in0.uses == {(value, 0)}
    assert in1.uses == {(value, 1)}
예제 #11
0
def test_copy():
    in0 = Constant(0)
    value0 = Apply([in0], Graph())
    value1 = copy.copy(value0)
    in1 = copy.copy(in0)
    assert value1.inputs == value0.inputs
    assert value1.inputs is not value0.inputs
    assert in0.uses == {(value0, 0), (value1, 0)}
    assert in1.uses == set()
예제 #12
0
 def process_Return(self, block: 'Block', node: ast.Return) -> 'Block':
     """Process a return statement."""
     inputs = [
         Constant(primops.return_),
         self.process_node(block, node.value)
     ]
     return_ = Apply(inputs, block.graph)
     block.graph.return_ = return_
     return block
예제 #13
0
    def jump(self, target: 'Block') -> Apply:
        """Jumping from one block to the next becomes a tail call.

        This method will generate the tail call by calling the graph
        corresponding to the target block using an `Apply` node, and returning
        its value with a `Return` node. It will update the predecessor blocks
        of the target appropriately.

        Args:
            target: The block to jump to from this statement.

        """
        jump = Apply([self.parser.get_block_function(target)], self.graph)
        self.jumps[target] = jump
        target.preds.append(self)
        inputs = [Constant(primops.return_), jump]
        return_ = Apply(inputs, self.graph)
        self.graph.return_ = return_
        return return_
예제 #14
0
def test_toposort():
    g0 = Graph()
    g0.output = Constant(1)
    g1 = Graph()
    in0 = Constant(g0)
    value = Apply([in0], g1)
    g1.output = value

    order = list(toposort(g1.return_))
    _check_toposort(order, g1.return_, succ_incoming)
예제 #15
0
def test_helpers():
    g = Graph()
    cg = Constant(g)
    assert is_constant_graph(cg)

    one = Constant(1)
    assert not is_constant_graph(one)
    assert is_constant(one)

    a = Apply([cg, one], g)
    assert is_apply(a)

    p = Parameter(g)
    assert is_parameter(p)
예제 #16
0
    def cond(self, cond: ANFNode, true: 'Block', false: 'Block') -> Apply:
        """Perform a conditional jump.

        This method will generate the call to the if expression and return its
        value. The predecessor blocks of the branches will be updated
        appropriately.

        Args:
            cond: The node representing the condition (true or false).
            true: The block to jump to if the condition is true.
            false: The block to jump to if the condition is false.

        """
        inputs = [
            Constant(primops.if_), cond,
            self.parser.get_block_function(true),
            self.parser.get_block_function(false)
        ]
        if_ = Apply(inputs, self.graph)
        inputs = [Constant(primops.return_), if_]
        return_ = Apply(inputs, self.graph)
        self.graph.return_ = return_
        return return_
예제 #17
0
def test_str_coverage():
    """Just a coverage test for __str__ and __repr__

    Doesn't check that they take particular values since that could change
    easily.
    """
    g = Graph()
    p = Parameter(g)
    p.name = 'param'
    objects = [g, Apply([], g), p, Parameter(g), Constant(0), Constant(g)]
    for o in objects:
        str(o)
        repr(o)
        o.debug.debug_name
예제 #18
0
        def write(targ, anf_node):

            if isinstance(targ, ast.Name):
                # CASE: x = value
                anf_node.debug.name = targ.id
                block.write(targ.id, anf_node)

            elif isinstance(targ, ast.Tuple):
                # CASE: x, y = value
                for i, elt in enumerate(targ.elts):
                    op = self.environment.map(operator.getitem)
                    new_node = Apply([op, anf_node, Constant(i)], block.graph)
                    write(elt, new_node)

            else:
                raise NotImplementedError(node.targets)  # pragma: no cover
예제 #19
0
 def process_Attribute(self, block: 'Block',
                       node: ast.Attribute) -> ANFNode:
     """Process attributes: `x.y`."""
     op = self.environment.map(getattr)
     value = self.process_node(block, node.value)
     return Apply([op, value, Constant(node.attr)], block.graph)
예제 #20
0
def test_append_inputs():
    in0 = Constant(0)
    value = Apply([], Graph())
    value.inputs.append(in0)
    assert in0.uses == {(value, 0)}
예제 #21
0
def test_outgoing():
    in0 = Constant(0)
    value = Apply([in0], Graph())
    assert list(value.outgoing) == []
    assert list(in0.outgoing) == [value]
예제 #22
0
def test_get_inputs(index):
    in0 = Constant(0)
    value = Apply([in0], Graph())
    assert value.inputs[index] == in0
예제 #23
0
def test_incoming():
    in0 = Constant(0)
    value = Apply([in0], Graph())
    assert list(value.incoming) == [in0]
    assert list(in0.incoming) == []
예제 #24
0
 def process_BinOp(self, block: 'Block', node: ast.BinOp) -> ANFNode:
     """Process binary operators: `a + b`, `a | b`, etc."""
     func = self._resolve_ast_type(node.op)
     left = self.process_node(block, node.left)
     right = self.process_node(block, node.right)
     return Apply([func, left, right], block.graph)
예제 #25
0
def test_len_inputs():
    in0 = Constant(0)
    in1 = Constant(1)
    value = Apply([in0, in1], Graph())
    assert len(value.inputs) == 2
예제 #26
0
def test_dfs():
    in0 = Constant(0)
    in1 = Constant(1)
    value = Apply([in0, in1], Graph())
    assert next(dfs(value)) == value
    assert set(dfs(value)) == {value, in0, in1}
예제 #27
0
 def cons(elts):
     if len(elts) == 0:
         return Constant(())
     else:
         x, *rest = elts
         return Apply([op, x, cons(rest)], block.graph)
예제 #28
0
def test_init_inputs():
    in0 = Constant(0)
    value = Apply([in0], Graph())
    assert in0.uses == {(value, 0)}
예제 #29
0
 def process_UnaryOp(self, block: 'Block', node: ast.UnaryOp) -> ANFNode:
     """Process unary operators: `+a`, `-a`, etc."""
     func = self._resolve_ast_type(node.op)
     operand = self.process_node(block, node.operand)
     return Apply([func, operand], block.graph)
예제 #30
0
 def process_Call(self, block: 'Block', node: ast.Call) -> ANFNode:
     """Process function calls: `f(x)`, etc."""
     func = self.process_node(block, node.func)
     args = [self.process_node(block, arg) for arg in node.args]
     return Apply([func] + args, block.graph)