def test_equaloplists_fail_args(): ops = """ [i0] i1 = int_add(i0, 1) i2 = int_add(i1, 1) guard_true(i1) [i2, i1] jump(i1) """ namespace = {} loop1 = pure_parse(ops, namespace=namespace) loop2 = pure_parse(ops.replace("[i2, i1]", "[i1, i2]"), namespace=namespace) with pytest.raises(AssertionError): equaloplists(loop1.operations, loop2.operations, remap=make_remap(loop1.inputargs, loop2.inputargs)) assert equaloplists(loop1.operations, loop2.operations, remap=make_remap(loop1.inputargs, loop2.inputargs), strict_fail_args=False) loop3 = pure_parse(ops.replace("[i2, i1]", "[i2, i0]"), namespace=namespace) with pytest.raises(AssertionError): equaloplists(loop1.operations, loop3.operations, remap=make_remap(loop1.inputargs, loop3.inputargs))
def test_jump(self): namespace = {'target': JitCellToken()} namespace['target'].number = 3 inp = ''' [i0] jump(i0, descr=target) ''' loop = pure_parse(inp, namespace=namespace) logger = Logger(self.make_metainterp_sd()) output = logger.log_loop(loop) assert output.splitlines()[-1] == "jump(i0, descr=<Loop3>)" pure_parse(output)
def reparse(self, inp, namespace=None, check_equal=True): """ parse loop once, then log it and parse again. Checks that we get the same thing. """ if namespace is None: namespace = {} loop = pure_parse(inp, namespace=namespace) logger = Logger(self.make_metainterp_sd()) output = logger.log_loop(loop, namespace) oloop = pure_parse(output, namespace=namespace) if check_equal: equaloplists(loop.operations, oloop.operations) assert oloop.inputargs == loop.inputargs return logger, loop, oloop
def test_class_name(self): from rpython.rtyper.lltypesystem import lltype AbcVTable = lltype.Struct('AbcVTable') abcvtable = lltype.malloc(AbcVTable, immortal=True) namespace = {'Name': abcvtable} inp = ''' [i0] p = new_with_vtable(ConstClass(Name)) ''' loop = pure_parse(inp, namespace=namespace) logger = Logger(self.make_metainterp_sd()) output = logger.log_loop(loop) assert output.splitlines()[-1].endswith( " = new_with_vtable(ConstClass(Name))") pure_parse(output, namespace=namespace)
def test_equaloplists(): ops = """ [i0] i1 = int_add(i0, 1) i2 = int_add(i1, 1) guard_true(i1) [i2] jump(i1) """ namespace = {} loop1 = pure_parse(ops, namespace=namespace) loop2 = pure_parse(ops, namespace=namespace) loop3 = pure_parse(ops.replace("i2 = int_add", "i2 = int_sub"), namespace=namespace) assert equaloplists(loop1.operations, loop2.operations) py.test.raises(AssertionError, "equaloplists(loop1.operations, loop3.operations)")
def test_ops_offset_with_forward(self): inp = ''' [i0] i1 = int_add(i0, 4) i2 = int_mul(i0, 8) jump(i2) ''' loop = pure_parse(inp) ops = loop.operations # again to get new ops with different identities to existing ones loop2 = pure_parse(inp) ops2 = loop.operations # Suppose a re-write occurs which replaces the operations with these. # The add 4 became a sub -4. The others are the same, but have a # different address, thus still require forwarding. inp2 = ''' [i0] i1 = int_sub(i0, -4) i2 = int_mul(i0, 8) jump(i2) ''' loop2 = pure_parse(inp2) ops2 = loop2.operations # Add forwarding for i in xrange(3): ops[i].set_forwarded(ops2[i]) # So the offsets are keyed by ops2 instances ops_offset = { ops2[0]: 10, ops2[1]: 20, ops2[2]: 30, None: 40 } logger = Logger(self.make_metainterp_sd()) output = logger.log_loop(loop, ops_offset=ops_offset, name="foo") # The logger should have followed the forwarding pointers lines = output.strip().splitlines() assert lines[2].startswith("+10") assert lines[3].startswith("+20") assert lines[4].startswith("+30") assert lines[5].startswith("+40")
def reparse(self, inp, namespace=None, check_equal=True): """ parse loop once, then log it and parse again. Checks that we get the same thing. """ if namespace is None: namespace = {} loop = pure_parse(inp, namespace=namespace) logger = Logger(self.make_metainterp_sd()) output = logger.log_loop(loop, namespace) oloop = pure_parse(output, namespace=namespace) if check_equal: remap = {} for box1, box2 in zip(loop.inputargs, oloop.inputargs): assert box1.__class__ == box2.__class__ remap[box2] = box1 equaloplists(loop.operations, oloop.operations, remap=remap) return logger, loop, oloop
def test_guard_descr(self): namespace = {'fdescr': BasicFailDescr()} inp = ''' [i0] guard_true(i0, descr=fdescr) [i0] ''' loop = pure_parse(inp, namespace=namespace) logger = Logger(self.make_metainterp_sd(), guard_number=True) output = logger.log_loop(loop) assert re.match("guard_true\(i0, descr=<Guard0x[\da-f]+>\) \[i0\]", output.splitlines()[-1]) pure_parse(output) logger = Logger(self.make_metainterp_sd(), guard_number=False) output = logger.log_loop(loop) lastline = output.splitlines()[-1] assert lastline.startswith("guard_true(i0, descr=<") assert not lastline.startswith("guard_true(i0, descr=<Guard")
def test_guard_not_invalidated(self): inp = """ [] guard_not_invalidated(descr=descr) [] finish(descr=finaldescr) """ loop = pure_parse(inp, namespace={"descr": Descr(), "finaldescr": BasicFinalDescr()}) logger = Logger(self.make_metainterp_sd()) output = logger.log_loop(loop, {"descr": Descr()}) assert "guard_not_invalidated(descr=" in output
def test_ops_offset_with_forward(self): inp = """ [i0] i1 = int_add(i0, 4) i2 = int_mul(i0, 8) jump(i2) """ loop = pure_parse(inp) ops = loop.operations # again to get new ops with different identities to existing ones loop2 = pure_parse(inp) ops2 = loop.operations # Suppose a re-write occurs which replaces the operations with these. # The add 4 became a sub -4. The others are the same, but have a # different address, thus still require forwarding. inp2 = """ [i0] i1 = int_sub(i0, -4) i2 = int_mul(i0, 8) jump(i2) """ loop2 = pure_parse(inp2) ops2 = loop2.operations # Add forwarding for i in xrange(3): ops[i].set_forwarded(ops2[i]) # So the offsets are keyed by ops2 instances ops_offset = {ops2[0]: 10, ops2[1]: 20, ops2[2]: 30, None: 40} logger = Logger(self.make_metainterp_sd()) output = logger.log_loop(loop, ops_offset=ops_offset, name="foo") # The logger should have followed the forwarding pointers lines = output.strip().splitlines() assert lines[2].startswith("+10") assert lines[3].startswith("+20") assert lines[4].startswith("+30") assert lines[5].startswith("+40")
def test_guard_not_invalidated(self): inp = ''' [] guard_not_invalidated(descr=descr) [] finish(descr=finaldescr) ''' loop = pure_parse(inp, namespace={'descr': Descr(), 'finaldescr': BasicFinalDescr()}) logger = Logger(self.make_metainterp_sd()) output = logger.log_loop(loop, {'descr': Descr()}) assert 'guard_not_invalidated(descr=' in output
def test_equaloplists(): ops = """ [i0] i1 = int_add(i0, 1) i2 = int_add(i1, 1) guard_true(i1) [i2] jump(i1) """ namespace = {} loop1 = pure_parse(ops, namespace=namespace) loop2 = pure_parse(ops, namespace=namespace) loop3 = pure_parse(ops.replace("i2 = int_add", "i2 = int_sub"), namespace=namespace) assert equaloplists(loop1.operations, loop2.operations, remap=make_remap(loop1.inputargs, loop2.inputargs)) with pytest.raises(AssertionError): equaloplists(loop1.operations, loop3.operations, remap=make_remap(loop1.inputargs, loop3.inputargs))
def test_equaloplists_fail_args(): ops = """ [i0] i1 = int_add(i0, 1) i2 = int_add(i1, 1) guard_true(i1) [i2, i1] jump(i1) """ namespace = {} loop1 = pure_parse(ops, namespace=namespace) loop2 = pure_parse(ops.replace("[i2, i1]", "[i1, i2]"), namespace=namespace) py.test.raises(AssertionError, "equaloplists(loop1.operations, loop2.operations)") assert equaloplists(loop1.operations, loop2.operations, strict_fail_args=False) loop3 = pure_parse(ops.replace("[i2, i1]", "[i2, i0]"), namespace=namespace) py.test.raises(AssertionError, "equaloplists(loop1.operations, loop3.operations)")
def test_ops_offset(self): inp = ''' [i0] i1 = int_add(i0, 1) i2 = int_mul(i1, 2) jump(i2) ''' loop = pure_parse(inp) ops = loop.operations ops_offset = {ops[0]: 10, ops[2]: 30, None: 40} logger = Logger(self.make_metainterp_sd()) output = logger.log_loop(loop, ops_offset=ops_offset, name="foo") assert output.strip() == """ # Loop 0 (foo) : noopt with 3 ops [i0] +10: i2 = int_add(i0, 1) i4 = int_mul(i2, 2) +30: jump(i4) +40: --end of the loop-- """.strip()
def test_ops_offset(self): inp = """ [i0] i1 = int_add(i0, 1) i2 = int_mul(i1, 2) jump(i2) """ loop = pure_parse(inp) ops = loop.operations ops_offset = {ops[0]: 10, ops[2]: 30, None: 40} logger = Logger(self.make_metainterp_sd()) output = logger.log_loop(loop, ops_offset=ops_offset, name="foo") assert ( output.strip() == """ # Loop 0 (foo) : noopt with 3 ops [i0] +10: i2 = int_add(i0, 1) i4 = int_mul(i2, 2) +30: jump(i4) +40: --end of the loop-- """.strip() )
def test_intro_loop(self): bare_logger = logger.Logger(self.make_metainterp_sd()) output = capturing(bare_logger.log_loop, [], [], 1, "foo") assert output.splitlines()[0] == "# Loop 1 () : foo with 0 ops" pure_parse(output)
def test_intro_bridge(self): bare_logger = logger.Logger(self.make_metainterp_sd()) output = capturing(bare_logger.log_bridge, [], [], 3) assert re.match("# bridge out of Guard 0x[\da-f]+ with 0 ops", output.splitlines()[0]) pure_parse(output)