[pypy-commit] pypy optresult: A bunch of progress
fijal
noreply at buildbot.pypy.org
Sun Nov 23 08:52:40 CET 2014
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: optresult
Changeset: r74644:2806b8d08734
Date: 2014-11-23 09:52 +0200
http://bitbucket.org/pypy/pypy/changeset/2806b8d08734/
Log: A bunch of progress
diff --git a/rpython/jit/backend/llgraph/runner.py b/rpython/jit/backend/llgraph/runner.py
--- a/rpython/jit/backend/llgraph/runner.py
+++ b/rpython/jit/backend/llgraph/runner.py
@@ -497,7 +497,9 @@
array = a._obj
return support.cast_result(descr.A.OF, array.getitem(index))
- bh_getarrayitem_gc_pure = bh_getarrayitem_gc
+ bh_getarrayitem_gc_pure_i = bh_getarrayitem_gc
+ bh_getarrayitem_gc_pure_r = bh_getarrayitem_gc
+ bh_getarrayitem_gc_pure_f = bh_getarrayitem_gc
bh_getarrayitem_gc_i = bh_getarrayitem_gc
bh_getarrayitem_gc_r = bh_getarrayitem_gc
bh_getarrayitem_gc_f = bh_getarrayitem_gc
diff --git a/rpython/jit/metainterp/executor.py b/rpython/jit/metainterp/executor.py
--- a/rpython/jit/metainterp/executor.py
+++ b/rpython/jit/metainterp/executor.py
@@ -466,6 +466,15 @@
else:
assert lltype.typeOf(value) == llmemory.GCREF
return ConstPtr(value)
+
+def constant_from_op(op):
+ if op.type == 'i':
+ return ConstInt(op.getint())
+ elif op.type == 'r':
+ return ConstPtr(op.getref_base())
+ else:
+ assert op.type == 'f'
+ return ConstFloat(op.getfloatstorage())
def execute_nonspec_const(cpu, metainterp, opnum, argboxes, descr=None,
type='i'):
diff --git a/rpython/jit/metainterp/history.py b/rpython/jit/metainterp/history.py
--- a/rpython/jit/metainterp/history.py
+++ b/rpython/jit/metainterp/history.py
@@ -780,6 +780,11 @@
self.operations.append(op)
return op
+ def record_default_val(self, opnum, argboxes, descr=None):
+ op = ResOperation(opnum, argboxes, descr)
+ self.operations.append(op)
+ return op
+
def substitute_operation(self, position, opnum, argboxes, descr=None):
resbox = self.operations[position].result
op = ResOperation(opnum, argboxes, resbox, descr)
diff --git a/rpython/jit/metainterp/optimizeopt/optimizer.py b/rpython/jit/metainterp/optimizeopt/optimizer.py
--- a/rpython/jit/metainterp/optimizeopt/optimizer.py
+++ b/rpython/jit/metainterp/optimizeopt/optimizer.py
@@ -340,20 +340,6 @@
return self.optimizer.optpure.get_pure_result(key)
return None
- def getfield_pure_for_descr(self, descr):
- if descr.is_pointer_field():
- return rop.GETFIELD_GC_PURE_R
- elif descr.is_float_field():
- return rop.GETFIELD_GC_PURE_F
- return rop.GETFIELD_GC_PURE_I
-
- def getarrayitem_pure_for_descr(self, descr):
- if descr.is_array_of_pointers():
- return rop.GETARRAYITEM_GC_PURE_R
- elif descr.is_array_of_floats():
- return rop.GETARRAYITEM_GC_PURE_F
- return rop.GETARRAYITEM_GC_PURE_I
-
def setup(self):
pass
@@ -716,7 +702,7 @@
# dissabled and unrolling emits some SAME_AS ops to setup the
# optimizier state. These needs to always be optimized out.
def optimize_SAME_AS_I(self, op):
- self.make_equal_to(op.result, self.getvalue(op.getarg(0)))
+ self.make_equal_to(op, self.getvalue(op.getarg(0)))
optimize_SAME_AS_R = optimize_SAME_AS_I
optimize_SAME_AS_F = optimize_SAME_AS_I
diff --git a/rpython/jit/metainterp/optimizeopt/simplify.py b/rpython/jit/metainterp/optimizeopt/simplify.py
--- a/rpython/jit/metainterp/optimizeopt/simplify.py
+++ b/rpython/jit/metainterp/optimizeopt/simplify.py
@@ -1,6 +1,6 @@
from rpython.jit.metainterp.optimizeopt.optimizer import Optimization
from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method
-from rpython.jit.metainterp.resoperation import ResOperation, rop
+from rpython.jit.metainterp.resoperation import ResOperation, rop, OpHelpers
from rpython.jit.metainterp.history import TargetToken, JitCellToken
class OptSimplify(Optimization):
@@ -15,9 +15,9 @@
Optimization.emit_operation(self, op)
def optimize_CALL_PURE_I(self, op):
- args = op.getarglist()
- self.emit_operation(ResOperation(rop.CALL, args, op.result,
- op.getdescr()))
+ opnum = OpHelpers.call_for_descr(op.getdescr())
+ newop = self.optimizer.replace_op_with(op, opnum)
+ self.emit_operation(newop)
optimize_CALL_PURE_R = optimize_CALL_PURE_I
optimize_CALL_PURE_F = optimize_CALL_PURE_I
optimize_CALL_PURE_N = optimize_CALL_PURE_I
diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py
--- a/rpython/jit/metainterp/pyjitpl.py
+++ b/rpython/jit/metainterp/pyjitpl.py
@@ -157,13 +157,13 @@
return env
def replace_active_box_in_frame(self, oldbox, newbox):
- if isinstance(oldbox, history.BoxInt):
+ if oldbox.type == 'i':
count = self.jitcode.num_regs_i()
registers = self.registers_i
- elif isinstance(oldbox, history.BoxPtr):
+ elif oldbox.type == 'r':
count = self.jitcode.num_regs_r()
registers = self.registers_r
- elif isinstance(oldbox, history.BoxFloat):
+ elif oldbox.type == 'f':
count = self.jitcode.num_regs_f()
registers = self.registers_f
else:
@@ -377,7 +377,7 @@
if not isinstance(box, Const):
self.metainterp.generate_guard(rop.GUARD_ISNULL, box,
resumepc=orgpc)
- promoted_box = box.constbox()
+ promoted_box = executor.constant_from_op(box)
self.metainterp.replace_box(box, promoted_box)
return value
@@ -440,23 +440,30 @@
if tobox:
# sanity check: see whether the current array value
# corresponds to what the cache thinks the value is
+ xxx
resbox = executor.execute(self.metainterp.cpu, self.metainterp, op,
arraydescr, arraybox, indexbox)
assert resbox.constbox().same_constant(tobox.constbox())
return tobox
- resbox = self.execute_with_descr(op, arraydescr, arraybox, indexbox)
+ resop = self.execute_with_descr(op, arraydescr, arraybox, indexbox)
self.metainterp.heapcache.getarrayitem_now_known(
- arraybox, indexbox, resbox, arraydescr)
- return resbox
+ arraybox, indexbox, resop, arraydescr)
+ return resop
@arguments("box", "box", "descr")
- def _opimpl_getarrayitem_gc_any(self, arraybox, indexbox, arraydescr):
- return self._do_getarrayitem_gc_any(rop.GETARRAYITEM_GC, arraybox,
+ def opimpl_getarrayitem_gc_i(self, arraybox, indexbox, arraydescr):
+ return self._do_getarrayitem_gc_any(rop.GETARRAYITEM_GC_I, arraybox,
indexbox, arraydescr)
- opimpl_getarrayitem_gc_i = _opimpl_getarrayitem_gc_any
- opimpl_getarrayitem_gc_r = _opimpl_getarrayitem_gc_any
- opimpl_getarrayitem_gc_f = _opimpl_getarrayitem_gc_any
+ @arguments("box", "box", "descr")
+ def opimpl_getarrayitem_gc_r(self, arraybox, indexbox, arraydescr):
+ return self._do_getarrayitem_gc_any(rop.GETARRAYITEM_GC_R, arraybox,
+ indexbox, arraydescr)
+
+ @arguments("box", "box", "descr")
+ def opimpl_getarrayitem_gc_f(self, arraybox, indexbox, arraydescr):
+ return self._do_getarrayitem_gc_any(rop.GETARRAYITEM_GC_F, arraybox,
+ indexbox, arraydescr)
@arguments("box", "box", "descr")
def _opimpl_getarrayitem_raw_any(self, arraybox, indexbox, arraydescr):
@@ -476,20 +483,40 @@
opimpl_getarrayitem_raw_f_pure = _opimpl_getarrayitem_raw_pure_any
@arguments("box", "box", "descr")
- def _opimpl_getarrayitem_gc_pure_any(self, arraybox, indexbox, arraydescr):
+ def opimpl_getarrayitem_gc_i_pure(self, arraybox, indexbox, arraydescr):
if isinstance(arraybox, ConstPtr) and isinstance(indexbox, ConstInt):
# if the arguments are directly constants, bypass the heapcache
# completely
- resbox = executor.execute(self.metainterp.cpu, self.metainterp,
- rop.GETARRAYITEM_GC_PURE, arraydescr,
+ val = executor.execute(self.metainterp.cpu, self.metainterp,
+ rop.GETARRAYITEM_GC_PURE_I, arraydescr,
arraybox, indexbox)
- return resbox.constbox()
- return self._do_getarrayitem_gc_any(rop.GETARRAYITEM_GC_PURE, arraybox,
- indexbox, arraydescr)
+ return executor.wrap_constant(val)
+ return self._do_getarrayitem_gc_any(rop.GETARRAYITEM_GC_PURE_I,
+ arraybox, indexbox, arraydescr)
- opimpl_getarrayitem_gc_i_pure = _opimpl_getarrayitem_gc_pure_any
- opimpl_getarrayitem_gc_r_pure = _opimpl_getarrayitem_gc_pure_any
- opimpl_getarrayitem_gc_f_pure = _opimpl_getarrayitem_gc_pure_any
+ @arguments("box", "box", "descr")
+ def opimpl_getarrayitem_gc_f_pure(self, arraybox, indexbox, arraydescr):
+ if isinstance(arraybox, ConstPtr) and isinstance(indexbox, ConstInt):
+ # if the arguments are directly constants, bypass the heapcache
+ # completely
+ resval = executor.execute(self.metainterp.cpu, self.metainterp,
+ rop.GETARRAYITEM_GC_PURE_F, arraydescr,
+ arraybox, indexbox)
+ return executor.wrap_constant(resval)
+ return self._do_getarrayitem_gc_any(rop.GETARRAYITEM_GC_PURE_F,
+ arraybox, indexbox, arraydescr)
+
+ @arguments("box", "box", "descr")
+ def opimpl_getarrayitem_gc_r_pure(self, arraybox, indexbox, arraydescr):
+ if isinstance(arraybox, ConstPtr) and isinstance(indexbox, ConstInt):
+ # if the arguments are directly constants, bypass the heapcache
+ # completely
+ val = executor.execute(self.metainterp.cpu, self.metainterp,
+ rop.GETARRAYITEM_GC_PURE_R, arraydescr,
+ arraybox, indexbox)
+ return executor.wrap_constant(val)
+ return self._do_getarrayitem_gc_any(rop.GETARRAYITEM_GC_PURE_R,
+ arraybox, indexbox, arraydescr)
@arguments("box", "box", "box", "descr")
def _opimpl_setarrayitem_gc_any(self, arraybox, indexbox, itembox,
@@ -1355,7 +1382,7 @@
if isinstance(box, Const):
return box # no promotion needed, already a Const
else:
- promoted_box = box.constbox()
+ promoted_box = executor.constant_from_op(box)
self.metainterp.generate_guard(rop.GUARD_VALUE, box, [promoted_box],
resumepc=orgpc)
self.metainterp.replace_box(box, promoted_box)
@@ -1375,20 +1402,20 @@
@specialize.arg(1)
def execute_varargs(self, opnum, argboxes, descr, exc, pure):
self.metainterp.clear_exception()
- resbox = self.metainterp.execute_and_record_varargs(opnum, argboxes,
+ op = self.metainterp.execute_and_record_varargs(opnum, argboxes,
descr=descr)
- if pure and self.metainterp.last_exc_value_box is None and resbox:
- resbox = self.metainterp.record_result_of_call_pure(resbox)
- exc = exc and not isinstance(resbox, Const)
+ if pure and self.metainterp.last_exc_value_box is None and op:
+ op = self.metainterp.record_result_of_call_pure(op)
+ exc = exc and not isinstance(op, Const)
if exc:
- if resbox is not None:
- self.make_result_of_lastop(resbox)
+ if op is not None:
+ self.make_result_of_lastop(op)
# ^^^ this is done before handle_possible_exception() because we
# need the box to show up in get_list_of_active_boxes()
self.metainterp.handle_possible_exception()
else:
self.metainterp.assert_no_exception()
- return resbox
+ return op
def _build_allboxes(self, funcbox, argboxes, descr):
allboxes = [None] * (len(argboxes)+1)
@@ -2158,10 +2185,9 @@
for i in range(endindex):
box = boxes[i]
if isinstance(box, Const) or box in duplicates:
- oldbox = box
- box = oldbox.clonebox()
- boxes[i] = box
- self.history.record(rop.SAME_AS, [oldbox], box)
+ opnum = OpHelpers.same_as_for_type(box.type)
+ op = self.history.record_default_val(opnum, [box])
+ boxes[i] = op
else:
duplicates[box] = None
@@ -2708,7 +2734,6 @@
None, descr=vinfo.vable_token_descr)
def replace_box(self, oldbox, newbox):
- assert isinstance(oldbox, Box)
for frame in self.framestack:
frame.replace_active_box_in_frame(oldbox, newbox)
boxes = self.virtualref_boxes
@@ -2745,12 +2770,12 @@
max_key = key
return max_key
- def record_result_of_call_pure(self, resbox):
+ def record_result_of_call_pure(self, op):
""" Patch a CALL into a CALL_PURE.
"""
- op = self.history.operations[-1]
- assert op.getopnum() == rop.CALL
- resbox_as_const = resbox.constbox()
+ opnum = op.getopnum()
+ assert opnum in [rop.CALL_R, rop.CALL_N, rop.CALL_I, rop.CALL_F]
+ resbox_as_const = executor.constant_from_op(op)
for i in range(op.numargs()):
if not isinstance(op.getarg(i), Const):
break
@@ -2761,11 +2786,12 @@
return resbox_as_const
# not all constants (so far): turn CALL into CALL_PURE, which might
# be either removed later by optimizeopt or turned back into CALL.
- arg_consts = [a.constbox() for a in op.getarglist()]
+ arg_consts = [executor.constant_from_op(a) for a in op.getarglist()]
self.call_pure_results[arg_consts] = resbox_as_const
- newop = op.copy_and_change(rop.CALL_PURE, args=op.getarglist())
+ opnum = OpHelpers.call_pure_for_descr(op.getdescr())
+ newop = op._copy_and_change(opnum, args=op.getarglist())
self.history.operations[-1] = newop
- return resbox
+ return newop
def direct_assembler_call(self, targetjitdriver_sd):
""" Generate a direct call to assembler for portal entry point,
diff --git a/rpython/jit/metainterp/resoperation.py b/rpython/jit/metainterp/resoperation.py
--- a/rpython/jit/metainterp/resoperation.py
+++ b/rpython/jit/metainterp/resoperation.py
@@ -1,6 +1,7 @@
from rpython.rlib.objectmodel import we_are_translated, specialize
from rpython.rlib.objectmodel import compute_identity_hash
from rpython.rtyper.lltypesystem import lltype, llmemory
+from rpython.jit.codewriter import longlong
class AbstractValue(object):
def _get_hash_(self):
@@ -303,6 +304,9 @@
def copy_value_from(self, other):
self.setint(other.getint())
+ def nonnull(self):
+ return self._resint != 0
+
class FloatOp(object):
_mixin_ = True
@@ -319,6 +323,9 @@
def copy_value_from(self, other):
self.setfloatstorage(other.getfloatstorage())
+ def nonnull(self):
+ return bool(longlong.extract_bits(self._resfloat))
+
class RefOp(object):
_mixin_ = True
@@ -335,6 +342,9 @@
def copy_value_from(self, other):
self.setref_base(other.getref_base())
+ def nonnull(self):
+ return bool(self._resref)
+
class AbstractInputArg(AbstractValue):
def repr(self, memo):
try:
@@ -880,3 +890,41 @@
return rop.CALL_F
assert tp == 'v'
return rop.CALL_N
+
+ @staticmethod
+ def call_pure_for_descr(descr):
+ tp = descr.get_result_type()
+ if tp == 'i':
+ return rop.CALL_PURE_I
+ elif tp == 'r':
+ return rop.CALL_PURE_R
+ elif tp == 'f':
+ return rop.CALL_PURE_F
+ assert tp == 'v'
+ return rop.CALL_PURE_N
+
+ @staticmethod
+ def getfield_pure_for_descr(descr):
+ if descr.is_pointer_field():
+ return rop.GETFIELD_GC_PURE_R
+ elif descr.is_float_field():
+ return rop.GETFIELD_GC_PURE_F
+ return rop.GETFIELD_GC_PURE_I
+
+ @staticmethod
+ def getarrayitem_pure_for_descr(descr):
+ if descr.is_array_of_pointers():
+ return rop.GETARRAYITEM_GC_PURE_R
+ elif descr.is_array_of_floats():
+ return rop.GETARRAYITEM_GC_PURE_F
+ return rop.GETARRAYITEM_GC_PURE_I
+
+ @staticmethod
+ def same_as_for_type(tp):
+ if tp == 'i':
+ return rop.SAME_AS_I
+ elif tp == 'r':
+ return rop.SAME_AS_R
+ else:
+ assert tp == 'f'
+ return rop.SAME_AS_F
diff --git a/rpython/jit/metainterp/test/test_loop.py b/rpython/jit/metainterp/test/test_loop.py
--- a/rpython/jit/metainterp/test/test_loop.py
+++ b/rpython/jit/metainterp/test/test_loop.py
@@ -191,8 +191,8 @@
if op.getopname() == 'guard_true':
liveboxes = op.getfailargs()
assert len(liveboxes) == 2 # x, y (in some order)
- assert isinstance(liveboxes[0], history.BoxInt)
- assert isinstance(liveboxes[1], history.BoxInt)
+ assert liveboxes[0].type == 'i'
+ assert liveboxes[1].type == 'i'
found += 1
if 'unroll' in self.enable_opts:
assert found == 2
diff --git a/rpython/jit/metainterp/typesystem.py b/rpython/jit/metainterp/typesystem.py
--- a/rpython/jit/metainterp/typesystem.py
+++ b/rpython/jit/metainterp/typesystem.py
@@ -66,7 +66,8 @@
return llmemory.cast_ptr_to_adr(fnptr)
def cls_of_box(self, box):
- obj = box.getref(lltype.Ptr(rclass.OBJECT))
+ PTR = lltype.Ptr(rclass.OBJECT)
+ obj = lltype.cast_opaque_ptr(PTR, box.getref_base())
cls = llmemory.cast_ptr_to_adr(obj.typeptr)
return history.ConstInt(heaptracker.adr2int(cls))
More information about the pypy-commit
mailing list