[pypy-commit] pypy optresult-unroll: a first go at adding proper operations to label args, not sure what I think about this go
fijal
noreply at buildbot.pypy.org
Sun Jul 12 20:23:11 CEST 2015
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: optresult-unroll
Changeset: r78531:078fc2be0b85
Date: 2015-07-12 20:23 +0200
http://bitbucket.org/pypy/pypy/changeset/078fc2be0b85/
Log: a first go at adding proper operations to label args, not sure what
I think about this go
diff --git a/rpython/jit/metainterp/optimizeopt/__init__.py b/rpython/jit/metainterp/optimizeopt/__init__.py
--- a/rpython/jit/metainterp/optimizeopt/__init__.py
+++ b/rpython/jit/metainterp/optimizeopt/__init__.py
@@ -16,8 +16,8 @@
('rewrite', OptRewrite),
('virtualize', OptVirtualize),
('string', OptString),
- ('earlyforce', OptEarlyForce),
('pure', OptPure),
+ #('earlyforce', OptEarlyForce), # XXX why do we have this hack?
('heap', OptHeap),
('unroll', None)]
# no direct instantiation of unroll
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
@@ -58,7 +58,9 @@
op = optimizer.get_box_replacement(op)
opnum = OpHelpers.getfield_for_descr(descr)
getfield_op = ResOperation(opnum, [structbox], descr=descr)
- shortboxes.add_potential(op, getfield_op)
+ if not op.is_constant():
+ # XXXX why?
+ shortboxes.add_potential(op, getfield_op)
return
for structvalue in self._cached_fields_getfield_op.keys():
op = self._cached_fields_getfield_op[structvalue]
@@ -151,7 +153,13 @@
return op.getarg(1)
def _getfield(self, opinfo, descr, optheap):
- return opinfo.getfield(descr, optheap)
+ from rpython.jit.metainterp.optimizeopt.unroll import PreambleOp
+
+ res = opinfo.getfield(descr, optheap)
+ if isinstance(res, PreambleOp):
+ res = optheap.optimizer.force_op_from_preamble(res)
+ opinfo._fields[descr.get_index()] == res
+ return res
def force_lazy_setfield(self, optheap, descr, can_cache=True):
op = self._lazy_setfield
@@ -180,7 +188,8 @@
def _setfield(self, op, opinfo, optheap):
arg = optheap.get_box_replacement(op.getarg(1))
- opinfo.setfield(op.getdescr(), op, arg, optheap, self)
+ struct = optheap.get_box_replacement(op.getarg(0))
+ opinfo.setfield(op.getdescr(), struct, arg, optheap, self)
class ArrayCachedField(CachedField):
def __init__(self, index):
@@ -531,6 +540,7 @@
optimize_GETFIELD_GC_PURE_F = optimize_GETFIELD_GC_PURE_I
def optimize_SETFIELD_GC(self, op):
+ self.setfield(op)
#opnum = OpHelpers.getfield_pure_for_descr(op.getdescr())
#if self.has_pure_result(opnum, [op.getarg(0)],
# op.getdescr()):
@@ -538,6 +548,8 @@
# (op.getdescr().repr_of_descr()))
# raise BogusImmutableField
#
+
+ def setfield(self, op):
cf = self.field_cache(op.getdescr())
cf.do_setfield(self, op)
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
@@ -51,6 +51,9 @@
def getstrlen(self, op, string_optimizer, mode, create_ops=True):
return None
+ def make_guards(self, op, short):
+ pass # XXX
+
class NonNullPtrInfo(PtrInfo):
_attrs_ = ('last_guard_pos',)
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
@@ -302,6 +302,17 @@
def force_box(self, op):
op = self.get_box_replacement(op)
info = op.get_forwarded()
+ if self.optunroll and self.optunroll.ops_to_import:
+ # XXX hack, use stuff on info somehow, a bit on the hard side
+ # but doable :-)
+ try:
+ preamble_op = self.optunroll.ops_to_import[op]
+ except KeyError:
+ pass
+ else:
+ self.optunroll.short.append(preamble_op)
+ self.optunroll.extra_label_args.append(op)
+ del self.optunroll.ops_to_import[op]
if info is not None:
return info.force_box(op, self)
return op
diff --git a/rpython/jit/metainterp/optimizeopt/shortpreamble.py b/rpython/jit/metainterp/optimizeopt/shortpreamble.py
--- a/rpython/jit/metainterp/optimizeopt/shortpreamble.py
+++ b/rpython/jit/metainterp/optimizeopt/shortpreamble.py
@@ -1,5 +1,6 @@
-from rpython.jit.metainterp.resoperation import ResOperation, OpHelpers
+from rpython.jit.metainterp.resoperation import ResOperation, OpHelpers,\
+ AbstractInputArg
from rpython.jit.metainterp.history import Const
@@ -29,13 +30,17 @@
self.short_boxes[op] = short_op
def produce_short_preamble_op(self, op, preamble_op):
- for arg in op.getarglist():
- if isinstance(arg, Const):
- pass
- elif arg in self.ops_used:
- pass
- else:
- return # can't produce
+ if isinstance(op, AbstractInputArg):
+ if op not in self.ops_used:
+ return
+ else:
+ for arg in op.getarglist():
+ if isinstance(arg, Const):
+ pass
+ elif arg in self.ops_used:
+ pass
+ else:
+ return # can't produce
if op in self.short_boxes:
opnum = OpHelpers.same_as_for_type(op.type)
same_as_op = ResOperation(opnum, [op])
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_util.py b/rpython/jit/metainterp/optimizeopt/test/test_util.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_util.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_util.py
@@ -450,8 +450,9 @@
preamble.inputargs = start_state.renamed_inputargs
start_label = ResOperation(rop.LABEL, start_state.renamed_inputargs)
preamble.operations = [start_label] + preamble_ops
- emit_end_label = ResOperation(rop.LABEL, start_state.end_args)
- loop.inputargs = start_state.end_args
+ inputargs = start_state.end_args + loop_info.extra_label_args
+ emit_end_label = ResOperation(rop.LABEL, inputargs)
+ loop.inputargs = inputargs
loop.operations = [emit_end_label] + ops
return Info(preamble, loop_info.short_preamble)
diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py b/rpython/jit/metainterp/optimizeopt/unroll.py
--- a/rpython/jit/metainterp/optimizeopt/unroll.py
+++ b/rpython/jit/metainterp/optimizeopt/unroll.py
@@ -16,6 +16,16 @@
class PreambleOp(AbstractResOp):
+ """ An operations that's only found in preamble and not
+ in the list of constructed operations. When encountered (can be found
+ either in pure ops or heap ops), it must be put in inputargs as well
+ as short preamble (together with corresponding guards). Extra_ops is
+ for extra things to be found in the label, for now only inputargs
+ of the preamble that have to be propagated further.
+
+ See force_op_from_preamble for details how the extra things are put.
+ """
+
def __init__(self, op, preamble_op, info):
self.op = op
self.preamble_op = preamble_op
@@ -57,6 +67,7 @@
distinction anymore)"""
inline_short_preamble = True
+ ops_to_import = None
def __init__(self, metainterp_sd, jitdriver_sd, optimizations):
self.optimizer = UnrollableOptimizer(metainterp_sd, jitdriver_sd,
@@ -84,19 +95,23 @@
def optimize_peeled_loop(self, start_label, end_jump, ops, state):
self.short = []
+ self.extra_label_args = []
self._check_no_forwarding([[start_label, end_jump], ops])
self.import_state(start_label, state)
self.optimizer.propagate_all_forward(start_label.getarglist()[:], ops,
rename_inputargs=False)
jump_args = [self.get_box_replacement(op)
for op in end_jump.getarglist()]
+ args_from_extras = [self.get_box_replacement(op) for op in
+ self.extra_label_args]
jump_args = state.virtual_state.make_inputargs(jump_args,
- self.optimizer,
- force_boxes=True)
+ self.optimizer, force_boxes=True) + args_from_extras
+
self.flush()
jump_op = ResOperation(rop.JUMP, jump_args)
self.optimizer._newoperations.append(jump_op)
- return (UnrollInfo(self.make_short_preamble(start_label.getarglist())),
+ return (UnrollInfo(self.make_short_preamble(start_label.getarglist()),
+ self.extra_label_args),
self.optimizer._newoperations)
def make_short_preamble(self, args):
@@ -264,17 +279,24 @@
def import_state(self, targetop, exported_state):
# the mapping between input args (from old label) and what we need
# to actually emit
+ self.ops_to_import = {}
for source, target in exported_state.inputarg_mapping:
if source is not target:
source.set_forwarded(target)
# import the optimizer state, starting from boxes that can be produced
# by short preamble
for op, preamble_op in exported_state.short_boxes.items():
+ self.ops_to_import[op] = preamble_op
if preamble_op.is_always_pure():
- self.pure(op.getopnum(), PreambleOp(op, preamble_op,
- self.optimizer.getinfo(op)))
+ self.pure(op.getopnum(), op)
else:
- yyy
+ assert preamble_op.is_getfield()
+ optheap = self.optimizer.optheap
+ if optheap is None:
+ continue
+ opinfo = self.optimizer.ensure_ptr_info_arg0(preamble_op)
+ assert not opinfo.is_virtual()
+ opinfo._fields[preamble_op.getdescr().get_index()] = op
for op, info in exported_state.exported_infos.iteritems():
self.optimizer.setinfo_from_preamble(op, info)
@@ -714,9 +736,11 @@
""" A state after optimizing the peeled loop, contains the following:
* short_preamble - list of operations that go into short preamble
+ * extra_label_args - list of extra operations that go into the label
"""
- def __init__(self, short_preamble):
+ def __init__(self, short_preamble, extra_label_args):
self.short_preamble = short_preamble
+ self.extra_label_args = extra_label_args
class ExportedState(LoopInfo):
""" Exported state consists of a few pieces of information:
diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py
--- a/rpython/rlib/jit.py
+++ b/rpython/rlib/jit.py
@@ -535,8 +535,9 @@
class JitHintError(Exception):
"""Inconsistency in the JIT hints."""
+# XXX earlyforce before pure
ENABLE_ALL_OPTS = (
- 'intbounds:rewrite:virtualize:string:earlyforce:pure:heap:unroll')
+ 'intbounds:rewrite:virtualize:string:pure:heap:unroll')
PARAMETER_DOCS = {
'threshold': 'number of times a loop has to run for it to become hot',
More information about the pypy-commit
mailing list