Author: Maciej Fijalkowski <[email protected]>
Branch: result-in-resops
Changeset: r57481:d72856f2e3a4
Date: 2012-09-23 18:03 +0200
http://bitbucket.org/pypy/pypy/changeset/d72856f2e3a4/
Log: hack enough to pass the overflow propagation. I think by now the op
propagation is done correctly.
diff --git a/pypy/jit/metainterp/optimizeopt/intbounds.py
b/pypy/jit/metainterp/optimizeopt/intbounds.py
--- a/pypy/jit/metainterp/optimizeopt/intbounds.py
+++ b/pypy/jit/metainterp/optimizeopt/intbounds.py
@@ -113,6 +113,7 @@
# nonneg % power-of-two ==> nonneg & (power-of-two - 1)
arg1 = op.getarg(0)
arg2 = ConstInt(val-1)
+ xxx
op = op.copy_and_change(rop.INT_AND, args=[arg1, arg2])
self.emit_operation(op)
if v2.is_constant():
@@ -202,7 +203,7 @@
# Transform into INT_ADD. The following guard will be killed
# by optimize_GUARD_NO_OVERFLOW; if we see instead an
# optimize_GUARD_OVERFLOW, then InvalidLoop.
- op = op.copy_and_change(rop.INT_ADD)
+ op = self.optimizer.copy_and_change(op, rop.INT_ADD)
self.emit_operation(op) # emit the op
r = self.getvalue(op)
r.intbound.intersect(resbound)
@@ -212,6 +213,7 @@
v2 = self.getvalue(op.getarg(1))
resbound = v1.intbound.sub_bound(v2.intbound)
if resbound.bounded():
+ xxx
op = op.copy_and_change(rop.INT_SUB)
self.emit_operation(op) # emit the op
r = self.getvalue(op)
@@ -222,6 +224,7 @@
v2 = self.getvalue(op.getarg(1))
resbound = v1.intbound.mul_bound(v2.intbound)
if resbound.bounded():
+ xxx
op = op.copy_and_change(rop.INT_MUL)
self.emit_operation(op)
r = self.getvalue(op)
diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py
b/pypy/jit/metainterp/optimizeopt/optimizer.py
--- a/pypy/jit/metainterp/optimizeopt/optimizer.py
+++ b/pypy/jit/metainterp/optimizeopt/optimizer.py
@@ -6,7 +6,7 @@
IntLowerBound, MININT,
MAXINT
from pypy.jit.metainterp.optimizeopt.util import make_dispatcher_method
from pypy.jit.metainterp.resoperation import rop, AbstractResOp, opgroups,\
- Const, ConstInt, ConstFloat
+ Const, ConstInt, ConstFloat, AbstractValue
from pypy.jit.metainterp.typesystem import llhelper
from pypy.rlib.objectmodel import specialize
@@ -29,13 +29,14 @@
return LenBound(self.mode, self.descr, self.bound.clone())
class OptValue(object):
- _attrs_ = ('box', 'known_class', 'last_guard', 'level', 'intbound',
'lenbound')
+ _attrs_ = ('box', 'known_class', 'last_guard', 'level', 'intbound',
'lenbound', 'is_bool_box')
last_guard = None
level = LEVEL_UNKNOWN
known_class = None
intbound = ImmutableIntUnbounded()
lenbound = None
+ is_bool_box = False
def __init__(self, box, level=None, known_class=None, intbound=None):
self.box = box
@@ -282,8 +283,8 @@
def make_constant_int(self, box, intconst):
return self.optimizer.make_constant_int(box, intconst)
- def make_equal_to(self, box, value):
- return self.optimizer.make_equal_to(box, value)
+ def replace(self, box, value):
+ return self.optimizer.replace(box, value)
def get_constant_box(self, box):
return self.optimizer.get_constant_box(box)
@@ -348,7 +349,6 @@
self.interned_refs = self.cpu.ts.new_ref_dict()
self.interned_ints = {}
self.resumedata_memo = resume.ResumeDataLoopMemo(metainterp_sd)
- self.bool_boxes = {}
self.pendingfields = []
self.quasi_immutable_deps = None
self.opaque_pointers = {}
@@ -437,6 +437,19 @@
self.ensure_imported(value)
return value
+ def copy_op_if_modified_by_optimization(self, op):
+ new_op = op.copy_if_modified_by_optimization(self)
+ if new_op is not op:
+ self.replace(op, new_op)
+ return new_op
+
+ @specialize.arg(2)
+ def copy_and_change(self, op, opnum, *args, **kwds):
+ new_op = op.copy_and_change(opnum, *args, **kwds)
+ if new_op is not op:
+ self.replace(op, new_op)
+ return new_op
+
def ensure_imported(self, value):
pass
@@ -462,17 +475,18 @@
def clear_newoperations(self):
self._newoperations = []
- def make_equal_to(self, box, value, replace=False):
- assert isinstance(value, OptValue)
- if replace:
- assert not box.has_extra("optimize_value")
- box.set_extra("optimize_value", value)
+ def replace(self, what, with_):
+ assert isinstance(what, AbstractValue)
+ assert isinstance(with_, AbstractValue)
+ val = self.getvalue(with_)
+ # completely remove the old optimize value
+ what.set_extra("optimize_value", val)
def make_constant(self, box, constbox):
- self.make_equal_to(box, ConstantValue(constbox))
+ self.getvalue(box).make_constant(constbox)
def make_constant_int(self, box, intvalue):
- self.make_constant(box, ConstInt(intvalue))
+ self.getvalue(box).make_constant(ConstInt(intvalue))
def new_ptr_box(self):
return self.cpu.ts.BoxRef()
@@ -531,7 +545,7 @@
def emit_operation(self, op):
if op.returns_bool_result():
- self.bool_boxes[self.getvalue(op)] = None
+ self.getvalue(op).is_bool_box = True
self._emit_operation(op)
def get_value_replacement(self, v):
@@ -549,7 +563,7 @@
@specialize.argtype(0)
def _emit_operation(self, op):
assert op.getopnum() not in opgroups.CALL_PURE
- op = op.copy_if_modified_by_optimization(self)
+ op = self.copy_op_if_modified_by_optimization(op)
if isinstance(op, Const):
return
self.metainterp_sd.profiler.count(jitprof.Counters.OPT_OPS)
@@ -579,6 +593,7 @@
def store_final_boxes_in_guard(self, op):
if op.getdescr() is not None:
# means we need to copy the op and attach a new descr
+ xxx
op = op.copy_and_change(op.getopnum(), descr=None)
descr = op.invent_descr()
modifier = resume.ResumeDataVirtualAdder(descr, self.resumedata_memo)
@@ -591,7 +606,7 @@
descr.store_final_boxes(op, newboxes)
#
if op.getopnum() == rop.GUARD_VALUE:
- if self.getvalue(op.getarg(0)) in self.bool_boxes:
+ if self.getvalue(op.getarg(0)).is_bool_box:
# Hack: turn guard_value(bool) into guard_true/guard_false.
# This is done after the operation is emitted to let
# store_final_boxes_in_guard set the guard_opnum field of the
diff --git a/pypy/jit/metainterp/optimizeopt/pure.py
b/pypy/jit/metainterp/optimizeopt/pure.py
--- a/pypy/jit/metainterp/optimizeopt/pure.py
+++ b/pypy/jit/metainterp/optimizeopt/pure.py
@@ -51,7 +51,7 @@
# otherwise, the operation remains
self.emit_operation(op)
if op.returns_bool_result():
- self.optimizer.bool_boxes[self.getvalue(op)] = None
+ self.getvalue(op).is_bool_box = True
if nextop:
self.emit_operation(nextop)
diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py
b/pypy/jit/metainterp/optimizeopt/rewrite.py
--- a/pypy/jit/metainterp/optimizeopt/rewrite.py
+++ b/pypy/jit/metainterp/optimizeopt/rewrite.py
@@ -133,6 +133,7 @@
# x & (x - 1) == 0 is a quick test for power of 2
if x & (x - 1) == 0:
new_rhs = ConstInt(highest_bit(lhs.box.getint()))
+ xxx
op = op.copy_and_change(rop.INT_LSHIFT, args=[rhs.box,
new_rhs])
break
self.emit_operation(op)
@@ -240,6 +241,7 @@
assert expected_classbox is not None
if not previous_classbox.same_constant(expected_classbox):
raise InvalidLoop('A GUARD_VALUE was proven to always
fail')
+ xxx
op = old_guard_op.copy_and_change(rop.GUARD_VALUE,
args = [old_guard_op.getarg(0),
op.getarg(1)])
self.optimizer.replaces_guard[op] = old_guard_op
@@ -288,6 +290,7 @@
if old_guard_op.getopnum() == rop.GUARD_NONNULL:
# it was a guard_nonnull, which we replace with a
# guard_nonnull_class.
+ xxx
op = old_guard_op.copy_and_change (rop.GUARD_NONNULL_CLASS,
args = [old_guard_op.getarg(0),
op.getarg(1)])
self.optimizer.replaces_guard[op] = old_guard_op
@@ -322,6 +325,7 @@
# change the op to be a normal call, from the backend's point of view
# there is no reason to have a separate operation for this
self.loop_invariant_producer[key] = op
+ xxx
op = op.copy_and_change(rop.CALL)
self.emit_operation(op)
resvalue = self.getvalue(op)
@@ -340,7 +344,7 @@
self.emit_operation(op)
def optimize_INT_IS_TRUE(self, op):
- if self.getvalue(op.getarg(0)) in self.optimizer.bool_boxes:
+ if self.getvalue(op.getarg(0)).is_bool_box:
self.make_equal_to(op, self.getvalue(op.getarg(0)))
return
self._optimize_nullness(op, op.getarg(0), True)
@@ -487,6 +491,7 @@
if v1.intbound.known_ge(IntBound(0, 0)) and v2.is_constant():
val = v2.box.getint()
if val & (val - 1) == 0 and val > 0: # val == 2**shift
+ xxx
op = op.copy_and_change(rop.INT_RSHIFT,
args = [op.getarg(0),
ConstInt(highest_bit(val))])
self.emit_operation(op)
diff --git a/pypy/jit/metainterp/optimizeopt/simplify.py
b/pypy/jit/metainterp/optimizeopt/simplify.py
--- a/pypy/jit/metainterp/optimizeopt/simplify.py
+++ b/pypy/jit/metainterp/optimizeopt/simplify.py
@@ -10,6 +10,7 @@
def _new_optimize_call(tp):
def optimize_call(self, op):
+ xxx
self.emit_operation(op.copy_and_change(getattr(rop, 'CALL_' + tp)))
optimize_CALL_PURE_i = _new_optimize_call('i')
optimize_CALL_PURE_f = _new_optimize_call('f')
@@ -39,6 +40,7 @@
if not self.unroll:
descr = op.getdescr()
if isinstance(descr, JitCellToken):
+ xxx
return self.optimize_JUMP(op.copy_and_change(rop.JUMP))
self.last_label_descr = op.getdescr()
self.emit_operation(op)
@@ -58,7 +60,8 @@
assert len(descr.target_tokens) == 1
newdescr = descr.target_tokens[0]
if newdescr is not descr or op.opnum != rop.JUMP:
- op = op.copy_and_change(op.opnum, descr=newdescr)
+ op = self.optimizer.copy_and_change(op, op.opnum,
+ descr=newdescr)
self.emit_operation(op)
dispatch_opt = make_dispatcher_method(OptSimplify, 'optimize_',
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
@@ -1036,8 +1036,12 @@
new_arg = opt.get_value_replacement(self._arg0)
if new_arg is None:
return self
- return create_resop_1(self.opnum, self.getresult(), new_arg,
- self.getdescr())
+ res = create_resop_1(self.opnum, self.getresult(), new_arg,
+ self.getdescr())
+ if self.is_guard():
+ res.set_rd_frame_info_list(self.get_rd_frame_info_list())
+ res.set_rd_snapshot(self.get_rd_snapshot())
+ return res
@specialize.arg(1)
def copy_and_change(self, newopnum, arg0=None, descr=None):
@@ -1091,10 +1095,14 @@
new_arg1 = opt.get_value_replacement(self._arg1)
if new_arg0 is None and new_arg1 is None:
return self
- return create_resop_2(self.opnum, self.getresult(),
- new_arg0 or self._arg0,
- new_arg1 or self._arg1,
- self.getdescr())
+ res = create_resop_2(self.opnum, self.getresult(),
+ new_arg0 or self._arg0,
+ new_arg1 or self._arg1,
+ self.getdescr())
+ if self.is_guard():
+ res.set_rd_frame_info_list(self.get_rd_frame_info_list())
+ res.set_rd_snapshot(self.get_rd_snapshot())
+ return res
@specialize.arg(1)
def copy_and_change(self, newopnum, arg0=None, arg1=None, descr=None):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit