[pypy-commit] pypy jit-leaner-frontend: pass the first tests of optimizeopt, yay!
fijal
pypy.commits at gmail.com
Fri Mar 4 08:14:02 EST 2016
Author: fijal
Branch: jit-leaner-frontend
Changeset: r82763:b36f4652488a
Date: 2016-03-04 15:13 +0200
http://bitbucket.org/pypy/pypy/changeset/b36f4652488a/
Log: pass the first tests of optimizeopt, yay!
diff --git a/rpython/jit/metainterp/opencoder.py b/rpython/jit/metainterp/opencoder.py
--- a/rpython/jit/metainterp/opencoder.py
+++ b/rpython/jit/metainterp/opencoder.py
@@ -1,10 +1,11 @@
-from rpython.jit.metainterp.history import ConstInt, Const, AbstractDescr,\
- AbstractValue
+""" Storage format:
+"""
+
+from rpython.jit.metainterp.history import ConstInt, Const
from rpython.jit.metainterp.resoperation import AbstractResOp, AbstractInputArg,\
- ResOperation, oparity, opname, rop, ResOperation, opwithdescr
+ ResOperation, oparity, rop, opwithdescr
from rpython.rlib.rarithmetic import intmask
-from rpython.jit.metainterp import resume
from rpython.rlib.objectmodel import we_are_translated
TAGINT, TAGCONST, TAGBOX = range(3)
@@ -20,7 +21,12 @@
self.trace = main_iter.trace
self.main_iter = main_iter
self.end = end_pos
+ self.start = pos
self.pos = pos
+ self.save_pos = -1
+
+ def length(self):
+ return self.end - self.start
def done(self):
return self.pos >= self.end
@@ -36,7 +42,16 @@
return r
def get_size_jitcode_pc(self):
- return self._next(), self._next(), self._next()
+ if self.save_pos >= 0:
+ self.pos = self.save_pos
+ size = self._next()
+ if size < 0:
+ self.save_pos = self.pos
+ self.pos = -size - 1
+ assert self.pos >= 0
+ size = self._next()
+ assert size >= 0
+ return size, self._next(), self._next()
class TraceIterator(object):
def __init__(self, trace, end):
@@ -204,6 +219,10 @@
assert isinstance(prev, Sentinel)
self._ops[p] = len(self._ops)
+ def check_snapshot_jitcode_pc(self, jitcode, pc, resumedata_pos):
+ assert self._ops[resumedata_pos + 1] == jitcode.index
+ assert self._ops[resumedata_pos + 2] == pc
+
def get_iter(self):
return TraceIterator(self, len(self._ops))
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
@@ -27,7 +27,7 @@
class BasicLoopInfo(LoopInfo):
def __init__(self, inputargs, quasi_immutable_deps):
self.inputargs = inputargs
- self.label_op = ResOperation(rop.LABEL, inputargs)
+ self.label_op = ResOperation(rop.LABEL, inputargs, -1)
self.quasi_immutable_deps = quasi_immutable_deps
self.extra_same_as = []
@@ -509,30 +509,24 @@
trace = trace.get_iter()
self.trace = trace
self.call_pure_results = call_pure_results
+ last_op = None
+ i = 0
while not trace.done():
self._really_emitted_operation = None
op = trace.next()
if op.getopnum() in (rop.FINISH, rop.JUMP):
- xxx
- self.first_optimization.propagate_forward(trace.next())
- xxxx
- if ops[-1].getopnum() in (rop.FINISH, rop.JUMP):
- last = len(ops) - 1
- extra_jump = True
- else:
- extra_jump = False
- last = len(ops)
- for i in range(last):
- self._really_emitted_operation = None
- self.first_optimization.propagate_forward(ops[i])
+ last_op = op
+ break
+ self.first_optimization.propagate_forward(op)
+ i += 1
# accumulate counters
if flush:
self.flush()
- if extra_jump:
- self.first_optimization.propagate_forward(ops[-1])
+ if last_op:
+ self.first_optimization.propagate_forward(last_op)
self.resumedata_memo.update_counters(self.metainterp_sd.profiler)
- return (BasicLoopInfo(newargs, self.quasi_immutable_deps),
+ return (BasicLoopInfo(trace.inputargs, self.quasi_immutable_deps),
self._newoperations)
def _clean_optimization_info(self, lst):
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
@@ -49,7 +49,6 @@
return None
def lookup(self, optimizer, op):
- return None
numargs = op.numargs()
if numargs == 1:
return self.lookup1(optimizer,
@@ -76,8 +75,8 @@
dispatch_opt(self, op)
def optimize_default(self, op):
- canfold = OpHelpers.is_always_pure(op.opnum)
- if OpHelpers.is_ovf(op.opnum):
+ canfold = op.is_always_pure()
+ if op.is_ovf():
self.postponed_op = op
return
if self.postponed_op:
@@ -91,7 +90,7 @@
save = False
if canfold:
for i in range(op.numargs()):
- if not self.optimizer.is_constant(op.getarg(i)):
+ if self.get_constant_box(op.getarg(i)) is None:
break
else:
# all constant arguments: constant-fold away
@@ -207,7 +206,7 @@
def pure_from_args(self, opnum, args, op, descr=None):
newop = ResOperation(opnum,
[self.get_box_replacement(arg) for arg in args],
- descr=descr)
+ -1, descr=descr)
newop.set_forwarded(op)
self.pure(opnum, newop)
@@ -222,7 +221,7 @@
def produce_potential_short_preamble_ops(self, sb):
ops = self.optimizer._newoperations
for i, op in enumerate(ops):
- if OpHelpers.is_always_pure(op.opnum):
+ if op.is_always_pure():
sb.add_pure_op(op)
if op.is_ovf() and ops[i + 1].getopnum() == rop.GUARD_NO_OVERFLOW:
sb.add_pure_op(op)
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
@@ -35,7 +35,7 @@
compile_data = compile.SimpleCompileData(label_op, trace,
call_pure_results)
info, ops = self._do_optimize_loop(compile_data)
- label_op = ResOperation(rop.LABEL, info.inputargs)
+ label_op = ResOperation(rop.LABEL, info.inputargs, -1)
loop.inputargs = info.inputargs
loop.operations = [label_op] + ops
#print '\n'.join([str(o) for o in loop.operations])
diff --git a/rpython/jit/metainterp/optimizeopt/util.py b/rpython/jit/metainterp/optimizeopt/util.py
--- a/rpython/jit/metainterp/optimizeopt/util.py
+++ b/rpython/jit/metainterp/optimizeopt/util.py
@@ -154,7 +154,7 @@
if op1.type != 'v':
remap[op2] = op1
if (op1.getopnum() not in [rop.JUMP, rop.LABEL, rop.FINISH] and
- not OpHelpers.is_guard(op1.getopnum())):
+ not rop.is_guard(op1.getopnum())):
assert op1.getdescr() == op2.getdescr()
if op1.getfailargs() or op2.getfailargs():
assert len(op1.getfailargs()) == len(op2.getfailargs())
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
@@ -396,7 +396,16 @@
except KeyError:
return '<%d>' % self.getopnum()
- # XXX kill all those in favor of ophelpers
+ def is_guard(self):
+ return rop.is_guard(self.getopnum())
+
+ def is_ovf(self):
+ return rop.is_ovf(self.getopnum())
+
+ def can_raise(self):
+ return rop.can_raise(self.getopnum())
+
+ # XXX fix
def is_foldable_guard(self):
return rop._GUARD_FOLDABLE_FIRST <= self.getopnum() <= rop._GUARD_FOLDABLE_LAST
@@ -1430,6 +1439,14 @@
xxxx
@staticmethod
+ def is_pure_getfield(opnum, descr):
+ if (opnum == rop.GETFIELD_GC_I or
+ opnum == rop.GETFIELD_GC_F or
+ opnum == rop.GETFIELD_GC_R):
+ return descr is not None and descr.is_always_pure()
+ return False
+
+ @staticmethod
def has_no_side_effect(opnum):
return rop._NOSIDEEFFECT_FIRST <= opnum <= rop._NOSIDEEFFECT_LAST
diff --git a/rpython/jit/metainterp/resume.py b/rpython/jit/metainterp/resume.py
--- a/rpython/jit/metainterp/resume.py
+++ b/rpython/jit/metainterp/resume.py
@@ -115,6 +115,7 @@
def _ensure_parent_resumedata(framestack, n, t):
if n == 0:
return
+ _ensure_parent_resumedata(framestack, n - 1, t)
target = framestack[n]
back = framestack[n - 1]
if target.parent_resumedata_position != -1:
@@ -124,7 +125,6 @@
return
pos = t.record_snapshot(back.jitcode, back.pc,
back.get_list_of_active_boxes(True))
- _ensure_parent_resumedata(framestack, n - 1, t)
target.parent_resumedata_position = pos
def capture_resumedata(framestack, virtualizable_boxes, virtualref_boxes, t):
@@ -138,9 +138,9 @@
if n >= 0:
top = framestack[n]
pos = t.get_patchable_position()
+ _ensure_parent_resumedata(framestack, n, t)
t.record_snapshot(top.jitcode, top.pc,
top.get_list_of_active_boxes(False))
- _ensure_parent_resumedata(framestack, n, t)
t.patch_position_to_current(pos)
else:
yyy
@@ -196,22 +196,13 @@
TAG_CONST_OFFSET = 0
class NumberingState(object):
- def __init__(self, snapshot_list):
+ def __init__(self, size):
self.liveboxes = {}
- self.current = [rffi.cast(rffi.SHORT, 0)] * self.count_boxes(snapshot_list)
- self.position = len(self.current)
+ self.current = [rffi.cast(rffi.SHORT, 0)] * (size + 2)
+ self.position = 0
self.n = 0
self.v = 0
- def count_boxes(self, lst):
- snapshot = lst[0]
- assert isinstance(snapshot, TopSnapshot)
- c = len(snapshot.vable_boxes)
- for snapshot in lst:
- c += len(snapshot.boxes)
- c += 2 * (len(lst) - 1) + 1 + 1
- return c
-
def append(self, item):
self.current[self.position] = item
self.position += 1
@@ -267,15 +258,14 @@
# env numbering
- def _number_boxes(self, boxes, optimizer, state):
+ def _number_boxes(self, iter, length, optimizer, state):
""" Number boxes from one snapshot
"""
n = state.n
v = state.v
liveboxes = state.liveboxes
- length = len(boxes)
for i in range(length):
- box = boxes[i]
+ box = iter.next()
box = optimizer.get_box_replacement(box)
if isinstance(box, Const):
@@ -302,32 +292,33 @@
state.v = v
def number(self, optimizer, position, trace):
- state = NumberingState(snapshot_list)
+ snapshot_iter = trace.get_snapshot_iter(position)
+ state = NumberingState(snapshot_iter.length())
+ while not snapshot_iter.done():
+ size, jitcode_index, pc = snapshot_iter.get_size_jitcode_pc()
+ state.append(rffi.cast(rffi.SHORT, jitcode_index))
+ state.append(rffi.cast(rffi.SHORT, pc))
+ self._number_boxes(snapshot_iter, size, optimizer, state)
- # we want to number snapshots starting from the back, but ending
- # with a forward list
- for i in range(len(snapshot_list) - 1, 0, -1):
- state.position -= len(snapshot_list[i].boxes) + 2
- frameinfo = framestack_list[i - 1]
- jitcode_pos, pc = unpack_uint(frameinfo.packed_jitcode_pc)
- state.append(rffi.cast(rffi.SHORT, jitcode_pos))
- state.append(rffi.cast(rffi.SHORT, pc))
- self._number_boxes(snapshot_list[i].boxes, optimizer, state)
- state.position -= len(snapshot_list[i].boxes) + 2
-
- assert isinstance(topsnapshot, TopSnapshot)
- special_boxes_size = (1 + len(topsnapshot.vable_boxes) +
- 1 + len(topsnapshot.boxes))
- assert state.position == special_boxes_size
-
- state.position = 0
- state.append(rffi.cast(rffi.SHORT, len(topsnapshot.vable_boxes)))
- self._number_boxes(topsnapshot.vable_boxes, optimizer, state)
- n = len(topsnapshot.boxes)
+ state.append(rffi.cast(rffi.SHORT, 0))
+ n = 0 # len(topsnapshot.boxes)
assert not (n & 1)
state.append(rffi.cast(rffi.SHORT, n >> 1))
- self._number_boxes(topsnapshot.boxes, optimizer, state)
- assert state.position == special_boxes_size
+ #
+ # XXX ignore vables and virtualrefs for now
+ #assert isinstance(topsnapshot, TopSnapshot)
+ #special_boxes_size = (1 + len(topsnapshot.vable_boxes) +
+ # 1 + len(topsnapshot.boxes))
+ #assert state.position == special_boxes_size
+
+ #state.position = 0
+ #state.append(rffi.cast(rffi.SHORT, len(topsnapshot.vable_boxes)))
+ #self._number_boxes(topsnapshot.vable_boxes, optimizer, state)
+ #n = len(topsnapshot.boxes)
+ #assert not (n & 1)
+ #state.append(rffi.cast(rffi.SHORT, n >> 1))
+ #self._number_boxes(topsnapshot.boxes, optimizer, state)
+ #assert state.position == special_boxes_size
numb = resumecode.create_numbering(state.current)
return numb, state.liveboxes, state.v
@@ -476,11 +467,10 @@
assert resume_position > 0
# count stack depth
numb, liveboxes_from_env, v = self.memo.number(optimizer,
- resume_position, self.optimize.trace)
+ resume_position, self.optimizer.trace)
self.liveboxes_from_env = liveboxes_from_env
self.liveboxes = {}
storage.rd_numb = numb
- self.snapshot_storage.rd_snapshot = None
# collect liveboxes and virtuals
n = len(liveboxes_from_env) - v
diff --git a/rpython/jit/metainterp/test/test_opencoder.py b/rpython/jit/metainterp/test/test_opencoder.py
--- a/rpython/jit/metainterp/test/test_opencoder.py
+++ b/rpython/jit/metainterp/test/test_opencoder.py
@@ -77,7 +77,7 @@
assert boxes == [i0, i1]
assert l[2].opnum == rop.GUARD_FALSE
boxes = self.unpack_snapshot(iter, l[2].rd_resume_position)
- assert boxes == [i0, i0, l[0], i0, i1]
+ assert boxes == [i0, i1, i0, i0, l[0]]
def test_read_snapshot_interface(self):
i0, i1, i2 = InputArgInt(), InputArgInt(), InputArgInt()
@@ -86,16 +86,26 @@
frame0 = FakeFrame(1, JitCode(2), [i0, i1])
frame1 = FakeFrame(3, JitCode(4), [i2, i2])
resume.capture_resumedata([frame0, frame1], None, [], t)
+ t.record_op(rop.GUARD_TRUE, [i1])
+ resume.capture_resumedata([frame0, frame1], None, [], t)
(i0, i1, i2), l, iter = self.unpack(t)
pos = l[0].rd_resume_position
snapshot_iter = iter.get_snapshot_iter(pos)
size, jc_index, pc = snapshot_iter.get_size_jitcode_pc()
assert size == 2
+ assert jc_index == 2
+ assert pc == 1
+ assert [snapshot_iter.next() for i in range(2)] == [i0, i1]
+ size, jc_index, pc = snapshot_iter.get_size_jitcode_pc()
+ assert size == 2
assert jc_index == 4
assert pc == 3
assert [snapshot_iter.next() for i in range(2)] == [i2, i2]
+ pos = l[1].rd_resume_position
+ snapshot_iter = iter.get_snapshot_iter(pos)
size, jc_index, pc = snapshot_iter.get_size_jitcode_pc()
assert size == 2
assert jc_index == 2
assert pc == 1
assert [snapshot_iter.next() for i in range(2)] == [i0, i1]
+
\ No newline at end of file
More information about the pypy-commit
mailing list