[pypy-commit] pypy jit-constptr-2: (arigo, fijal around)
arigo
pypy.commits at gmail.com
Thu Mar 31 06:03:11 EDT 2016
Author: Armin Rigo <arigo at tunes.org>
Branch: jit-constptr-2
Changeset: r83452:cc9cdb30a812
Date: 2016-03-31 11:07 +0100
http://bitbucket.org/pypy/pypy/changeset/cc9cdb30a812/
Log: (arigo, fijal around)
Add a LOAD_FROM_GC_TABLE operation, emitted by rewrite.py. It should
be a replacement for gc.py's _record_constptr.
diff --git a/rpython/jit/backend/llsupport/gc.py b/rpython/jit/backend/llsupport/gc.py
--- a/rpython/jit/backend/llsupport/gc.py
+++ b/rpython/jit/backend/llsupport/gc.py
@@ -137,7 +137,7 @@
v = op.getarg(i)
if isinstance(v, ConstPtr) and bool(v.value):
p = v.value
- if rgc._make_sure_does_not_move(p):
+ if not rgc.can_move(p):
gcrefs_output_list.append(p)
else:
if l is None:
@@ -177,7 +177,10 @@
def rewrite_assembler(self, cpu, operations, gcrefs_output_list):
rewriter = GcRewriterAssembler(self, cpu)
- newops = rewriter.rewrite(operations)
+ newops = rewriter.rewrite(operations, gcrefs_output_list)
+ return newops
+
+ XXX # kill the rest
# the key is an operation that contains a ConstPtr as an argument and
# this ConstPtrs pointer might change as it points to an object that
diff --git a/rpython/jit/backend/llsupport/rewrite.py b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -97,6 +97,8 @@
for i in range(op.numargs()):
orig_arg = op.getarg(i)
arg = self.get_box_replacement(orig_arg)
+ if isinstance(arg, ConstPtr) and bool(arg.value):
+ arg = self.remove_constptr(arg)
if orig_arg is not arg:
if not replaced:
op = op.copy_and_change(op.getopnum())
@@ -304,13 +306,15 @@
return False
- def rewrite(self, operations):
+ def rewrite(self, operations, gcrefs_output_list):
# we can only remember one malloc since the next malloc can possibly
# collect; but we can try to collapse several known-size mallocs into
# one, both for performance and to reduce the number of write
# barriers. We do this on each "basic block" of operations, which in
# this case means between CALLs or unknown-size mallocs.
#
+ self.gcrefs_output_list = gcrefs_output_list
+ self.gcrefs_map = {}
operations = self.remove_bridge_exception(operations)
self._changed_op = None
for i in range(len(operations)):
@@ -940,3 +944,29 @@
operations[start+2].getopnum() == rop.RESTORE_EXCEPTION):
return operations[:start] + operations[start+3:]
return operations
+
+ def _gcref_index(self, gcref):
+ if we_are_translated():
+ # can only use the dictionary after translation
+ try:
+ return self.gcrefs_map[gcref]
+ except KeyError:
+ pass
+ index = len(self.gcrefs_output_list)
+ self.gcrefs_map[gcref] = index
+ else:
+ # untranslated: linear scan
+ for i, gcref1 in enumerate(self.gcrefs_output_list):
+ if gcref == gcref1:
+ return i
+ index = len(self.gcrefs_output_list)
+ self.gcrefs_output_list.append(gcref)
+ return index
+
+ def remove_constptr(self, c):
+ """Remove all ConstPtrs, and replace them with load_from_gc_table.
+ """
+ index = self._gcref_index(c.value)
+ load_op = ResOperation(rop.LOAD_FROM_GC_TABLE, [ConstInt(index)])
+ self._newops.append(load_op)
+ return load_op
diff --git a/rpython/jit/backend/llsupport/test/test_rewrite.py b/rpython/jit/backend/llsupport/test/test_rewrite.py
--- a/rpython/jit/backend/llsupport/test/test_rewrite.py
+++ b/rpython/jit/backend/llsupport/test/test_rewrite.py
@@ -10,7 +10,7 @@
from rpython.jit.metainterp.optimizeopt.util import equaloplists
from rpython.jit.metainterp.history import JitCellToken, FLOAT
from rpython.jit.metainterp.history import AbstractFailDescr
-from rpython.rtyper.lltypesystem import lltype, rffi
+from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
from rpython.rtyper import rclass
from rpython.jit.backend.x86.arch import WORD
from rpython.jit.backend.llsupport.symbolic import (WORD,
@@ -77,6 +77,8 @@
tdescr = get_size_descr(self.gc_ll_descr, T)
tdescr.tid = 5678
tzdescr = get_field_descr(self.gc_ll_descr, T, 'z')
+ myT = lltype.cast_opaque_ptr(llmemory.GCREF,
+ lltype.malloc(T, zero=True))
#
A = lltype.GcArray(lltype.Signed)
adescr = get_array_descr(self.gc_ll_descr, A)
@@ -112,6 +114,8 @@
xdescr = get_field_descr(self.gc_ll_descr, R1, 'x')
ydescr = get_field_descr(self.gc_ll_descr, R1, 'y')
zdescr = get_field_descr(self.gc_ll_descr, R1, 'z')
+ myR1 = lltype.cast_opaque_ptr(llmemory.GCREF,
+ lltype.malloc(R1, zero=True))
#
E = lltype.GcStruct('Empty')
edescr = get_size_descr(self.gc_ll_descr, E)
@@ -1281,3 +1285,59 @@
{t}
jump()
""".format(**locals()))
+
+ def test_load_from_gc_table_1i(self):
+ self.check_rewrite("""
+ [i1]
+ setfield_gc(ConstPtr(myR1), i1, descr=xdescr)
+ jump()
+ """, """
+ [i1]
+ p0 = load_from_gc_table(0)
+ gc_store(p0, %(xdescr.offset)s, i1, %(xdescr.field_size)s)
+ jump()
+ """)
+
+ def test_load_from_gc_table_1p(self):
+ self.check_rewrite("""
+ [p1]
+ setfield_gc(ConstPtr(myT), p1, descr=tzdescr)
+ jump()
+ """, """
+ [i1]
+ p0 = load_from_gc_table(0)
+ cond_call_gc_wb(p0, descr=wbdescr)
+ gc_store(p0, %(tzdescr.offset)s, i1, %(tzdescr.field_size)s)
+ jump()
+ """)
+
+ def test_load_from_gc_table_2(self):
+ self.check_rewrite("""
+ [i1, f2]
+ setfield_gc(ConstPtr(myR1), i1, descr=xdescr)
+ setfield_gc(ConstPtr(myR1), f2, descr=ydescr)
+ jump()
+ """, """
+ [i1, f2]
+ p0 = load_from_gc_table(0)
+ gc_store(p0, %(xdescr.offset)s, i1, %(xdescr.field_size)s)
+ gc_store(p0, %(ydescr.offset)s, f2, %(ydescr.field_size)s)
+ jump()
+ """)
+
+ def test_load_from_gc_table_3(self):
+ self.check_rewrite("""
+ [i1, f2]
+ setfield_gc(ConstPtr(myR1), i1, descr=xdescr)
+ label(f2)
+ setfield_gc(ConstPtr(myR1), f2, descr=ydescr)
+ jump()
+ """, """
+ [i1, f2]
+ p0 = load_from_gc_table(0)
+ gc_store(p0, %(xdescr.offset)s, i1, %(xdescr.field_size)s)
+ label(f2)
+ p1 = load_from_gc_table(0)
+ gc_store(p1, %(ydescr.offset)s, f2, %(ydescr.field_size)s)
+ jump()
+ """)
diff --git a/rpython/jit/metainterp/executor.py b/rpython/jit/metainterp/executor.py
--- a/rpython/jit/metainterp/executor.py
+++ b/rpython/jit/metainterp/executor.py
@@ -408,6 +408,7 @@
rop.GC_LOAD_INDEXED_R,
rop.GC_STORE,
rop.GC_STORE_INDEXED,
+ rop.LOAD_FROM_GC_TABLE,
): # list of opcodes never executed by pyjitpl
continue
if rop._VEC_PURE_FIRST <= value <= rop._VEC_PURE_LAST:
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
@@ -1056,6 +1056,8 @@
'UNICODELEN/1/i',
'UNICODEGETITEM/2/i',
#
+ 'LOAD_FROM_GC_TABLE/1/r', # only emitted by rewrite.py
+ #
'_ALWAYS_PURE_LAST', # ----- end of always_pure operations -----
# parameters GC_LOAD
More information about the pypy-commit
mailing list