Author: Maciej Fijalkowski <[email protected]>
Branch: resume-refactor
Changeset: r68601:95b2f5879a2a
Date: 2014-01-12 11:25 +0100
http://bitbucket.org/pypy/pypy/changeset/95b2f5879a2a/
Log: (fijal, rguillebert) fix test_resumebuilder for removal of
backend_attach
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
@@ -11,7 +11,7 @@
class TempBox(Box):
type = 't' # none of the types
-
+
def __init__(self):
pass
@@ -688,8 +688,18 @@
else:
return [self.loc(op.getarg(0))]
+def flatten(inputframes):
+ count = 0
+ for frame in inputframes:
+ count += len(frame)
+ inputargs = [None] * count
+ i = 0
+ for frame in inputframes:
+ inputargs[i:i + len(frame)] = frame
+ i += len(frame)
+ return inputargs
-def compute_vars_longevity(inputargs, operations, descr=None):
+def compute_vars_longevity(inputframes, operations, descr=None):
# compute a dictionary that maps variables to index in
# operations that is a "last-time-seen"
@@ -701,7 +711,12 @@
last_used = {}
last_real_usage = {}
frontend_alive = {}
- liveness_analyzer = LivenessAnalyzer()
+ if descr is None:
+ inputargs = inputframes[0]
+ liveness_analyzer = LivenessAnalyzer()
+ else:
+ inputargs = flatten(inputframes)
+ liveness_analyzer = LivenessAnalyzer(inputframes)
start_pos = 0
for position, op in enumerate(operations):
if op.is_guard():
diff --git a/rpython/jit/backend/llsupport/resumebuilder.py
b/rpython/jit/backend/llsupport/resumebuilder.py
--- a/rpython/jit/backend/llsupport/resumebuilder.py
+++ b/rpython/jit/backend/llsupport/resumebuilder.py
@@ -4,11 +4,15 @@
from rpython.jit.metainterp.resume2 import ResumeBytecode, AbstractResumeReader
class LivenessAnalyzer(AbstractResumeReader):
- def __init__(self):
+ def __init__(self, inputframes=None):
self.liveness = {}
self.frame_starts = [0]
self.framestack = []
self.deps = {}
+ if inputframes is not None:
+ for frame in inputframes:
+ self.frame_starts.append(self.frame_starts[-1] + len(frame))
+ self.framestack.append(frame)
def enter_frame(self, pc, jitcode):
self.frame_starts.append(self.frame_starts[-1] + jitcode.num_regs())
@@ -47,19 +51,33 @@
self.regalloc = regalloc
self.current_attachment = {}
self.frontend_liveness = frontend_liveness
+ self.frontend_pos = {}
def process(self, op):
- self.newops.append(op)
+ if op.getopnum() == rop.RESUME_PUT:
+ box = op.getarg(0)
+ args = op.getarglist()
+ pos = self.regalloc.loc(box).get_jitframe_position()
+ self.current_attachment[box] = pos
+ self.frontend_pos[box] = (args[1], args[2])
+ args[0] = ConstInt(pos)
+ newop = op.copy_and_change(rop.RESUME_PUT, args=args)
+ else:
+ newop = op
+ self.newops.append(newop)
def _mark_visited(self, v, loc):
pos = loc.get_jitframe_position()
if (v not in self.frontend_liveness or
self.frontend_liveness[v] < self.regalloc.rm.position):
return
- if (v not in self.current_attachment or
- self.current_attachment[v] != pos):
- self.newops.append(ResOperation(rop.BACKEND_ATTACH, [
- v, ConstInt(pos)], None))
+ if v not in self.current_attachment:
+ return
+ if self.current_attachment[v] != pos:
+ frame_index, frame_pos = self.frontend_pos[v]
+ self.newops.append(ResOperation(rop.RESUME_PUT, [
+ ConstInt(pos), frame_index, frame_pos],
+ None))
self.current_attachment[v] = pos
def mark_resumable_position(self):
diff --git a/rpython/jit/backend/llsupport/test/test_resumebuilder.py
b/rpython/jit/backend/llsupport/test/test_resumebuilder.py
--- a/rpython/jit/backend/llsupport/test/test_resumebuilder.py
+++ b/rpython/jit/backend/llsupport/test/test_resumebuilder.py
@@ -35,19 +35,15 @@
self.cpu.compile_loop(None, loop.inputargs, loop.operations,
looptoken)
descr = loop.operations[2].getdescr()
- assert descr.rd_bytecode_position == 3
+ assert descr.rd_bytecode_position == 2
expected_resume = parse("""
- [i0]
+ []
enter_frame(-1, descr=jitcode)
- resume_put(i0, 0, 2)
- backend_attach(i0, 28)
+ resume_put(28, 0, 2)
leave_frame()
""", namespace={'jitcode': jitcode})
- i0 = descr.rd_resume_bytecode.opcodes[1].getarg(0)
- i0b = expected_resume.inputargs[0]
equaloplists(descr.rd_resume_bytecode.opcodes,
- expected_resume.operations,
- remap={i0b:i0})
+ expected_resume.operations)
def test_resume_new(self):
jitcode = JitCode("name")
@@ -76,17 +72,13 @@
enter_frame(-1, descr=jitcode)
p0 = resume_new(descr=structdescr)
resume_setfield_gc(p0, i0, descr=fielddescr)
- resume_put(p0, 0, 0)
- backend_attach(i0, 28)
+ resume_put(30, 0, 0)
leave_frame()
""", namespace=namespace)
descr = loop.operations[-3].getdescr()
- assert descr.rd_bytecode_position == 5
- i0 = descr.rd_resume_bytecode.opcodes[2].getarg(1)
- i0b = expected_resume.inputargs[0]
+ assert descr.rd_bytecode_position == 4
equaloplists(descr.rd_resume_bytecode.opcodes,
- expected_resume.operations,
- remap={i0b:i0})
+ expected_resume.operations)
def test_spill(self):
jitcode = JitCode("name")
@@ -111,17 +103,13 @@
expected_resume = parse("""
[i2]
enter_frame(-1, descr=jitcode)
- resume_put(i2, 0, 1)
- backend_attach(i2, 1)
- backend_attach(i2, 29)
+ resume_put(1, 0, 1)
+ resume_put(29, 0, 1)
leave_frame()
""", namespace={'jitcode':jitcode})
descr1 = loop.operations[3].getdescr()
descr2 = loop.operations[5].getdescr()
- assert descr1.rd_bytecode_position == 3
- assert descr2.rd_bytecode_position == 4
- i0 = descr1.rd_resume_bytecode.opcodes[1].getarg(0)
- i0b = expected_resume.inputargs[0]
+ assert descr1.rd_bytecode_position == 2
+ assert descr2.rd_bytecode_position == 3
equaloplists(descr1.rd_resume_bytecode.opcodes,
- expected_resume.operations,
- remap={i0b:i0})
+ expected_resume.operations)
diff --git a/rpython/jit/backend/model.py b/rpython/jit/backend/model.py
--- a/rpython/jit/backend/model.py
+++ b/rpython/jit/backend/model.py
@@ -68,7 +68,7 @@
"""
raise NotImplementedError
- def compile_bridge(self, logger, faildescr, inputargs, backend_positions,
+ def compile_bridge(self, logger, faildescr, inputframes, backend_positions,
operations, original_loop_token, log=True):
"""Assemble the bridge.
The FailDescr is the descr of the original guard that failed.
diff --git a/rpython/jit/backend/test/runner_test.py
b/rpython/jit/backend/test/runner_test.py
--- a/rpython/jit/backend/test/runner_test.py
+++ b/rpython/jit/backend/test/runner_test.py
@@ -248,7 +248,7 @@
]
locs = rebuild_locs_from_resumedata(faildescr1)
- self.cpu.compile_bridge(None, faildescr1, [i1b], locs, bridge,
looptoken)
+ self.cpu.compile_bridge(None, faildescr1, [[i1b]], locs, bridge,
looptoken)
deadframe = self.cpu.execute_token(looptoken, 2)
fail = self.cpu.get_latest_descr(deadframe)
@@ -294,7 +294,7 @@
descr=BasicFinalDescr(4)))
faillocs = rebuild_locs_from_resumedata(faildescr1)
- self.cpu.compile_bridge(None, faildescr1, [i0], faillocs, bridge,
looptoken)
+ self.cpu.compile_bridge(None, faildescr1, [[i0]], faillocs, bridge,
looptoken)
deadframe = self.cpu.execute_token(looptoken, 1)
fail = self.cpu.get_latest_descr(deadframe)
@@ -1426,7 +1426,7 @@
ResOperation(rop.JUMP, [f3]+fboxes2[1:], None, descr=targettoken),
]
- self.cpu.compile_bridge(None, faildescr1, fboxes2,
+ self.cpu.compile_bridge(None, faildescr1, [fboxes2],
rebuild_locs_from_resumedata(faildescr1),
bridge, looptoken)
@@ -1491,7 +1491,7 @@
ResOperation(rop.LEAVE_FRAME, [], None),
ResOperation(rop.FINISH, [], None, descr=faildescr2),
]
- self.cpu.compile_bridge(None, faildescr1, fboxes,
+ self.cpu.compile_bridge(None, faildescr1, [fboxes],
locs, bridgeops, looptoken)
args = [1,
longlong.getfloatstorage(132.25),
@@ -2953,7 +2953,7 @@
ResOperation(rop.GUARD_NOT_INVALIDATED, [],None, descr=faildescr2),
ResOperation(rop.FINISH, [i2], None, descr=BasicFinalDescr(3))
]
- self.cpu.compile_bridge(None, faildescr, [i2], locs, ops, looptoken)
+ self.cpu.compile_bridge(None, faildescr, [[i2]], locs, ops, looptoken)
deadframe = self.cpu.execute_token(looptoken, -42, 9)
fail = self.cpu.get_latest_descr(deadframe)
@@ -2993,7 +2993,7 @@
ops2 = [
ResOperation(rop.JUMP, [ConstInt(333)], None, descr=labeldescr),
]
- self.cpu.compile_bridge(None, faildescr, [], [], ops2, looptoken)
+ self.cpu.compile_bridge(None, faildescr, [[]], [], ops2, looptoken)
# run: must not be caught in an infinite loop
deadframe = self.cpu.execute_token(looptoken, 16)
fail = self.cpu.get_latest_descr(deadframe)
@@ -3872,7 +3872,7 @@
ResOperation(rop.INT_SUB, [i0, ConstInt(20)], i2),
ResOperation(rop.JUMP, [i2], None, descr=targettoken2),
]
- self.cpu.compile_bridge(None, faildescr, inputargs2, locs,
operations2, looptoken)
+ self.cpu.compile_bridge(None, faildescr, [inputargs2], locs,
operations2, looptoken)
deadframe = self.cpu.execute_token(looptoken, 2)
fail = self.cpu.get_latest_descr(deadframe)
@@ -3925,7 +3925,7 @@
self.cpu.assembler.set_debug(False)
info = self.cpu.compile_loop(None, loop.inputargs, loop.operations,
looptoken)
locs = rebuild_locs_from_resumedata(faildescr)
- bridge_info = self.cpu.compile_bridge(None, faildescr,
bridge.inputargs,
+ bridge_info = self.cpu.compile_bridge(None, faildescr,
[bridge.inputargs],
locs, bridge.operations,
looptoken)
self.cpu.assembler.set_debug(True) # always on untranslated
@@ -4027,7 +4027,7 @@
ResOperation(rop.JUMP, [i19], None, descr=targettoken1),
]
locs = rebuild_locs_from_resumedata(faildescr1)
- self.cpu.compile_bridge(None, faildescr1, inputargs, locs,
operations2, looptoken1)
+ self.cpu.compile_bridge(None, faildescr1, [inputargs], locs,
operations2, looptoken1)
looptoken2 = JitCellToken()
inputargs = [BoxInt()]
@@ -4054,7 +4054,7 @@
operations = [
ResOperation(rop.FINISH, [], None, descr=BasicFinalDescr(99))
]
- self.cpu.compile_bridge(None, faildescr, [], [], operations, looptoken)
+ self.cpu.compile_bridge(None, faildescr, [[]], [], operations,
looptoken)
deadframe = self.cpu.execute_token(looptoken, null_box.getref_base())
fail = self.cpu.get_latest_descr(deadframe)
assert fail.identifier == 99
@@ -4291,8 +4291,6 @@
assert values[0] == 0
def test_compile_bridge_while_running(self):
- XXX # it crashes because the regalloc does not inherit liveness
- # rules from the parent, while it shoul
def func():
jitcode2 = JitCode('name2')
@@ -4333,7 +4331,7 @@
'guarddescr': guarddescr, 'func2_ptr': func2_ptr,
'jitcode2': jitcode2})
locs = rebuild_locs_from_resumedata(faildescr)
- self.cpu.compile_bridge(None, faildescr, bridge.inputargs, locs,
+ self.cpu.compile_bridge(None, faildescr, [bridge.inputargs], locs,
bridge.operations, looptoken)
cpu = self.cpu
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
@@ -3,14 +3,14 @@
from rpython.jit.backend.llsupport import symbolic, jitframe, rewrite
from rpython.jit.backend.llsupport.assembler import (GuardToken, BaseAssembler,
- DEBUG_COUNTER, debug_bridge)
+ debug_bridge)
from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper
-from rpython.jit.backend.llsupport.gcmap import allocate_gcmap
+from rpython.jit.backend.llsupport.regalloc import flatten
from rpython.jit.metainterp.history import Const, Box, VOID
from rpython.jit.metainterp.history import AbstractFailDescr, INT, REF, FLOAT
from rpython.rtyper.lltypesystem import lltype, rffi, rstr, llmemory
from rpython.rtyper.lltypesystem.lloperation import llop
-from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref
+from rpython.rtyper.annlowlevel import cast_instance_to_gcref
from rpython.rlib.jit import AsmInfo
from rpython.jit.backend.model import CompiledLoopToken
from rpython.jit.backend.x86.regalloc import (RegAlloc, get_ebp_ofs,
@@ -29,7 +29,6 @@
from rpython.jit.metainterp.resoperation import rop
from rpython.jit.backend.x86 import support
from rpython.rlib.debug import debug_print, debug_start, debug_stop
-from rpython.rlib import rgc
from rpython.jit.codewriter.effectinfo import EffectInfo
from rpython.jit.codewriter import longlong
from rpython.rlib.rarithmetic import intmask, r_uint
@@ -514,11 +513,8 @@
return AsmInfo(ops_offset, rawstart + looppos,
size_excluding_failure_stuff - looppos)
- def assemble_bridge(self, logger, faildescr, inputargs, backend_positions,
+ def assemble_bridge(self, logger, faildescr, inputframes,
backend_positions,
operations, original_loop_token, log):
- if not we_are_translated():
- # Arguments should be unique
- assert len(set(inputargs)) == len(inputargs)
self.setup(original_loop_token)
descr_number = compute_unique_id(faildescr)
@@ -526,10 +522,11 @@
operations = self._inject_debugging_code(faildescr, operations,
'b', descr_number)
+ inputargs = flatten(inputframes)
arglocs = self.rebuild_faillocs_from_descr(faildescr, inputargs,
backend_positions)
regalloc = RegAlloc(self, self.cpu.translate_support_code)
startpos = self.mc.get_relative_pos()
- operations = regalloc.prepare_bridge(inputargs, arglocs,
+ operations = regalloc.prepare_bridge(inputframes, arglocs,
operations,
self.current_clt.allgcrefs,
self.current_clt.frame_info,
diff --git a/rpython/jit/backend/x86/regalloc.py
b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -9,7 +9,8 @@
from rpython.jit.backend.llsupport.gcmap import allocate_gcmap
from rpython.jit.backend.llsupport.resumebuilder import ResumeBuilder
from rpython.jit.backend.llsupport.regalloc import (FrameManager, BaseRegalloc,
- RegisterManager, TempBox, compute_vars_longevity, is_comparison_or_ovf_op)
+ RegisterManager, TempBox, compute_vars_longevity, is_comparison_or_ovf_op,
+ flatten)
from rpython.jit.backend.x86 import rx86
from rpython.jit.backend.x86.arch import (WORD, JITFRAME_FIXED_SIZE, IS_X86_32,
IS_X86_64)
@@ -132,13 +133,13 @@
self.jump_target_descr = None
self.final_jump_op = None
- def _prepare(self, inputargs, operations, allgcrefs, descr=None):
+ def _prepare(self, inputframes, operations, allgcrefs, descr=None):
cpu = self.assembler.cpu
self.fm = X86FrameManager(cpu.get_baseofs_of_frame_field())
operations = cpu.gc_ll_descr.rewrite_assembler(cpu, operations,
allgcrefs)
# compute longevity of variables
- x = compute_vars_longevity(inputargs, operations, descr)
+ x = compute_vars_longevity(inputframes, operations, descr)
longevity, last_real_usage, frontend_liveness = x
self.resumebuilder = ResumeBuilder(self, frontend_liveness, descr)
self.longevity = longevity
@@ -151,7 +152,7 @@
return operations
def prepare_loop(self, inputargs, operations, looptoken, allgcrefs):
- operations = self._prepare(inputargs, operations, allgcrefs)
+ operations = self._prepare([inputargs], operations, allgcrefs)
self._set_initial_bindings(inputargs, looptoken)
# note: we need to make a copy of inputargs because possibly_free_vars
# is also used on op args, which is a non-resizable list
@@ -162,10 +163,10 @@
self.min_bytes_before_label = 13
return operations
- def prepare_bridge(self, inputargs, arglocs, operations, allgcrefs,
+ def prepare_bridge(self, inputframes, arglocs, operations, allgcrefs,
frame_info, descr):
- operations = self._prepare(inputargs, operations, allgcrefs, descr)
- self._update_bindings(arglocs, inputargs)
+ operations = self._prepare(inputframes, operations, allgcrefs, descr)
+ self._update_bindings(arglocs, inputframes)
self.min_bytes_before_label = 0
return operations
@@ -229,10 +230,11 @@
else:
return self.xrm.make_sure_var_in_reg(var, forbidden_vars)
- def _update_bindings(self, locs, inputargs):
+ def _update_bindings(self, locs, inputframes):
# XXX this should probably go to llsupport/regalloc.py
used = {}
i = 0
+ inputargs = flatten(inputframes)
for loc in locs:
if loc is None: # xxx bit kludgy
loc = ebp
diff --git a/rpython/jit/backend/x86/runner.py
b/rpython/jit/backend/x86/runner.py
--- a/rpython/jit/backend/x86/runner.py
+++ b/rpython/jit/backend/x86/runner.py
@@ -93,11 +93,11 @@
return self.assembler.assemble_loop(logger, name, inputargs,
operations,
looptoken, log=log)
- def compile_bridge(self, logger, faildescr, inputargs, backend_positions,
+ def compile_bridge(self, logger, faildescr, inputframes, backend_positions,
operations, original_loop_token, log=True):
clt = original_loop_token.compiled_loop_token
clt.compiling_a_bridge()
- return self.assembler.assemble_bridge(logger, faildescr, inputargs,
+ return self.assembler.assemble_bridge(logger, faildescr, inputframes,
backend_positions, operations,
original_loop_token, log=log)
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
@@ -472,10 +472,11 @@
# resume-only operations that never make it to the real assembler
'ENTER_FRAME/1d',
'LEAVE_FRAME/0',
- 'RESUME_PUT/3',
+ 'RESUME_PUT/3', # arguments are as follows - box or position in the
backend,
+ # the frame index (counting from top) and position in the
+ # frontend
'RESUME_NEW/0d',
'RESUME_SETFIELD_GC/2d',
- 'BACKEND_ATTACH/2',
'_RESUME_LAST', # ----- end of resume only operations ------
'_NOSIDEEFFECT_LAST', # ----- end of no_side_effect operations -----
diff --git a/rpython/jit/metainterp/resume2.py
b/rpython/jit/metainterp/resume2.py
--- a/rpython/jit/metainterp/resume2.py
+++ b/rpython/jit/metainterp/resume2.py
@@ -41,8 +41,6 @@
elif op.getopnum() == rop.RESUME_SETFIELD_GC:
self.resume_setfield_gc(op.getarg(0), op.getarg(1),
op.getdescr())
- elif op.getopnum() == rop.BACKEND_ATTACH:
- self.resume_backend_attach(op.getarg(0), op.getarg(1).getint())
elif not op.is_resume():
pos += 1
continue
@@ -72,9 +70,6 @@
self.deadframe = deadframe
self.backend_values = {}
- def resume_backend_attach(self, box, position):
- self.backend_values[box] = position
-
def enter_frame(self, pc, jitcode):
if pc != -1:
self.metainterp.framestack[-1].pc = pc
diff --git a/rpython/jit/metainterp/test/test_resume2.py
b/rpython/jit/metainterp/test/test_resume2.py
--- a/rpython/jit/metainterp/test/test_resume2.py
+++ b/rpython/jit/metainterp/test/test_resume2.py
@@ -26,7 +26,7 @@
def dump_registers(self, lst, backend_values):
lst += [backend_values[x] for x in self.registers_i]
lst += [backend_values[x] for x in self.registers_r]
- lst += [backend_values[x] for x in self.registers_f]
+ lst += [backend_values[x] for x in self.registers_f]
class MockMetaInterp(object):
def __init__(self):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit