[pypy-commit] pypy no-failargs: in-progress
arigo
noreply at buildbot.pypy.org
Sat Oct 27 17:15:30 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: no-failargs
Changeset: r58502:432e12af25ca
Date: 2012-10-27 15:44 +0200
http://bitbucket.org/pypy/pypy/changeset/432e12af25ca/
Log: in-progress
diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py
--- a/pypy/jit/backend/llgraph/runner.py
+++ b/pypy/jit/backend/llgraph/runner.py
@@ -3,7 +3,7 @@
from pypy.jit.backend.llgraph import support
from pypy.jit.metainterp.history import AbstractDescr
from pypy.jit.metainterp.resoperation import Const, getkind
-from pypy.jit.metainterp.resoperation import INT, REF, FLOAT, VOID
+from pypy.jit.metainterp.resoperation import INT, REF, FLOAT, VOID, FLOAT_SIZE
from pypy.jit.metainterp.resoperation import rop
from pypy.jit.codewriter import longlong, heaptracker
from pypy.jit.codewriter.effectinfo import EffectInfo
@@ -47,8 +47,6 @@
map(mapping, op.getarglist()),
mapping(op.result),
newdescr)
- if op.getfailargs() is not None:
- newop.setfailargs(map(mapping, op.getfailargs()))
self.operations.append(newop)
class WeakrefDescr(AbstractDescr):
@@ -56,15 +54,13 @@
self.realdescrref = weakref.ref(realdescr)
class GuardFailed(Exception):
- def __init__(self, failargs, descr):
- self.failargs = failargs
+ def __init__(self, descr):
self.descr = descr
class ExecutionFinished(Exception):
- def __init__(self, descr, arg, failargs):
+ def __init__(self, descr, arg):
self.descr = descr
self.arg = arg
- self.failargs = failargs
class Jump(Exception):
def __init__(self, descr, args):
@@ -261,22 +257,17 @@
assert False
except ExecutionFinished, e:
frame.finish_value = e.arg
- frame.latest_values = e.failargs
frame.latest_descr = e.descr
frame._execution_finished_normally = e.descr.fast_path_done
return frame
except GuardFailed, e:
- frame.latest_values = e.failargs
frame.latest_descr = e.descr
return frame
- def get_latest_value_int(self, frame, index):
- return frame.latest_values[index]
- get_latest_value_float = get_latest_value_int
- get_latest_value_ref = get_latest_value_int
-
- def get_latest_value_count(self, frame):
- return len(frame.latest_values)
+ def get_frame_value_int(self, frame, index):
+ return frame.framecontent[index]
+ get_frame_value_float = get_frame_value_int
+ get_frame_value_ref = get_frame_value_int
def get_latest_descr(self, frame):
return frame.latest_descr
@@ -635,17 +626,26 @@
def __init__(self, cpu, argboxes, args):
self.env = {}
+ self.framecontent = {}
self.cpu = cpu
assert len(argboxes) == len(args)
for box, arg in zip(argboxes, args):
- self.env[box] = arg
+ self.setenv(box, arg)
self.overflow_flag = False
self.last_exception = None
+ def setenv(self, box, arg):
+ self.env[box] = arg
+ self.framecontent[box.getvarindex()] = arg
+ if box.type == FLOAT and FLOAT_SIZE > 1:
+ self.framecontent[box.getvarindex() + 1] = '2nd float word'
+
def lookup(self, arg):
if isinstance(arg, Const):
return arg.value
- return self.env[arg]
+ result = self.env[arg]
+ assert result is self.framecontent[arg.getvarindex()]
+ return result
def execute(self, lltrace):
self.lltrace = lltrace
@@ -670,9 +670,8 @@
if hasattr(gf.descr, '_llgraph_bridge'):
i = 0
self.lltrace = gf.descr._llgraph_bridge
- newargs = [self.env[arg] for arg in
- self.current_op.getfailargs() if arg is not None]
- self.do_renaming(self.lltrace.inputargs, newargs)
+ newvals = [self.env[arg] for arg in self.lltrace.inputargs]
+ self.do_renaming(self.lltrace.inputargs, newvals)
continue
raise
if op.type == INT:
@@ -687,43 +686,27 @@
else:
assert op.type == VOID
assert resval is None
- self.env[op] = resval
+ if op.type != VOID:
+ self.setenv(op, resval)
i += 1
- def _getfailargs(self, op=None, skip=None):
- if op is None:
- op = self.current_op
- r = []
- for arg in op.getfailargs():
- if arg is None:
- r.append(None)
- elif arg is skip:
- r.append(_example_res[skip.type])
- else:
- r.append(self.env[arg])
- return r
-
- def do_renaming(self, newargs, oldargs):
- assert len(newargs) == len(oldargs)
- newenv = {}
- for new, old in zip(newargs, oldargs):
- newenv[new] = old
- self.env = newenv
+ def do_renaming(self, newargs, newvalues):
+ assert len(newargs) == len(newvalues)
+ self.env = {}
+ self.framecontent = {}
+ for new, newvalue in zip(newargs, newvalues):
+ self.setenv(new, newvalue)
# -----------------------------------------------------
def fail_guard(self, descr):
- raise GuardFailed(self._getfailargs(), descr)
+ raise GuardFailed(descr)
def execute_force_spill(self, _, arg):
pass
def execute_finish(self, descr, arg=None):
- if self.current_op.getfailargs() is not None:
- failargs = self._getfailargs()
- else:
- failargs = None # compatibility
- raise ExecutionFinished(descr, arg, failargs)
+ raise ExecutionFinished(descr, arg)
def execute_label(self, descr, *args):
argboxes = self.current_op.getarglist()
@@ -864,6 +847,7 @@
call_op = self.lltrace.operations[self.current_index]
guard_op = self.lltrace.operations[self.current_index + 1]
assert guard_op.getopnum() == rop.GUARD_NOT_FORCED
+ XXX
self.latest_values = self._getfailargs(guard_op, skip=call_op)
self.latest_descr = _getdescr(guard_op)
res = self.execute_call(calldescr, func, *args)
@@ -890,6 +874,7 @@
call_op = self.lltrace.operations[self.current_index]
guard_op = self.lltrace.operations[self.current_index + 1]
assert guard_op.getopnum() == rop.GUARD_NOT_FORCED
+ XXX
self.latest_values = self._getfailargs(guard_op, skip=call_op)
self.latest_descr = _getdescr(guard_op)
#
diff --git a/pypy/jit/backend/model.py b/pypy/jit/backend/model.py
--- a/pypy/jit/backend/model.py
+++ b/pypy/jit/backend/model.py
@@ -106,7 +106,7 @@
Execute the generated code referenced by the looptoken.
It runs it until either a guard fails, or until we reach
the FINISH operation. It returns the "jit frame" object
- which should be inspected with the get_latest_xyz() methods.
+ which should be inspected with the get_frame_value_xyz() methods.
"""
argtypes = [lltype.typeOf(x) for x in args]
execute = self.make_execute_token(*argtypes)
@@ -123,24 +123,19 @@
jitframe."""
raise NotImplementedError
- def get_latest_value_int(self, jitframe, index):
- """Returns the value for the index'th 'fail_args' of the
- last executed operation. Returns an int."""
+ def get_frame_value_int(self, jitframe, index):
+ """Returns the value for the index'th value in the frame.
+ Returns an int."""
raise NotImplementedError
- def get_latest_value_float(self, jitframe, index):
- """Returns the value for the index'th 'fail_args' of the
- last executed operation. Returns a FLOATSTORAGE."""
+ def get_frame_value_float(self, jitframe, index):
+ """Returns the value for the index'th value in the frame.
+ Returns a FLOATSTORAGE."""
raise NotImplementedError
- def get_latest_value_ref(self, jitframe, index):
- """Returns the value for the index'th 'fail_args' of the
- last executed operation. Returns a GCREF."""
- raise NotImplementedError
-
- def get_latest_value_count(self, jitframe):
- """Return how many values are ready to be returned by
- get_latest_value_xxx()."""
+ def get_frame_value_ref(self, jitframe, index):
+ """Returns the value for the index'th value in the frame.
+ Returns a GCREF."""
raise NotImplementedError
def get_finish_value_int(self, jitframe):
diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py
--- a/pypy/jit/backend/test/runner_test.py
+++ b/pypy/jit/backend/test/runner_test.py
@@ -95,7 +95,7 @@
avoid_instances = False
- def parse(self, s, namespace):
+ def parse(self, s, namespace, invent_varindex=True):
if namespace is None:
namespace = {}
else:
@@ -112,15 +112,28 @@
namespace['faildescr3'] = BasicFailDescr(3)
if 'faildescr4' not in namespace:
namespace['faildescr4'] = BasicFailDescr(4)
- loop = oparser.parse(s, namespace=namespace, guards_with_failargs=True)
+ loop = oparser.parse(s, namespace=namespace, mutable=True,
+ vars=getattr(self, 'original_vars', {}))
+ self.original_vars = loop.original_vars
return loop.inputargs, loop.operations, JitCellToken()
+ def get_frame_value(self, frame, varname):
+ op = self.original_vars[varname]
+ index = op.getvarindex()
+ if varname.startswith('i'):
+ return self.cpu.get_frame_value_int(frame, index)
+ if varname.startswith('p'):
+ return self.cpu.get_frame_value_ref(frame, index)
+ if varname.startswith('f'):
+ return self.cpu.get_frame_value_float(frame, index)
+ raise ValueError(varname)
+
def test_compile_linear_loop(self):
faildescr = BasicFailDescr(1)
inputargs, ops, token = self.parse("""
[i0]
i1 = int_add(i0, 1)
- finish(i1, descr=faildescr) []
+ finish(i1, descr=faildescr)
""", namespace=locals())
self.cpu.compile_loop(inputargs, ops, token)
frame = self.cpu.execute_token(token, 2)
@@ -133,7 +146,7 @@
inputargs, ops, token = self.parse("""
[f0]
f1 = float_add(f0, 1.)
- finish(f1, descr=faildescr) []
+ finish(f1, descr=faildescr)
""", namespace=locals())
self.cpu.compile_loop(inputargs, ops, token)
frame = self.cpu.execute_token(token, longlong.getfloatstorage(2.8))
@@ -149,16 +162,16 @@
label(i0, descr=targettoken)
i1 = int_add(i0, 1)
i2 = int_le(i1, 9)
- guard_true(i2, descr=faildescr) [i1]
+ guard_true(i2, descr=faildescr)
jump(i1, descr=targettoken)
''', namespace=locals())
self.cpu.compile_loop(inputargs, operations, looptoken)
frame = self.cpu.execute_token(looptoken, 2)
assert self.cpu.get_latest_descr(frame).identifier == 2
- res = self.cpu.get_latest_value_int(frame, 0)
+ res = self.get_frame_value(frame, 'i1')
assert res == 10
- def test_compile_with_holes_in_fail_args(self):
+ def test_compile_loop_2(self):
faildescr3 = BasicFailDescr(3)
targettoken = TargetToken()
inputargs, operations, looptoken = self.parse("""
@@ -167,14 +180,14 @@
label(i0, descr=targettoken)
i1 = int_add(i0, 1)
i2 = int_le(i1, 9)
- guard_true(i2, descr=faildescr3) [None, None, i1, None]
+ guard_true(i2, descr=faildescr3)
jump(i1, descr=targettoken)
""", namespace=locals())
self.cpu.compile_loop(inputargs, operations, looptoken)
frame = self.cpu.execute_token(looptoken, 44)
assert self.cpu.get_latest_descr(frame).identifier == 3
- res = self.cpu.get_latest_value_int(frame, 2)
+ res = self.get_frame_value(frame, 'i1')
assert res == 10
def test_backends_dont_keep_loops_alive(self):
@@ -185,7 +198,7 @@
label(i0, descr=targettoken)
i1 = int_add(i0, 1)
i2 = int_le(i1, 9)
- guard_true(i2, descr=faildescr) [i1]
+ guard_true(i2, descr=faildescr)
jump(i1, descr=targettoken)
""", namespace={'targettoken': TargetToken()})
i1 = inputargs[0]
@@ -210,17 +223,17 @@
label(i0, descr=targettoken)
i1 = int_add(i0, 1)
i2 = int_le(i1, 9)
- guard_true(i2, descr=faildescr) [i1]
+ guard_true(i2, descr=faildescr)
jump(i1, descr=targettoken)
""", namespace={'faildescr': faildescr4,
'targettoken': targettoken})
self.cpu.compile_loop(inputargs, operations, looptoken)
inputargs, bridge_ops, _ = self.parse("""
- [i1b]
- i3 = int_le(i1b, 19)
- guard_true(i3, descr=faildescr5) [i1b]
- jump(i1b, descr=targettoken)
+ [i1]
+ i3 = int_le(i1, 19)
+ guard_true(i3, descr=faildescr5)
+ jump(i1, descr=targettoken)
""", namespace={'faildescr5': BasicFailDescr(5),
'targettoken': targettoken})
self.cpu.compile_bridge(faildescr4,
diff --git a/pypy/jit/metainterp/optmodel.py b/pypy/jit/metainterp/optmodel.py
--- a/pypy/jit/metainterp/optmodel.py
+++ b/pypy/jit/metainterp/optmodel.py
@@ -4,7 +4,7 @@
from pypy.tool.sourcetools import func_with_new_name
from pypy.jit.metainterp.resoperation import opclasses, opclasses_mutable, rop,\
- INT, REF, ConstInt, Const
+ VOID, INT, REF, ConstInt, Const
from pypy.jit.metainterp.optimizeopt.intutils import ImmutableIntUnbounded,\
ConstantIntBound
@@ -56,8 +56,10 @@
else:
def force(self, _):
return self
- if cls.is_guard() or cls.getopnum() == rop.FINISH:
- addattr(Mutable, 'failargs')
+ if cls.type != VOID:
+ addattr(Mutable, 'varindex', -1)
+ #if cls.type == REF:
+ # addattr(Mutable, 'varrange', sys.maxint // 2)
if cls.is_guard():
addattr(Mutable, 'descr') # mutable guards have descrs
if cls.type == INT:
diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py
--- a/pypy/jit/metainterp/resoperation.py
+++ b/pypy/jit/metainterp/resoperation.py
@@ -12,6 +12,7 @@
"""
+import sys
from pypy.jit.codewriter import longlong
from pypy.jit.codewriter import heaptracker
from pypy.rpython.lltypesystem import lltype, llmemory, rffi
@@ -28,6 +29,12 @@
VOID = 'v'
HOLE = '_'
+if sys.maxint == 2**31 - 1:
+ FLOAT_SIZE = 2 # a FLOAT variable uses two INT or REF positions
+else:
+ FLOAT_SIZE = 1 # FLOAT is the same size as INT and REF
+
+
def create_resop_dispatch(opnum, result, args, descr=None, mutable=False):
""" NOT_RPYTHON this is for tests only!
"""
@@ -555,10 +562,15 @@
t = 'i'
elif self.type == FLOAT:
t = 'f'
+ elif self.type == REF:
+ t = 'p'
else:
- t = 'p'
- self._str = '%s%d' % (t, AbstractResOp._counter)
- AbstractResOp._counter += 1
+ t = '?'
+ if not hasattr(self, '_varindex'):
+ self._str = '%s%d' % (t, AbstractResOp._counter)
+ AbstractResOp._counter += 1
+ else:
+ self._str = '%s%s' % (t.upper(), self._varindex)
return self._str
def repr(self, graytext=False):
diff --git a/pypy/jit/tool/oparser.py b/pypy/jit/tool/oparser.py
--- a/pypy/jit/tool/oparser.py
+++ b/pypy/jit/tool/oparser.py
@@ -20,22 +20,17 @@
use_mock_model = False
def __init__(self, input, cpu, namespace, type_system,
- invent_fail_descr=True, results=None,
- guards_with_failargs=False):
+ invent_fail_descr=True, results=None, mutable=False, vars={}):
self.input = input
- self.vars = {}
+ self.vars = vars.copy()
self.cpu = cpu
self._consts = namespace
self.type_system = type_system
- self.guards_with_failargs = guards_with_failargs
- if namespace is not None:
- self._cache = namespace.setdefault('_CACHE_', {})
- else:
- self._cache = {}
self.invent_fail_descr = invent_fail_descr
self.model = get_model(self.use_mock_model)
self.original_jitcell_token = self.model.JitCellToken()
self.results = results
+ self.mutable = mutable
def get_const(self, name, typ):
if self._consts is None:
@@ -70,24 +65,6 @@
return tt
raise
- def box_for_var(self, elem):
- try:
- return self._cache[self.type_system, elem]
- except KeyError:
- pass
- if elem[0] in 'ifp':
- if elem[0] == 'p':
- p = 'r'
- else:
- p = elem[0]
- opnum = getattr(rop, 'INPUT_' + p)
- box = create_resop_0(opnum, example_for_opnum(opnum))
- else:
- raise ParseError("Unknown variable type: %s" % elem)
- self._cache[self.type_system, elem] = box
- box._str = elem
- return box
-
def parse_header_line(self, line):
elements = line.split(",")
vars = []
@@ -97,9 +74,26 @@
return vars
def newvar(self, elem):
- box = self.box_for_var(elem)
- self.vars[elem] = box
- return box
+ if elem not in self.vars:
+ if elem[0] in 'ifp':
+ if elem[0] == 'p':
+ p = 'r'
+ else:
+ p = elem[0]
+ opnum = getattr(rop, 'INPUT_' + p)
+ box = create_resop_0(opnum, example_for_opnum(opnum),
+ mutable=self.mutable)
+ else:
+ raise ParseError("Unknown variable type: %s" % elem)
+ self.setstr(box, elem)
+ self.vars[elem] = box
+ return self.vars[elem]
+
+ def setstr(self, op, text):
+ if hasattr(op, 'setvarindex') and text[1:].isdigit():
+ op.setvarindex(int(text[1:]))
+ else:
+ op._res = text
def is_float(self, arg):
try:
@@ -185,44 +179,15 @@
endnum = line.rfind(')')
if endnum == -1:
raise ParseError("invalid line: %s" % line)
+ if line.find('[', endnum) >= 0:
+ raise ParseError("fail_args should be removed: %s" % line)
args, descr = self.parse_args(opname, line[num + 1:endnum])
- fail_args = None
- if rop._GUARD_FIRST <= opnum <= rop._GUARD_LAST or opnum == rop.FINISH:
- i = line.find('[', endnum) + 1
- j = line.find(']', i)
- if i <= 0 or j <= 0:
- if self.guards_with_failargs and opnum != rop.FINISH:
- raise ParseError("missing fail_args for guard operation")
- fail_args = None
- else:
- if not self.guards_with_failargs:
- raise ParseError("fail_args should be NULL")
- fail_args = []
- if i < j:
- for arg in line[i:j].split(','):
- arg = arg.strip()
- if arg == 'None':
- fail_arg = None
- else:
- try:
- fail_arg = self.vars[arg]
- except KeyError:
- raise ParseError(
- "Unknown var in fail_args: %s" % arg)
- fail_args.append(fail_arg)
- else:
- if opnum == rop.FINISH:
- if descr is None and self.invent_fail_descr:
- descr = self.invent_fail_descr(self.model, fail_args)
- elif opnum == rop.JUMP:
- if descr is None and self.invent_fail_descr:
- descr = self.original_jitcell_token
-
- return opnum, args, descr, fail_args
+ if descr is None and opnum == rop.JUMP:
+ descr = self.original_jitcell_token
+ return opnum, args, descr
def create_op(self, opnum, result, args, descr):
- r = create_resop_dispatch(opnum, result, args,
- mutable=self.guards_with_failargs)
+ r = create_resop_dispatch(opnum, result, args, mutable=self.mutable)
if descr is not None:
r.setdescr(descr)
return r
@@ -231,7 +196,7 @@
res, op = line.split("=", 1)
res = res.strip()
op = op.strip()
- opnum, args, descr, fail_args = self.parse_op(op)
+ opnum, args, descr = self.parse_op(op)
if res in self.vars:
raise ParseError("Double assign to var %s in line: %s" % (res, line))
if self.results is None:
@@ -239,16 +204,13 @@
else:
result = self.results[num]
opres = self.create_op(opnum, result, args, descr)
+ self.setstr(opres, res)
self.vars[res] = opres
- if fail_args is not None:
- opres.setfailargs(fail_args)
return opres
def parse_op_no_result(self, line):
- opnum, args, descr, fail_args = self.parse_op(line)
+ opnum, args, descr = self.parse_op(line)
res = self.create_op(opnum, None, args, descr)
- if fail_args is not None:
- res.setfailargs(fail_args)
return res
def parse_next_op(self, line, num):
@@ -287,6 +249,7 @@
loop.operations = ops
loop.inputargs = inpargs
loop.last_offset = last_offset
+ loop.original_vars = self.vars
return loop
def parse_ops(self, indent, lines, start):
@@ -344,11 +307,11 @@
def parse(input, cpu=None, namespace=DEFAULT, type_system='lltype',
invent_fail_descr=True, OpParser=OpParser,
- results=None, guards_with_failargs=False):
+ results=None, mutable=False, vars={}):
if namespace is DEFAULT:
namespace = {}
return OpParser(input, cpu, namespace, type_system,
- invent_fail_descr, results, guards_with_failargs).parse()
+ invent_fail_descr, results, mutable, vars).parse()
def pure_parse(*args, **kwds):
kwds['invent_fail_descr'] = False
More information about the pypy-commit
mailing list