فهرست منبع

Support single-level break/continue in the JIT

jonathanvdc 8 سال پیش
والد
کامیت
72b2c6bb73
2فایلهای تغییر یافته به همراه32 افزوده شده و 3 حذف شده
  1. 31 2
      kernel/modelverse_jit/jit.py
  2. 1 1
      kernel/modelverse_kernel/main.py

+ 31 - 2
kernel/modelverse_jit/jit.py

@@ -409,6 +409,7 @@ class AnalysisState(object):
         self.jit = jit
         self.local_mapping = local_mapping
         self.function_name = jit.jitted_entry_points[body_id]
+        self.enclosing_loop_instruction = None
 
     def get_local_name(self, local_id):
         """Gets the name for a local with the given id."""
@@ -544,7 +545,15 @@ class AnalysisState(object):
             ("RD", [instruction_id, "cond"]),
             ("RD", [instruction_id, "body"])]
 
-        (cond_r, body_r), = yield [("CALL_ARGS", [self.analyze_all, ([cond, body],)])]
+        # Analyze the condition.
+        cond_r, = yield [("CALL_ARGS", [self.analyze, (cond,)])]
+        # Store the old enclosing loop on the stack, and make this loop the
+        # new enclosing loop.
+        old_loop_instruction = self.enclosing_loop_instruction
+        self.enclosing_loop_instruction = instruction_id
+        body_r, = yield [("CALL_ARGS", [self.analyze, (body,)])]
+        # Restore hte old enclosing loop.
+        self.enclosing_loop_instruction = old_loop_instruction
         if self.jit.nop_insertion_enabled:
             create_loop_body = lambda check, body: tree_ir.create_block(
                 check,
@@ -1016,6 +1025,24 @@ class AnalysisState(object):
         yield [("END_TRY", [])]
         raise primitive_functions.PrimitiveFinished(result)
 
+    def analyze_break(self, instruction_id):
+        """Tries to analyze the given 'break' instruction."""
+        target_instruction_id, = yield [("RD", [instruction_id, "while"])]
+        if target_instruction_id == self.enclosing_loop_instruction:
+            raise primitive_functions.PrimitiveFinished(tree_ir.BreakInstruction())
+        else:
+            raise JitCompilationFailedException(
+                "Multilevel 'break' is not supported by the baseline JIT.")
+
+    def analyze_continue(self, instruction_id):
+        """Tries to analyze the given 'continue' instruction."""
+        target_instruction_id, = yield [("RD", [instruction_id, "while"])]
+        if target_instruction_id == self.enclosing_loop_instruction:
+            raise primitive_functions.PrimitiveFinished(tree_ir.ContinueInstruction())
+        else:
+            raise JitCompilationFailedException(
+                "Multilevel 'continue' is not supported by the baseline JIT.")
+
     instruction_analyzers = {
         'if' : analyze_if,
         'while' : analyze_while,
@@ -1028,6 +1055,8 @@ class AnalysisState(object):
         'access' : analyze_access,
         'output' : analyze_output,
         'input' : analyze_input,
-        'call' : analyze_call
+        'call' : analyze_call,
+        'break' : analyze_break,
+        'continue' : analyze_continue
     }
 

+ 1 - 1
kernel/modelverse_kernel/main.py

@@ -65,7 +65,7 @@ class ModelverseKernel(object):
         # To make the JIT print JIT successes and errors to the command-line,
         # uncomment the line below:
         #
-        self.jit.set_jit_success_log()
+        #     self.jit.set_jit_success_log()
         #
         # If you want, you can use a custom logging function:
         #