[pypy-svn] r74629 - in pypy/branch/blackhole-improvement/pypy/jit: codewriter codewriter/test metainterp
arigo at codespeak.net
arigo at codespeak.net
Fri May 21 15:46:59 CEST 2010
Author: arigo
Date: Fri May 21 15:46:57 2010
New Revision: 74629
Modified:
pypy/branch/blackhole-improvement/pypy/jit/codewriter/assembler.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/codewriter.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/format.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/jtransform.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_assembler.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_codewriter.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py
pypy/branch/blackhole-improvement/pypy/jit/metainterp/blackhole.py
pypy/branch/blackhole-improvement/pypy/jit/metainterp/history.py
pypy/branch/blackhole-improvement/pypy/jit/metainterp/pyjitpl.py
pypy/branch/blackhole-improvement/pypy/jit/metainterp/resoperation.py
Log:
Finish the refactoring of codewriter to the new format of -live- operations.
Now starting to work on pyjitpl...
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/assembler.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/assembler.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/assembler.py Fri May 21 15:46:57 2010
@@ -45,7 +45,6 @@
self.switchdictdescrs = []
self.count_regs = dict.fromkeys(KINDS, 0)
self.liveness = {}
- self.nextlive = None
self.startpoints = set()
self.alllabels = set()
@@ -88,21 +87,18 @@
return False
def write_insn(self, insn):
+ if insn[0] == '---':
+ return
if isinstance(insn[0], Label):
self.label_positions[insn[0].name] = len(self.code)
return
if insn[0] == '-live-':
- assert self.nextlive is None
- self.nextlive = (
- self.get_liveness_info(insn, 'int'),
- self.get_liveness_info(insn, 'ref'),
- self.get_liveness_info(insn, 'float'))
- return
- if insn[0] == 'keepalive':
- # The 'keepalive' instruction is useful when doing register
- # allocation, to ensure that the register holding the value is
- # not overwritten too early. But it does not need to be
- # present at all in the final code.
+ key = len(self.code)
+ live_i, live_r, live_f = self.liveness.get(key, ("", "", ""))
+ live_i = self.get_liveness_info(live_i, insn[1:], 'int')
+ live_r = self.get_liveness_info(live_r, insn[1:], 'ref')
+ live_f = self.get_liveness_info(live_f, insn[1:], 'float')
+ self.liveness[key] = live_i, live_r, live_f
return
startposition = len(self.code)
self.code.append("temporary placeholder")
@@ -154,24 +150,29 @@
argcodes.append('d')
elif isinstance(x, IndirectCallTargets):
self.indirectcalltargets.update(x.lst)
+ elif x == '->':
+ assert '>' not in argcodes
+ argcodes.append('>')
else:
raise NotImplementedError(x)
#
opname = insn[0]
- if opname.startswith('G_'): opname = opname[2:]
+ assert '>' not in argcodes or argcodes.index('>') == len(argcodes) - 2
key = opname + '/' + ''.join(argcodes)
num = self.insns.setdefault(key, len(self.insns))
self.code[startposition] = chr(num)
self.startpoints.add(startposition)
- #
- if self.nextlive is not None:
- self.liveness[len(self.code)] = self.nextlive
- self.nextlive = None
-
- def get_liveness_info(self, insn, kind):
- lives = [chr(reg.index) for reg in insn[1:] if reg.kind == kind]
- lives.sort()
- return ''.join(lives)
+
+ def get_liveness_info(self, prevstring, args, kind):
+ """Return a string whose characters are register numbers.
+ We sort the numbers, too, to increase the chances of duplicate
+ strings (which are collapsed into a single string during translation).
+ """
+ lives = set(prevstring) # set of characters
+ for reg in args:
+ if isinstance(reg, Register) and reg.kind == kind:
+ lives.add(chr(reg.index))
+ return ''.join(sorted(lives))
def fix_labels(self):
for name, pos in self.tlabel_positions:
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/codewriter.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/codewriter.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/codewriter.py Fri May 21 15:46:57 2010
@@ -38,20 +38,20 @@
# that we want in the JitCode, but still as a control flow graph
transform_graph(graph, self.cpu, self.callcontrol, portal)
#
- # step 2a: perform register allocation on it
+ # step 2: perform register allocation on it
regallocs = {}
for kind in KINDS:
regallocs[kind] = perform_register_allocation(graph, kind)
#
- # step 2b: compute the liveness around certain operations
- compute_liveness(graph)
- #
# step 3: flatten the graph to produce human-readable "assembler",
# which means mostly producing a linear list of operations and
# inserting jumps or conditional jumps. This is a list of tuples
# of the shape ("opname", arg1, ..., argN) or (Label(...),).
ssarepr = flatten_graph(graph, regallocs)
#
+ # step 3b: compute the liveness around certain operations
+ compute_liveness(ssarepr)
+ #
# print the resulting assembler
self.print_ssa_repr(ssarepr, portal, verbose)
#
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py Fri May 21 15:46:57 2010
@@ -168,14 +168,18 @@
elif block.exitswitch is c_last_exception:
# An exception block. See test_exc_exitswitch in test_flatten.py
# for an example of what kind of code this makes.
- lastopname = block.operations[-1].opname
- assert lastopname != '-live-'
+ index = -1
+ while True:
+ lastopname = block.operations[index].opname
+ if lastopname != '-live-':
+ break
+ index -= 1
assert block.exits[0].exitcase is None # is this always True?
#
if not self._include_all_exc_links:
- if (len(block.operations) == 1 or
- block.operations[-2].opname != '-live-'):
- # cannot actually raise
+ if index == -1:
+ # cannot raise: the last instruction is not
+ # actually a '-live-'
self.make_link(block.exits[0])
return
#
@@ -212,8 +216,7 @@
opname = 'goto_if_not'
if isinstance(block.exitswitch, tuple):
# special case produced by jtransform.optimize_goto_if_not()
- if block.exitswitch[0] != 'int_is_true':
- opname = 'goto_if_not_' + block.exitswitch[0]
+ opname = 'goto_if_not_' + block.exitswitch[0]
opargs = block.exitswitch[1:]
else:
assert block.exitswitch.concretetype == lltype.Bool
@@ -221,6 +224,7 @@
#
lst = self.flatten_list(opargs) + [TLabel(linkfalse)]
self.emitline(opname, *lst)
+ self.emitline('-live-', TLabel(linkfalse))
# true path:
self.make_link(linktrue)
# false path:
@@ -236,6 +240,7 @@
else:
self.emitline("---")
#
+ self.emitline('-live-')
switches = [link for link in block.exits
if link.exitcase != 'default']
switches.sort(key=lambda link: link.llexitcase)
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/format.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/format.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/format.py Fri May 21 15:46:57 2010
@@ -50,7 +50,7 @@
#
output = StringIO()
insns = ssarepr.insns
- if insns[-1] == ('---',):
+ if insns and insns[-1] == ('---',):
insns = insns[:-1]
for asm in insns:
if isinstance(asm[0], Label):
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/jtransform.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/jtransform.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/jtransform.py Fri May 21 15:46:57 2010
@@ -580,6 +580,7 @@
('cast_float_to_uint', 'cast_float_to_int'),
('int_add_nonneg_ovf', 'int_add_ovf'),
+ ('keepalive', '-live-'),
('char_lt', 'int_lt'),
('char_le', 'int_le'),
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_assembler.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_assembler.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_assembler.py Fri May 21 15:46:57 2010
@@ -12,14 +12,14 @@
ssarepr = SSARepr("test")
i0, i1, i2 = Register('int', 0), Register('int', 1), Register('int', 2)
ssarepr.insns = [
- ('int_add', i0, i1, i2),
+ ('int_add', i0, i1, '->', i2),
('int_return', i2),
]
assembler = Assembler()
jitcode = assembler.assemble(ssarepr)
assert jitcode.code == ("\x00\x00\x01\x02"
"\x01\x02")
- assert assembler.insns == {'int_add/iii': 0,
+ assert assembler.insns == {'int_add/ii>i': 0,
'int_return/i': 1}
assert jitcode.num_regs_i() == 3
assert jitcode.num_regs_r() == 0
@@ -94,8 +94,8 @@
ssarepr.insns = [
(Label('L1'),),
('goto_if_not_int_gt', i0, Constant(4, lltype.Signed), TLabel('L2')),
- ('int_add', i1, i0, i1),
- ('int_sub', i0, Constant(1, lltype.Signed), i0),
+ ('int_add', i1, i0, '->', i1),
+ ('int_sub', i0, Constant(1, lltype.Signed), '->', i0),
('goto', TLabel('L1')),
(Label('L2'),),
('int_return', i1),
@@ -108,8 +108,8 @@
"\x03\x00\x00"
"\x04\x17")
assert assembler.insns == {'goto_if_not_int_gt/icL': 0,
- 'int_add/iii': 1,
- 'int_sub/ici': 2,
+ 'int_add/ii>i': 1,
+ 'int_sub/ic>i': 2,
'goto/L': 3,
'int_return/i': 4}
@@ -149,13 +149,6 @@
assembler.assemble(ssarepr)
assert assembler.indirectcalltargets == set(lst1).union(lst2)
-def test_assemble_keepalive():
- ssarepr = SSARepr("test")
- ssarepr.insns = [('keepalive', Register('ref', 2))]
- assembler = Assembler()
- jitcode = assembler.assemble(ssarepr)
- assert jitcode.code == "" # the keepalive is removed
-
def test_num_regs():
assembler = Assembler()
ssarepr = SSARepr("test")
@@ -176,37 +169,20 @@
def test_liveness():
ssarepr = SSARepr("test")
i0, i1, i2 = Register('int', 0), Register('int', 1), Register('int', 2)
- i3, i4, i5 = Register('int', 3), Register('int', 4), Register('int', 5)
ssarepr.insns = [
- ('-live-', i0),
- ('G_int_add', i0, Constant(10, lltype.Signed), i1),
+ ('int_add', i0, Constant(10, lltype.Signed), '->', i1),
('-live-', i0, i1),
- ('G_int_add', i0, Constant(3, lltype.Signed), i2),
- ('-live-', i0),
- ('G_int_mul', i1, i2, i3),
- ('-live-', i3),
- ('G_int_add', i0, Constant(6, lltype.Signed), i4),
- ('-live-',),
- ('G_int_mul', i3, i4, i5),
- ('int_return', i5),
+ ('-live-', i1, i2),
+ ('int_add', i0, Constant(3, lltype.Signed), '->', i2),
+ ('-live-', i2),
]
assembler = Assembler()
jitcode = assembler.assemble(ssarepr)
assert jitcode.code == ("\x00\x00\x0A\x01" # ends at 4
- "\x00\x00\x03\x02" # ends at 8
- "\x01\x01\x02\x03" # ends at 12
- "\x00\x00\x06\x04" # ends at 16
- "\x01\x03\x04\x05" # ends at 20
- "\x02\x05")
- assert assembler.insns == {'int_add/ici': 0,
- 'int_mul/iii': 1,
- 'int_return/i': 2}
- py.test.raises(MissingLiveness, jitcode._live_vars, 0)
- py.test.raises(MissingLiveness, jitcode._live_vars, 3)
- py.test.raises(MissingLiveness, jitcode._live_vars, 5)
- py.test.raises(MissingLiveness, jitcode._live_vars, 24)
- assert jitcode._live_vars(4) == '%i0'
- assert jitcode._live_vars(8) == '%i0 %i1'
- assert jitcode._live_vars(12) == '%i0'
- assert jitcode._live_vars(16) == '%i3'
- assert jitcode._live_vars(20) == ''
+ "\x00\x00\x03\x02") # ends at 8
+ assert assembler.insns == {'int_add/ic>i': 0}
+ for i in range(8):
+ if i != 4:
+ py.test.raises(MissingLiveness, jitcode._live_vars, i)
+ assert jitcode._live_vars(4) == '%i0 %i1 %i2'
+ assert jitcode._live_vars(8) == '%i2'
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_codewriter.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_codewriter.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_codewriter.py Fri May 21 15:46:57 2010
@@ -36,8 +36,8 @@
"\x03\x00\x00"
"\x04\x01")
assert cw.assembler.insns == {'goto_if_not_int_gt/icL': 0,
- 'int_add/iii': 1,
- 'int_sub/ici': 2,
+ 'int_add/ii>i': 1,
+ 'int_sub/ic>i': 2,
'goto/L': 3,
'int_return/i': 4}
assert jitcode.num_regs_i() == 2
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py Fri May 21 15:46:57 2010
@@ -95,18 +95,18 @@
if transform:
from pypy.jit.codewriter.jtransform import transform_graph
transform_graph(graphs[0], FakeCPU(), FakeCallControl())
- if liveness:
- from pypy.jit.codewriter.liveness import compute_liveness
- compute_liveness(graphs[0])
ssarepr = flatten_graph(graphs[0], fake_regallocs(),
_include_all_exc_links=not transform)
+ if liveness:
+ from pypy.jit.codewriter.liveness import compute_liveness
+ compute_liveness(ssarepr)
assert_format(ssarepr, expected)
def test_simple(self):
def f(n):
return n + 10
self.encoding_test(f, [5], """
- int_add %i0, $10, %i1
+ int_add %i0, $10 -> %i1
int_return %i1
""")
@@ -117,18 +117,20 @@
a -= 1
return b
self.encoding_test(f, [5, 6], """
- int_copy %i0, %i2
- int_copy %i1, %i3
+ int_copy %i0 -> %i2
+ int_copy %i1 -> %i3
L1:
- int_gt %i2, $0, %i4
+ int_gt %i2, $0 -> %i4
goto_if_not %i4, L2
- int_copy %i2, %i5
- int_copy %i3, %i6
- int_add %i6, %i5, %i7
- int_sub %i5, $1, %i8
- int_copy %i8, %i2
- int_copy %i7, %i3
+ -live- L2
+ int_copy %i2 -> %i5
+ int_copy %i3 -> %i6
+ int_add %i6, %i5 -> %i7
+ int_sub %i5, $1 -> %i8
+ int_copy %i8 -> %i2
+ int_copy %i7 -> %i3
goto L1
+ ---
L2:
int_return %i3
""")
@@ -140,17 +142,19 @@
a -= 1
return b
self.encoding_test(f, [5, 6], """
- int_copy %i0, %i2
- int_copy %i1, %i3
+ int_copy %i0 -> %i2
+ int_copy %i1 -> %i3
L1:
goto_if_not_int_gt %i2, $0, L2
- int_copy %i2, %i4
- int_copy %i3, %i5
- int_add %i5, %i4, %i6
- int_sub %i4, $1, %i7
- int_copy %i7, %i2
- int_copy %i6, %i3
+ -live- L2
+ int_copy %i2 -> %i4
+ int_copy %i3 -> %i5
+ int_add %i5, %i4 -> %i6
+ int_sub %i4, $1 -> %i7
+ int_copy %i7 -> %i2
+ int_copy %i6 -> %i3
goto L1
+ ---
L2:
int_return %i3
""", transform=True)
@@ -159,10 +163,10 @@
def f(i, f):
return (i*5) + (f*0.25)
self.encoding_test(f, [4, 7.5], """
- int_mul %i0, $5, %i1
- float_mul %f0, $0.25, %f1
- cast_int_to_float %i1, %f2
- float_add %f2, %f1, %f3
+ int_mul %i0, $5 -> %i1
+ float_mul %f0, $0.25 -> %f1
+ cast_int_to_float %i1 -> %f2
+ float_add %f2, %f1 -> %f3
float_return %f3
""")
@@ -180,7 +184,7 @@
flattener = GraphFlattener(None, fake_regallocs())
flattener.serialize_op(op)
assert_format(flattener.ssarepr, """
- residual_call_ir_f $12345, I[%i0, %i1], R[%r0, %r1], %f0
+ residual_call_ir_f $12345, I[%i0, %i1], R[%r0, %r1] -> %f0
""")
def test_same_as_removal(self):
@@ -188,7 +192,7 @@
b = chr(a)
return ord(b) + a
self.encoding_test(f, [65], """
- int_add %i0, %i0, %i1
+ int_add %i0, %i0 -> %i1
int_return %i1
""", transform=True)
@@ -210,15 +214,19 @@
elif n == 7: return 1212
else: return 42
self.encoding_test(f, [65], """
+ -live-
int_guard_value %i0
goto_if_not_int_eq %i0, $-5, L1
int_return $12
+ ---
L1:
goto_if_not_int_eq %i0, $2, L2
int_return $51
+ ---
L2:
goto_if_not_int_eq %i0, $7, L3
int_return $1212
+ ---
L3:
int_return $42
""")
@@ -233,18 +241,25 @@
elif x == 6: return 54
return -1
self.encoding_test(f, [65], """
+ -live-
switch %i0, <SwitchDictDescr 1:L1, 2:L2, 3:L3, 4:L4, 5:L5, 6:L6>
int_return $-1
+ ---
L1:
int_return $61
+ ---
L2:
int_return $511
+ ---
L3:
int_return $-22
+ ---
L4:
int_return $81
+ ---
L5:
int_return $17
+ ---
L6:
int_return $54
""")
@@ -267,12 +282,15 @@
direct_call $<* fn g>, %i0
catch_exception L1
int_return $3
+ ---
L1:
goto_if_exception_mismatch $<* struct object_vtable>, L2
int_return $1
+ ---
L2:
goto_if_exception_mismatch $<* struct object_vtable>, L3
int_return $2
+ ---
L3:
reraise
""")
@@ -295,15 +313,18 @@
return 4
self.encoding_test(f, [65], """
- G_residual_call_ir_v $<* fn g>, <Descr>, I[%i0], R[]
+ residual_call_ir_v $<* fn g>, <Descr>, I[%i0], R[]
+ -live-
catch_exception L1
int_return $4
+ ---
L1:
goto_if_exception_mismatch $<* struct object_vtable>, L2
- last_exc_value %r0
- ref_copy %r0, %r1
- getfield_gc_i %r1, <Descr>, %i1
+ last_exc_value -> %r0
+ ref_copy %r0 -> %r1
+ getfield_gc_i %r1, <Descr> -> %i1
int_return %i1
+ ---
L2:
int_return $3
""", transform=True)
@@ -332,6 +353,7 @@
direct_call $<* fn g>, %i0
catch_exception L1
void_return
+ ---
L1:
raise $<* struct object>
""")
@@ -340,11 +362,13 @@
def f(i):
return not i
- # note that 'goto_if_not_int_is_true' is actually the same thing
- # as just 'goto_if_not'.
+ # note that 'goto_if_not_int_is_true' is not the same thing
+ # as just 'goto_if_not', because the last one expects a boolean
self.encoding_test(f, [7], """
- goto_if_not %i0, L1
+ goto_if_not_int_is_true %i0, L1
+ -live- L1
int_return $False
+ ---
L1:
int_return $True
""", transform=True)
@@ -360,15 +384,19 @@
except ZeroDivisionError:
return -42
self.encoding_test(f, [7, 2], """
- G_residual_call_ir_i $<* fn int_floordiv_ovf_zer>, <Descr>, I[%i0, %i1], R[], %i2
+ residual_call_ir_i $<* fn int_floordiv_ovf_zer>, <Descr>, I[%i0, %i1], R[] -> %i2
+ -live-
catch_exception L1
int_return %i2
+ ---
L1:
goto_if_exception_mismatch $<* struct object_vtable>, L2
int_return $42
+ ---
L2:
goto_if_exception_mismatch $<* struct object_vtable>, L3
int_return $-42
+ ---
L3:
reraise
""", transform=True)
@@ -383,16 +411,34 @@
return 42
# XXX so far, this really produces a int_mod_ovf_zer...
self.encoding_test(f, [7, 2], """
- G_residual_call_ir_i $<* fn int_mod_ovf_zer>, <Descr>, I[%i0, %i1], R[], %i2
+ residual_call_ir_i $<* fn int_mod_ovf_zer>, <Descr>, I[%i0, %i1], R[] -> %i2
+ -live-
catch_exception L1
int_return %i2
+ ---
L1:
goto_if_exception_mismatch $<* struct object_vtable>, L2
int_return $42
+ ---
L2:
reraise
""", transform=True)
+ def test_simple_branch(self):
+ def f(n, m1, m2):
+ if n:
+ return m1
+ else:
+ return m2
+ self.encoding_test(f, [4, 5, 6], """
+ goto_if_not_int_is_true %i0, L1
+ -live- %i1, %i2, L1
+ int_return %i1
+ ---
+ L1:
+ int_return %i2
+ """, transform=True, liveness=True)
+
def test_int_add_ovf(self):
def f(i, j):
try:
@@ -400,10 +446,11 @@
except OverflowError:
return 42
self.encoding_test(f, [7, 2], """
- -live-
- G_int_add_ovf %i0, %i1, %i2
+ int_add_ovf %i0, %i1 -> %i2
+ -live- %i2
catch_exception L1
int_return %i2
+ ---
L1:
int_return $42
""", transform=True, liveness=True)
@@ -418,13 +465,14 @@
except Exception:
return 42 + j
self.encoding_test(f, [7, 2], """
- -live- %i1
- G_residual_call_ir_i $<* fn g>, <Descr>, I[%i0, %i1], R[], %i2
+ residual_call_ir_i $<* fn g>, <Descr>, I[%i0, %i1], R[] -> %i2
+ -live- %i1, %i2
catch_exception L1
int_return %i2
+ ---
L1:
- int_copy %i1, %i3
- int_add %i3, $42, %i4
+ int_copy %i1 -> %i3
+ int_add %i3, $42 -> %i4
int_return %i4
""", transform=True, liveness=True)
@@ -438,7 +486,7 @@
except Exception:
return 42 + j
self.encoding_test(f, [7, 2], """
- residual_call_ir_i $<* fn cannot_raise>, <Descr>, I[%i0, %i1], R[], %i2
+ residual_call_ir_i $<* fn cannot_raise>, <Descr>, I[%i0, %i1], R[] -> %i2
int_return %i2
""", transform=True, liveness=True)
@@ -458,11 +506,12 @@
myjitdriver.jit_merge_point(x=x, y=y)
myjitdriver.can_enter_jit(x=y, y=x)
self.encoding_test(f, [4, 5], """
- G_int_guard_value %i0
+ int_guard_value %i0
+ -live- %i0, %i1
jit_merge_point I[%i0], R[], F[], I[%i1], R[], F[]
can_enter_jit
void_return
- """, transform=True)
+ """, transform=True, liveness=True)
def test_keepalive(self):
S = lltype.GcStruct('S')
@@ -475,9 +524,20 @@
keepalive_until_here(q)
return x
self.encoding_test(f, [5], """
- G_residual_call_r_r $<* fn g>, <Descr>, R[], %r0
- G_residual_call_r_r $<* fn g>, <Descr>, R[], %r1
- keepalive %r0
- keepalive %r1
+ residual_call_r_r $<* fn g>, <Descr>, R[] -> %r0
+ -live-
+ residual_call_r_r $<* fn g>, <Descr>, R[] -> %r1
+ -live-
+ -live- %r0
+ -live- %r1
int_return %i0
""", transform=True)
+ self.encoding_test(f, [5], """
+ residual_call_r_r $<* fn g>, <Descr>, R[] -> %r0
+ -live- %i0, %r0
+ residual_call_r_r $<* fn g>, <Descr>, R[] -> %r1
+ -live- %i0, %r0, %r1
+ -live- %i0, %r0, %r1
+ -live- %i0, %r1
+ int_return %i0
+ """, transform=True, liveness=True)
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py Fri May 21 15:46:57 2010
@@ -59,11 +59,13 @@
graph = self.make_graphs(f, [5, 6])[0]
self.check_assembler(graph, """
L1:
- int_gt %i0, $0, %i2
+ int_gt %i0, $0 -> %i2
goto_if_not %i2, L2
- int_add %i1, %i0, %i1
- int_sub %i0, $1, %i0
+ -live- L2
+ int_add %i1, %i0 -> %i1
+ int_sub %i0, $1 -> %i0
goto L1
+ ---
L2:
int_return %i1
""")
@@ -76,12 +78,14 @@
graph = self.make_graphs(f, [5, 6])[0]
self.check_assembler(graph, """
L1:
- int_gt %i0, $0, %i2
+ int_gt %i0, $0 -> %i2
goto_if_not %i2, L2
+ -live- L2
int_push %i1
- int_copy %i0, %i1
- int_pop %i0
+ int_copy %i0 -> %i1
+ int_pop -> %i0
goto L1
+ ---
L2:
int_return %i1
""")
@@ -94,11 +98,13 @@
graph = self.make_graphs(f, [5, 6])[0]
self.check_assembler(graph, """
L1:
- int_gt %i0, $0, %i0
+ int_gt %i0, $0 -> %i0
goto_if_not %i0, L2
- int_copy %i1, %i0
- int_copy $2, %i1
+ -live- L2
+ int_copy %i1 -> %i0
+ int_copy $2 -> %i1
goto L1
+ ---
L2:
int_return %i1
""")
@@ -111,13 +117,15 @@
graph = self.make_graphs(f, [5, 6, 7])[0]
self.check_assembler(graph, """
L1:
- int_gt %i0, $0, %i3
+ int_gt %i0, $0 -> %i3
goto_if_not %i3, L2
+ -live- L2
int_push %i1
- int_copy %i2, %i1
- int_copy %i0, %i2
- int_pop %i0
+ int_copy %i2 -> %i1
+ int_copy %i0 -> %i2
+ int_pop -> %i0
goto L1
+ ---
L2:
int_return %i1
""")
@@ -130,10 +138,12 @@
graph = self.make_graphs(f, [5, 6, 7])[0]
self.check_assembler(graph, """
L1:
- int_gt %i0, $0, %i3
+ int_gt %i0, $0 -> %i3
goto_if_not %i3, L2
- int_copy %i2, %i1
+ -live- L2
+ int_copy %i2 -> %i1
goto L1
+ ---
L2:
int_return %i1
""")
@@ -152,8 +162,8 @@
block.closeblock(Link([v3], graph.returnblock))
#
self.check_assembler(graph, """
- int_add %i0, $1, %i1
- rescall I[%i0, %i1], %i0
+ int_add %i0, $1 -> %i1
+ rescall I[%i0, %i1] -> %i0
int_return %i0
""")
@@ -164,7 +174,8 @@
v4 = Variable(); v4.concretetype = rclass.CLASSTYPE
block = Block([])
block.operations = [
- SpaceOperation('G_res_call', [], v1),
+ SpaceOperation('res_call', [], v1),
+ SpaceOperation('-live-', [], None),
]
graph = FunctionGraph('f', block, v4)
exclink = Link([v2], graph.returnblock)
@@ -176,13 +187,16 @@
exclink)
#
self.check_assembler(graph, """
- G_res_call %i0
+ res_call -> %i0
+ -live-
catch_exception L1
int_return %i0
+ ---
L1:
goto_if_exception_mismatch $123, L2
- last_exception %i0
+ last_exception -> %i0
int_return %i0
+ ---
L2:
reraise
""")
@@ -203,8 +217,8 @@
block.closeblock(Link([v3], graph.returnblock))
#
self.check_assembler(graph, """
- int_add %i0, $1, %i1
- rescall I[%i0, %i1], %i2
- rescall I[%i0, %i1], %i0
+ int_add %i0, $1 -> %i1
+ rescall I[%i0, %i1] -> %i2
+ rescall I[%i0, %i1] -> %i0
int_return %i0
""")
Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/blackhole.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/blackhole.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/blackhole.py Fri May 21 15:46:57 2010
@@ -195,8 +195,9 @@
if resulttype == 'i':
# argcode should be 'i' too
- assert argcodes[next_argcode] == 'i'
- next_argcode = next_argcode + 1
+ assert argcodes[next_argcode] == '>'
+ assert argcodes[next_argcode+1] == 'i'
+ next_argcode = next_argcode + 2
if lltype.typeOf(result) is lltype.Bool:
result = int(result)
assert lltype.typeOf(result) is lltype.Signed
@@ -204,15 +205,17 @@
position += 1
elif resulttype == 'r':
# argcode should be 'r' too
- assert argcodes[next_argcode] == 'r'
- next_argcode = next_argcode + 1
+ assert argcodes[next_argcode] == '>'
+ assert argcodes[next_argcode+1] == 'r'
+ next_argcode = next_argcode + 2
assert lltype.typeOf(result) == llmemory.GCREF
self.registers_r[ord(code[position])] = result
position += 1
elif resulttype == 'f':
# argcode should be 'f' too
- assert argcodes[next_argcode] == 'f'
- next_argcode = next_argcode + 1
+ assert argcodes[next_argcode] == '>'
+ assert argcodes[next_argcode+1] == 'f'
+ next_argcode = next_argcode + 2
assert lltype.typeOf(result) is lltype.Float
self.registers_f[ord(code[position])] = result
position += 1
@@ -979,16 +982,34 @@
def _prepare_resume_from_failure(self, opnum):
from pypy.jit.metainterp.resoperation import rop
- if opnum == rop.GUARD_TRUE: # a goto_if_not_xxx that jumps only now
+ #
+ if opnum == rop.GUARD_TRUE:
+ # Produced directly by some goto_if_not_xxx() opcode that did not
+ # jump, but which must now jump. The pc is just after the opcode.
self.position = self.jitcode.follow_jump(self.position)
- elif opnum == rop.GUARD_FALSE: # a goto_if_not that stops jumping
+ #
+ elif opnum == rop.GUARD_FALSE:
+ # Produced directly by some goto_if_not_xxx() opcode that jumped,
+ # but which must no longer jump. The pc is just after the opcode.
pass
- elif opnum == rop.GUARD_NO_EXCEPTION or opnum == rop.GUARD_EXCEPTION:
+ #
+ elif opnum == rop.GUARD_VALUE or opnum == rop.GUARD_CLASS:
+ # Produced by guard_class(), xxx_guard_value(), or a few other
+ # opcodes like switch(). The pc is at the start of the opcode
+ # (so it will be redone).
pass
- elif opnum == rop.GUARD_CLASS or opnum == rop.GUARD_VALUE:
+ #
+ elif opnum == rop.GUARD_NONNULL or opnum == rop.GUARD_ISNULL:
+ xxx
+ elif (opnum == rop.GUARD_NO_EXCEPTION or
+ opnum == rop.GUARD_EXCEPTION or
+ opnum == rop.GUARD_NOT_FORCED or
+ opnum == rop.GUARD_NO_OVERFLOW or
+ opnum == rop.GUARD_OVERFLOW):
pass
else:
- raise NotImplementedError(opnum)
+ from pypy.jit.metainterp.resoperation import opname
+ raise NotImplementedError(opname[opnum])
# connect the return of values from the called frame to the
# 'xxx_call_yyy' instructions from the caller frame
Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/history.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/history.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/history.py Fri May 21 15:46:57 2010
@@ -366,6 +366,8 @@
except lltype.UninitializedMemoryAccess:
return '<uninitialized string>'
+CONST_NULL = ConstPtr(ConstPtr.value)
+
class ConstObj(Const):
type = REF
value = ootype.NULL
Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/pyjitpl.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/pyjitpl.py Fri May 21 15:46:57 2010
@@ -182,7 +182,6 @@
for _opimpl in ['int_is_true', 'int_is_zero', 'int_neg', 'int_invert',
'cast_ptr_to_int', 'cast_float_to_int',
'cast_int_to_float', 'float_neg', 'float_abs',
- 'ptr_iszero', 'ptr_nonzero',
]:
exec py.code.Source('''
@arguments("box")
@@ -191,6 +190,14 @@
''' % (_opimpl, _opimpl.upper())).compile()
@arguments("box")
+ def opimpl_ptr_nonzero(self, box):
+ return self.execute(rop.PTR_NE, box, history.CONST_NULL)
+
+ @arguments("box")
+ def opimpl_ptr_iszero(self, box):
+ return self.execute(rop.PTR_EQ, box, history.CONST_NULL)
+
+ @arguments("box")
def _opimpl_any_return(self, box):
self.metainterp.finishframe(box)
@@ -252,13 +259,15 @@
if not switchcase:
self.pc = target
- for _opimpl in ['int_is_zero', 'ptr_iszero', 'ptr_nonzero']:
- exec py.code.Source('''
- @arguments("box", "label")
- def opimpl_goto_if_not_%s(self, box, target):
- condbox = self.execute(rop.%s, box)
- self.opimpl_goto_if_not(condbox, target)
- ''' % (_opimpl, _opimpl.upper())).compile()
+ @arguments("box", "label")
+ def opimpl_goto_if_not_int_is_true(self, box, target):
+ condbox = self.execute(rop.INT_IS_TRUE, box)
+ self.opimpl_goto_if_not(condbox, target)
+
+ @arguments("box", "label")
+ def opimpl_goto_if_not_int_is_zero(self, box, target):
+ condbox = self.execute(rop.INT_IS_ZERO, box)
+ self.opimpl_goto_if_not(condbox, target)
for _opimpl in ['int_lt', 'int_le', 'int_eq', 'int_ne', 'int_gt', 'int_ge',
'ptr_eq', 'ptr_ne']:
@@ -268,7 +277,29 @@
condbox = self.execute(rop.%s, b1, b2)
self.opimpl_goto_if_not(condbox, target)
''' % (_opimpl, _opimpl.upper())).compile()
-
+
+ @arguments("box", "label")
+ def opimpl_goto_if_not_ptr_nonzero(self, box, target):
+ value = box.nonnull()
+ if value:
+ opnum = rop.GUARD_NONNULL
+ else:
+ opnum = rop.GUARD_ISNULL
+ self.generate_guard(opnum, box)
+ if not value:
+ self.pc = target
+
+ @arguments("box", "label")
+ def opimpl_goto_if_not_ptr_iszero(self, box, target):
+ value = box.nonnull()
+ if value:
+ opnum = rop.GUARD_NONNULL
+ else:
+ opnum = rop.GUARD_ISNULL
+ self.generate_guard(opnum, box)
+ if value:
+ self.pc = target
+
## def follow_jump(self):
## _op_goto_if_not = self.metainterp.staticdata._op_goto_if_not
## assert ord(self.bytecode[self.pc]) == _op_goto_if_not
@@ -1003,6 +1034,9 @@
self.indirectcalltargets = list(indirectcalltargets)
def finish_setup(self, codewriter, optimizer=None):
+ from pypy.jit.metainterp.blackhole import BlackholeInterpBuilder
+ self.blackholeinterpbuilder = BlackholeInterpBuilder(codewriter, self)
+ #
asm = codewriter.assembler
self.setup_insns(asm.insns)
self.setup_descrs(asm.descrs)
@@ -1012,9 +1046,6 @@
RESULT = codewriter.portal_graph.getreturnvar().concretetype
self.result_type = history.getkind(RESULT)
#
- from pypy.jit.metainterp.blackhole import BlackholeInterpBuilder
- self.blackholeinterpbuilder = BlackholeInterpBuilder(codewriter, self)
- #
warmrunnerdesc = self.warmrunnerdesc
if warmrunnerdesc is not None:
self.num_green_args = warmrunnerdesc.num_green_args
@@ -1514,6 +1545,10 @@
frame.pc = frame.jitcode.follow_jump(frame.pc)
elif opnum == rop.GUARD_FALSE: # a goto_if_not that stops jumping
pass
+ elif opnum == rop.GUARD_VALUE or opnum == rop.GUARD_CLASS:
+ pass # the pc is already set to the *start* of the opcode
+ elif opnum == rop.GUARD_NONNULL or opnum == rop.GUARD_ISNULL:
+ xxx #self.framestack[-1].ignore_next_guard_nullness(opnum)
elif (opnum == rop.GUARD_NO_EXCEPTION or opnum == rop.GUARD_EXCEPTION
or opnum == rop.GUARD_NOT_FORCED):
exception = self.cpu.grab_exc_value()
@@ -1523,13 +1558,13 @@
self.execute_did_not_raise()
self.handle_possible_exception()
elif opnum == rop.GUARD_NO_OVERFLOW: # an overflow now detected
- xxx #self.raise_overflow_error()
- elif opnum == rop.GUARD_NONNULL or opnum == rop.GUARD_ISNULL:
- xxx #self.framestack[-1].ignore_next_guard_nullness(opnum)
- elif opnum == rop.GUARD_CLASS or opnum == rop.GUARD_VALUE:
+ self.execute_raised(OverflowError(), constant=True)
+ self.finishframe_exception()
+ elif opnum == rop.GUARD_OVERFLOW: # no longer overflowing
pass
else:
- raise NotImplementedError(opnum)
+ from pypy.jit.metainterp.resoperation import opname
+ raise NotImplementedError(opname[opnum])
def compile(self, original_boxes, live_arg_boxes, start):
num_green_args = self.staticdata.num_green_args
Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/resoperation.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/resoperation.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/resoperation.py Fri May 21 15:46:57 2010
@@ -183,8 +183,6 @@
#
'SAME_AS/1', # gets a Const or a Box, turns it into another Box
#
- 'PTR_ISZERO/1b',
- 'PTR_NONZERO/1b',
'PTR_EQ/2b',
'PTR_NE/2b',
#
More information about the Pypy-commit
mailing list