[pypy-svn] r63453 - in pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp: . test
arigo at codespeak.net
arigo at codespeak.net
Tue Mar 31 17:44:49 CEST 2009
Author: arigo
Date: Tue Mar 31 17:44:47 2009
New Revision: 63453
Modified:
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/codewriter.py
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_basic.py
Log:
This is a partial revert of r63074.
Instead of making the liveboxes list as compact as possible for
each of the true and false cases, generate a single livebox list
for both cases. This is needed for the following checkin.
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/codewriter.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/codewriter.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/codewriter.py Tue Mar 31 17:44:47 2009
@@ -263,9 +263,6 @@
def make_bytecode_block(self, block):
if block.exits == ():
- # note: the same label might be generated multiple times, but a
- # jump to this label is free to pick whichever target so it's fine
- self.emit(label(block))
if len(block.inputargs) == 1:
# return from function
returnvar, = block.inputargs
@@ -322,16 +319,19 @@
linkfalse, linktrue = block.exits
if linkfalse.llexitcase == True:
linkfalse, linktrue = linktrue, linkfalse
- truelist = self.get_renaming_list(linktrue.args)
- falselist = self.get_renaming_list(linkfalse.args)
self.emit("goto_if_not",
- self.var_position(block.exitswitch),
- tlabel(linkfalse.target))
- self.emit(len(truelist), *truelist)
- self.emit(len(falselist), *falselist)
+ tlabel(linkfalse),
+ self.var_position(block.exitswitch))
+ self.minimize_variables(argument_only=True, exitswitch=False)
+ truerenaming = self.insert_renaming(linktrue.args)
+ falserenaming = self.insert_renaming(linkfalse.args)
+ # true path:
+ self.emit(*truerenaming)
self.make_bytecode_block(linktrue.target)
- if linkfalse.target not in self.seen_blocks:
- self.make_bytecode_block(linkfalse.target)
+ # false path:
+ self.emit(label(linkfalse))
+ self.emit(*falserenaming)
+ self.make_bytecode_block(linkfalse.target)
else:
self.minimize_variables()
switches = [link for link in block.exits
@@ -426,11 +426,12 @@
else:
return ["make_new_vars_%d" % len(list)] + list
- def minimize_variables(self):
+ def minimize_variables(self, argument_only=False, exitswitch=True):
if self.dont_minimize_variables:
+ assert not argument_only
return
block, index = self.current_position
- allvars = self.vars_alive_through_op(block, index)
+ allvars = self.vars_alive_through_op(block, index, exitswitch)
seen = {} # {position: unique Variable} without Voids
unique = {} # {Variable: unique Variable} without Voids
for v in allvars:
@@ -441,7 +442,12 @@
vars = seen.items()
vars.sort()
vars = [v1 for pos, v1 in vars]
- self.emit(*self.insert_renaming(vars))
+ if argument_only:
+ # only generate the list of vars as an arg in a complex operation
+ renaming_list = self.get_renaming_list(vars)
+ self.emit(len(renaming_list), *renaming_list)
+ else:
+ self.emit(*self.insert_renaming(vars))
self.free_vars = 0
self.var_positions.clear()
for v1 in vars:
@@ -449,7 +455,7 @@
for v, v1 in unique.items():
self.var_positions[v] = self.var_positions[v1]
- def vars_alive_through_op(self, block, index):
+ def vars_alive_through_op(self, block, index, include_exitswitch=True):
"""Returns the list of variables that are really used by or after
the operation at 'index'.
"""
@@ -468,7 +474,8 @@
for op in block.operations[index:]:
for v in op.args:
see(v)
- see(block.exitswitch)
+ if include_exitswitch:
+ see(block.exitswitch)
for link in block.exits:
for v in link.args:
if v not in (link.last_exception, link.last_exc_value):
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/pyjitpl.py Tue Mar 31 17:44:47 2009
@@ -176,6 +176,11 @@
count = self.load_int()
return [self.load_const_arg() for i in range(count)]
+ def ignore_varargs(self):
+ count = self.load_int()
+ for i in range(count):
+ self.load_int()
+
def getvarenv(self, i):
return self.env[i]
@@ -279,25 +284,27 @@
def opimpl_goto(self, target):
self.pc = target
- @arguments("box", "jumptarget", "varargs", "varargs")
- def opimpl_goto_if_not(self, box, target, truelist, falselist):
+ @arguments("orgpc", "jumptarget", "box", "varargs")
+ def opimpl_goto_if_not(self, pc, target, box, livelist):
switchcase = box.getint()
if switchcase:
- currentpc = self.pc
- currentenv = truelist
- targetpc = target
- targetenv = falselist
opnum = rop.GUARD_TRUE
else:
- currentpc = target
- currentenv = falselist
- targetpc = self.pc
- targetenv = truelist
+ self.pc = target
opnum = rop.GUARD_FALSE
- self.env = targetenv
- self.generate_guard(targetpc, opnum, box)
- self.pc = currentpc
- self.env = currentenv
+ self.env = livelist
+ self.generate_guard(pc, opnum, box)
+
+ def follow_jump(self):
+ self.pc += 1 # past the bytecode for 'goto_if_not'
+ target = self.load_3byte() # load the 'target' argument
+ self.pc = target # jump
+
+ def dont_follow_jump(self):
+ self.pc += 1 # past the bytecode for 'goto_if_not'
+ self.load_3byte() # past the 'target' argument
+ self.load_int() # past the 'box' argument
+ self.ignore_varargs() # past the 'livelist' argument
@arguments("orgpc", "box", "constargs", "jumptargets")
def opimpl_switch(self, pc, valuebox, constargs, jumptargets):
@@ -847,9 +854,7 @@
self.initialize_state_from_guard_failure(guard_failure)
key = guard_failure.key
try:
- if key.guard_op.opnum in (rop.GUARD_NO_EXCEPTION,
- rop.GUARD_EXCEPTION):
- self.handle_exception()
+ self.prepare_resume_from_failure(key.guard_op.opnum)
self.interpret()
assert False, "should always raise"
except GenerateMergePoint, gmp:
@@ -866,6 +871,14 @@
gmp.argboxes[num_green_args:])
return (loop, residual_args)
+ def prepare_resume_from_failure(self, opnum):
+ if opnum == rop.GUARD_TRUE: # a goto_if_not that fails only now
+ self.framestack[-1].follow_jump()
+ elif opnum == rop.GUARD_FALSE: # a goto_if_not that stops failing
+ self.framestack[-1].dont_follow_jump()
+ elif opnum == rop.GUARD_NO_EXCEPTION or opnum == rop.GUARD_EXCEPTION:
+ self.handle_exception()
+
def compile(self, original_boxes, live_arg_boxes):
num_green_args = self.num_green_args
for i in range(num_green_args):
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_basic.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_basic.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/test/test_basic.py Tue Mar 31 17:44:47 2009
@@ -152,8 +152,9 @@
for op in get_stats().loops[0]._all_operations():
if op.getopname() == 'fail':
liveboxes = op.args
- assert len(liveboxes) == 1
- assert isinstance(liveboxes[0], history.BoxInt)
+ assert len(liveboxes) == 3
+ for box in liveboxes:
+ assert isinstance(box, history.BoxInt)
found += 1
assert found == 1
More information about the Pypy-commit
mailing list