[pypy-commit] pypy unrecursive-opt: All the rest of the unrecursion.
jerith
noreply at buildbot.pypy.org
Mon Oct 12 11:31:10 CEST 2015
Author: Jeremy Thurgood <firxen at gmail.com>
Branch: unrecursive-opt
Changeset: r80125:9945934d8515
Date: 2015-10-12 11:03 +0200
http://bitbucket.org/pypy/pypy/changeset/9945934d8515/
Log: All the rest of the unrecursion.
diff --git a/rpython/jit/metainterp/optimizeopt/earlyforce.py b/rpython/jit/metainterp/optimizeopt/earlyforce.py
--- a/rpython/jit/metainterp/optimizeopt/earlyforce.py
+++ b/rpython/jit/metainterp/optimizeopt/earlyforce.py
@@ -26,7 +26,10 @@
for arg in op.getarglist():
self.optimizer.force_box(arg, self)
- self.emit_operation(op)
+ return self.emit(op)
+
+ def propagate_postprocess(self, op, oldop):
+ pass
def setup(self):
self.optimizer.optearlyforce = self
diff --git a/rpython/jit/metainterp/optimizeopt/heap.py b/rpython/jit/metainterp/optimizeopt/heap.py
--- a/rpython/jit/metainterp/optimizeopt/heap.py
+++ b/rpython/jit/metainterp/optimizeopt/heap.py
@@ -144,7 +144,7 @@
if a is optheap.postponed_op:
optheap.emit_postponed_op()
break
- optheap.next_optimization.propagate_forward(op)
+ optheap.emit_extra(op, emit=False)
if not can_cache:
return
# Once it is done, we can put at least one piece of information
@@ -228,7 +228,7 @@
if self.postponed_op:
postponed_op = self.postponed_op
self.postponed_op = None
- self.next_optimization.propagate_forward(postponed_op)
+ self.emit_extra(postponed_op, emit=False)
def produce_potential_short_preamble_ops(self, sb):
descrkeys = self.cached_fields.keys()
@@ -288,14 +288,14 @@
cf = submap[index] = ArrayCachedField(index)
return cf
- def emit_operation(self, op):
+ def emit(self, op, callback_func=None, *callback_args):
self.emitting_operation(op)
self.emit_postponed_op()
if (op.is_comparison() or op.is_call_may_force()
or op.is_ovf()):
self.postponed_op = op
else:
- Optimization.emit_operation(self, op)
+ return Optimization.emit(self, op, callback_func, *callback_args)
def emitting_operation(self, op):
if op.has_no_side_effect():
@@ -344,7 +344,7 @@
if oopspecindex == EffectInfo.OS_DICT_LOOKUP:
if self._optimize_CALL_DICT_LOOKUP(op):
return
- self.emit_operation(op)
+ return self.emit(op)
optimize_CALL_F = optimize_CALL_I
optimize_CALL_R = optimize_CALL_I
optimize_CALL_N = optimize_CALL_I
@@ -402,7 +402,7 @@
def optimize_GUARD_NO_EXCEPTION(self, op):
if self.last_emitted_operation is REMOVED:
return
- self.emit_operation(op)
+ return self.emit(op)
optimize_GUARD_EXCEPTION = optimize_GUARD_NO_EXCEPTION
@@ -499,15 +499,20 @@
return
# default case: produce the operation
self.make_nonnull(op.getarg(0))
- self.emit_operation(op)
- self.optimize_GETFIELD_GC_I_callback(op, structinfo, cf)
+ # return self.emit(op)
+ return self.emit(op)
- def optimize_GETFIELD_GC_I_callback(self, op, structinfo, cf):
+ def postprocess_GETFIELD_GC_I(self, op, oldop):
# then remember the result of reading the field
+ structinfo = self.ensure_ptr_info_arg0(op)
+ cf = self.field_cache(op.getdescr())
structinfo.setfield(op.getdescr(), op.getarg(0), op, self, cf)
optimize_GETFIELD_GC_R = optimize_GETFIELD_GC_I
optimize_GETFIELD_GC_F = optimize_GETFIELD_GC_I
+ postprocess_GETFIELD_GC_R = postprocess_GETFIELD_GC_I
+ postprocess_GETFIELD_GC_F = postprocess_GETFIELD_GC_I
+
def optimize_GETFIELD_GC_PURE_I(self, op):
structinfo = self.ensure_ptr_info_arg0(op)
cf = self.field_cache(op.getdescr())
@@ -517,7 +522,7 @@
return
# default case: produce the operation
self.make_nonnull(op.getarg(0))
- self.emit_operation(op)
+ return self.emit(op)
optimize_GETFIELD_GC_PURE_R = optimize_GETFIELD_GC_PURE_I
optimize_GETFIELD_GC_PURE_F = optimize_GETFIELD_GC_PURE_I
@@ -554,12 +559,16 @@
self.getintbound(op.getarg(1)))
# default case: produce the operation
self.make_nonnull(op.getarg(0))
- self.emit_operation(op)
- self.optimize_GETARRAYITEM_GC_I_callback(op, cf, arrayinfo, indexb)
+ # return self.emit(op)
+ return self.emit(op)
- def optimize_GETARRAYITEM_GC_I_callback(self, op, cf, arrayinfo, indexb):
+ def postprocess_GETARRAYITEM_GC_I(self, op, oldop):
# the remember the result of reading the array item
- if cf is not None:
+ arrayinfo = self.ensure_ptr_info_arg0(op)
+ indexb = self.getintbound(op.getarg(1))
+ if indexb.is_constant():
+ index = indexb.getint()
+ cf = self.arrayitem_cache(op.getdescr(), index)
arrayinfo.setitem(op.getdescr(), indexb.getint(),
self.get_box_replacement(op.getarg(0)),
self.get_box_replacement(op), cf,
@@ -567,6 +576,9 @@
optimize_GETARRAYITEM_GC_R = optimize_GETARRAYITEM_GC_I
optimize_GETARRAYITEM_GC_F = optimize_GETARRAYITEM_GC_I
+ postprocess_GETARRAYITEM_GC_R = postprocess_GETARRAYITEM_GC_I
+ postprocess_GETARRAYITEM_GC_F = postprocess_GETARRAYITEM_GC_I
+
def optimize_GETARRAYITEM_GC_PURE_I(self, op):
arrayinfo = self.ensure_ptr_info_arg0(op)
indexb = self.getintbound(op.getarg(1))
@@ -585,7 +597,7 @@
self.force_lazy_setarrayitem(op.getdescr(), self.getintbound(op.getarg(1)))
# default case: produce the operation
self.make_nonnull(op.getarg(0))
- self.emit_operation(op)
+ return self.emit(op)
optimize_GETARRAYITEM_GC_PURE_R = optimize_GETARRAYITEM_GC_PURE_I
optimize_GETARRAYITEM_GC_PURE_F = optimize_GETARRAYITEM_GC_PURE_I
@@ -609,7 +621,7 @@
# variable index, so make sure the lazy setarrayitems are done
self.force_lazy_setarrayitem(op.getdescr(), indexb, can_cache=False)
# and then emit the operation
- self.emit_operation(op)
+ return self.emit(op)
def optimize_QUASIIMMUT_FIELD(self, op):
# Pattern: QUASIIMMUT_FIELD(s, descr=QuasiImmutDescr)
@@ -647,9 +659,11 @@
if self._seen_guard_not_invalidated:
return
self._seen_guard_not_invalidated = True
- self.emit_operation(op)
+ return self.emit(op)
dispatch_opt = make_dispatcher_method(OptHeap, 'optimize_',
- default=OptHeap.emit_operation)
+ default=OptHeap.emit)
OptHeap.propagate_forward = dispatch_opt
+dispatch_postprocess = make_dispatcher_method(OptHeap, 'postprocess_')
+OptHeap.propagate_postprocess = dispatch_postprocess
diff --git a/rpython/jit/metainterp/optimizeopt/info.py b/rpython/jit/metainterp/optimizeopt/info.py
--- a/rpython/jit/metainterp/optimizeopt/info.py
+++ b/rpython/jit/metainterp/optimizeopt/info.py
@@ -141,7 +141,7 @@
return constptr
#
op.set_forwarded(None)
- optforce.emit_operation(op)
+ optforce.emit_extra(op)
newop = optforce.getlastop()
op.set_forwarded(newop)
newop.set_forwarded(self)
@@ -218,7 +218,7 @@
setfieldop = ResOperation(rop.SETFIELD_GC, [op, subbox],
descr=flddescr)
self._fields[i] = None
- optforce.emit_operation(setfieldop)
+ optforce.emit_extra(setfieldop)
def _force_at_the_end_of_preamble(self, op, optforce, rec):
if self._fields is None:
@@ -406,7 +406,7 @@
itembox = buffer.values[i]
setfield_op = ResOperation(rop.RAW_STORE,
[op, ConstInt(offset), itembox], descr=descr)
- optforce.emit_operation(setfield_op)
+ optforce.emit_extra(setfield_op)
def _visitor_walk_recursive(self, op, visitor, optimizer):
itemboxes = [optimizer.get_box_replacement(box)
@@ -519,7 +519,7 @@
[op, ConstInt(i), subbox],
descr=descr)
self._items[i] = None
- optforce.emit_operation(setop)
+ optforce.emit_extra(setop)
optforce.pure_from_args(rop.ARRAYLEN_GC, [op], ConstInt(len(self._items)))
def setitem(self, descr, index, struct, op, cf=None, optheap=None):
@@ -632,7 +632,7 @@
setfieldop = ResOperation(rop.SETINTERIORFIELD_GC,
[op, ConstInt(index), subbox],
descr=flddescr)
- optforce.emit_operation(setfieldop)
+ optforce.emit_extra(setfieldop)
# heapcache does not work for interiorfields
# if it does, we would need a fix here
i += 1
diff --git a/rpython/jit/metainterp/optimizeopt/intbounds.py b/rpython/jit/metainterp/optimizeopt/intbounds.py
--- a/rpython/jit/metainterp/optimizeopt/intbounds.py
+++ b/rpython/jit/metainterp/optimizeopt/intbounds.py
@@ -42,9 +42,6 @@
"""Keeps track of the bounds placed on integers by guards and remove
redundant guards"""
- def opt_default(self, op):
- return op
-
def propagate_forward(self, op):
return dispatch_opt(self, op)
@@ -63,7 +60,7 @@
dispatch_bounds_ops(self, box)
def _optimize_guard_true_false_value(self, op):
- return op
+ return self.emit(op)
def _postprocess_guard_true_false_value(self, op, oldop):
if op.getarg(0).type == 'i':
@@ -86,7 +83,7 @@
else:
self.make_constant_int(op, 0)
return None
- return op
+ return self.emit(op)
def postprocess_INT_OR_or_XOR(self, op, oldop):
v1 = self.get_box_replacement(op.getarg(0))
@@ -106,7 +103,7 @@
postprocess_INT_XOR = postprocess_INT_OR_or_XOR
def optimize_INT_AND(self, op):
- return op
+ return self.emit(op)
def postprocess_INT_AND(self, op, oldop):
b1 = self.getintbound(op.getarg(0))
@@ -125,7 +122,7 @@
r.intersect(IntBound(0, next_pow2_m1(lesser)))
def optimize_INT_SUB(self, op):
- return op
+ return self.emit(op)
def postprocess_INT_SUB(self, op, oldop):
b1 = self.getintbound(op.getarg(0))
@@ -138,7 +135,7 @@
arg1 = self.get_box_replacement(op.getarg(0))
arg2 = self.get_box_replacement(op.getarg(1))
if self.is_raw_ptr(arg1) or self.is_raw_ptr(arg2):
- return op
+ return self.emit(op)
v1 = self.getintbound(arg1)
v2 = self.getintbound(arg2)
@@ -172,7 +169,7 @@
arg2 = ConstInt(sum)
op = self.replace_op_with(op, rop.INT_ADD, args=[arg1, arg2])
- return op
+ return self.emit(op)
def postprocess_INT_ADD(self, op, oldop):
b1 = self.getintbound(op.getarg(0))
@@ -183,7 +180,7 @@
r.intersect(b)
def optimize_INT_MUL(self, op):
- return op
+ return self.emit(op)
def postprocess_INT_MUL(self, op, oldop):
b1 = self.getintbound(op.getarg(0))
@@ -194,7 +191,7 @@
r.intersect(b)
def optimize_INT_FLOORDIV(self, op):
- return op
+ return self.emit(op)
def postprocess_INT_FLOORDIV(self, op, oldop):
b1 = self.getintbound(op.getarg(0))
@@ -215,7 +212,7 @@
arg2 = ConstInt(val-1)
op = self.replace_op_with(op, rop.INT_AND,
args=[arg1, arg2])
- return op
+ return self.emit(op)
def postprocess_INT_MOD(self, op, oldop):
b1 = self.getintbound(op.getarg(0))
@@ -236,7 +233,7 @@
r.make_lt(IntBound(val, val))
def optimize_INT_LSHIFT(self, op):
- return op
+ return self.emit(op)
def postprocess_INT_LSHIFT(self, op, oldop):
arg0 = self.get_box_replacement(op.getarg(0))
@@ -262,7 +259,7 @@
# constant result (likely 0, for rshifts that kill all bits)
self.make_constant_int(op, b.lower)
return None
- return op
+ return self.emit(op)
def postprocess_INT_RSHIFT(self, op, oldop):
b1 = self.getintbound(op.getarg(0))
@@ -295,7 +292,7 @@
self.pure_from_args(rop.INT_SUB, [args[0], result], args[1])
#elif opnum == rop.INT_MUL_OVF:
# self.pure(rop.INT_MUL, args[:], result)
- return op
+ return self.emit(op)
def optimize_GUARD_OVERFLOW(self, op):
# If INT_xxx_OVF was replaced by INT_xxx, *but* we still see
@@ -308,7 +305,7 @@
raise InvalidLoop('An INT_xxx_OVF was proven not to overflow but' +
'guarded with GUARD_OVERFLOW')
- return op
+ return self.emit(op)
def optimize_INT_ADD_OVF(self, op):
b1 = self.getintbound(op.getarg(0))
@@ -319,7 +316,7 @@
# by optimize_GUARD_NO_OVERFLOW; if we see instead an
# optimize_GUARD_OVERFLOW, then InvalidLoop.
op = self.replace_op_with(op, rop.INT_ADD)
- return op
+ return self.emit(op)
def postprocess_INT_ADD_OVF(self, op, oldop):
b1 = self.getintbound(op.getarg(0))
@@ -339,7 +336,7 @@
resbound = b0.sub_bound(b1)
if resbound.bounded():
op = self.replace_op_with(op, rop.INT_SUB)
- return op
+ return self.emit(op)
def postprocess_INT_SUB_OVF(self, op, oldop):
arg0 = self.get_box_replacement(op.getarg(0))
@@ -356,7 +353,7 @@
resbound = b1.mul_bound(b2)
if resbound.bounded():
op = self.replace_op_with(op, rop.INT_MUL)
- return op
+ return self.emit(op)
def postprocess_INT_MUL_OVF(self, op, oldop):
b1 = self.getintbound(op.getarg(0))
@@ -375,7 +372,7 @@
elif b1.known_ge(b2) or arg1 is arg2:
self.make_constant_int(op, 0)
else:
- return op
+ return self.emit(op)
def optimize_INT_GT(self, op):
arg1 = self.get_box_replacement(op.getarg(0))
@@ -387,7 +384,7 @@
elif b1.known_le(b2) or arg1 is arg2:
self.make_constant_int(op, 0)
else:
- return op
+ return self.emit(op)
def optimize_INT_LE(self, op):
arg1 = self.get_box_replacement(op.getarg(0))
@@ -399,7 +396,7 @@
elif b1.known_gt(b2):
self.make_constant_int(op, 0)
else:
- return op
+ return self.emit(op)
def optimize_INT_GE(self, op):
arg1 = self.get_box_replacement(op.getarg(0))
@@ -411,7 +408,7 @@
elif b1.known_lt(b2):
self.make_constant_int(op, 0)
else:
- return op
+ return self.emit(op)
def optimize_INT_EQ(self, op):
arg0 = self.get_box_replacement(op.getarg(0))
@@ -425,7 +422,7 @@
elif arg0.same_box(arg1):
self.make_constant_int(op, 1)
else:
- return op
+ return self.emit(op)
def optimize_INT_NE(self, op):
arg0 = self.get_box_replacement(op.getarg(0))
@@ -439,14 +436,14 @@
elif arg0 is arg1:
self.make_constant_int(op, 0)
else:
- return op
+ return self.emit(op)
def optimize_INT_FORCE_GE_ZERO(self, op):
b = self.getintbound(op.getarg(0))
if b.known_ge(IntBound(0, 0)):
self.make_equal_to(op, op.getarg(0))
else:
- return op
+ return self.emit(op)
def optimize_INT_SIGNEXT(self, op):
b = self.getintbound(op.getarg(0))
@@ -457,7 +454,7 @@
if bounds.contains_bound(b):
self.make_equal_to(op, op.getarg(0))
else:
- return op
+ return self.emit(op)
def postprocess_INT_SIGNEXT(self, op, oldop):
numbits = op.getarg(1).getint() * 8
@@ -468,14 +465,14 @@
bres.intersect(bounds)
def optimize_ARRAYLEN_GC(self, op):
- return op
+ return self.emit(op)
def postprocess_ARRAYLEN_GC(self, op, oldop):
array = self.ensure_ptr_info_arg0(op)
self.optimizer.setintbound(op, array.getlenbound(None))
def optimize_STRLEN(self, op):
- return op
+ return self.emit(op)
def postprocess_STRLEN(self, op, oldop):
self.make_nonnull_str(op.getarg(0), vstring.mode_string)
@@ -483,7 +480,7 @@
self.optimizer.setintbound(op, array.getlenbound(vstring.mode_string))
def optimize_UNICODELEN(self, op):
- return op
+ return self.emit(op)
def postprocess_UNICODELEN(self, op, oldop):
self.make_nonnull_str(op.getarg(0), vstring.mode_unicode)
@@ -491,7 +488,7 @@
self.optimizer.setintbound(op, array.getlenbound(vstring.mode_unicode))
def optimize_STRGETITEM(self, op):
- return op
+ return self.emit(op)
def postprocess_STRGETITEM(self, op, oldop):
v1 = self.getintbound(op)
@@ -505,7 +502,7 @@
v1.make_lt(IntUpperBound(256))
def optimize_GETFIELD_RAW_I(self, op):
- return op
+ return self.emit(op)
def postprocess_GETFIELD_RAW_I(self, op, oldop):
descr = op.getdescr()
@@ -535,7 +532,7 @@
postprocess_GETINTERIORFIELD_GC_F = postprocess_GETFIELD_RAW_I
def optimize_GETARRAYITEM_RAW_I(self, op):
- return op
+ return self.emit(op)
def postprocess_GETARRAYITEM_RAW_I(self, op, oldop):
descr = op.getdescr()
@@ -555,7 +552,7 @@
postprocess_GETARRAYITEM_GC_R = postprocess_GETARRAYITEM_RAW_I
def optimize_UNICODEGETITEM(self, op):
- return op
+ return self.emit(op)
def postprocess_UNICODEGETITEM(self, op, oldop):
b1 = self.getintbound(op)
@@ -722,6 +719,6 @@
dispatch_opt = make_dispatcher_method(OptIntBounds, 'optimize_',
- default=OptIntBounds.opt_default)
+ default=OptIntBounds.emit)
dispatch_bounds_ops = make_dispatcher_method(OptIntBounds, 'propagate_bounds_')
dispatch_postprocess = make_dispatcher_method(OptIntBounds, 'postprocess_')
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
@@ -34,6 +34,19 @@
return True
+class OptimizationResult(object):
+ def __init__(self, opt, op, callback_func=None, *callback_args):
+ self.opt = opt
+ self.op = op
+ if callback_func is None:
+ callback_func = opt.propagate_postprocess
+ self.callback_func = callback_func
+ self.callback_args = callback_args
+
+ def callback(self, oldop):
+ self.callback_func(self.op, oldop, *self.callback_args)
+
+
class Optimization(object):
next_optimization = None
potential_extra_ops = None
@@ -41,15 +54,26 @@
def __init__(self):
pass # make rpython happy
- def send_extra_operation(self, op):
- self.optimizer.send_extra_operation(op)
+ def send_extra_operation(self, op, opt=None):
+ self.optimizer.send_extra_operation(op, opt)
def propagate_forward(self, op):
raise NotImplementedError
+ def propagate_postprocess(self, op):
+ raise NotImplementedError
+
def emit_operation(self, op):
+ assert False, "This should never be called."
+
+ def emit(self, op, callback_func=None, *callback_args):
self.last_emitted_operation = op
- self.next_optimization.propagate_forward(op)
+ return OptimizationResult(self, op, callback_func, *callback_args)
+
+ def emit_extra(self, op, emit=True):
+ if emit:
+ self.emit(op)
+ self.send_extra_operation(op, self.next_optimization)
def getintbound(self, op):
assert op.type == 'i'
@@ -272,7 +296,7 @@
def set_optimizations(self, optimizations):
if optimizations:
- self.first_optimization = optimizations[3]
+ self.first_optimization = optimizations[0]
for i in range(1, len(optimizations)):
optimizations[i - 1].next_optimization = optimizations[i]
optimizations[-1].next_optimization = self
@@ -284,7 +308,7 @@
optimizations = []
self.first_optimization = self
- self.optimizations = optimizations
+ self.optimizations = optimizations
def force_op_from_preamble(self, op):
return op
@@ -537,21 +561,34 @@
if op.get_forwarded() is not None:
op.set_forwarded(None)
- def send_extra_operation(self, op):
+ def send_extra_operation(self, op, opt=None):
+ if opt is None:
+ opt = self.first_optimization
oldop = op
- for optimization in self.optimizations[:3]:
- op = optimization.propagate_forward(op)
- if op is None:
- return
- optimization.last_emitted_operation = op
- self.first_optimization.propagate_forward(op)
- for optimization in reversed(self.optimizations[:3]):
- optimization.propagate_postprocess(op, oldop)
+ opt_results = []
+ while opt is not None:
+ opt_result = opt.propagate_forward(op)
+ if opt_result is None:
+ op = None
+ break
+ opt_results.append(opt_result)
+ op = opt_result.op
+ opt = opt.next_optimization
+ for opt_result in reversed(opt_results):
+ opt_result.callback(oldop)
def propagate_forward(self, op):
dispatch_opt(self, op)
- def emit_operation(self, op):
+ def propagate_postprocess(self, op):
+ pass
+
+ def emit_extra(self, op):
+ # no forwarding, because we're at the end of the chain
+ self.emit(op)
+
+ def emit(self, op, callback_func=None, *callback_args):
+ # this actually emits the operation instead of forwarding it
if op.returns_bool_result():
self.getintbound(op).make_bool()
self._emit_operation(op)
@@ -725,7 +762,7 @@
return op
def optimize_default(self, op):
- self.emit_operation(op)
+ self.emit(op)
def constant_fold(self, op):
argboxes = [self.get_constant_box(op.getarg(i))
@@ -803,14 +840,14 @@
#def optimize_GUARD_NO_OVERFLOW(self, op):
# # otherwise the default optimizer will clear fields, which is unwanted
# # in this case
- # self.emit_operation(op)
+ # self.emit(op)
# FIXME: Is this still needed?
def optimize_DEBUG_MERGE_POINT(self, op):
- self.emit_operation(op)
+ self.emit(op)
def optimize_JIT_DEBUG(self, op):
- self.emit_operation(op)
+ self.emit(op)
def optimize_STRGETITEM(self, op):
indexb = self.getintbound(op.getarg(1))
diff --git a/rpython/jit/metainterp/optimizeopt/pure.py b/rpython/jit/metainterp/optimizeopt/pure.py
--- a/rpython/jit/metainterp/optimizeopt/pure.py
+++ b/rpython/jit/metainterp/optimizeopt/pure.py
@@ -71,7 +71,10 @@
self.extra_call_pure = []
def propagate_forward(self, op):
- dispatch_opt(self, op)
+ return dispatch_opt(self, op)
+
+ def propagate_postprocess(self, op, oldop):
+ dispatch_postprocess(self, op, oldop)
def optimize_default(self, op):
canfold = op.is_always_pure()
@@ -108,17 +111,17 @@
return
# otherwise, the operation remains
- self.emit_operation(op)
- self.optimize_default_callback(op, save, nextop)
+ return self.emit(op, self.postprocess_default, save, nextop)
- def optimize_default_callback(self, op, save, nextop):
+ def postprocess_default(self, op, oldop, save, nextop):
+ # postprocessor for optimize_default, not default postprocessor
if op.returns_bool_result():
self.getintbound(op).make_bool()
if save:
recentops = self.getrecentops(op.getopnum())
recentops.add(op)
if nextop:
- self.emit_operation(nextop)
+ self.emit_extra(nextop)
def getrecentops(self, opnum):
if rop._OVF_FIRST <= opnum <= rop._OVF_LAST:
@@ -161,10 +164,9 @@
# replace CALL_PURE with just CALL
opnum = OpHelpers.call_for_descr(op.getdescr())
newop = self.optimizer.replace_op_with(op, opnum)
- self.emit_operation(newop)
- self.optimize_CALL_PURE_I_callback(op)
+ return self.emit(newop, self.postprocess_call_pure)
- def optimize_CALL_PURE_I_callback(self, op):
+ def postprocess_call_pure(self, op, oldop):
self.call_pure_positions.append(
len(self.optimizer._newoperations) - 1)
@@ -196,7 +198,7 @@
# it was a CALL_PURE that was killed; so we also kill the
# following GUARD_NO_EXCEPTION
return
- self.emit_operation(op)
+ return self.emit(op)
def flush(self):
assert self.postponed_op is None
@@ -242,3 +244,4 @@
dispatch_opt = make_dispatcher_method(OptPure, 'optimize_',
default=OptPure.optimize_default)
+dispatch_postprocess = make_dispatcher_method(OptPure, 'postprocess_')
diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py b/rpython/jit/metainterp/optimizeopt/rewrite.py
--- a/rpython/jit/metainterp/optimizeopt/rewrite.py
+++ b/rpython/jit/metainterp/optimizeopt/rewrite.py
@@ -24,9 +24,6 @@
self.loop_invariant_results = {}
self.loop_invariant_producer = {}
- def opt_default(self, op):
- return op
-
def setup(self):
self.optimizer.optrewrite = self
@@ -103,7 +100,7 @@
self.make_equal_to(op, op.getarg(1))
return
- return op
+ return self.emit(op)
def optimize_INT_OR(self, op):
b1 = self.getintbound(op.getarg(0))
@@ -113,7 +110,7 @@
elif b2.equal(0):
self.make_equal_to(op, op.getarg(0))
else:
- return op
+ return self.emit(op)
def optimize_INT_SUB(self, op):
arg1 = self.get_box_replacement(op.getarg(0))
@@ -124,18 +121,18 @@
self.make_equal_to(op, arg1)
elif b1.equal(0):
op = self.replace_op_with(op, rop.INT_NEG, args=[arg2])
- return op
+ return self.emit(op)
elif arg1.same_box(arg2):
self.make_constant_int(op, 0)
else:
- return op
+ return self.emit(op)
def postprocess_INT_SUB(self, op, oldop):
self.optimizer.pure_reverse(op)
def optimize_INT_ADD(self, op):
if self.is_raw_ptr(op.getarg(0)) or self.is_raw_ptr(op.getarg(1)):
- return op
+ return self.emit(op)
arg1 = self.get_box_replacement(op.getarg(0))
b1 = self.getintbound(arg1)
arg2 = self.get_box_replacement(op.getarg(1))
@@ -147,7 +144,7 @@
elif b2.equal(0):
self.make_equal_to(op, arg1)
else:
- return op
+ return self.emit(op)
def postprocess_INT_ADD(self, op, oldop):
self.optimizer.pure_reverse(op)
@@ -175,7 +172,7 @@
new_rhs = ConstInt(highest_bit(lh_info.getint()))
op = self.replace_op_with(op, rop.INT_LSHIFT, args=[rhs, new_rhs])
break
- return op
+ return self.emit(op)
def optimize_UINT_FLOORDIV(self, op):
b2 = self.getintbound(op.getarg(1))
@@ -183,7 +180,7 @@
if b2.is_constant() and b2.getint() == 1:
self.make_equal_to(op, op.getarg(0))
else:
- return op
+ return self.emit(op)
def optimize_INT_LSHIFT(self, op):
b1 = self.getintbound(op.getarg(0))
@@ -194,7 +191,7 @@
elif b1.is_constant() and b1.getint() == 0:
self.make_constant_int(op, 0)
else:
- return op
+ return self.emit(op)
def optimize_INT_RSHIFT(self, op):
b1 = self.getintbound(op.getarg(0))
@@ -205,7 +202,7 @@
elif b1.is_constant() and b1.getint() == 0:
self.make_constant_int(op, 0)
else:
- return op
+ return self.emit(op)
def optimize_INT_XOR(self, op):
b1 = self.getintbound(op.getarg(0))
@@ -216,7 +213,7 @@
elif b2.equal(0):
self.make_equal_to(op, op.getarg(0))
else:
- return op
+ return self.emit(op)
def optimize_FLOAT_MUL(self, op):
arg1 = op.getarg(0)
@@ -234,8 +231,8 @@
return
elif v1.getfloat() == -1.0:
newop = self.replace_op_with(op, rop.FLOAT_NEG, args=[rhs])
- return newop
- return op
+ return self.emit(newop)
+ return self.emit(op)
def postprocess_FLOAT_MUL(self, op, oldop):
self.optimizer.pure_reverse(op)
@@ -259,10 +256,10 @@
c = ConstFloat(longlong.getfloatstorage(reciprocal))
newop = self.replace_op_with(op, rop.FLOAT_MUL,
args=[arg1, c])
- return newop
+ return self.emit(newop)
def optimize_FLOAT_NEG(self, op):
- return op
+ return self.emit(op)
def postprocess_FLOAT_NEG(self, op, oldop):
self.optimizer.pure_reverse(op)
@@ -288,7 +285,7 @@
'was proven to always fail' % r)
return
- return op
+ return self.emit(op)
def optimize_GUARD_ISNULL(self, op):
info = self.getptrinfo(op.getarg(0))
@@ -299,7 +296,7 @@
r = self.optimizer.metainterp_sd.logger_ops.repr_of_resop(op)
raise InvalidLoop('A GUARD_ISNULL (%s) was proven to always '
'fail' % r)
- return op
+ return self.emit(op)
def postprocess_GUARD_ISNULL(self, op, oldop):
self.make_constant(op.getarg(0), self.optimizer.cpu.ts.CONST_NULL)
@@ -318,7 +315,7 @@
return
if info.is_precise():
raise InvalidLoop()
- return op
+ return self.emit(op)
def optimize_GUARD_GC_TYPE(self, op):
info = self.getptrinfo(op.getarg(0))
@@ -332,7 +329,7 @@
if info.get_descr().get_type_id() != op.getarg(1).getint():
raise InvalidLoop("wrong GC types passed around!")
return
- return op
+ return self.emit(op)
def _check_subclass(self, vtable1, vtable2):
# checks that vtable1 is a subclass of vtable2
@@ -366,7 +363,7 @@
if self._check_subclass(info.get_descr().get_vtable(),
op.getarg(1).getint()):
return
- return op
+ return self.emit(op)
def optimize_GUARD_NONNULL(self, op):
opinfo = self.getptrinfo(op.getarg(0))
@@ -377,7 +374,7 @@
r = self.optimizer.metainterp_sd.logger_ops.repr_of_resop(op)
raise InvalidLoop('A GUARD_NONNULL (%s) was proven to always '
'fail' % r)
- return op
+ return self.emit(op)
def postprocess_GUARD_NONNULL(self, op, oldop):
self.make_nonnull(op.getarg(0))
@@ -486,8 +483,8 @@
# not put in short preambles guard_nonnull and guard_class
# on the same box.
self.optimizer.replace_guard(op, info)
- return op
- return op
+ return self.emit(op)
+ return self.emit(op)
def postprocess_GUARD_CLASS(self, op, oldop):
expectedclassbox = op.getarg(1)
@@ -525,7 +522,7 @@
# there is no reason to have a separate operation for this
newop = self.replace_op_with(op,
OpHelpers.call_for_descr(op.getdescr()))
- return op
+ return self.emit(op)
def postprocess_CALL_LOOPINVARIANT_I(self, op, oldop):
key = make_hashable_int(op.getarg(0).getint())
@@ -549,7 +546,7 @@
return
opnum = OpHelpers.call_for_type(op.type)
op = op.copy_and_change(opnum, args=op.getarglist()[1:])
- return op
+ return self.emit(op)
def _optimize_nullness(self, op, box, expect_nonnull):
info = self.getnullness(box)
@@ -558,7 +555,7 @@
elif info == INFO_NULL:
self.make_constant_int(op, not expect_nonnull)
else:
- return op
+ return self.emit(op)
def optimize_INT_IS_TRUE(self, op):
if (not self.is_raw_ptr(op.getarg(0)) and
@@ -605,7 +602,7 @@
# class is different
self.make_constant_int(op, expect_isnot)
return
- return op
+ return self.emit(op)
def optimize_PTR_EQ(self, op):
return self._optimize_oois_ooisnot(op, False, False)
@@ -627,7 +624,7 @@
oopspecindex = effectinfo.oopspecindex
if oopspecindex == EffectInfo.OS_ARRAYCOPY:
return self._optimize_CALL_ARRAYCOPY(op)
- return op
+ return self.emit(op)
def _optimize_CALL_ARRAYCOPY(self, op):
length = self.get_constant_box(op.getarg(5))
@@ -648,7 +645,7 @@
dest_start = dest_start_box.getint()
arraydescr = extrainfo.write_descrs_arrays[0]
if arraydescr.is_array_of_structs():
- return op # not supported right now
+ return self.emit(op) # not supported right now
# XXX fish fish fish
for index in range(length.getint()):
@@ -676,7 +673,7 @@
descr=arraydescr)
self.optimizer.send_extra_operation(newop)
return None
- return op
+ return self.emit(op)
def optimize_CALL_PURE_I(self, op):
# this removes a CALL_PURE with all constant arguments.
@@ -686,7 +683,7 @@
self.make_constant(op, result)
self.last_emitted_operation = REMOVED
return
- return op
+ return self.emit(op)
optimize_CALL_PURE_R = optimize_CALL_PURE_I
optimize_CALL_PURE_F = optimize_CALL_PURE_I
@@ -697,7 +694,7 @@
# it was a CALL_PURE or a CALL_LOOPINVARIANT that was killed;
# so we also kill the following GUARD_NO_EXCEPTION
return
- return op
+ return self.emit(op)
def optimize_GUARD_FUTURE_CONDITION(self, op):
self.optimizer.notice_guard_future_condition(op)
@@ -719,15 +716,15 @@
if val & (val - 1) == 0 and val > 0: # val == 2**shift
op = self.replace_op_with(op, rop.INT_RSHIFT,
args = [op.getarg(0), ConstInt(highest_bit(val))])
- return op
+ return self.emit(op)
def optimize_CAST_PTR_TO_INT(self, op):
self.optimizer.pure_reverse(op)
- return op
+ return self.emit(op)
def optimize_CAST_INT_TO_PTR(self, op):
self.optimizer.pure_reverse(op)
- return op
+ return self.emit(op)
def optimize_SAME_AS_I(self, op):
self.make_equal_to(op, op.getarg(0))
@@ -735,6 +732,6 @@
optimize_SAME_AS_F = optimize_SAME_AS_I
dispatch_opt = make_dispatcher_method(OptRewrite, 'optimize_',
- default=OptRewrite.opt_default)
+ default=OptRewrite.emit)
optimize_guards = _findall(OptRewrite, 'optimize_', 'GUARD')
dispatch_postprocess = make_dispatcher_method(OptRewrite, 'postprocess_')
diff --git a/rpython/jit/metainterp/optimizeopt/virtualize.py b/rpython/jit/metainterp/optimizeopt/virtualize.py
--- a/rpython/jit/metainterp/optimizeopt/virtualize.py
+++ b/rpython/jit/metainterp/optimizeopt/virtualize.py
@@ -15,9 +15,6 @@
_last_guard_not_forced_2 = None
_finish_guard_op = None
- def opt_default(self, op):
- return op
-
def make_virtual(self, known_class, source_op, descr):
opinfo = info.InstancePtrInfo(descr, known_class, is_virtual=True)
opinfo.init_fields(descr, 0)
@@ -59,19 +56,19 @@
def optimize_GUARD_NO_EXCEPTION(self, op):
if self.last_emitted_operation is REMOVED:
return
- return op
+ return self.emit(op)
def optimize_GUARD_NOT_FORCED(self, op):
if self.last_emitted_operation is REMOVED:
return
- return op
+ return self.emit(op)
def optimize_GUARD_NOT_FORCED_2(self, op):
self._last_guard_not_forced_2 = op
def optimize_FINISH(self, op):
self._finish_guard_op = self._last_guard_not_forced_2
- return op
+ return self.emit(op)
def postprocess_FINISH(self, op, oldop):
guard_op = self._finish_guard_op
@@ -87,7 +84,7 @@
if oopspecindex == EffectInfo.OS_JIT_FORCE_VIRTUAL:
if self._optimize_JIT_FORCE_VIRTUAL(op):
return
- return op
+ return self.emit(op)
optimize_CALL_MAY_FORCE_R = optimize_CALL_MAY_FORCE_I
optimize_CALL_MAY_FORCE_F = optimize_CALL_MAY_FORCE_I
optimize_CALL_MAY_FORCE_N = optimize_CALL_MAY_FORCE_I
@@ -99,7 +96,7 @@
opinfo = self.getptrinfo(op.getarg(2))
if opinfo and opinfo.is_virtual():
return
- return op
+ return self.emit(op)
def optimize_VIRTUAL_REF(self, op):
# get some constants
@@ -120,7 +117,7 @@
vrefvalue.setfield(descr_virtual_token, newop, token)
vrefvalue.setfield(descr_forced, newop,
self.optimizer.cpu.ts.CONST_NULLREF)
- return token
+ return self.emit(token)
def optimize_VIRTUAL_REF_FINISH(self, op):
# This operation is used in two cases. In normal cases, it
@@ -183,7 +180,7 @@
self.make_equal_to(op, fieldop)
else:
self.make_nonnull(op.getarg(0))
- return op
+ return self.emit(op)
optimize_GETFIELD_GC_R = optimize_GETFIELD_GC_I
optimize_GETFIELD_GC_F = optimize_GETFIELD_GC_I
@@ -201,7 +198,7 @@
self.get_box_replacement(op.getarg(1)))
else:
self.make_nonnull(struct)
- return op
+ return self.emit(op)
def optimize_NEW_WITH_VTABLE(self, op):
known_class = ConstInt(op.getdescr().get_vtable())
@@ -215,14 +212,14 @@
if sizebox is not None:
self.make_varray(op.getdescr(), sizebox.getint(), op)
else:
- return op
+ return self.emit(op)
def optimize_NEW_ARRAY_CLEAR(self, op):
sizebox = self.get_constant_box(op.getarg(0))
if sizebox is not None:
self.make_varray(op.getdescr(), sizebox.getint(), op, clear=True)
else:
- return op
+ return self.emit(op)
def optimize_CALL_N(self, op):
effectinfo = op.getdescr().get_extra_info()
@@ -236,14 +233,14 @@
if info and info.is_virtual():
return
else:
- return op
+ return self.emit(op)
optimize_CALL_R = optimize_CALL_N
optimize_CALL_I = optimize_CALL_N
def do_RAW_MALLOC_VARSIZE_CHAR(self, op):
sizebox = self.get_constant_box(op.getarg(1))
if sizebox is None:
- return op
+ return self.emit(op)
self.make_virtual_raw_memory(sizebox.getint(), op)
self.last_emitted_operation = REMOVED
@@ -251,7 +248,7 @@
opinfo = self.getrawptrinfo(op.getarg(1))
if opinfo and opinfo.is_virtual():
return
- return op
+ return self.emit(op)
def optimize_INT_ADD(self, op):
opinfo = self.getrawptrinfo(op.getarg(0), create=False)
@@ -264,7 +261,7 @@
isinstance(opinfo, info.RawSlicePtrInfo)):
self.make_virtual_raw_slice(offset, opinfo, op)
return
- return op
+ return self.emit(op)
def optimize_ARRAYLEN_GC(self, op):
opinfo = self.getptrinfo(op.getarg(0))
@@ -272,7 +269,7 @@
self.make_constant_int(op, opinfo.getlength())
else:
self.make_nonnull(op.getarg(0))
- return op
+ return self.emit(op)
def optimize_GETARRAYITEM_GC_I(self, op):
opinfo = self.getptrinfo(op.getarg(0))
@@ -286,7 +283,7 @@
self.make_equal_to(op, item)
return
self.make_nonnull(op.getarg(0))
- return op
+ return self.emit(op)
optimize_GETARRAYITEM_GC_R = optimize_GETARRAYITEM_GC_I
optimize_GETARRAYITEM_GC_F = optimize_GETARRAYITEM_GC_I
@@ -306,7 +303,7 @@
self.get_box_replacement(op.getarg(2)))
return
self.make_nonnull(op.getarg(0))
- return op
+ return self.emit(op)
def _unpack_arrayitem_raw_op(self, op, indexbox):
index = indexbox.getint()
@@ -331,7 +328,7 @@
self.make_equal_to(op, itemvalue)
return
self.make_nonnull(op.getarg(0))
- return op
+ return self.emit(op)
optimize_GETARRAYITEM_RAW_F = optimize_GETARRAYITEM_RAW_I
def optimize_SETARRAYITEM_RAW(self, op):
@@ -347,7 +344,7 @@
except InvalidRawOperation:
pass
self.make_nonnull(op.getarg(0))
- return op
+ return self.emit(op)
def _unpack_raw_load_store_op(self, op, offsetbox):
offset = offsetbox.getint()
@@ -369,7 +366,7 @@
else:
self.make_equal_to(op, itemop)
return
- return op
+ return self.emit(op)
optimize_RAW_LOAD_F = optimize_RAW_LOAD_I
def optimize_RAW_STORE(self, op):
@@ -383,7 +380,7 @@
return
except InvalidRawOperation:
pass
- return op
+ return self.emit(op)
def optimize_GETINTERIORFIELD_GC_I(self, op):
opinfo = self.getptrinfo(op.getarg(0))
@@ -399,7 +396,7 @@
self.make_equal_to(op, fld)
return
self.make_nonnull(op.getarg(0))
- return op
+ return self.emit(op)
optimize_GETINTERIORFIELD_GC_R = optimize_GETINTERIORFIELD_GC_I
optimize_GETINTERIORFIELD_GC_F = optimize_GETINTERIORFIELD_GC_I
@@ -413,11 +410,11 @@
self.get_box_replacement(op.getarg(2)))
return
self.make_nonnull(op.getarg(0))
- return op
+ return self.emit(op)
dispatch_opt = make_dispatcher_method(OptVirtualize, 'optimize_',
- default=OptVirtualize.opt_default)
+ default=OptVirtualize.emit)
OptVirtualize.propagate_forward = dispatch_opt
dispatch_postprocess = make_dispatcher_method(OptVirtualize, 'postprocess_')
diff --git a/rpython/jit/metainterp/optimizeopt/vstring.py b/rpython/jit/metainterp/optimizeopt/vstring.py
--- a/rpython/jit/metainterp/optimizeopt/vstring.py
+++ b/rpython/jit/metainterp/optimizeopt/vstring.py
@@ -97,7 +97,7 @@
newop = ResOperation(self.mode.NEWSTR, [lengthbox])
if not we_are_translated():
newop.name = 'FORCE'
- optforce.emit_operation(newop)
+ optforce.emit_extra(newop)
newop = optforce.getlastop()
newop.set_forwarded(self)
op = optforce.get_box_replacement(op)
@@ -120,7 +120,7 @@
lengthop = ResOperation(mode.STRLEN, [op])
lengthop.set_forwarded(self.getlenbound(mode))
self.lgtop = lengthop
- string_optimizer.emit_operation(lengthop)
+ string_optimizer.emit_extra(lengthop)
return lengthop
def make_guards(self, op, short, optimizer):
@@ -204,7 +204,7 @@
op = ResOperation(mode.STRSETITEM, [targetbox,
offsetbox,
charbox])
- string_optimizer.emit_operation(op)
+ string_optimizer.emit_extra(op)
offsetbox = _int_add(string_optimizer, offsetbox, CONST_1)
return offsetbox
@@ -356,7 +356,7 @@
mode)
srcoffsetbox = _int_add(string_optimizer, srcoffsetbox, CONST_1)
assert not isinstance(targetbox, Const)# ConstPtr never makes sense
- string_optimizer.emit_operation(ResOperation(mode.STRSETITEM,
+ string_optimizer.emit_extra(ResOperation(mode.STRSETITEM,
[targetbox, offsetbox, charbox]))
offsetbox = _int_add(string_optimizer, offsetbox, CONST_1)
else:
@@ -368,7 +368,7 @@
op = ResOperation(mode.COPYSTRCONTENT, [srcbox, targetbox,
srcoffsetbox, offsetbox,
lengthbox])
- string_optimizer.emit_operation(op)
+ string_optimizer.emit_extra(op)
offsetbox = nextoffsetbox
return offsetbox
@@ -412,7 +412,7 @@
else:
resbox = string_optimizer.replace_op_with(resbox, mode.STRGETITEM,
[strbox, indexbox])
- string_optimizer.emit_operation(resbox)
+ string_optimizer.emit_extra(resbox)
return resbox
@@ -422,6 +422,12 @@
def setup(self):
self.optimizer.optstring = self
+ def propagate_forward(self, op):
+ return dispatch_opt(self, op)
+
+ def propagate_postprocess(self, op, oldop):
+ return dispatch_postprocess(self, op, oldop)
+
def make_vstring_plain(self, op, mode, length):
vvalue = VStringPlainInfo(mode, True, length)
op = self.replace_op_with(op, op.getopnum())
@@ -441,9 +447,9 @@
return vvalue
def optimize_NEWSTR(self, op):
- self._optimize_NEWSTR(op, mode_string)
+ return self._optimize_NEWSTR(op, mode_string)
def optimize_NEWUNICODE(self, op):
- self._optimize_NEWSTR(op, mode_unicode)
+ return self._optimize_NEWSTR(op, mode_unicode)
def _optimize_NEWSTR(self, op, mode):
length_box = self.get_constant_box(op.getarg(0))
@@ -452,11 +458,13 @@
self.make_vstring_plain(op, mode, length_box.getint())
else:
self.make_nonnull_str(op, mode)
- self.emit_operation(op)
- self._optimize_NEWSTR_callback(op, mode)
+ return self.emit(op)
- def _optimize_NEWSTR_callback(self, op, mode):
- self.pure_from_args(mode.STRLEN, [op], op.getarg(0))
+ def postprocess_NEWSTR(self, op, oldop):
+ self.pure_from_args(mode_string.STRLEN, [op], op.getarg(0))
+
+ def postprocess_NEWUNICODE(self, op, oldop):
+ self.pure_from_args(mode_unicode.STRLEN, [op], op.getarg(0))
def optimize_STRSETITEM(self, op):
opinfo = self.getptrinfo(op.getarg(0))
@@ -467,17 +475,17 @@
indexbox = self.get_constant_box(op.getarg(1))
if indexbox is not None:
opinfo.strsetitem(indexbox.getint(),
- self.get_box_replacement(op.getarg(2)))
+ self.get_box_replacement(op.getarg(2)))
return
self.make_nonnull(op.getarg(0))
- self.emit_operation(op)
+ return self.emit(op)
optimize_UNICODESETITEM = optimize_STRSETITEM
def optimize_STRGETITEM(self, op):
- self._optimize_STRGETITEM(op, mode_string)
+ return self._optimize_STRGETITEM(op, mode_string)
def optimize_UNICODEGETITEM(self, op):
- self._optimize_STRGETITEM(op, mode_unicode)
+ return self._optimize_STRGETITEM(op, mode_unicode)
def _optimize_STRGETITEM(self, op, mode):
self.strgetitem(op, op.getarg(0), op.getarg(1), mode)
@@ -517,9 +525,9 @@
return _strgetitem(self, s, index, mode, op)
def optimize_STRLEN(self, op):
- self._optimize_STRLEN(op, mode_string)
+ return self._optimize_STRLEN(op, mode_string)
def optimize_UNICODELEN(self, op):
- self._optimize_STRLEN(op, mode_unicode)
+ return self._optimize_STRLEN(op, mode_unicode)
def _optimize_STRLEN(self, op, mode):
opinfo = self.getptrinfo(op.getarg(0))
@@ -528,13 +536,13 @@
if lgtop is not None:
self.make_equal_to(op, lgtop)
return
- self.emit_operation(op)
+ return self.emit(op)
def optimize_COPYSTRCONTENT(self, op):
- self._optimize_COPYSTRCONTENT(op, mode_string)
+ return self._optimize_COPYSTRCONTENT(op, mode_string)
def optimize_COPYUNICODECONTENT(self, op):
- self._optimize_COPYSTRCONTENT(op, mode_unicode)
+ return self._optimize_COPYSTRCONTENT(op, mode_unicode)
def _optimize_COPYSTRCONTENT(self, op, mode):
# args: src dst srcstart dststart length
@@ -569,7 +577,7 @@
op.getarg(1), ConstInt(index + dst_start),
vresult,
])
- self.emit_operation(new_op)
+ self.emit_extra(new_op)
else:
copy_str_content(self, op.getarg(0), op.getarg(1), op.getarg(2),
op.getarg(3), op.getarg(4), mode,
@@ -584,13 +592,15 @@
if oopspecindex != EffectInfo.OS_NONE:
for value, meth in opt_call_oopspec_ops:
if oopspecindex == value: # a match with the OS_STR_xxx
- if meth(self, op, mode_string):
- return
+ handled, newop = meth(self, op, mode_string)
+ if handled:
+ return newop
break
if oopspecindex == value + EffectInfo._OS_offset_uni:
# a match with the OS_UNI_xxx
- if meth(self, op, mode_unicode):
- return
+ handled, newop = meth(self, op, mode_unicode)
+ if handled:
+ return newop
break
if oopspecindex == EffectInfo.OS_STR2UNICODE:
if self.opt_call_str_STR2UNICODE(op):
@@ -598,7 +608,7 @@
if oopspecindex == EffectInfo.OS_SHRINK_ARRAY:
if self.opt_call_SHRINK_ARRAY(op):
return
- self.emit_operation(op)
+ return self.emit(op)
optimize_CALL_R = optimize_CALL_I
optimize_CALL_F = optimize_CALL_I
optimize_CALL_N = optimize_CALL_I
@@ -610,7 +620,7 @@
def optimize_GUARD_NO_EXCEPTION(self, op):
if self.last_emitted_operation is REMOVED:
return
- self.emit_operation(op)
+ return self.emit(op)
def opt_call_str_STR2UNICODE(self, op):
# Constant-fold unicode("constant string").
@@ -638,7 +648,7 @@
self.get_box_replacement(op.getarg(1)),
self.get_box_replacement(op.getarg(2)))
self.last_emitted_operation = REMOVED
- return True
+ return True, None
def opt_call_stroruni_STR_SLICE(self, op, mode):
self.make_nonnull_str(op.getarg(1), mode)
@@ -651,7 +661,7 @@
value = self.make_vstring_plain(op, mode, -1)
value.setup_slice(vstr._chars, vstart.getint(),
vstop.getint())
- return True
+ return True, None
#
startbox = op.getarg(2)
strbox = op.getarg(1)
@@ -664,7 +674,7 @@
#
self.make_vstring_slice(op, strbox, startbox, mode, lengthbox)
self.last_emitted_operation = REMOVED
- return True
+ return True, None
@specialize.arg(2)
def opt_call_stroruni_STR_EQUAL(self, op, mode):
@@ -687,25 +697,28 @@
l1box.value != l2box.value):
# statically known to have a different length
self.make_constant(op, CONST_0)
- return True
+ return True, None
#
- if self.handle_str_equal_level1(arg1, arg2, op, mode):
- return True
- if self.handle_str_equal_level1(arg2, arg1, op, mode):
- return True
- if self.handle_str_equal_level2(arg1, arg2, op, mode):
- return True
- if self.handle_str_equal_level2(arg2, arg1, op, mode):
- return True
+ handled, result = self.handle_str_equal_level1(arg1, arg2, op, mode)
+ if handled:
+ return True, result
+ handled, result = self.handle_str_equal_level1(arg2, arg1, op, mode)
+ if handled:
+ return True, result
+ handled, result = self.handle_str_equal_level2(arg1, arg2, op, mode)
+ if handled:
+ return True, result
+ handled, result = self.handle_str_equal_level2(arg2, arg1, op, mode)
+ if handled:
+ return True, result
#
if i1 and i1.is_nonnull() and i2 and i2.is_nonnull():
if l1box is not None and l2box is not None and l1box.same_box(l2box):
do = EffectInfo.OS_STREQ_LENGTHOK
else:
do = EffectInfo.OS_STREQ_NONNULL
- self.generate_modified_call(do, [arg1, arg2], op, mode)
- return True
- return False
+ return True, self.generate_modified_call(do, [arg1, arg2], op, mode)
+ return False, None
def handle_str_equal_level1(self, arg1, arg2, resultop, mode):
i1 = self.getptrinfo(arg1)
@@ -728,7 +741,7 @@
[lengthbox, CONST_0],
descr=DONT_CHANGE)
seo(op)
- return True
+ return True, None
if l2box.value == 1:
if i1:
l1box = i1.getstrlen(arg1, self, mode, False)
@@ -742,30 +755,28 @@
op = self.optimizer.replace_op_with(resultop, rop.INT_EQ,
[vchar1, vchar2], descr=DONT_CHANGE)
seo(op)
- return True
+ return True, None
if isinstance(i1, VStringSliceInfo):
vchar = self.strgetitem(None, arg2, optimizer.CONST_0,
mode)
do = EffectInfo.OS_STREQ_SLICE_CHAR
- self.generate_modified_call(do, [i1.s, i1.start,
- i1.lgtop, vchar],
- resultop, mode)
- return True
+ return True, self.generate_modified_call(do, [i1.s, i1.start,
+ i1.lgtop, vchar],
+ resultop, mode)
#
if i2 and i2.is_null():
if i1 and i1.is_nonnull():
self.make_constant(resultop, CONST_0)
- return True
+ return True, None
if i1 and i1.is_null():
self.make_constant(resultop, CONST_1)
- return True
+ return True, None
op = self.optimizer.replace_op_with(resultop, rop.PTR_EQ,
[arg1, llhelper.CONST_NULL],
descr=DONT_CHANGE)
- self.emit_operation(op)
- return True
+ return True, self.emit(op)
#
- return False
+ return False, None
def handle_str_equal_level2(self, arg1, arg2, resultbox, mode):
i1 = self.getptrinfo(arg1)
@@ -782,25 +793,23 @@
do = EffectInfo.OS_STREQ_NONNULL_CHAR
else:
do = EffectInfo.OS_STREQ_CHECKNULL_CHAR
- self.generate_modified_call(do, [arg1, vchar],
- resultbox, mode)
- return True
+ return True, self.generate_modified_call(do, [arg1, vchar],
+ resultbox, mode)
#
if isinstance(i1, VStringSliceInfo) and i1.is_virtual():
if i2 and i2.is_nonnull():
do = EffectInfo.OS_STREQ_SLICE_NONNULL
else:
do = EffectInfo.OS_STREQ_SLICE_CHECKNULL
- self.generate_modified_call(do, [i1.s, i1.start, i1.lgtop,
- arg2], resultbox, mode)
- return True
- return False
+ return True, self.generate_modified_call(do, [i1.s, i1.start, i1.lgtop,
+ arg2], resultbox, mode)
+ return False, None
def opt_call_stroruni_STR_CMP(self, op, mode):
i1 = self.getptrinfo(op.getarg(1))
i2 = self.getptrinfo(op.getarg(2))
if not i1 or not i2:
- return False
+ return False, None
l1box = i1.getstrlen(None, self, mode, False)
l2box = i2.getstrlen(None, self, mode, False)
if (l1box is not None and l2box is not None and
@@ -814,8 +823,8 @@
op = self.replace_op_with(op, rop.INT_SUB, [char1, char2],
descr=DONT_CHANGE)
seo(op)
- return True
- return False
+ return True, None
+ return False, None
def opt_call_SHRINK_ARRAY(self, op):
i1 = self.getptrinfo(op.getarg(1))
@@ -838,14 +847,12 @@
op = self.optimizer.replace_op_with(result, rop.CALL_I,
[ConstInt(func)] + args,
descr=calldescr)
- self.emit_operation(op)
-
- def propagate_forward(self, op):
- dispatch_opt(self, op)
+ return self.emit(op)
dispatch_opt = make_dispatcher_method(OptString, 'optimize_',
- default=OptString.emit_operation)
+ default=OptString.emit)
+dispatch_postprocess = make_dispatcher_method(OptString, 'postprocess_')
def _findall_call_oopspec():
More information about the pypy-commit
mailing list