Beispiel #1
0
    def test_sccp_dead_loop(self):
        simple = textwrap.dedent("""
        #include <pykit_ir.h>

        Int32 f(Int32 i) {
            Int32 x, y, z;

            x = 2;
            y = 3;
            z = 4;

            while (y < x) {
                if (y < x) {
                    x = 1;
                    x = x + 1;
                    y = x - z;
                }
            }

            return x + z;
        }
        """)
        mod = from_c(simple)
        f = mod.get_function("f")
        cfa.run(f)
        sccp.run(f)
        verify(f)

        verify(f)
        ops = list(f.ops)
        assert len(list(f.ops)) == 1
        [op] = ops
        assert op.opcode == 'ret'
        assert isinstance(op.args[0], Const)
        self.assertEqual(op.args[0].const, 6)
Beispiel #2
0
    def test_sccp_endless_loop(self):
        simple = textwrap.dedent("""
        #include <pykit_ir.h>

        Int32 f(Int32 i) {
            Int32 x, y, z;

            x = 2;
            y = 3;
            z = 4;

            while (x < y) {
                if (x < y) {
                    x = 2;
                }
            }

            return x + z;
        }
        """)
        mod = from_c(simple)
        f = mod.get_function("f")
        cfa.run(f)
        sccp.run(f)
        verify(f)

        assert len(f.blocks) == 2
        start, loop = f.blocks
        assert start.terminator.opcode == 'jump'
        assert start.terminator.args[0] == loop
        assert loop.terminator.opcode == 'jump'
        assert loop.terminator.args[0] == loop
Beispiel #3
0
    def test_swap(self):
        simple = textwrap.dedent("""
        #include <pykit_ir.h>

        int f(int i) {
            int x = 1;
            int y = 2;
            int tmp;
            while (i > 0) {
                tmp = x;
                x = y;
                y = tmp;
                i = i - 1;
            }
            return x;
        }
        """)
        mod = from_c(simple)
        func = mod.get_function("f")
        cfa.run(func)

        verify(func)
        ssa_result1 = interp.run(func, args=[1])
        ssa_result2 = interp.run(func, args=[2])

        reg2mem.reg2mem(func)
        verify(func)

        stack_result1 = interp.run(func, args=[1])
        stack_result2 = interp.run(func, args=[2])

        self.assertEqual(ssa_result1, stack_result1)
        self.assertEqual(ssa_result2, stack_result2)
Beispiel #4
0
    def test_inline2(self):
        harder = """
        int callee(int i) {
            (void) print(i);
            while (i < 10) {
                i = i + 1;
                return i * 2;
            }
            return i;
        }

        int caller() {
            int x = 4;
            while (x < 10) {
                (void) print(x);
                x = call(callee, list(x));
            }
            return x;
        }
        """
        mod = from_c(harder)
        func = mod.get_function("caller")
        verify(func)
        result = interp.run(func)

        [callsite] = findallops(func, 'call')
        inline.inline(func, callsite)
        cfa.run(func)
        verify(func)
Beispiel #5
0
 def test_ssa2(self):
     mod = from_c(source)
     f = mod.get_function('func')
     cfa.run(f)
     verify(f)
     codes = opcodes(f)
     self.assertEqual(codes.count('phi'), 3)
Beispiel #6
0
    def test_sccp_dead_loop(self):
        simple = textwrap.dedent("""
        #include <pykit_ir.h>

        Int32 f(Int32 i) {
            Int32 x, y, z;

            x = 2;
            y = 3;
            z = 4;

            while (y < x) {
                if (y < x) {
                    x = 1;
                    x = x + 1;
                    y = x - z;
                }
            }

            return x + z;
        }
        """)
        mod = from_c(simple)
        f = mod.get_function("f")
        cfa.run(f)
        sccp.run(f)
        verify(f)

        verify(f)
        ops = list(f.ops)
        assert len(list(f.ops)) == 1
        [op] = ops
        assert op.opcode == 'ret'
        assert isinstance(op.args[0], Const)
        self.assertEqual(op.args[0].const, 6)
Beispiel #7
0
    def test_sccp(self):
        simple = textwrap.dedent("""
        #include <pykit_ir.h>

        Int32 f(Int32 i) {
            Int32 x, y, z;

            x = 2;
            y = 3;
            z = 4;

            if (x < y)
                x = y;
            else
                x = i;

            return x + z;
        }
        """)
        mod = from_c(simple)
        f = mod.get_function("f")
        cfa.run(f)
        sccp.run(f)
        verify(f)

        ops = list(f.ops)
        assert len(list(f.ops)) == 1
        [op] = ops
        assert op.opcode == 'ret'
        assert isinstance(op.args[0], Const)
        self.assertEqual(op.args[0].const, 7)
Beispiel #8
0
    def test_sccp(self):
        simple = textwrap.dedent("""
        #include <pykit_ir.h>

        Int32 f(Int32 i) {
            Int32 x, y, z;

            x = 2;
            y = 3;
            z = 4;

            if (x < y)
                x = y;
            else
                x = i;

            return x + z;
        }
        """)
        mod = from_c(simple)
        f = mod.get_function("f")
        cfa.run(f)
        sccp.run(f)
        verify(f)

        ops = list(f.ops)
        assert len(list(f.ops)) == 1
        [op] = ops
        assert op.opcode == 'ret'
        assert isinstance(op.args[0], Const)
        self.assertEqual(op.args[0].const, 7)
Beispiel #9
0
    def test_sccp_endless_loop(self):
        simple = textwrap.dedent("""
        #include <pykit_ir.h>

        Int32 f(Int32 i) {
            Int32 x, y, z;

            x = 2;
            y = 3;
            z = 4;

            while (x < y) {
                if (x < y) {
                    x = 2;
                }
            }

            return x + z;
        }
        """)
        mod = from_c(simple)
        f = mod.get_function("f")
        cfa.run(f)
        sccp.run(f)
        verify(f)

        assert len(f.blocks) == 2
        start, loop = f.blocks
        assert start.terminator.opcode == 'jump'
        assert start.terminator.args[0] == loop
        assert loop.terminator.opcode == 'jump'
        assert loop.terminator.args[0] == loop
Beispiel #10
0
    def test_inline2(self):
        harder = textwrap.dedent("""
        int callee(int i) {
            (void) print(i);
            while (i < 10) {
                i = i + 1;
                return i * 2;
            }
            return i;
        }

        int caller() {
            int x = 4;
            while (x < 10) {
                (void) print(x);
                x = call(callee, list(x));
            }
            return x;
        }
        """)
        mod = from_c(harder)
        func = mod.get_function("caller")
        verify(func)
        result = interp.run(func)

        [callsite] = findallops(func, 'call')
        inline.inline(func, callsite)
        cfa.run(func)
        verify(func)

        # TODO: update phi when splitting blocks
        result2 = interp.run(func)
        assert result == result2
Beispiel #11
0
 def test_ssa2(self):
     mod = from_c(source)
     f = mod.get_function('func')
     cfa.run(f)
     verify(f)
     codes = opcodes(f)
     self.assertEqual(codes.count('phi'), 3)
Beispiel #12
0
    def test_inline2(self):
        harder = textwrap.dedent("""
        int callee(int i) {
            (void) print(i);
            while (i < 10) {
                i = i + 1;
                return i * 2;
            }
            return i;
        }

        int caller() {
            int x = 4;
            while (x < 10) {
                (void) print(x);
                x = call(callee, list(x));
            }
            return x;
        }
        """)
        mod = from_c(harder)
        func = mod.get_function("caller")
        verify(func)
        result = interp.run(func)

        [callsite] = findallops(func, 'call')
        inline.inline(func, callsite)
        cfa.run(func)
        verify(func)
Beispiel #13
0
    def test_swap(self):
        simple = textwrap.dedent("""
        #include <pykit_ir.h>

        int f(int i) {
            int x = 1;
            int y = 2;
            int tmp;
            while (i > 0) {
                tmp = x;
                x = y;
                y = tmp;
                i = i - 1;
            }
            return x;
        }
        """)
        mod = from_c(simple)
        func = mod.get_function("f")
        cfa.run(func)

        verify(func)
        ssa_result1 = interp.run(func, args=[1])
        ssa_result2 = interp.run(func, args=[2])

        reg2mem.reg2mem(func)
        verify(func)

        stack_result1 = interp.run(func, args=[1])
        stack_result2 = interp.run(func, args=[2])

        self.assertEqual(ssa_result1, stack_result1)
        self.assertEqual(ssa_result2, stack_result2)
Beispiel #14
0
    def test_cfg(self):
        mod = from_c(source)
        f = mod.get_function('func_simple')
        verify(f)
        flow = cfa.cfg(f)

        cond_block = findop(f, 'cbranch').block
        self.assertEqual(len(flow[cond_block]), 2)
Beispiel #15
0
    def test_cfg(self):
        mod = from_c(source)
        f = mod.get_function('func_simple')
        verify(f)
        flow = cfa.cfg(f)

        cond_block = findop(f, 'cbranch').block
        self.assertEqual(len(flow[cond_block]), 2)
Beispiel #16
0
def inline(func, call, uses=None):
    """
    Inline the call instruction into func.

    :param uses: defuse information
    """
    callee = call.args[0]
    # assert_inlinable(func, call, callee, uses)

    builder = Builder(func)
    builder.position_before(call)
    inline_header, inline_exit = builder.splitblock()
    new_callee = copy_function(callee, temper=func.temp)
    result = rewrite_return(new_callee)

    # Fix up arguments
    for funcarg, arg in zip(new_callee.args, call.args[1]):
        funcarg.replace_uses(arg)

    # Copy blocks
    after = inline_header
    for block in new_callee.blocks:
        block.parent = None
        func.add_block(block, after=after)
        after = block

    # Fix up wiring
    builder.jump(new_callee.startblock)
    with builder.at_end(new_callee.exitblock):
        builder.jump(inline_exit)

    # Fix up final result of call
    if result is not None:
        # non-void return
        result.unlink()
        result.result = call.result
        call.replace(result)
    else:
        call.delete()

    func.reset_uses()
    verify(func)
Beispiel #17
0
    def test_swap_loop(self):
        simple = textwrap.dedent("""
        #include <pykit_ir.h>

        int f(int i, int j) {
            int x = 1;
            int y = 2;
            int tmp;
            while (i > 0) {
                while (j > 0) {
                    tmp = x;
                    x = y;
                    y = tmp;
                    j = j - 1;
                }
                i = i - 1;
            }
            return x;
        }
        """)
        mod = from_c(simple)
        func = mod.get_function("f")
        cfa.run(func)

        verify(func)

        ssa_results = []
        for i in range(10):
            for j in range(10):
                ssa_result = interp.run(func, args=[i, j])
                ssa_results.append(ssa_result)

        #print(func)
        reg2mem.reg2mem(func)
        verify(func)
        #print(func)

        stack_results = []
        for i in range(10):
            for j in range(10):
                stack_result = interp.run(func, args=[i, j])
                stack_results.append(stack_result)
Beispiel #18
0
    def test_swap_loop(self):
        simple = textwrap.dedent("""
        #include <pykit_ir.h>

        int f(int i, int j) {
            int x = 1;
            int y = 2;
            int tmp;
            while (i > 0) {
                while (j > 0) {
                    tmp = x;
                    x = y;
                    y = tmp;
                    j = j - 1;
                }
                i = i - 1;
            }
            return x;
        }
        """)
        mod = from_c(simple)
        func = mod.get_function("f")
        cfa.run(func)

        verify(func)

        ssa_results = []
        for i in range(10):
            for j in range(10):
                ssa_result = interp.run(func, args=[i, j])
                ssa_results.append(ssa_result)

        #print(func)
        reg2mem.reg2mem(func)
        verify(func)
        #print(func)

        stack_results = []
        for i in range(10):
            for j in range(10):
                stack_result = interp.run(func, args=[i, j])
                stack_results.append(stack_result)
Beispiel #19
0
    def test_ops(self):
        source = textwrap.dedent("""
        #include <pykit_ir.h>

        Int32 f(Int32 i) {
            Int32 x;

            x = 2;

            if (x < 3)
                x = x + 1;
            if (x <= 3)
                x = x + 1;
            if (x >= 3)
                x = x + 1;
            if (x >= 3)
                x = x + 1;
            if (x > 3)
                x = x + 1;

            return x;
        }
        """)

        mod = from_c(source)
        f = mod.get_function("f")
        remove_convert(f)
        cfa.run(f)
        sccp.run(f)
        verify(f)

        # print(f)

        ops = list(f.ops)

        assert len(list(f.ops)) == 1
        [op] = ops
        assert op.opcode == 'ret'
        assert isinstance(op.args[0], Const)
        self.assertEqual(op.args[0].const, 7)
Beispiel #20
0
    def test_ops(self):
        source = textwrap.dedent("""
        #include <pykit_ir.h>

        Int32 f(Int32 i) {
            Int32 x;

            x = 2;

            if (x < 3)
                x = x + 1;
            if (x <= 3)
                x = x + 1;
            if (x >= 3)
                x = x + 1;
            if (x >= 3)
                x = x + 1;
            if (x > 3)
                x = x + 1;

            return x;
        }
        """)

        mod = from_c(source)
        f = mod.get_function("f")
        remove_convert(f)
        cfa.run(f)
        sccp.run(f)
        verify(f)

        # print(f)

        ops = list(f.ops)

        assert len(list(f.ops)) == 1
        [op] = ops
        assert op.opcode == 'ret'
        assert isinstance(op.args[0], Const)
        self.assertEqual(op.args[0].const, 7)
Beispiel #21
0
    def test_inline(self):
        simple = """
        #include <pykit_ir.h>

        int callee(int i) {
            return i * i;
        }

        int caller(int i) {
            int x = call(callee, list(i));
            return x;
        }
        """
        mod = from_c(simple)
        func = mod.get_function("caller")
        [callsite] = findallops(func, 'call')
        inline.inline(func, callsite)
        cfa.run(func)
        verify(func)
        assert interp.run(func, args=[10]) == 100
        assert len(list(func.blocks)) == 1
        assert opcodes(func) == ['mul', 'ret']
Beispiel #22
0
    def test_ssa(self):
        mod = from_c(source)
        f = mod.get_function('func_simple')
        verify(f)
        self.assertEqual(opcodes(f.startblock),
                         ['alloca', 'store', 'load', 'gt', 'cbranch'])

        # SSA
        CFG = cfa.cfg(f)
        cfa.ssa(f, CFG)

        assert len(f.blocks) == 4
        blocks = list(f.blocks)
        self.assertEqual(opcodes(blocks[0]), ['gt', 'cbranch'])
        self.assertEqual(opcodes(blocks[1]), ['jump'])
        self.assertEqual(opcodes(blocks[2]), ['jump'])
        self.assertEqual(opcodes(blocks[3]), ['phi', 'convert', 'ret'])

        phi = findop(f, 'phi')
        iblocks, ivals = phi.args
        self.assertEqual(sorted(iblocks), sorted([blocks[1], blocks[2]]))
        self.assertEqual(len(ivals), 2)
Beispiel #23
0
    def test_inline(self):
        simple = textwrap.dedent("""
        #include <pykit_ir.h>

        int callee(int i) {
            return i * i;
        }

        int caller(int i) {
            int x = call(callee, list(i));
            return x;
        }
        """)
        mod = from_c(simple)
        func = mod.get_function("caller")
        [callsite] = findallops(func, 'call')
        inline.inline(func, callsite)
        cfa.run(func)
        verify(func)
        assert interp.run(func, args=[10]) == 100
        assert len(list(func.blocks)) == 1
        assert opcodes(func) == ['mul', 'ret']
Beispiel #24
0
    def test_ssa(self):
        mod = from_c(source)
        f = mod.get_function('func_simple')
        verify(f)
        self.assertEqual(opcodes(f.startblock),
                         ['alloca', 'store', 'load', 'gt', 'cbranch'])

        # SSA
        CFG = cfa.cfg(f)
        cfa.ssa(f, CFG)

        assert len(f.blocks) == 4
        blocks = list(f.blocks)
        self.assertEqual(opcodes(blocks[0]), ['gt', 'cbranch'])
        self.assertEqual(opcodes(blocks[1]), ['jump'])
        self.assertEqual(opcodes(blocks[2]), ['jump'])
        self.assertEqual(opcodes(blocks[3]), ['phi', 'ret'])

        phi = findop(f, 'phi')
        iblocks, ivals = phi.args
        self.assertEqual(sorted(iblocks), sorted([blocks[1], blocks[2]]))
        self.assertEqual(len(ivals), 2)
Beispiel #25
0
    def test_inline(self):
        simple = textwrap.dedent("""
        #include <pykit_ir.h>

        int callee(int i) {
            return i * i;
        }

        int caller(int i) {
            int x = call(callee, list(i));
            return x;
        }
        """)
        mod = from_c(simple)
        func = mod.get_function("caller")
        [callsite] = findallops(func, 'call')
        inline.inline(func, callsite)
        cfa.run(func)
        verify(func)
        assert interp.run(func, args=[10]) == 100
        assert len(list(func.blocks)) == 1
        self.assertEqual([o for o in opcodes(func) if o != 'convert'],
                         ['mul', 'ret'])
Beispiel #26
0
    Int32 i, sum = 0;
    for (i = 0; i < 10; i = i + 1) {
        sum = sum + i;
    }
    return sum;
}

Int32 raise() {
    Exception exc = new_exc("TypeError", "");
    exc_throw(exc);
    return 0;
}
"""

mod = cirparser.from_c(source)
verify(mod)


class TestInterp(unittest.TestCase):
    def test_simple(self):
        f = mod.get_function('simple')
        result = interp.run(f, args=[10.0])
        assert result == 100.0, result

    def test_loop(self):
        loop = mod.get_function('loop')
        result = interp.run(loop)
        assert result == 45, result

    def test_exceptions(self):
        f = mod.get_function('raise')
Beispiel #27
0
    int i, sum = 0;
    for (i = 0; i < 10; i = i + 1) {
        sum = sum + i;
    }
    return sum;
}

int raise() {
    Exception exc = new_exc("TypeError", list());
    exc_throw(exc);
    return 0;
}
"""

mod = cirparser.from_c(source)
verify(mod)

class TestInterp(unittest.TestCase):

    def test_simple(self):
        f = mod.get_function('simple')
        result = interp.run(f, args=[10.0])
        assert result == 100.0, result

    def test_loop(self):
        loop = mod.get_function('loop')
        result = interp.run(loop)
        assert result == 45, result

    def test_exceptions(self):
        f = mod.get_function('raise')
Beispiel #28
0
 def test_parse(self):
     mod = cirparser.from_c(source)
     verify(mod)
     func = mod.get_function('myfunc')
     result = interp.run(func, args=[10.0])
     self.assertEqual(result, 12)
Beispiel #29
0
 def test_parse(self):
     mod = cirparser.from_c(source)
     verify(mod)
     func = mod.get_function('myfunc')
     result = interp.run(func, args=[10.0])
     self.assertEqual(result, 12)