Author: Maciej Fijalkowski <[email protected]>
Branch: share-guard-info
Changeset: r79854:3fb386e048dd
Date: 2015-09-26 13:35 +0200
http://bitbucket.org/pypy/pypy/changeset/3fb386e048dd/

Log:    implement fishing guard_value value directly from a jitframe, hence
        removing the need of failargs storing the argument, hence we can
        share stuff across guard_value

diff --git a/rpython/jit/backend/arm/regalloc.py 
b/rpython/jit/backend/arm/regalloc.py
--- a/rpython/jit/backend/arm/regalloc.py
+++ b/rpython/jit/backend/arm/regalloc.py
@@ -671,6 +671,8 @@
         a0, a1 = boxes
         imm_a1 = check_imm_box(a1)
         l0 = self.make_sure_var_in_reg(a0, boxes)
+        op.getdescr().make_a_counter_per_value(op,
+            self.cpu.all_reg_indexes[l0.value])
         if not imm_a1:
             l1 = self.make_sure_var_in_reg(a1, boxes)
         else:
diff --git a/rpython/jit/backend/llgraph/runner.py 
b/rpython/jit/backend/llgraph/runner.py
--- a/rpython/jit/backend/llgraph/runner.py
+++ b/rpython/jit/backend/llgraph/runner.py
@@ -40,6 +40,10 @@
         self.inputargs = map(mapping, inputargs)
         self.operations = []
         for op in operations:
+            if op.getopnum() == rop.GUARD_VALUE:
+                # we don't care about the value 13 here, because we gonna
+                # fish it from the extra slot on frame anyway
+                op.getdescr().make_a_counter_per_value(op, 13)
             if op.getdescr() is not None:
                 if op.is_guard() or op.getopnum() == rop.FINISH:
                     newdescr = op.getdescr()
@@ -372,6 +376,18 @@
         except ExecutionFinished, e:
             return e.deadframe
 
+    def get_value_direct(self, deadframe, tp, index):
+        v = deadframe._extra_value
+        if tp == 'i':
+            assert lltype.typeOf(v) == lltype.Signed
+        elif tp == 'r':
+            assert lltype.typeOf(v) == llmemory.GCREF
+        elif tp == 'f':
+            assert lltype.typeOf(v) == longlong.FLOATSTORAGE
+        else:
+            assert False
+        return v
+
     def get_int_value(self, deadframe, index):
         v = deadframe._values[index]
         assert lltype.typeOf(v) == lltype.Signed
@@ -775,11 +791,13 @@
     _TYPE = llmemory.GCREF
 
     def __init__(self, latest_descr, values,
-                 last_exception=None, saved_data=None):
+                 last_exception=None, saved_data=None,
+                 extra_value=None):
         self._latest_descr = latest_descr
         self._values = values
         self._last_exception = last_exception
         self._saved_data = saved_data
+        self._extra_value = extra_value
 
 
 class LLFrame(object):
@@ -872,7 +890,7 @@
 
     # -----------------------------------------------------
 
-    def fail_guard(self, descr, saved_data=None):
+    def fail_guard(self, descr, saved_data=None, extra_value=None):
         values = []
         for box in self.current_op.getfailargs():
             if box is not None:
@@ -887,7 +905,7 @@
         else:
             raise ExecutionFinished(LLDeadFrame(descr, values,
                                                 self.last_exception,
-                                                saved_data))
+                                                saved_data, extra_value))
 
     def execute_force_spill(self, _, arg):
         pass
@@ -909,7 +927,7 @@
 
     def execute_guard_value(self, descr, arg1, arg2):
         if arg1 != arg2:
-            self.fail_guard(descr)
+            self.fail_guard(descr, extra_value=arg1)
 
     def execute_guard_nonnull(self, descr, arg):
         if not arg:
diff --git a/rpython/jit/backend/llsupport/llmodel.py 
b/rpython/jit/backend/llsupport/llmodel.py
--- a/rpython/jit/backend/llsupport/llmodel.py
+++ b/rpython/jit/backend/llsupport/llmodel.py
@@ -389,20 +389,40 @@
         descr = self.get_latest_descr(deadframe)
         return rffi.cast(lltype.Signed, descr.rd_locs[index]) * WORD
 
+    @specialize.arg(2)
+    def get_value_direct(self, deadframe, tp, index):
+        if tp == 'i':
+            return self.get_int_value_direct(deadframe, index * WORD)
+        elif tp == 'r':
+            return self.get_ref_value_direct(deadframe, index * WORD)
+        elif tp == 'f':
+            return self.get_float_value_direct(deadframe, index * WORD)
+        else:
+            assert False
+
     def get_int_value(self, deadframe, index):
         pos = self._decode_pos(deadframe, index)
+        return self.get_int_value_direct(deadframe, pos)
+
+    def get_int_value_direct(self, deadframe, pos):
         descr = self.gc_ll_descr.getframedescrs(self).arraydescr
         ofs = self.unpack_arraydescr(descr)
         return self.read_int_at_mem(deadframe, pos + ofs, WORD, 1)
 
     def get_ref_value(self, deadframe, index):
         pos = self._decode_pos(deadframe, index)
+        return self.get_ref_value_direct(deadframe, pos)
+
+    def get_ref_value_direct(self, deadframe, pos):
         descr = self.gc_ll_descr.getframedescrs(self).arraydescr
         ofs = self.unpack_arraydescr(descr)
         return self.read_ref_at_mem(deadframe, pos + ofs)
 
     def get_float_value(self, deadframe, index):
         pos = self._decode_pos(deadframe, index)
+        return self.get_float_value_direct(deadframe, pos)
+
+    def get_float_value_direct(self, deadframe, pos):
         descr = self.gc_ll_descr.getframedescrs(self).arraydescr
         ofs = self.unpack_arraydescr(descr)
         return self.read_float_at_mem(deadframe, pos + ofs)
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
@@ -424,6 +424,8 @@
 
     def consider_guard_value(self, op):
         x = self.make_sure_var_in_reg(op.getarg(0))
+        loc = self.assembler.cpu.all_reg_indexes[x.value]
+        op.getdescr().make_a_counter_per_value(op, loc)
         y = self.loc(op.getarg(1))
         self.perform_guard(op, [x, y], None)
 
diff --git a/rpython/jit/metainterp/compile.py 
b/rpython/jit/metainterp/compile.py
--- a/rpython/jit/metainterp/compile.py
+++ b/rpython/jit/metainterp/compile.py
@@ -777,12 +777,15 @@
             # fetch the actual value of the guard_value, possibly turning
             # it to an integer
             if typetag == self.TY_INT:
-                intval = metainterp_sd.cpu.get_int_value(deadframe, index)
+                intval = metainterp_sd.cpu.get_value_direct(deadframe, 'i',
+                                                            index)
             elif typetag == self.TY_REF:
-                refval = metainterp_sd.cpu.get_ref_value(deadframe, index)
+                refval = metainterp_sd.cpu.get_value_direct(deadframe, 'r',
+                                                            index)
                 intval = lltype.cast_ptr_to_int(refval)
             elif typetag == self.TY_FLOAT:
-                floatval = metainterp_sd.cpu.get_float_value(deadframe, index)
+                floatval = metainterp_sd.cpu.get_value_direct(deadframe, 'f',
+                                                              index)
                 intval = longlong.gethash_fast(floatval)
             else:
                 assert 0, typetag
@@ -798,11 +801,6 @@
         increment = jitdriver_sd.warmstate.increment_trace_eagerness
         return jitcounter.tick(hash, increment)
 
-    def get_index_of_guard_value(self):
-        if (self.status & self.ST_TYPE_MASK) == 0:
-            return -1
-        return intmask(self.status >> self.ST_SHIFT)
-
     def start_compiling(self):
         # start tracing and compiling from this guard.
         self.status |= self.ST_BUSY_FLAG
@@ -829,23 +827,18 @@
                                new_loop.original_jitcell_token,
                                metainterp.box_names_memo)
 
-    def make_a_counter_per_value(self, guard_value_op):
+    def make_a_counter_per_value(self, guard_value_op, index):
         assert guard_value_op.getopnum() == rop.GUARD_VALUE
         box = guard_value_op.getarg(0)
-        try:
-            i = guard_value_op.getfailargs().index(box)
-        except ValueError:
-            return     # xxx probably very rare
+        if box.type == history.INT:
+            ty = self.TY_INT
+        elif box.type == history.REF:
+            ty = self.TY_REF
+        elif box.type == history.FLOAT:
+            ty = self.TY_FLOAT
         else:
-            if box.type == history.INT:
-                ty = self.TY_INT
-            elif box.type == history.REF:
-                ty = self.TY_REF
-            elif box.type == history.FLOAT:
-                ty = self.TY_FLOAT
-            else:
-                assert 0, box.type
-            self.status = ty | (r_uint(i) << self.ST_SHIFT)
+            assert 0, box.type
+        self.status = ty | (r_uint(index) << self.ST_SHIFT)
 
 class ResumeGuardExcDescr(ResumeGuardDescr):
     pass
diff --git a/rpython/jit/metainterp/optimizeopt/optimizer.py 
b/rpython/jit/metainterp/optimizeopt/optimizer.py
--- a/rpython/jit/metainterp/optimizeopt/optimizer.py
+++ b/rpython/jit/metainterp/optimizeopt/optimizer.py
@@ -597,8 +597,7 @@
     def emit_guard_operation(self, op, pendingfields):
         guard_op = self.replace_op_with(op, op.getopnum())
         opnum = guard_op.getopnum()
-        if (self._last_guard_op and guard_op.getdescr() is None and
-            opnum != rop.GUARD_VALUE):
+        if (self._last_guard_op and guard_op.getdescr() is None):
             self.metainterp_sd.profiler.count_ops(opnum,
                                             jitprof.Counters.OPT_GUARDS_SHARED)
             op = self._copy_resume_data_from(guard_op,
diff --git a/rpython/jit/metainterp/test/test_ajit.py 
b/rpython/jit/metainterp/test/test_ajit.py
--- a/rpython/jit/metainterp/test/test_ajit.py
+++ b/rpython/jit/metainterp/test/test_ajit.py
@@ -1480,16 +1480,6 @@
         res = self.meta_interp(f, [299], listops=True)
         assert res == f(299)
         self.check_resops(guard_class=4, guard_value=6)
-        #
-        # The original 'guard_class' is rewritten to be directly 'guard_value'.
-        # Check that this rewrite does not interfere with the descr, which
-        # should be a full-fledged multivalued 'guard_value' descr.
-        if self.basic:
-            for loop in get_stats().get_all_loops():
-                for op in loop.get_operations():
-                    if op.getopname() == "guard_value":
-                        descr = op.getdescr()
-                        assert descr.get_index_of_guard_value() >= 0
 
     def test_merge_guardnonnull_guardclass(self):
         myjitdriver = JitDriver(greens = [], reds = ['x', 'l'])
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to