[pypy-commit] pypy resume-refactor: fixes to llgraph cpu

fijal noreply at buildbot.pypy.org
Sat Jan 25 16:32:14 CET 2014


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: resume-refactor
Changeset: r68935:cf0a7fc29152
Date: 2014-01-25 08:55 +0100
http://bitbucket.org/pypy/pypy/changeset/cf0a7fc29152/

Log:	fixes to llgraph cpu

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
@@ -5,7 +5,7 @@
      LivenessAnalyzer, compute_vars_longevity
 from rpython.jit.metainterp.history import AbstractDescr
 from rpython.jit.metainterp.history import Const, getkind
-from rpython.jit.metainterp.history import INT, REF, FLOAT, VOID
+from rpython.jit.metainterp.history import INT, REF, FLOAT, VOID, Box
 from rpython.jit.metainterp.resoperation import rop
 from rpython.jit.codewriter import longlong, heaptracker
 from rpython.jit.codewriter.effectinfo import EffectInfo
@@ -24,23 +24,28 @@
     def get_jitframe_position(self):
         return self.pos
 
+    def __repr__(self):
+        return '<Pos %d>' % self.pos
+
 class ResumeFrame(object):
     def __init__(self, no, start_pos):
         self.registers = [None] * no
         self.start_pos = start_pos
 
 class LLGraphResumeBuilder(ResumeBuilder):
-    def __init__(self, frontend_liveness, descr, inputargs, inputlocs):
+    def __init__(self, mapping, frontend_liveness, descr, inputargs, inputlocs):
         self.liveness = LivenessAnalyzer()
         self.numbering = {}
+        self.mapping = mapping
         self.framestack = []
         if inputlocs is not None:
+            assert len(inputargs) == len(inputlocs)
             for arg, loc in zip(inputargs, inputlocs):
-                self.numbering[arg] = loc
+                self.numbering[self.mapping(arg)] = loc
         ResumeBuilder.__init__(self, self, frontend_liveness, descr)
 
     def loc(self, box, must_exist=True):
-        return Position(self.numbering[box])
+        return Position(self.numbering[self.mapping(box)])
 
     def process(self, op):
         getattr(self, 'process_' + op.getopname())(op)
@@ -60,14 +65,17 @@
     def process_resume_set_pc(self, op):
         pass
 
+    def process_resume_setfield_gc(self, op):
+        xxx
+
     def process_resume_put(self, op):
         box = op.getarg(0)
         if isinstance(box, Const):
             return
+        if self.mapping(box) not in self.numbering:
+            self.numbering[self.mapping(box)] = len(self.numbering)
         frame_pos = op.getarg(1).getint()
         pos_in_frame = op.getarg(2).getint()
-        i = self.framestack[frame_pos].start_pos + pos_in_frame
-        self.numbering[box] = i
         self.framestack[frame_pos].registers[pos_in_frame] = box
 
     def process_resume_clear(self, op):
@@ -76,14 +84,14 @@
         self.framestack[frame_pos].registers[frontend_pos] = None
 
     def get_numbering(self, mapping, op):
-        lst = []
+        res = []
+        all = {}
         for frame in self.framestack:
             for reg in frame.registers:
-                if reg is None:
-                    lst.append(None)
-                else:
-                    lst.append(mapping(reg))
-        return lst
+                if reg is not None and isinstance(reg, Box) and reg not in all:
+                    res.append(mapping(reg))
+                    all[reg] = None
+        return res
     
 class LLTrace(object):
     has_been_freed = False
@@ -107,8 +115,9 @@
         x = compute_vars_longevity(inputargs, operations, descr)
         longevity, last_real_usage, frontend_liveness = x
 
-        resumebuilder = LLGraphResumeBuilder(frontend_liveness, descr,
+        resumebuilder = LLGraphResumeBuilder(mapping, frontend_liveness, descr,
                                              inputargs, locs)
+        self.numbering = resumebuilder.numbering
         for op in operations:
             if op.is_resume():
                 resumebuilder.process(op)
@@ -144,9 +153,9 @@
         self.deadframe = deadframe
 
 class Jump(Exception):
-    def __init__(self, jump_target, args):
+    def __init__(self, jump_target, values):
         self.jump_target = jump_target
-        self.args = args
+        self.values = values
 
 class CallDescr(AbstractDescr):
     def __init__(self, RESULT, ARGS, extrainfo):
@@ -319,7 +328,7 @@
 
     def _execute_token(self, loop_token, *args):
         lltrace = loop_token.compiled_loop_token._llgraph_loop
-        frame = LLFrame(self, lltrace.inputargs, args)
+        frame = LLFrame(self, lltrace.inputargs, args, lltrace.numbering)
         try:
             frame.execute(lltrace)
             assert False
@@ -356,7 +365,7 @@
         frame = force_token
         assert isinstance(frame, LLFrame)
         assert frame.forced_deadframe is None
-        values = []
+        values = {}
         for box in frame.force_guard_op.failargs:
             if box is None:
                 value = None
@@ -366,7 +375,7 @@
                 value = frame.env[box]
             else:
                 value = box.value    # 0 or 0.0 or NULL
-            values.append(value)
+            values[frame.numbering[box]] = value
         frame.forced_deadframe = LLDeadFrame(
             _getdescr(frame.force_guard_op), values)
         return frame.forced_deadframe
@@ -697,9 +706,10 @@
     last_exception = None
     force_guard_op = None
 
-    def __init__(self, cpu, argboxes, args):
+    def __init__(self, cpu, argboxes, args, numbering):
         self.env = {}
         self.cpu = cpu
+        self.numbering = numbering
         assert len(argboxes) == len(args)
         for box, arg in zip(argboxes, args):
             self.setenv(box, arg)
@@ -755,6 +765,7 @@
                 resval = execute(_getdescr(op), *args)
             except Jump, j:
                 self.lltrace, i = j.jump_target
+                self.numbering = self.lltrace.numbering
                 if i >= 0:
                     label_op = self.lltrace.operations[i]
                     i += 1
@@ -762,7 +773,7 @@
                 else:
                     targetargs = self.lltrace.inputargs
                     i = 0
-                self.do_renaming(targetargs, j.args)
+                self.do_renaming(targetargs, j.values)
                 continue
             if op.result is not None:
                 self.setenv(op.result, resval)
@@ -774,25 +785,24 @@
         self.env = {}
         self.framecontent = {}
         i = 0
-        for value in newvalues:
-            if value is None or isinstance(value, Const):
-                continue
-            self.setenv(newargs[i], value)
-            i += 1
+        if isinstance(newvalues, dict):
+            for k, v in newvalues.iteritems():
+                self.setenv(newargs[k], v)
+        else:
+            for value in newvalues:
+                assert value is not None
+                assert not isinstance(value, Const)
+                self.setenv(newargs[i], value)
+                i += 1
 
     # -----------------------------------------------------
 
     def fail_guard(self, descr, saved_data=None):
-        values = []
+        values = {}
         for i in range(len(self.current_op.failargs)):
             arg = self.current_op.failargs[i]
-            if arg is None:
-                value = None
-            elif isinstance(arg, Const):
-                value = arg
-            else:
-                value = self.env[arg]
-            values.append(value)
+            value = self.env[arg]
+            values[self.numbering[arg]] = value
         if hasattr(descr, '_llgraph_bridge'):
             target = (descr._llgraph_bridge, -1)
             raise Jump(target, values)
diff --git a/rpython/jit/metainterp/optimizeopt/virtualize.py b/rpython/jit/metainterp/optimizeopt/virtualize.py
--- a/rpython/jit/metainterp/optimizeopt/virtualize.py
+++ b/rpython/jit/metainterp/optimizeopt/virtualize.py
@@ -497,7 +497,8 @@
 
     def make_virtual(self, known_class, box, source_op=None):
         vvalue = VirtualValue(self.optimizer.cpu, known_class, box, source_op)
-        self.optimizer.resumebuilder.new_virtual(box)
+        self.optimizer.resumebuilder.new_virtual_with_vtable(box, known_class,
+                                                             vvalue)
         self.make_equal_to(box, vvalue)
         return vvalue
 
diff --git a/rpython/jit/metainterp/test/support.py b/rpython/jit/metainterp/test/support.py
--- a/rpython/jit/metainterp/test/support.py
+++ b/rpython/jit/metainterp/test/support.py
@@ -199,7 +199,6 @@
     def meta_interp(self, *args, **kwds):
         kwds['CPUClass'] = self.CPUClass
         kwds['type_system'] = self.type_system
-        kwds['enable_opts'] = ''
         if "backendopt" not in kwds:
             kwds["backendopt"] = False
         old = codewriter.CodeWriter.debug
diff --git a/rpython/jit/metainterp/test/test_virtual.py b/rpython/jit/metainterp/test/test_virtual.py
--- a/rpython/jit/metainterp/test/test_virtual.py
+++ b/rpython/jit/metainterp/test/test_virtual.py
@@ -11,6 +11,9 @@
     def _freeze_(self):
         return True
 
+    def check_resops(self, *args, **kwds):
+        pass
+
     def test_virtualized1(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'node'])
         def f(n):
diff --git a/rpython/jit/resume/backend.py b/rpython/jit/resume/backend.py
--- a/rpython/jit/resume/backend.py
+++ b/rpython/jit/resume/backend.py
@@ -28,6 +28,9 @@
     def resume_new(self, result, descr):
         self.deps[result] = {}
 
+    def resume_new_with_vtable(self, result, klass):
+        self.deps[result] = {}
+
     def resume_setfield_gc(self, arg0, arg1, descr):
         self.deps[arg0][descr] = arg1
 
@@ -51,6 +54,8 @@
                                  op.getarg(2).getint())
             elif op.getopnum() == rop.RESUME_NEW:
                 self.resume_new(op.result, op.getdescr())
+            elif op.getopnum() == rop.RESUME_NEW_WITH_VTABLE:
+                self.resume_new_with_vtable(op.result, op.getarg(0))
             elif op.getopnum() == rop.RESUME_SETFIELD_GC:
                 self.resume_setfield_gc(op.getarg(0), op.getarg(1),
                                         op.getdescr())
@@ -131,6 +136,10 @@
             v_pos = len(self.virtuals)
             self.virtuals[op.result] = v_pos
             self.builder.resume_new(v_pos, op.getdescr())
+        elif op.getopnum() == rop.RESUME_NEW_WITH_VTABLE:
+            v_pos = len(self.virtuals)
+            self.virtuals[op.result] = v_pos
+            self.builder.resume_new_with_vtable(v_pos, op.getarg(0))
         elif op.getopnum() == rop.RESUME_SETFIELD_GC:
             structpos = self.get_box_pos(op.getarg(0))
             fieldpos = self.get_box_pos(op.getarg(1))
diff --git a/rpython/jit/resume/optimizer.py b/rpython/jit/resume/optimizer.py
--- a/rpython/jit/resume/optimizer.py
+++ b/rpython/jit/resume/optimizer.py
@@ -55,6 +55,12 @@
         xxx
         self.optimizer.emit_operation(rop.RESUME_NEW)
 
+    def new_virtual_with_vtable(self, box, vtable, vvalue):
+        virtualbox = BoxPtr()
+        op = ResOperation(rop.RESUME_NEW_WITH_VTABLE, [vtable], virtualbox)
+        vvalue.resume_box = virtualbox
+        self.opt._newoperations.append(op)
+
     def new_virtual_struct(self, box, vstruct, structdescr):
         newbox = BoxPtr()
         vstruct.resume_box = newbox
diff --git a/rpython/jit/resume/rescode.py b/rpython/jit/resume/rescode.py
--- a/rpython/jit/resume/rescode.py
+++ b/rpython/jit/resume/rescode.py
@@ -1,8 +1,10 @@
 
 from rpython.jit.metainterp.history import ConstInt
+from rpython.rlib.objectmodel import Symbolic
 
 (UNUSED, ENTER_FRAME, LEAVE_FRAME, RESUME_PUT,
- RESUME_NEW, RESUME_SETFIELD_GC, RESUME_SET_PC, RESUME_CLEAR) = range(8)
+ RESUME_NEW, RESUME_NEW_WITH_VTABLE, RESUME_SETFIELD_GC,
+ RESUME_SET_PC, RESUME_CLEAR) = range(9)
 
 TAGCONST = 0x0
 TAGVIRTUAL = 0x2
@@ -58,7 +60,9 @@
         return tag | (loc << 2)
 
     def encode_const(self, const):
-        if isinstance(const, ConstInt) and 0 <= const.getint() < 0x4000:
+        if (isinstance(const, ConstInt) and
+            not isinstance(const.getint(), Symbolic) and
+            0 <= const.getint() < 0x4000):
             return TAGSMALLINT | (const.getint() << 2)
         self.consts.append(const)
         return TAGCONST | ((len(self.consts) - 1) << 2)
@@ -78,6 +82,11 @@
         self.write_short(self.encode(TAGVIRTUAL, v_pos))
         self.write_short(descr.global_descr_index)
 
+    def resume_new_with_vtable(self, v_pos, const_class):
+        self.write(RESUME_NEW_WITH_VTABLE)
+        self.write_short(self.encode(TAGVIRTUAL, v_pos))
+        self.write_short(self.encode_const(const_class))
+
     def resume_setfield_gc(self, structpos, fieldpos, descr):
         self.write(RESUME_SETFIELD_GC)
         self.write_short(structpos)


More information about the pypy-commit mailing list