Parcourir la source

Get fast-jit to work on normal Python

jonathanvdc il y a 8 ans
Parent
commit
dd7dc07414

+ 1 - 0
kernel/modelverse_jit/bytecode_ir.py

@@ -106,6 +106,7 @@ class ConstantInstruction(Instruction):
     def __init__(self, constant_id):
         Instruction.__init__(self)
         self.constant_id = constant_id
+        assert self.constant_id is not None
 
     constructor_parameters = (('node', int),)
 

+ 1 - 3
kernel/modelverse_jit/cfg_dominators.py

@@ -96,9 +96,7 @@ def get_immediate_dominators(entry_point):
 
             new_idom = None
             for pred in predecessor_map[block]:
-                if pred not in postorder_nums:
-                    continue
-
+                assert pred in postorder_nums
                 if new_idom is None:
                     new_idom = pred
                 elif idoms[pred] is not None:

+ 26 - 15
kernel/modelverse_jit/cfg_ir.py

@@ -988,20 +988,22 @@ def is_call(def_or_value, target_name=None, calling_convention=None):
 def get_all_predecessor_blocks(entry_point):
     """Creates a mapping of blocks to their direct predecessors for every block in the control-flow
        graph defined by the given entry point."""
-    results = defaultdict(set)
-    processed = set()
-    def __find_predecessors_step(block):
-        if block in processed:
-            return
+    # Use both lists and sets to keep the ordering of the resulting collections deterministic, and
+    # to maintain the same complexity as a set-only approach.
+    result_sets = {}
+    result_lists = {}
+    all_blocks = get_all_blocks(entry_point)
+    for block in all_blocks:
+        result_sets[block] = set()
+        result_lists[block] = list()
 
-        processed.add(block)
-        for branch in block.flow.branches():
-            target_block = branch.block
-            results[target_block].add(block)
-            __find_predecessors_step(target_block)
+    for block in all_blocks:
+        for reachable_block in get_directly_reachable_blocks(block):
+            if block not in result_sets[reachable_block]:
+                result_lists[reachable_block].append(block)
+                result_sets[reachable_block].add(block)
 
-    __find_predecessors_step(entry_point)
-    return results
+    return result_lists
 
 def get_directly_reachable_blocks(block):
     """Gets the set of all blocks that can be reached by taking a single branch from the
@@ -1035,9 +1037,18 @@ def get_all_reachable_blocks(entry_point):
 
 def get_all_blocks(entry_point):
     """Gets all basic blocks in the control-flow graph defined by the given entry point."""
-    reachable_blocks = get_reachable_blocks(entry_point)
-    reachable_blocks.add(entry_point)
-    return reachable_blocks
+    def __find_blocks_step(block, results):
+        if block in results:
+            return
+
+        results.add(block)
+        for branch in block.flow.branches():
+            __find_blocks_step(branch.block, results)
+
+    all_blocks = set()
+    __find_blocks_step(entry_point, all_blocks)
+    # Sort the blocks to make their order deterministic.
+    return list(sorted(all_blocks, key=lambda b: b.index))
 
 def get_trivial_phi_value(parameter_def, values):
     """Tests if the given parameter definition is an alias for another definition.

+ 6 - 5
kernel/modelverse_jit/cfg_optimization.py

@@ -70,10 +70,11 @@ def merge_blocks(entry_point):
             source.append_definition(target_def)
 
         source.flow = target.flow
-        for pred_set in predecessor_map.values():
-            if target in pred_set:
-                pred_set.remove(target)
-                pred_set.add(source)
+        for preds in predecessor_map.values():
+            if target in preds:
+                preds[preds.index(target)] = source
+                # preds.remove(target)
+                # preds.add(source)
 
     while len(queue) > 0:
         block = queue.pop()
@@ -103,7 +104,7 @@ def elide_local_checks(entry_point):
             if isinstance(def_value, cfg_ir.CheckLocalExists):
                 local_checks.append((def_value.variable.node_id, definition))
             elif isinstance(def_value, cfg_ir.DeclareLocal):
-                local_defs[cfg_ir.get_def_variable(definition).node_id].append(definition)
+                local_defs[def_value.variable.node_id].append(definition)
 
     dominator_tree = cfg_dominators.get_dominator_tree(entry_point)
     reachable_blocks = cfg_ir.get_all_reachable_blocks(entry_point)