Bladeren bron

Demote input/output to macros in CFG IR

jonathanvdc 8 jaren geleden
bovenliggende
commit
90fc6c2e19
3 gewijzigde bestanden met toevoegingen van 32 en 66 verwijderingen
  1. 2 2
      kernel/modelverse_jit/bytecode_to_cfg.py
  2. 19 44
      kernel/modelverse_jit/cfg_ir.py
  3. 11 20
      kernel/modelverse_jit/cfg_to_tree.py

+ 2 - 2
kernel/modelverse_jit/bytecode_to_cfg.py

@@ -273,11 +273,11 @@ class AnalysisState(object):
     def analyze_output(self, instruction):
         """Analyzes an 'output' instruction."""
         value_result = self.analyze(instruction.value)
-        return self.current_block.append_definition(cfg_ir.Output(value_result))
+        return self.current_block.append_definition(cfg_ir.create_output(value_result))
 
     def analyze_input(self, _):
         """Analyzes an 'input' instruction."""
-        return self.current_block.append_definition(cfg_ir.Input())
+        return self.current_block.append_definition(cfg_ir.create_input())
 
     def analyze_break(self, instruction):
         """Analyzes a 'break' instruction."""

+ 19 - 44
kernel/modelverse_jit/cfg_ir.py

@@ -453,6 +453,12 @@ MACRO_POSITIONAL_CALLING_CONVENTION = 'macro-positional'
 PRINT_MACRO_NAME = 'print'
 """The name of the 'print' macro."""
 
+INPUT_MACRO_NAME = 'input'
+"""The name of the macro that pops a value from the input queue."""
+
+OUTPUT_MACRO_NAME = 'output'
+"""The name of the macro that pushes an output onto the output queue."""
+
 READ_DICT_KEYS_MACRO_NAME = 'read_dict_keys'
 """The name of the macro that reads all keys from a dictionary."""
 
@@ -744,50 +750,6 @@ class CreateNode(Value):
     def __str__(self):
         return 'create-node %s' % (self.value.ref_str())
 
-class Input(Value):
-    """A value that pops a node from the input queue."""
-    def get_dependencies(self):
-        """Gets all definitions and instructions on which this instruction depends."""
-        return []
-
-    def create(self, new_dependencies):
-        """Creates an instruction of this type from the given set of dependencies."""
-        assert len(new_dependencies) == 0
-        return Input()
-
-    def has_side_effects(self):
-        """Tells if this instruction has side-effects."""
-        return True
-
-    def __str__(self):
-        return 'input'
-
-class Output(Value):
-    """A value that pushes a node onto the output queue."""
-    def __init__(self, value):
-        Value.__init__(self)
-        self.value = value
-        assert isinstance(value, Definition)
-
-    def get_dependencies(self):
-        """Gets all definitions and instructions on which this instruction depends."""
-        return [self.value]
-
-    def create(self, new_dependencies):
-        """Creates an instruction of this type from the given set of dependencies."""
-        return Output(*new_dependencies)
-
-    def has_value(self):
-        """Tells if this value produces a result that is not None."""
-        return False
-
-    def has_side_effects(self):
-        """Tells if this instruction has side-effects."""
-        return True
-
-    def __str__(self):
-        return 'output %s' % self.value.ref_str()
-
 class Binary(Value):
     """A value that applies a binary operator to two other values."""
     def __init__(self, lhs, operator, rhs):
@@ -821,6 +783,19 @@ def create_print(argument):
         calling_convention=MACRO_POSITIONAL_CALLING_CONVENTION,
         has_value=False)
 
+def create_output(argument):
+    """Creates a value that outputs the specified argument."""
+    return DirectFunctionCall(
+        OUTPUT_MACRO_NAME, [('argument', argument)],
+        calling_convention=MACRO_POSITIONAL_CALLING_CONVENTION,
+        has_value=False)
+
+def create_input():
+    """Creates a value that pops a value from the input queue."""
+    return DirectFunctionCall(
+        INPUT_MACRO_NAME, [],
+        calling_convention=MACRO_POSITIONAL_CALLING_CONVENTION)
+
 def get_def_value(def_or_value):
     """Returns the given value, or the underlying value of the given definition, whichever is
        appropriate."""

+ 11 - 20
kernel/modelverse_jit/cfg_to_tree.py

@@ -649,6 +649,15 @@ class LoweringState(object):
         self.root_edge_names = {}
         self.inlinable_definitions = inlinable_definitions
         self.scheduler = None
+        self.macro_lowerings = {
+            cfg_ir.PRINT_MACRO_NAME: tree_ir.PrintInstruction,
+            cfg_ir.OUTPUT_MACRO_NAME: bytecode_to_tree.create_output,
+            cfg_ir.INPUT_MACRO_NAME: lambda: bytecode_to_tree.create_input(self.jit.use_input_function),
+            cfg_ir.READ_DICT_KEYS_MACRO_NAME: tree_ir.ReadDictionaryKeysInstruction,
+            cfg_ir.REVERSE_LIST_MACRO_NAME:
+            lambda seq:
+            tree_ir.ListSliceInstruction(seq, None, None, tree_ir.LiteralInstruction(-1))
+        }
 
     def __get_root_edge_name(self, root_node):
         """Gets the name of the given root edge's variable."""
@@ -807,14 +816,6 @@ class LoweringState(object):
         lhs, rhs = self.use_definition(value.lhs), self.use_definition(value.rhs)
         return tree_ir.BinaryInstruction(lhs, value.operator, rhs)
 
-    def lower_input(self, _):
-        """Lowers an 'input' value."""
-        return bytecode_to_tree.create_input(self.jit.use_input_function)
-
-    def lower_output(self, value):
-        """Lowers an 'output' value."""
-        return bytecode_to_tree.create_output(self.use_definition(value.value))
-
     def lower_direct_call(self, value):
         """Lowers a direct function call."""
         calling_convention = value.calling_convention
@@ -862,8 +863,8 @@ class LoweringState(object):
     def lower_macro_call(self, value):
         """Expands a macro call."""
         arg_list = [self.use_definition(arg) for _, arg in value.argument_list]
-        if value.target_name in LoweringState.macro_lowerings:
-            return LoweringState.macro_lowerings[value.target_name](*arg_list)
+        if value.target_name in self.macro_lowerings:
+            return self.macro_lowerings[value.target_name](*arg_list)
         else:
             raise jit_runtime.JitCompilationFailedException(
                 "Unknown macro: '%s' in instruction '%s'" %
@@ -947,8 +948,6 @@ class LoweringState(object):
         cfg_ir.Read : lower_read,
         cfg_ir.CreateNode : lower_create_node,
         cfg_ir.Binary : lower_binary,
-        cfg_ir.Input : lower_input,
-        cfg_ir.Output : lower_output,
         cfg_ir.DirectFunctionCall : lower_direct_call,
         cfg_ir.IndirectFunctionCall : lower_indirect_call,
         cfg_ir.JumpFlow : lower_jump,
@@ -967,14 +966,6 @@ class LoweringState(object):
         cfg_ir.MACRO_POSITIONAL_CALLING_CONVENTION : lower_macro_call
     }
 
-    macro_lowerings = {
-        cfg_ir.PRINT_MACRO_NAME: tree_ir.PrintInstruction,
-        cfg_ir.READ_DICT_KEYS_MACRO_NAME: tree_ir.ReadDictionaryKeysInstruction,
-        cfg_ir.REVERSE_LIST_MACRO_NAME:
-        lambda seq:
-        tree_ir.ListSliceInstruction(seq, None, None, tree_ir.LiteralInstruction(-1))
-    }
-
 def lower_flow_graph(entry_point, jit):
     """Lowers the control-flow graph defined by the given entry point to tree IR."""
     cfg_lowerer = LoweringState(jit, find_inlinable_definitions(entry_point))