[pypy-svn] r77270 - in pypy/branch/jit-str/pypy/jit/codewriter: . test
arigo at codespeak.net
arigo at codespeak.net
Wed Sep 22 15:23:33 CEST 2010
Author: arigo
Date: Wed Sep 22 15:23:31 2010
New Revision: 77270
Modified:
pypy/branch/jit-str/pypy/jit/codewriter/call.py
pypy/branch/jit-str/pypy/jit/codewriter/effectinfo.py
pypy/branch/jit-str/pypy/jit/codewriter/jtransform.py
pypy/branch/jit-str/pypy/jit/codewriter/support.py
pypy/branch/jit-str/pypy/jit/codewriter/test/test_jtransform.py
pypy/branch/jit-str/pypy/jit/codewriter/test/test_list.py
Log:
Start refactoring ARRAYCOPY and the string operations. The idea is
to reach a point in which we can cleanly have a call operation
remain as a call, unless some special case applies in optimizeopt.
Modified: pypy/branch/jit-str/pypy/jit/codewriter/call.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/codewriter/call.py (original)
+++ pypy/branch/jit-str/pypy/jit/codewriter/call.py Wed Sep 22 15:23:31 2010
@@ -185,7 +185,7 @@
FUNC.RESULT)
return (fnaddr, calldescr)
- def getcalldescr(self, op):
+ def getcalldescr(self, op, oopspecindex=EffectInfo.OS_NONE):
"""Return the calldescr that describes all calls done by 'op'.
This returns a calldescr that we can put in the corresponding
call operation in the calling jitcode. It gets an effectinfo
@@ -226,7 +226,8 @@
extraeffect = EffectInfo.EF_CANNOT_RAISE
#
effectinfo = effectinfo_from_writeanalyze(
- self.readwrite_analyzer.analyze(op), self.cpu, extraeffect)
+ self.readwrite_analyzer.analyze(op), self.cpu, extraeffect,
+ oopspecindex)
#
if pure or loopinvariant:
assert effectinfo is not None
Modified: pypy/branch/jit-str/pypy/jit/codewriter/effectinfo.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/codewriter/effectinfo.py (original)
+++ pypy/branch/jit-str/pypy/jit/codewriter/effectinfo.py Wed Sep 22 15:23:31 2010
@@ -15,13 +15,27 @@
EF_LOOPINVARIANT = 3 #special: call it only once per loop
EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE = 4 #can raise and force virtualizables
+ # the 'oopspecindex' field is one of the following values:
+ OS_NONE = 0 # normal case, no oopspec
+ OS_ARRAYCOPY = 1 # "list.ll_arraycopy"
+ OS_STR_CONCAT = 2 # "stroruni.concat"
+ OS_STR_SLICE_STARTONLY = 3 # "stroruni.slice_startonly"
+ OS_STR_SLICE_STARTSTOP = 4 # "stroruni.slice_startstop"
+ OS_STR_SLICE_MINUSONE = 5 # "stroruni.slice_minusone"
+ OS_UNI_CONCAT = 82 # "stroruni.concat" (+80)
+ OS_UNI_SLICE_STARTONLY = 83 # "stroruni.slice_startonly" (+80)
+ OS_UNI_SLICE_STARTSTOP = 84 # "stroruni.slice_startstop" (+80)
+ OS_UNI_SLICE_MINUSONE = 85 # "stroruni.slice_minusone" (+80)
+
def __new__(cls, readonly_descrs_fields,
write_descrs_fields, write_descrs_arrays,
- extraeffect=EF_CAN_RAISE):
+ extraeffect=EF_CAN_RAISE,
+ oopspecindex=OS_NONE):
key = (frozenset(readonly_descrs_fields),
frozenset(write_descrs_fields),
frozenset(write_descrs_arrays),
- extraeffect)
+ extraeffect,
+ oopspecindex)
if key in cls._cache:
return cls._cache[key]
result = object.__new__(cls)
@@ -29,6 +43,7 @@
result.write_descrs_fields = write_descrs_fields
result.write_descrs_arrays = write_descrs_arrays
result.extraeffect = extraeffect
+ result.oopspecindex = oopspecindex
cls._cache[key] = result
return result
@@ -36,7 +51,8 @@
return self.extraeffect >= self.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE
def effectinfo_from_writeanalyze(effects, cpu,
- extraeffect=EffectInfo.EF_CAN_RAISE):
+ extraeffect=EffectInfo.EF_CAN_RAISE,
+ oopspecindex=EffectInfo.OS_NONE):
from pypy.translator.backendopt.writeanalyze import top_set
if effects is top_set:
return None
Modified: pypy/branch/jit-str/pypy/jit/codewriter/jtransform.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/codewriter/jtransform.py (original)
+++ pypy/branch/jit-str/pypy/jit/codewriter/jtransform.py Wed Sep 22 15:23:31 2010
@@ -6,6 +6,7 @@
from pypy.objspace.flow.model import Block, Link, c_last_exception
from pypy.jit.codewriter.flatten import ListOfKind, IndirectCallTargets
from pypy.jit.codewriter import support, heaptracker
+from pypy.jit.codewriter.effectinfo import EffectInfo
from pypy.jit.codewriter.policy import log
from pypy.jit.metainterp.typesystem import deref, arrayItem
from pypy.rlib import objectmodel
@@ -310,6 +311,8 @@
# dispatch to various implementations depending on the oopspec_name
if oopspec_name.startswith('list.') or oopspec_name == 'newlist':
prepare = self._handle_list_call
+ elif oopspec_name.startswith('stroruni.'):
+ prepare = self._handle_stroruni_call
elif oopspec_name.startswith('virtual_ref'):
prepare = self._handle_virtual_ref_call
else:
@@ -982,10 +985,7 @@
return extraop + [op]
def do_fixed_list_ll_arraycopy(self, op, args, arraydescr):
- calldescr = self.callcontrol.getcalldescr(op)
- return SpaceOperation('arraycopy',
- [calldescr, op.args[0]] + args + [arraydescr],
- op.result)
+ return self._handle_oopspec_call(op, args, EffectInfo.OS_ARRAYCOPY)
# ---------- resizable lists ----------
@@ -1023,6 +1023,30 @@
[args[0], lengthdescr], op.result)
# ----------
+ # Strings and Unicodes.
+
+ def _handle_oopspec_call(self, op, args, oopspecindex):
+ cc = self.callcontrol
+ calldescr = cc.getcalldescr(op, oopspecindex=oopspecindex)
+ return SpaceOperation('oopspec_call',
+ [calldescr, op.args[0]] + args,
+ op.result)
+
+ def _handle_stroruni_call(self, op, oopspec_name, args):
+ dict = {"stroruni.concat": EffectInfo.OS_STR_CONCAT,
+ "stroruni.slice_startonly": EffectInfo.OS_STR_SLICE_STARTONLY,
+ "stroruni.slice_startstop": EffectInfo.OS_STR_SLICE_STARTSTOP,
+ "stroruni.slice_minusone": EffectInfo.OS_STR_SLICE_MINUSONE}
+ base = dict[oopspec_name]
+ if args[0].concretetype.TO == rstr.STR:
+ offset = 0
+ elif args[0].concretetype.TO == rstr.UNICODE:
+ offset = 80
+ else:
+ assert 0, "args[0].concretetype must be STR or UNICODE"
+ return self._handle_oopspec_call(op, args, base + offset)
+
+ # ----------
# VirtualRefs.
def _handle_virtual_ref_call(self, op, oopspec_name, args):
Modified: pypy/branch/jit-str/pypy/jit/codewriter/support.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/codewriter/support.py (original)
+++ pypy/branch/jit-str/pypy/jit/codewriter/support.py Wed Sep 22 15:23:31 2010
@@ -277,11 +277,6 @@
_ll_1_str_str2unicode = ll_rstr.LLHelpers.ll_str2unicode
- _ll_2_stroruni_concat = ll_rstr.LLHelpers.ll_strconcat
- _ll_2_stroruni_slice_startonly = ll_rstr.LLHelpers.ll_stringslice_startonly
- _ll_3_stroruni_slice_startstop = ll_rstr.LLHelpers.ll_stringslice_startstop
- _ll_1_stroruni_slice_minusone = ll_rstr.LLHelpers.ll_stringslice_minusone
-
# ---------- malloc with del ----------
def _ll_2_raw_malloc(TP, size):
Modified: pypy/branch/jit-str/pypy/jit/codewriter/test/test_jtransform.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/codewriter/test/test_jtransform.py (original)
+++ pypy/branch/jit-str/pypy/jit/codewriter/test/test_jtransform.py Wed Sep 22 15:23:31 2010
@@ -4,9 +4,9 @@
from pypy.objspace.flow.model import SpaceOperation, Variable, Constant
from pypy.jit.codewriter.jtransform import Transformer
from pypy.jit.metainterp.history import getkind
-from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr
+from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr, rlist
from pypy.translator.unsimplify import varoftype
-from pypy.jit.codewriter import heaptracker
+from pypy.jit.codewriter import heaptracker, effectinfo
def const(x):
return Constant(x, lltype.typeOf(x))
@@ -21,6 +21,8 @@
return ('calldescr', FUNC, ARGS, RESULT)
def fielddescrof(self, STRUCT, name):
return ('fielddescr', STRUCT, name)
+ def arraydescrof(self, ARRAY):
+ return FakeDescr(('arraydescr', ARRAY))
def sizeof(self, STRUCT):
return FakeDescr(('sizedescr', STRUCT))
@@ -74,8 +76,8 @@
class FakeBuiltinCallControl:
def guess_call_kind(self, op):
return 'builtin'
- def getcalldescr(self, op):
- return 'calldescr'
+ def getcalldescr(self, op, oopspecindex):
+ return 'calldescr-%d' % oopspecindex
def calldescr_canraise(self, calldescr):
return False
@@ -681,7 +683,6 @@
assert op1.result == v2
def test_str_concat():
- py.test.xfail('later')
# test that the oopspec is present and correctly transformed
PSTR = lltype.Ptr(rstr.STR)
FUNC = lltype.FuncType([PSTR, PSTR], PSTR)
@@ -693,8 +694,28 @@
op = SpaceOperation('direct_call', [const(func), v1, v2], v3)
tr = Transformer(FakeCPU(), FakeBuiltinCallControl())
op1 = tr.rewrite_operation(op)
- assert op1.opname == 'residual_call_r_r'
- assert list(op1.args[2]) == [v1, v2]
+ assert op1.opname == 'oopspec_call'
+ assert op1.args[0] == 'calldescr-%d' % effectinfo.EffectInfo.OS_STR_CONCAT
+ assert op1.args[1].value == func
+ assert op1.args[2:] == [v1, v2]
+ assert op1.result == v3
+
+def test_unicode_concat():
+ # test that the oopspec is present and correctly transformed
+ PSTR = lltype.Ptr(rstr.UNICODE)
+ FUNC = lltype.FuncType([PSTR, PSTR], PSTR)
+ func = lltype.functionptr(FUNC, 'll_strconcat',
+ _callable=rstr.LLHelpers.ll_strconcat)
+ v1 = varoftype(PSTR)
+ v2 = varoftype(PSTR)
+ v3 = varoftype(PSTR)
+ op = SpaceOperation('direct_call', [const(func), v1, v2], v3)
+ tr = Transformer(FakeCPU(), FakeBuiltinCallControl())
+ op1 = tr.rewrite_operation(op)
+ assert op1.opname == 'oopspec_call'
+ assert op1.args[0] == 'calldescr-%d' % effectinfo.EffectInfo.OS_UNI_CONCAT
+ assert op1.args[1].value == func
+ assert op1.args[2:] == [v1, v2]
assert op1.result == v3
def test_str_stringslice_startonly():
@@ -710,9 +731,11 @@
op = SpaceOperation('direct_call', [const(func), v1, v2], v3)
tr = Transformer(FakeCPU(), FakeBuiltinCallControl())
op1 = tr.rewrite_operation(op)
- assert op1.opname == 'residual_call_ir_r'
- assert list(op1.args[2]) == [v2]
- assert list(op1.args[3]) == [v1]
+ assert op1.opname == 'oopspec_call'
+ assert op1.args[0] == 'calldescr-%d' % (
+ effectinfo.EffectInfo.OS_STR_SLICE_STARTONLY)
+ assert op1.args[1].value == func
+ assert op1.args[2:] == [v1, v2]
assert op1.result == v3
def test_str_stringslice_startstop():
@@ -720,8 +743,8 @@
PSTR = lltype.Ptr(rstr.STR)
INT = lltype.Signed
FUNC = lltype.FuncType([PSTR, INT, INT], PSTR)
- func = lltype.functionptr(FUNC, 'll_stringslice_startstop',
- _callable=rstr.LLHelpers.ll_stringslice_startstop)
+ func = lltype.functionptr(FUNC, '_ll_stringslice_startstop',
+ _callable=rstr.LLHelpers._ll_stringslice_startstop)
v1 = varoftype(PSTR)
v2 = varoftype(INT)
v3 = varoftype(INT)
@@ -729,9 +752,11 @@
op = SpaceOperation('direct_call', [const(func), v1, v2, v3], v4)
tr = Transformer(FakeCPU(), FakeBuiltinCallControl())
op1 = tr.rewrite_operation(op)
- assert op1.opname == 'residual_call_ir_r'
- assert list(op1.args[2]) == [v2, v3]
- assert list(op1.args[3]) == [v1]
+ assert op1.opname == 'oopspec_call'
+ assert op1.args[0] == 'calldescr-%d' % (
+ effectinfo.EffectInfo.OS_STR_SLICE_STARTSTOP)
+ assert op1.args[1].value == func
+ assert op1.args[2:] == [v1, v2, v3]
assert op1.result == v4
def test_str_stringslice_minusone():
@@ -745,6 +770,31 @@
op = SpaceOperation('direct_call', [const(func), v1], v2)
tr = Transformer(FakeCPU(), FakeBuiltinCallControl())
op1 = tr.rewrite_operation(op)
- assert op1.opname == 'residual_call_r_r'
- assert list(op1.args[2]) == [v1]
+ assert op1.opname == 'oopspec_call'
+ assert op1.args[0] == 'calldescr-%d' % (
+ effectinfo.EffectInfo.OS_STR_SLICE_MINUSONE)
+ assert op1.args[1].value == func
+ assert op1.args[2:] == [v1]
assert op1.result == v2
+
+def test_list_ll_arraycopy():
+ from pypy.rlib.rgc import ll_arraycopy
+ LIST = lltype.GcArray(lltype.Signed)
+ PLIST = lltype.Ptr(LIST)
+ INT = lltype.Signed
+ FUNC = lltype.FuncType([PLIST]*2+[INT]*3, lltype.Void)
+ func = lltype.functionptr(FUNC, 'll_arraycopy', _callable=ll_arraycopy)
+ v1 = varoftype(PLIST)
+ v2 = varoftype(PLIST)
+ v3 = varoftype(INT)
+ v4 = varoftype(INT)
+ v5 = varoftype(INT)
+ v6 = varoftype(lltype.Void)
+ op = SpaceOperation('direct_call', [const(func), v1, v2, v3, v4, v5], v6)
+ tr = Transformer(FakeCPU(), FakeBuiltinCallControl())
+ op1 = tr.rewrite_operation(op)
+ assert op1.opname == 'oopspec_call'
+ assert op1.args[0] == 'calldescr-%d' % effectinfo.EffectInfo.OS_ARRAYCOPY
+ assert op1.args[1].value == func
+ assert op1.args[2:] == [v1, v2, v3, v4, v5]
+ assert op1.result == v6
Modified: pypy/branch/jit-str/pypy/jit/codewriter/test/test_list.py
==============================================================================
--- pypy/branch/jit-str/pypy/jit/codewriter/test/test_list.py (original)
+++ pypy/branch/jit-str/pypy/jit/codewriter/test/test_list.py Wed Sep 22 15:23:31 2010
@@ -36,10 +36,14 @@
class FakeCallControl:
class getcalldescr(AbstractDescr):
- def __init__(self, op):
+ def __init__(self, op, oopspecindex=0):
self.op = op
+ self.oopspecindex = oopspecindex
def __repr__(self):
- return '<CallDescr>'
+ if self.oopspecindex == 0:
+ return '<CallDescr>'
+ else:
+ return '<CallDescrOS%d>' % self.oopspecindex
def builtin_test(oopspec_name, args, RESTYPE, expected):
v_result = varoftype(RESTYPE)
@@ -99,7 +103,7 @@
varoftype(lltype.Signed),
varoftype(lltype.Signed)],
lltype.Void, """
- arraycopy <CallDescr>, $'myfunc', %r0, %r1, %i0, %i1, %i2, <ArrayDescr>
+ oopspec_call <CallDescrOS1>, $'myfunc', %r0, %r1, %i0, %i1, %i2
""")
def test_fixed_getitem():
More information about the Pypy-commit
mailing list