Selaa lähdekoodia

Implement tracing in the fast JIT

jonathanvdc 8 vuotta sitten
vanhempi
commit
fd0277c139

+ 16 - 1
kernel/modelverse_jit/bytecode_to_cfg.py

@@ -4,9 +4,20 @@ import modelverse_jit.bytecode_ir as bytecode_ir
 import modelverse_jit.cfg_ir as cfg_ir
 import modelverse_jit.runtime as jit_runtime
 
+def emit_debug_info_trace(block, debug_info, function_name):
+    """Appends a tracing instruction to the given block that prints
+       the given debug information and function name."""
+    if debug_info is not None or function_name is not None:
+        block.append_definition(
+            cfg_ir.create_print(
+                block.append_definition(
+                    cfg_ir.Literal(jit_runtime.format_trace_message(debug_info, function_name)))))
+
 class AnalysisState(object):
     """State that is common to the bytecode->CFG transformation of a function."""
-    def __init__(self, param_dict):
+    def __init__(self, jit, function_name, param_dict):
+        self.jit = jit
+        self.function_name = function_name
         self.counter = cfg_ir.SharedCounter()
         self.analyzed_instructions = set()
         self.loop_instructions = {}
@@ -48,6 +59,10 @@ class AnalysisState(object):
         # Find an analyzer.
         instruction_type = type(instruction)
         if instruction_type in self.instruction_analyzers:
+            if self.jit.tracing_enabled:
+                emit_debug_info_trace(
+                    self.current_block, instruction.debug_information, self.function_name)
+
             # Analyze the instruction.
             result = self.instruction_analyzers[instruction_type](self, instruction)
 

+ 20 - 1
kernel/modelverse_jit/cfg_to_tree.py

@@ -507,6 +507,8 @@ class DefinitionScheduler(object):
         assert not self.has_scheduled(definition)
         statements = []
 
+        # print('Scheduling %s; store_and_forget: %s' % (definition, store_and_forget))
+
         self.remove_definition(definition)
         if isinstance(definition, cfg_ir.FlowInstruction):
             statements.append(self.lowering_state.lower_value(definition))
@@ -529,6 +531,8 @@ class DefinitionScheduler(object):
                 else:
                     statements.append(lowered_value)
 
+        # print('Done scheduling %s; result: %s' % (definition, tree_ir.create_block(*statements)))
+
         return statements
 
     def schedule(self, definition, store_and_forget=False):
@@ -765,6 +769,16 @@ class LoweringState(object):
                 arg_list,
                 tree_ir.LoadLocalInstruction(jit_runtime.KWARGS_PARAMETER_NAME))
 
+    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)
+        else:
+            raise jit_runtime.JitCompilationFailedException(
+                "Unknown macro: '%s' in instruction '%s'" %
+                (value.target_name, value))
+
     def lower_jump(self, flow):
         """Lowers the given 'jump' flow instruction to a tree."""
         return self.lower_branch(flow.branch)
@@ -844,7 +858,12 @@ class LoweringState(object):
 
     call_lowerings = {
         cfg_ir.SIMPLE_POSITIONAL_CALLING_CONVENTION : lower_simple_positional_call,
-        cfg_ir.JIT_CALLING_CONVENTION : lower_jit_call
+        cfg_ir.JIT_CALLING_CONVENTION : lower_jit_call,
+        cfg_ir.MACRO_POSITIONAL_CALLING_CONVENTION : lower_macro_call
+    }
+
+    macro_lowerings = {
+        cfg_ir.PRINT_MACRO_NAME: tree_ir.PrintInstruction
     }
 
 def lower_flow_graph(entry_point, jit):

+ 1 - 1
kernel/modelverse_jit/jit.py

@@ -646,7 +646,7 @@ def compile_function_body_fast(jit, function_name, body_id, _):
         ("CALL_ARGS", [jit.jit_signature, (body_id,)])]
     param_dict = dict(zip(parameter_ids, parameter_list))
     body_bytecode, = yield [("CALL_ARGS", [jit.jit_parse_bytecode, (body_id,)])]
-    bytecode_analyzer = bytecode_to_cfg.AnalysisState(param_dict)
+    bytecode_analyzer = bytecode_to_cfg.AnalysisState(jit, function_name, param_dict)
     bytecode_analyzer.analyze(body_bytecode)
     yield [
         ("CALL_ARGS", [cfg_optimization.optimize, (bytecode_analyzer.entry_point, jit)])]