Browse Source

Include function parameters in CFG IR prologs

jonathanvdc 8 years ago
parent
commit
a3dcaa74a1

+ 14 - 3
kernel/modelverse_jit/bytecode_to_cfg.py

@@ -6,25 +6,36 @@ import modelverse_jit.runtime as jit_runtime
 
 class AnalysisState(object):
     """State that is common to the bytecode->CFG transformation of a function."""
-    def __init__(self):
+    def __init__(self, param_dict):
         self.counter = cfg_ir.SharedCounter()
         self.analyzed_instructions = set()
         self.loop_instructions = {}
         self.entry_point = cfg_ir.BasicBlock(self.counter)
         self.current_block = self.entry_point
         self.root_node = None
-        self.__write_prolog()
+        self.__write_prolog(param_dict)
 
-    def __write_prolog(self):
+    def __write_prolog(self, param_dict):
         # Write a prolog in CFG IR.
         # We want to create the following definition:
         #
         #     !entry_point():
         #         $jit_locals = alloc-root-node
+        #         $_ = declare-local var(...)
+        #         $param_1 = resolve-local var(...)
+        #         $arg_1 = function-parameter ...
+        #         $_ = store $param_1, $arg_1
+        #         ...
         #
         # We also want to store '$jit_locals' in an attribute, so we can
         # use it to shield locals from the GC.
         self.root_node = self.current_block.append_definition(cfg_ir.AllocateRootNode())
+        for node_id, name in param_dict.items():
+            variable = bytecode_ir.VariableNode(node_id, name)
+            self.current_block.append_definition(cfg_ir.DeclareLocal(variable, self.root_node))
+            param_i = self.current_block.append_definition(cfg_ir.ResolveLocal(variable))
+            arg_i = self.current_block.append_definition(cfg_ir.FunctionParameter(name))
+            self.current_block.append_definition(cfg_ir.StoreAtPointer(param_i, arg_i))
 
     def analyze(self, instruction):
         """Analyzes the given instruction as a basic block."""

+ 5 - 1
kernel/modelverse_jit/cfg_ir.py

@@ -111,7 +111,7 @@ class Definition(object):
         return '$%d' % self.index
 
     def __str__(self):
-        return '$%d = %s' % (self.index, str(self.value))
+        return '$%d = %s' % (self.index, self.value.ref_str())
 
 class Instruction(object):
     """Represents an instruction."""
@@ -256,6 +256,10 @@ class Value(Instruction):
         """Tells if this instruction has side-effects."""
         return False
 
+    def ref_str(self):
+        """Gets a string that represents this value."""
+        return str(self)
+
 class BlockParameter(Value):
     """A basic block parameter."""
     def get_dependencies(self):

+ 5 - 0
kernel/modelverse_jit/cfg_to_tree.py

@@ -431,6 +431,10 @@ class LoweringState(object):
                 tree_ir.LiteralInstruction('globals')),
             tree_ir.LiteralInstruction(value.variable.name))
 
+    def lower_function_parameter(self, value):
+        """Lowers a 'function-parameter' value."""
+        return tree_ir.LoadLocalInstruction(value.name)
+
     def lower_alloc_root_node(self, value):
         """Lowers an 'alloc-root-node' value."""
         local_name = tree_ir.VariableName(self.__get_root_node_name(value))
@@ -500,6 +504,7 @@ class LoweringState(object):
         cfg_ir.ResolveLocal : lower_resolve_local,
         cfg_ir.DeclareGlobal : lower_declare_global,
         cfg_ir.ResolveGlobal : lower_resolve_global,
+        cfg_ir.FunctionParameter : lower_function_parameter,
         cfg_ir.AllocateRootNode : lower_alloc_root_node,
         cfg_ir.DeallocateRootNode : lower_free_root_node,
         cfg_ir.LoadPointer : lower_load_pointer,

+ 1 - 1
kernel/modelverse_jit/jit.py

@@ -438,7 +438,7 @@ class ModelverseJit(object):
             self.max_instructions)
         constructed_body, = yield [("CALL_ARGS", [state.analyze, (body_bytecode,)])]
         if self.jit_code_log_function is not None:
-            bytecode_analyzer = bytecode_to_cfg.AnalysisState()
+            bytecode_analyzer = bytecode_to_cfg.AnalysisState(param_dict)
             bytecode_analyzer.analyze(body_bytecode)
             cfg_optimization.optimize(bytecode_analyzer.entry_point)
             self.jit_code_log_function(