Author: Maciej Fijalkowski <[email protected]>
Branch: resume-refactor
Changeset: r66402:73b0937bd931
Date: 2013-08-28 15:57 +0100
http://bitbucket.org/pypy/pypy/changeset/73b0937bd931/
Log: (fijal, arigo, antocuni, rguillebert) Commit in-progress of resume
refactoring
diff --git a/rpython/jit/backend/llsupport/assembler.py
b/rpython/jit/backend/llsupport/assembler.py
--- a/rpython/jit/backend/llsupport/assembler.py
+++ b/rpython/jit/backend/llsupport/assembler.py
@@ -22,15 +22,13 @@
class GuardToken(object):
- def __init__(self, cpu, gcmap, faildescr, failargs, fail_locs, exc,
+ def __init__(self, cpu, gcmap, faildescr, exc,
frame_depth, is_guard_not_invalidated, is_guard_not_forced):
assert isinstance(faildescr, AbstractFailDescr)
self.cpu = cpu
self.faildescr = faildescr
- self.failargs = failargs
- self.fail_locs = fail_locs
- self.gcmap = self.compute_gcmap(gcmap, failargs,
- fail_locs, frame_depth)
+ #self.gcmap = self.compute_gcmap(gcmap, failargs,
+ # fail_locs, frame_depth)
self.exc = exc
self.is_guard_not_invalidated = is_guard_not_invalidated
self.is_guard_not_forced = is_guard_not_forced
@@ -157,27 +155,7 @@
target = self.failure_recovery_code[exc + 2 * withfloats]
fail_descr = cast_instance_to_gcref(guardtok.faildescr)
fail_descr = rffi.cast(lltype.Signed, fail_descr)
- base_ofs = self.cpu.get_baseofs_of_frame_field()
- positions = [0] * len(guardtok.fail_locs)
- for i, loc in enumerate(guardtok.fail_locs):
- if loc is None:
- positions[i] = -1
- elif loc.is_stack():
- positions[i] = loc.value - base_ofs
- else:
- assert loc is not self.cpu.frame_reg # for now
- if self.cpu.IS_64_BIT:
- coeff = 1
- else:
- coeff = 2
- if loc.is_float():
- v = len(self.cpu.gen_regs) + loc.value * coeff
- else:
- v = self.cpu.all_reg_indexes[loc.value]
- positions[i] = v * WORD
- # write down the positions of locs
- guardtok.faildescr.rd_locs = positions
- # we want the descr to keep alive
+ # we want the descr to keep loop alive
guardtok.faildescr.rd_loop_token = self.current_clt
return fail_descr, target
diff --git a/rpython/jit/backend/llsupport/regalloc.py
b/rpython/jit/backend/llsupport/regalloc.py
--- a/rpython/jit/backend/llsupport/regalloc.py
+++ b/rpython/jit/backend/llsupport/regalloc.py
@@ -2,6 +2,7 @@
from rpython.jit.metainterp.history import Const, Box, REF, JitCellToken
from rpython.rlib.objectmodel import we_are_translated, specialize
from rpython.jit.metainterp.resoperation import rop
+from rpython.jit.backend.llsupport.resumebuilder import LivenessAnalyzer
try:
from collections import OrderedDict
@@ -689,6 +690,22 @@
produced = {}
last_used = {}
last_real_usage = {}
+ liveness_analyzer = LivenessAnalyzer()
+ for position, op in enumerate(operations):
+ if op.getopnum() == rop.ENTER_FRAME:
+ liveness_analyzer.enter_frame(op.getdescr())
+ elif op.getopnum() == rop.LEAVE_FRAME:
+ liveness_analyzer.leave_frame()
+ elif op.getopnum() == rop.RESUME_PUT:
+ liveness_analyzer.put(op.getarg(0), op.getarg(1).getint(),
+ op.getarg(2).getint())
+ elif op.is_guard():
+ framestack = liveness_analyzer.get_live_info()
+ for frame in framestack:
+ for item in frame:
+ if item is not None:
+ last_used[item] = position
+
for i in range(len(operations)-1, -1, -1):
op = operations[i]
if op.result:
@@ -703,6 +720,8 @@
continue
if arg not in last_used:
last_used[arg] = i
+ else:
+ last_used[arg] = max(last_used[arg], i)
if opnum != rop.JUMP and opnum != rop.LABEL:
if arg not in last_real_usage:
last_real_usage[arg] = i
diff --git a/rpython/jit/backend/llsupport/resumebuilder.py
b/rpython/jit/backend/llsupport/resumebuilder.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/backend/llsupport/resumebuilder.py
@@ -0,0 +1,58 @@
+
+from rpython.jit.metainterp.resoperation import rop
+from rpython.jit.metainterp.history import ConstInt
+from rpython.jit.codewriter.jitcode import JitCode
+
+class LivenessAnalyzer(object):
+ def __init__(self):
+ self.framestack = []
+
+ def enter_frame(self, jitcode):
+ assert isinstance(jitcode, JitCode)
+ self.framestack.append([None] * jitcode.num_regs())
+
+ def put(self, value, depth, position):
+ # - depth - 1 can be expressed as ~depth (haha)
+ self.framestack[- depth - 1][position] = value
+
+ def get_live_info(self):
+ return self.framestack
+
+ def leave_frame(self):
+ self.framestack.pop()
+
+class ResumeBuilder(object):
+ def __init__(self, regalloc):
+ self.framestack = []
+ self.newops = []
+ self.regalloc = regalloc
+
+ def process(self, op):
+ oplist[op.getopnum()](self, op)
+
+ def process_enter_frame(self, op):
+ self.framestack.append(None)
+ self.newops.append(op)
+
+ def process_resume_put(self, op):
+ v = op.getarg(0)
+ loc = self.regalloc.loc(v)
+ pos = loc.get_jitframe_position()
+ self.newops.append(op.copy_and_change(rop.RESUME_PUT,
+ args=[ConstInt(pos),
+ op.getarg(1),
+ op.getarg(2)]))
+
+ def process_leave_frame(self, op):
+ self.framestack.pop()
+ self.newops.append(op)
+
+ def not_implemented_op(self, op):
+ print "Not implemented", op.getopname()
+ raise NotImplementedError(op.getopname())
+
+oplist = [ResumeBuilder.not_implemented_op] * rop._LAST
+for name, value in ResumeBuilder.__dict__.iteritems():
+ if name.startswith('process_'):
+ num = getattr(rop, name[len('process_'):].upper())
+ oplist[num] = value
diff --git a/rpython/jit/backend/llsupport/test/test_regalloc.py
b/rpython/jit/backend/llsupport/test/test_regalloc.py
--- a/rpython/jit/backend/llsupport/test/test_regalloc.py
+++ b/rpython/jit/backend/llsupport/test/test_regalloc.py
@@ -3,6 +3,7 @@
BoxPtr
from rpython.jit.backend.llsupport.regalloc import FrameManager, LinkedList
from rpython.jit.backend.llsupport.regalloc import RegisterManager as
BaseRegMan
+from rpython.jit.backend.llsupport.regalloc import compute_vars_longevity
def newboxes(*values):
return [BoxInt(v) for v in values]
@@ -68,7 +69,7 @@
class MockAsm(object):
def __init__(self):
self.moves = []
-
+
def regalloc_mov(self, from_loc, to_loc):
self.moves.append((from_loc, to_loc))
@@ -98,7 +99,7 @@
rm._check_invariants()
assert len(rm.free_regs) == 4
assert len(rm.reg_bindings) == 0
-
+
def test_register_exhaustion(self):
boxes, longevity = boxes_and_longevity(5)
rm = RegisterManager(longevity)
@@ -114,7 +115,7 @@
class XRegisterManager(RegisterManager):
no_lower_byte_regs = [r2, r3]
-
+
rm = XRegisterManager(longevity)
rm.next_instruction()
loc0 = rm.try_allocate_reg(b0, need_lower_byte=True)
@@ -149,7 +150,7 @@
class XRegisterManager(RegisterManager):
no_lower_byte_regs = [r2, r3]
-
+
rm = XRegisterManager(longevity,
frame_manager=fm,
assembler=MockAsm())
@@ -172,7 +173,7 @@
assert isinstance(loc, FakeReg)
assert loc not in [r2, r3]
rm._check_invariants()
-
+
def test_make_sure_var_in_reg(self):
boxes, longevity = boxes_and_longevity(5)
fm = TFrameManager()
@@ -186,7 +187,7 @@
loc = rm.make_sure_var_in_reg(b0)
assert isinstance(loc, FakeReg)
rm._check_invariants()
-
+
def test_force_result_in_reg_1(self):
b0, b1 = newboxes(0, 0)
longevity = {b0: (0, 1), b1: (1, 3)}
@@ -341,7 +342,7 @@
rm.after_call(boxes[-1])
assert len(rm.reg_bindings) == 1
rm._check_invariants()
-
+
def test_different_frame_width(self):
class XRegisterManager(RegisterManager):
@@ -358,7 +359,7 @@
xrm.loc(f0)
rm.loc(b0)
assert fm.get_frame_depth() == 3
-
+
def test_spilling(self):
b0, b1, b2, b3, b4, b5 = newboxes(0, 1, 2, 3, 4, 5)
longevity = {b0: (0, 3), b1: (0, 3), b3: (0, 5), b2: (0, 2), b4: (1,
4), b5: (1, 3)}
@@ -592,3 +593,31 @@
assert fm.get_loc_index(floc) == 0
for box in fm.bindings.keys():
fm.mark_as_free(box)
+
+def test_vars_longevity():
+ from rpython.jit.tool.oparser import parse
+ from rpython.jit.codewriter.jitcode import JitCode
+
+ class MockJitcode(JitCode):
+ def __init__(self, no):
+ self.no = no
+
+ def num_regs(self):
+ return self.no
+
+ loop = parse("""
+ [i0, i1]
+ enter_frame(0, descr=jitcode)
+ resume_put(i0, 0, 1)
+ guard_true(1)
+ i5 = int_add(1, 2)
+ resume_put(i1, 0, 1)
+ i4 = int_add(1, 2)
+ guard_false(1)
+ i3 = int_add(1, 2)
+ leave_frame()
+ """, namespace={'jitcode': MockJitcode(3)})
+ longevity, _ = compute_vars_longevity(loop.inputargs, loop.operations)
+ assert longevity[loop.inputargs[0]] == (0, 2)
+ assert longevity[loop.inputargs[1]] == (0, 6)
+
diff --git a/rpython/jit/backend/x86/assembler.py
b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -1719,9 +1719,8 @@
is_guard_not_invalidated = guard_opnum == rop.GUARD_NOT_INVALIDATED
is_guard_not_forced = guard_opnum == rop.GUARD_NOT_FORCED
gcmap = allocate_gcmap(self, frame_depth, JITFRAME_FIXED_SIZE)
- XXX
- return GuardToken(self.cpu, gcmap, faildescr, failargs,
- fail_locs, exc, frame_depth,
+ return GuardToken(self.cpu, gcmap, faildescr,
+ exc, frame_depth,
is_guard_not_invalidated, is_guard_not_forced)
def generate_propagate_error_64(self):
diff --git a/rpython/jit/codewriter/jitcode.py
b/rpython/jit/codewriter/jitcode.py
--- a/rpython/jit/codewriter/jitcode.py
+++ b/rpython/jit/codewriter/jitcode.py
@@ -47,6 +47,9 @@
def num_regs_f(self):
return ord(self.c_num_regs_f)
+ def num_regs(self):
+ return self.num_regs_i() + self.num_regs_r() + self.num_regs_f()
+
def has_liveness_info(self, pc):
return pc in self.liveness
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit