class TestBuilder(unittest.TestCase): def setUp(self): self.f = Function("testfunc", ['a'], types.Function(types.Float32, [types.Int32])) self.b = Builder(self.f) self.b.position_at_end(self.f.add_block('entry')) self.a = self.f.get_arg('a') def test_basic_builder(self): v = self.b.alloca(types.Pointer(types.Float32), []) result = self.b.mul(types.Int32, [self.a, self.a], result='r') c = self.b.convert(types.Float32, [result]) self.b.store(c, v) val = self.b.load(types.Float32, [v]) self.b.ret(val) # print(string(self.f)) self.assertEqual(str(self.f).strip(), basic_expected) def test_splitblock(self): old, new = self.b.splitblock('newblock') with self.b.at_front(old): self.b.add(types.Int32, [self.a, self.a]) with self.b.at_end(new): self.b.div(types.Int32, [self.a, self.a]) # print(string(self.f)) self.assertEqual(split_expected, string(self.f)) def test_loop_builder(self): square = self.b.mul(types.Int32, [self.a, self.a]) c = self.b.convert(types.Float32, [square]) self.b.position_after(square) _, block = self.b.splitblock('start', terminate=True) self.b.position_at_end(block) const = partial(Const, type=types.Int32) cond, body, exit = self.b.gen_loop(const(5), const(10), const(2)) with self.b.at_front(body): self.b.print_(c) with self.b.at_end(exit): self.b.ret(c) # print(string(self.f)) # verify.verify(self.f) # self.assertEqual(loop_expected, string(self.f)) # TestBuilder('test_basic_builder').debug() # TestBuilder('test_splitblock').debug() # TestBuilder('test_loop_builder').debug() # unittest.main()
class TestBuilder(unittest.TestCase): def setUp(self): self.f = Function("testfunc", ['a'], types.Function(types.Float32, [types.Int32])) self.b = Builder(self.f) self.b.position_at_end(self.f.new_block('entry')) self.a = self.f.get_arg('a') def test_basic_builder(self): v = self.b.alloca(types.Pointer(types.Float32), []) result = self.b.mul(types.Int32, [self.a, self.a], result='r') c = self.b.convert(types.Float32, [result]) self.b.store(c, v) val = self.b.load(types.Float32, [v]) self.b.ret(val) # print(string(self.f)) assert interp.run(self.f, args=[10]) == 100 def test_splitblock(self): old, new = self.b.splitblock('newblock') with self.b.at_front(old): self.b.add(types.Int32, [self.a, self.a]) with self.b.at_end(new): self.b.div(types.Int32, [self.a, self.a]) self.assertEqual(opcodes(self.f), ['add', 'div']) def test_loop_builder(self): square = self.b.mul(types.Int32, [self.a, self.a]) c = self.b.convert(types.Float32, [square]) self.b.position_after(square) _, block = self.b.splitblock('start', terminate=True) self.b.position_at_end(block) const = partial(Const, type=types.Int32) cond, body, exit = self.b.gen_loop(const(5), const(10), const(2)) with self.b.at_front(body): self.b.print(c) with self.b.at_end(exit): self.b.ret(c) self.assertEqual(interp.run(self.f, args=[10]), 100.0)
class TestIR(unittest.TestCase): def setUp(self): self.m = from_c(source) self.f = self.m.get_function('testfunc') self.b = Builder(self.f) def test_replace(self): entry = self.f.get_block('entry') for op in entry: if op.opcode == ops.convert: r, = op.args t = self.b.add(types.Int32, [r, r]) c = self.b.convert(types.Float32, [t], result=op.result) op.replace([t, c]) break cfa.run(self.f) self.assertEqual(opcodes(self.f), ['mul', 'add', 'convert', 'ret'])
class TestInterp(unittest.TestCase): def setUp(self): self.f = from_assembly(testfunc) self.b = Builder(self.f) def test_replace(self): entry = self.f.get_block('entry') for op in entry: if op.opcode == ops.convert: r, = op.args t = self.b.add(types.Int32, [r, r], result="temp") c = self.b.convert(types.Float32, [t], result=op.result) op.replace([t, c]) break result = [(op.opcode, op.result) for op in entry] assert result == [('alloca', '0'), ('mul', 'r'), ('add', 'temp'), ('convert', '1'), ('store', '2'), ('load', '3'), ('ret', '4')]
class TestBuilder(unittest.TestCase): def setUp(self): self.f = Function("testfunc", ['a'], types.Function(types.Float32, [types.Int32], False)) self.b = Builder(self.f) self.b.position_at_end(self.f.new_block('entry')) self.a = self.f.get_arg('a') def test_basic_builder(self): v = self.b.alloca(types.Pointer(types.Float32)) result = self.b.mul(self.a, self.a, result='r') c = self.b.convert(types.Float32, result) self.b.store(c, v) val = self.b.load(v) self.b.ret(val) # print(string(self.f)) assert interp.run(self.f, args=[10]) == 100 def test_splitblock(self): old, new = self.b.splitblock('newblock') with self.b.at_front(old): self.b.add(self.a, self.a) with self.b.at_end(new): self.b.div(self.a, self.a) self.assertEqual(opcodes(self.f), ['add', 'div']) def test_loop_builder(self): square = self.b.mul(self.a, self.a) c = self.b.convert(types.Float32, square) self.b.position_after(square) _, block = self.b.splitblock('start', terminate=True) self.b.position_at_end(block) const = partial(Const, type=types.Int32) cond, body, exit = self.b.gen_loop(const(5), const(10), const(2)) with self.b.at_front(body): self.b.print(c) with self.b.at_end(exit): self.b.ret(c) self.assertEqual(interp.run(self.f, args=[10]), 100.0) def test_splitblock_preserve_phis(self): """ block1: %0 = mul a a jump(newblock) newblock: %1 = phi([block1], [%0]) ret %1 """ square = self.b.mul(self.a, self.a) old, new = self.b.splitblock('newblock', terminate=True) with self.b.at_front(new): phi = self.b.phi(types.Int32, [self.f.startblock], [square]) self.b.ret(phi) # Now split block1 self.b.position_after(square) block1, split = self.b.splitblock(terminate=True) phi, ret = new.ops blocks, values = phi.args self.assertEqual(blocks, [split])