[pypy-commit] pypy framestate: wip

rlamy noreply at buildbot.pypy.org
Mon Nov 24 17:30:07 CET 2014


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: framestate
Changeset: r74695:71547c416c37
Date: 2014-11-23 01:57 +0000
http://bitbucket.org/pypy/pypy/changeset/71547c416c37/

Log:	wip

diff --git a/rpython/flowspace/bytecode.py b/rpython/flowspace/bytecode.py
--- a/rpython/flowspace/bytecode.py
+++ b/rpython/flowspace/bytecode.py
@@ -139,44 +139,54 @@
         while self.offset < len(code.co_code):
             self.pos_map[self.offset] = i
             if self.offset in self.pending_cuts:
-                self.cuts.append(self.pos_map[self.offset])
+                self.new_block()
             next_offset, instr = self.read(code, self.offset)
             yield instr
             self.offset = next_offset
             i += 1
 
-    def _add_jump(self, i, target):
-        self.cuts.append(i + 1)
+    def find_position(self, offset):
+        for i, block in enumerate(self.blocks):
+            if block.startpos <= offset:
+                n = i
+            else:
+                break
+        for i, instr in enumerate(self.blocks[n]):
+            if instr.offset == offset:
+                return n, i
+
+    def new_block(self):
+        if self.blocks[-1].operations:
+            new_block = SimpleBlock([])
+            self.blocks.append(new_block)
+
+    def _add_jump(self, target):
         if target <= self.offset:
-            j = self.pos_map[target]
-            self.cuts.append(j)
+            i_block, i_instr = self.find_position(target)
+            self.blocks[i_block:i_block + 1] = self.blocks[i_block].split_at(i_instr)
         else:
             self.pending_cuts.add(target)
 
     def build_flow(self, code):
-        contents = []
         offsets = []
         self.pending_cuts = set()
         self.pos_map = {}
-        self.cuts = []
+        self.blocks = [SimpleBlock([])]
         for instr in self._iter_instr(code):
             offsets.append(self.offset)
-            contents.append(instr)
+            self.blocks[-1].operations.append(instr)
             if instr.has_jump():
-                self._add_jump(self.pos_map[self.offset], instr.arg)
-        self.cuts.sort()
-        pendingblocks = [SimpleBlock(contents[i:j])
-                for i, j in zip([0] + self.cuts, self.cuts + [len(code.co_code)])]
+                self.new_block()
+                self._add_jump(instr.arg)
 
-        graph = BytecodeGraph(pendingblocks[0])
-        for block in pendingblocks:
+        graph = BytecodeGraph(self.blocks[0])
+        for block in self.blocks:
             for i, op in enumerate(block.operations):
                 graph.pos_index[op.offset] = block, i
-        graph._next_pos = dict([(offsets[i], offsets[i+1])
+        graph._next_pos = dict([(offsets[i], offsets[i + 1])
             for i in range(len(offsets) - 1)])
         graph._next_pos[offsets[-1]] = len(code.co_code)
-        while pendingblocks:
-            block = pendingblocks.pop()
+        for block in self.blocks:
             for i, op in enumerate(block.operations):
                 op.bc_flow(block, graph)
         return graph
@@ -235,6 +245,16 @@
     def startpos(self):
         return self.operations[0].offset
 
+    def split_at(self, i):
+        if i == 0 or i == len(self.operations):
+            return [self]
+        assert 0 < i < len(self.operations)
+        tail = self.operations[i:]
+        assert tail
+        del self.operations[i:]
+        new_block = SimpleBlock(tail)
+        return [self, new_block]
+
 
 class EntryBlock(BytecodeBlock):
     """A fake block to represent the beginning of a code object"""


More information about the pypy-commit mailing list