[pypy-svn] pypy default: Fixes test_virtual_streq_bug by introducing a dict storgin call_pure results indexed by its constant arguments. Breaks test_ztranslation
hakanardo
commits-noreply at bitbucket.org
Wed Mar 16 11:14:44 CET 2011
Author: Hakan Ardo <hakan at debian.org>
Branch:
Changeset: r42705:581436e2ded2
Date: 2011-03-16 10:09 +0100
http://bitbucket.org/pypy/pypy/changeset/581436e2ded2/
Log: Fixes test_virtual_streq_bug by introducing a dict storgin call_pure
results indexed by its constant arguments. Breaks test_ztranslation
diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py
--- a/pypy/jit/metainterp/compile.py
+++ b/pypy/jit/metainterp/compile.py
@@ -39,7 +39,10 @@
def create_empty_loop(metainterp, name_prefix=''):
name = metainterp.staticdata.stats.name_for_new_loop()
- return TreeLoop(name_prefix + name)
+ loop = TreeLoop(name_prefix + name)
+ loop.call_pure_results = metainterp.call_pure_results
+ return loop
+
def make_loop_token(nb_args, jitdriver_sd):
loop_token = LoopToken()
diff --git a/pypy/jit/metainterp/history.py b/pypy/jit/metainterp/history.py
--- a/pypy/jit/metainterp/history.py
+++ b/pypy/jit/metainterp/history.py
@@ -787,6 +787,7 @@
inputargs = None
operations = None
token = None
+ call_pure_results = None
def __init__(self, name):
self.name = name
diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -21,7 +21,7 @@
from pypy.rlib.objectmodel import specialize
from pypy.jit.codewriter.jitcode import JitCode, SwitchDictDescr, MissingLiveness
from pypy.jit.codewriter import heaptracker, longlong
-from pypy.jit.metainterp.optimizeutil import RetraceLoop
+from pypy.jit.metainterp.optimizeutil import RetraceLoop, args_dict_box, args_dict
# ____________________________________________________________
@@ -1410,6 +1410,7 @@
self.free_frames_list = []
self.last_exc_value_box = None
self.retracing_loop_from = None
+ self.call_pure_results = args_dict_box()
def perform_call(self, jitcode, boxes, greenkey=None):
# causes the metainterp to enter the given subfunction
@@ -2278,7 +2279,9 @@
return resbox_as_const
# not all constants (so far): turn CALL into CALL_PURE, which might
# be either removed later by optimizeopt or turned back into CALL.
- newop = op.copy_and_change(rop.CALL_PURE, args=[resbox_as_const]+op.getarglist())
+ arg_consts = [a.constbox() for a in op.getarglist()]
+ self.call_pure_results[arg_consts] = resbox_as_const
+ newop = op.copy_and_change(rop.CALL_PURE, args=op.getarglist())
self.history.operations[-1] = newop
return resbox
diff --git a/pypy/jit/metainterp/optimizeopt/string.py b/pypy/jit/metainterp/optimizeopt/string.py
--- a/pypy/jit/metainterp/optimizeopt/string.py
+++ b/pypy/jit/metainterp/optimizeopt/string.py
@@ -652,7 +652,7 @@
if not self.enabled:
self.emit_operation(op)
return
-
+
opnum = op.getopnum()
for value, func in optimize_ops:
if opnum == value:
diff --git a/pypy/jit/metainterp/test/test_compile.py b/pypy/jit/metainterp/test/test_compile.py
--- a/pypy/jit/metainterp/test/test_compile.py
+++ b/pypy/jit/metainterp/test/test_compile.py
@@ -60,6 +60,7 @@
pass
class FakeMetaInterp:
+ call_pure_results = {}
class jitdriver_sd:
warmstate = FakeState()
diff --git a/pypy/jit/metainterp/optimizeopt/simplify.py b/pypy/jit/metainterp/optimizeopt/simplify.py
--- a/pypy/jit/metainterp/optimizeopt/simplify.py
+++ b/pypy/jit/metainterp/optimizeopt/simplify.py
@@ -5,7 +5,7 @@
class OptSimplify(Optimization):
def optimize_CALL_PURE(self, op):
- args = op.getarglist()[1:]
+ args = op.getarglist()
self.emit_operation(ResOperation(rop.CALL, args, op.result,
op.getdescr()))
diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py
--- a/pypy/jit/metainterp/optimizeopt/rewrite.py
+++ b/pypy/jit/metainterp/optimizeopt/rewrite.py
@@ -155,16 +155,24 @@
self.emit_operation(op)
def optimize_CALL_PURE(self, op):
+ arg_consts = []
for i in range(op.numargs()):
arg = op.getarg(i)
- if self.get_constant_box(arg) is None:
+ const = self.get_constant_box(arg)
+ if const is None:
break
+ arg_consts.append(const)
else:
- # all constant arguments: constant-fold away
- self.make_constant(op.result, op.getarg(0))
- return
+ # all constant arguments: check if we already know the reslut
+ try:
+ result = self.optimizer.call_pure_results[arg_consts]
+ except KeyError:
+ pass
+ else:
+ self.make_constant(op.result, result)
+ return
# replace CALL_PURE with just CALL
- args = op.getarglist()[1:]
+ args = op.getarglist()
self.emit_operation(ResOperation(rop.CALL, args, op.result,
op.getdescr()))
diff --git a/pypy/jit/metainterp/optimizeutil.py b/pypy/jit/metainterp/optimizeutil.py
--- a/pypy/jit/metainterp/optimizeutil.py
+++ b/pypy/jit/metainterp/optimizeutil.py
@@ -108,3 +108,6 @@
def args_dict():
return r_dict(args_eq, args_hash)
+
+def args_dict_box():
+ return r_dict(args_eq, args_hash)
diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py
--- a/pypy/jit/metainterp/optimizeopt/optimizer.py
+++ b/pypy/jit/metainterp/optimizeopt/optimizer.py
@@ -258,6 +258,8 @@
self.posponedop = None
self.exception_might_have_happened = False
self.newoperations = []
+ if loop is not None:
+ self.call_pure_results = loop.call_pure_results
self.set_optimizations(optimizations)
diff --git a/pypy/jit/metainterp/test/test_optimizeopt.py b/pypy/jit/metainterp/test/test_optimizeopt.py
--- a/pypy/jit/metainterp/test/test_optimizeopt.py
+++ b/pypy/jit/metainterp/test/test_optimizeopt.py
@@ -14,6 +14,7 @@
from pypy.jit.metainterp.resoperation import rop, opname, ResOperation
from pypy.jit.tool.oparser import pure_parse
from pypy.jit.metainterp.test.test_optimizebasic import equaloplists
+from pypy.jit.metainterp.optimizeutil import args_dict
class Fake(object):
failargs_limit = 1000
@@ -161,7 +162,8 @@
assert equaloplists(optimized.operations,
expected.operations, False, remap, text_right)
- def optimize_loop(self, ops, optops, expected_preamble=None):
+ def optimize_loop(self, ops, optops, expected_preamble=None,
+ call_pure_results=None):
loop = self.parse(ops)
if optops != "crash!":
expected = self.parse(optops)
@@ -171,6 +173,10 @@
expected_preamble = self.parse(expected_preamble)
#
self.loop = loop
+ loop.call_pure_results = args_dict()
+ if call_pure_results is not None:
+ for k, v in call_pure_results.items():
+ loop.call_pure_results[list(k)] = v
loop.preamble = TreeLoop('preamble')
loop.preamble.inputargs = loop.inputargs
loop.preamble.token = LoopToken()
@@ -2893,7 +2899,7 @@
ops = '''
[p1, i1, i4]
setfield_gc(p1, i1, descr=valuedescr)
- i3 = call_pure(42, p1, descr=plaincalldescr)
+ i3 = call_pure(p1, descr=plaincalldescr)
setfield_gc(p1, i3, descr=valuedescr)
jump(p1, i4, i3)
'''
@@ -2911,7 +2917,7 @@
ops = '''
[p1, i1, i4]
setfield_gc(p1, i1, descr=valuedescr)
- i3 = call_pure(42, p1, descr=plaincalldescr)
+ i3 = call_pure(p1, descr=plaincalldescr)
setfield_gc(p1, i1, descr=valuedescr)
jump(p1, i4, i3)
'''
@@ -2931,12 +2937,14 @@
# the result of the call, recorded as the first arg), or turned into
# a regular CALL.
# XXX can this test be improved with unrolling?
+ arg_consts = [ConstInt(i) for i in (123456, 4, 5, 6)]
+ call_pure_results = {tuple(arg_consts): ConstInt(42)}
ops = '''
[i0, i1, i2]
escape(i1)
escape(i2)
- i3 = call_pure(42, 123456, 4, 5, 6, descr=plaincalldescr)
- i4 = call_pure(43, 123456, 4, i0, 6, descr=plaincalldescr)
+ i3 = call_pure(123456, 4, 5, 6, descr=plaincalldescr)
+ i4 = call_pure(123456, 4, i0, 6, descr=plaincalldescr)
jump(i0, i3, i4)
'''
preamble = '''
@@ -2953,7 +2961,7 @@
i4 = call(123456, 4, i0, 6, descr=plaincalldescr)
jump(i0, i4)
'''
- self.optimize_loop(ops, expected, preamble)
+ self.optimize_loop(ops, expected, preamble, call_pure_results)
# ----------
diff --git a/pypy/jit/metainterp/test/test_optimizebasic.py b/pypy/jit/metainterp/test/test_optimizebasic.py
--- a/pypy/jit/metainterp/test/test_optimizebasic.py
+++ b/pypy/jit/metainterp/test/test_optimizebasic.py
@@ -11,6 +11,7 @@
from pypy.jit.metainterp import executor, compile, resume, history
from pypy.jit.metainterp.resoperation import rop, opname, ResOperation
from pypy.jit.tool.oparser import pure_parse
+from pypy.jit.metainterp.optimizeutil import args_dict
##class FakeFrame(object):
## parent_resumedata_snapshot = None
@@ -245,10 +246,14 @@
assert equaloplists(optimized.operations,
expected.operations, False, remap)
- def optimize_loop(self, ops, optops):
+ def optimize_loop(self, ops, optops, call_pure_results=None):
loop = self.parse(ops)
#
self.loop = loop
+ loop.call_pure_results = args_dict()
+ if call_pure_results is not None:
+ for k, v in call_pure_results.items():
+ loop.call_pure_results[list(k)] = v
metainterp_sd = FakeMetaInterpStaticData(self.cpu)
if hasattr(self, 'vrefinfo'):
metainterp_sd.virtualref_info = self.vrefinfo
@@ -2861,7 +2866,7 @@
ops = '''
[p1, i1]
setfield_gc(p1, i1, descr=valuedescr)
- i3 = call_pure(42, p1, descr=plaincalldescr)
+ i3 = call_pure(p1, descr=plaincalldescr)
setfield_gc(p1, i3, descr=valuedescr)
jump(p1, i3)
'''
@@ -2880,12 +2885,14 @@
# time. Check that it is either constant-folded (and replaced by
# the result of the call, recorded as the first arg), or turned into
# a regular CALL.
+ arg_consts = [ConstInt(i) for i in (123456, 4, 5, 6)]
+ call_pure_results = {tuple(arg_consts): ConstInt(42)}
ops = '''
[i0, i1, i2]
escape(i1)
escape(i2)
- i3 = call_pure(42, 123456, 4, 5, 6, descr=plaincalldescr)
- i4 = call_pure(43, 123456, 4, i0, 6, descr=plaincalldescr)
+ i3 = call_pure(123456, 4, 5, 6, descr=plaincalldescr)
+ i4 = call_pure(123456, 4, i0, 6, descr=plaincalldescr)
jump(i0, i3, i4)
'''
expected = '''
@@ -2895,7 +2902,7 @@
i4 = call(123456, 4, i0, 6, descr=plaincalldescr)
jump(i0, 42, i4)
'''
- self.optimize_loop(ops, expected)
+ self.optimize_loop(ops, expected, call_pure_results)
def test_vref_nonvirtual_nonescape(self):
ops = """
More information about the Pypy-commit
mailing list