Author: Maciej Fijalkowski <fij...@gmail.com>
Branch: optresult-unroll
Changeset: r79098:49ba7cf0f814
Date: 2015-08-21 11:52 +0200
http://bitbucket.org/pypy/pypy/changeset/49ba7cf0f814/

Log:    pass the first test about mul_bridge_ovf1

diff --git a/rpython/jit/metainterp/compile.py 
b/rpython/jit/metainterp/compile.py
--- a/rpython/jit/metainterp/compile.py
+++ b/rpython/jit/metainterp/compile.py
@@ -225,27 +225,14 @@
                                     call_pure_results=call_pure_results,
                                     enable_opts=enable_opts)
     try:
-        try:
-            start_state, preamble_ops = optimize_trace(metainterp_sd,
-                                                       jitdriver_sd,
-                                                       preamble_data)
-        except InvalidLoop:
-            return None
-    finally:
-        forget_optimization_info(ops)
-        forget_optimization_info(inputargs)
+        start_state, preamble_ops = optimize_trace(metainterp_sd, jitdriver_sd,
+                                                   preamble_data)
+    except InvalidLoop:
+        return None
 
-    #loop = create_empty_loop(metainterp)
-    #loop.inputargs = part.inputargs
-    #loop.operations = part.operations
-    #loop.quasi_immutable_deps = {}
-    #if part.quasi_immutable_deps:
-    #    loop.quasi_immutable_deps.update(part.quasi_immutable_deps)
-    #lastopnum = preamble_ops[-1].getopnum()
-    #if lastopnum != rop.FINISH:
-    #if start_state is not None:
-    assert start_state is not None
-    end_label = ResOperation(rop.LABEL, start_state.end_args,
+    metainterp_sd = metainterp.staticdata
+    jitdriver_sd = metainterp.jitdriver_sd
+    end_label = ResOperation(rop.LABEL, inputargs,
                              descr=jitcell_token)
     jump_op = ResOperation(rop.JUMP, jumpargs, descr=jitcell_token)
     loop_data = UnrolledLoopData(end_label, jump_op, ops, start_state,
@@ -279,44 +266,6 @@
     send_loop_to_backend(greenkey, jitdriver_sd, metainterp_sd, loop, "loop")
     record_loop_or_bridge(metainterp_sd, loop)
     return start_descr
-            
-            #part.quasi_immutable_deps = None
-    #         part.operations = [part.operations[-1]] + \
-    #                           [inliner.inline_op(h_ops[i]) for i in 
range(start, len(h_ops))] + \
-    #                           [ResOperation(rop.JUMP, [inliner.inline_arg(a) 
for a in jumpargs],
-    #                                         None, descr=jitcell_token)]
-    #         target_token = part.operations[0].getdescr()
-    #         assert isinstance(target_token, TargetToken)
-    #         all_target_tokens.append(target_token)
-    #         inputargs = jumpargs
-    #         jumpargs = part.operations[-1].getarglist()
-
-    #         try:
-    #             optimize_trace(metainterp_sd, jitdriver_sd, part, 
enable_opts,
-    #                            start_state=start_state, export_state=False)
-    #         except InvalidLoop:
-    #             return None
-
-    #         loop.operations = loop.operations[:-1] + part.operations
-    #         if part.quasi_immutable_deps:
-    #             loop.quasi_immutable_deps.update(part.quasi_immutable_deps)
-    # assert part.operations[-1].getopnum() != rop.LABEL
-
-    # if not loop.quasi_immutable_deps:
-    #     loop.quasi_immutable_deps = None
-    # for box in loop.inputargs:
-    #     assert not isinstance(box, Const)
-
-    # loop.original_jitcell_token = jitcell_token
-    # for label in all_target_tokens:
-    #     assert isinstance(label, TargetToken)
-    #     if label.virtual_state and label.short_preamble:
-    #         metainterp_sd.logger_ops.log_short_preamble([], 
label.short_preamble)
-    # jitcell_token.target_tokens = all_target_tokens
-    # propagate_original_jitcell_token(loop)
-    # send_loop_to_backend(greenkey, jitdriver_sd, metainterp_sd, loop, "loop")
-    # record_loop_or_bridge(metainterp_sd, loop)
-    # return all_target_tokens[0]
 
 def compile_retrace(metainterp, greenkey, start,
                     inputargs, jumpargs,
@@ -324,7 +273,6 @@
     """Try to compile a new procedure by closing the current history back
     to the first operation.
     """
-    xxx
     from rpython.jit.metainterp.optimizeopt import optimize_trace
 
     history = metainterp.history
@@ -333,24 +281,21 @@
 
     loop_jitcell_token = metainterp.get_procedure_token(greenkey)
     assert loop_jitcell_token
-    assert partial_trace.operations[-1].getopnum() == rop.LABEL
 
-    part = create_empty_loop(metainterp)
-    part.inputargs = inputargs[:]
-    h_ops = history.operations
-
-    part.operations = [partial_trace.operations[-1]] + \
-                      h_ops[start:] + \
-                      [ResOperation(rop.JUMP, jumpargs, 
descr=loop_jitcell_token)]
-    label = part.operations[0]
-    orignial_label = label.clone()
-    assert label.getopnum() == rop.LABEL
+    end_label = ResOperation(rop.LABEL, inputargs,
+                             descr=loop_jitcell_token)
+    jump_op = ResOperation(rop.JUMP, jumpargs, descr=loop_jitcell_token)
+    enable_opts = jitdriver_sd.warmstate.enable_opts
+    ops = history.operations[start:]
+    call_pure_results = metainterp.call_pure_results
+    loop_data = UnrolledLoopData(end_label, jump_op, ops, start_state,
+                                 call_pure_results=call_pure_results,
+                                 enable_opts=enable_opts)
     try:
-        optimize_trace(metainterp_sd, jitdriver_sd, part,
-                       jitdriver_sd.warmstate.enable_opts,
-                       start_state=start_state, export_state=False)
+        loop_info, loop_ops = optimize_trace(metainterp_sd, jitdriver_sd,
+                                             loop_data)
     except InvalidLoop:
-        xxx # XXX forget optimizations
+        xxx
         # Fall back on jumping to preamble
         target_token = label.getdescr()
         assert isinstance(target_token, TargetToken)
@@ -365,33 +310,29 @@
         except InvalidLoop:
             xxx # XXX forget optimizations
             return None
-    assert part.operations[-1].getopnum() != rop.LABEL
-    target_token = label.getdescr()
-    assert isinstance(target_token, TargetToken)
-    assert loop_jitcell_token.target_tokens
-    loop_jitcell_token.target_tokens.append(target_token)
-    if target_token.short_preamble:
-        metainterp_sd.logger_ops.log_short_preamble([], 
target_token.short_preamble)
 
     loop = partial_trace
-    loop.operations = loop.operations[:-1] + part.operations
+    target_token = TargetToken(loop_jitcell_token)
+    target_token.original_jitcell_token = loop_jitcell_token
+    target_token.short_preamble = loop_info.short_preamble
+    target_token.virtual_state = start_state.virtual_state
+    loop_ops[-1].setdescr(target_token)
+    mid_label = ResOperation(rop.LABEL, loop_info.label_args,
+                             descr=target_token)
+    loop.operations = (loop.operations + loop_info.extra_same_as + [mid_label]
+                       + loop_ops)
+    loop_jitcell_token.target_tokens.append(target_token)
 
-    quasi_immutable_deps = {}
-    if loop.quasi_immutable_deps:
-        quasi_immutable_deps.update(loop.quasi_immutable_deps)
-    if part.quasi_immutable_deps:
-        quasi_immutable_deps.update(part.quasi_immutable_deps)
-    if quasi_immutable_deps:
-        loop.quasi_immutable_deps = quasi_immutable_deps
+    #quasi_immutable_deps = {}
+    #if loop.quasi_immutable_deps:
+    #    quasi_immutable_deps.update(loop.quasi_immutable_deps)
+    #if part.quasi_immutable_deps:
+    #    quasi_immutable_deps.update(part.quasi_immutable_deps)
+    #if quasi_immutable_deps:
+    #    loop.quasi_immutable_deps = quasi_immutable_deps
 
-    for box in loop.inputargs:
-        assert isinstance(box, Box)
-
-    target_token = loop.operations[-1].getdescr()
     resumekey.compile_and_attach(metainterp, loop)
 
-    target_token = label.getdescr()
-    assert isinstance(target_token, TargetToken)
     record_loop_or_bridge(metainterp_sd, loop)
     return target_token
 
@@ -1036,20 +977,18 @@
     call_pure_results = metainterp.call_pure_results
 
     if operations[-1].getopnum() == rop.JUMP:
+        jump_op = operations[-1]
         data = BridgeCompileData(label, operations[:],
                                  call_pure_results=call_pure_results,
                                  enable_opts=enable_opts,
                                  inline_short_preamble=inline_short_preamble)
     else:
+        jump_op = None
         data = SimpleCompileData(label, operations[:],
                                  call_pure_results=call_pure_results,
                                  enable_opts=enable_opts)
     try:
-        try:
-            info, newops = optimize_trace(metainterp_sd, jitdriver_sd, data)
-        finally:
-            forget_optimization_info(inputargs)
-            forget_optimization_info(operations)
+        info, newops = optimize_trace(metainterp_sd, jitdriver_sd, data)
     except InvalidLoop:
         debug_print("compile_new_bridge: got an InvalidLoop")
         # XXX I am fairly convinced that optimize_bridge cannot actually raise
@@ -1058,24 +997,16 @@
         return None
 
     new_trace = create_empty_loop(metainterp)
-    new_trace.inputargs = info.inputargs
     new_trace.operations = newops
-    target_token = new_trace.operations[-1].getdescr()
-    resumekey.compile_and_attach(metainterp, new_trace)
-    record_loop_or_bridge(metainterp_sd, new_trace)
-    return target_token
-    xxxx
-    if new_trace.operations[-1].getopnum() != rop.LABEL:
-        # We managed to create a bridge.  Dispatch to resumekey to
-        # know exactly what we must do (ResumeGuardDescr/ResumeFromInterpDescr)
+    if info.final():
+        new_trace.inputargs = info.inputargs
         target_token = new_trace.operations[-1].getdescr()
         resumekey.compile_and_attach(metainterp, new_trace)
         record_loop_or_bridge(metainterp_sd, new_trace)
         return target_token
-    else:
-        raise Exception("should not occur with tracing disabled")
-        metainterp.retrace_needed(new_trace, state)
-        return None
+    new_trace.inputargs = info.renamed_inputargs
+    metainterp.retrace_needed(new_trace, info)
+    return None
 
 # ____________________________________________________________
 
diff --git a/rpython/jit/metainterp/optimizeopt/__init__.py 
b/rpython/jit/metainterp/optimizeopt/__init__.py
--- a/rpython/jit/metainterp/optimizeopt/__init__.py
+++ b/rpython/jit/metainterp/optimizeopt/__init__.py
@@ -58,6 +58,7 @@
         return compile_data.optimize(metainterp_sd, jitdriver_sd,
                                      optimizations, unroll)
     finally:
+        compile_data.forget_optimization_info()
         debug_stop("jit-optimize")
 
 if __name__ == '__main__':
diff --git a/rpython/jit/metainterp/optimizeopt/optimizer.py 
b/rpython/jit/metainterp/optimizeopt/optimizer.py
--- a/rpython/jit/metainterp/optimizeopt/optimizer.py
+++ b/rpython/jit/metainterp/optimizeopt/optimizer.py
@@ -27,6 +27,9 @@
     def __init__(self, inputargs):
         self.inputargs = inputargs
 
+    def final(self):
+        return True
+
 
 class Optimization(object):
     next_optimization = None
@@ -337,7 +340,7 @@
         return op
 
     def is_inputarg(self, op):
-        #return True
+        return True
         return op in self.inparg_dict
 
     def get_constant_box(self, box):
diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py 
b/rpython/jit/metainterp/optimizeopt/unroll.py
--- a/rpython/jit/metainterp/optimizeopt/unroll.py
+++ b/rpython/jit/metainterp/optimizeopt/unroll.py
@@ -6,7 +6,7 @@
 from rpython.jit.metainterp.optimizeopt.optimizer import Optimizer,\
      Optimization, LoopInfo, MININT, MAXINT
 from rpython.jit.metainterp.optimizeopt.virtualstate import (
-    VirtualStateConstructor)
+    VirtualStateConstructor, VirtualStatesCantMatch)
 from rpython.jit.metainterp.resoperation import rop, ResOperation
 
 class UnrollableOptimizer(Optimizer):
@@ -90,7 +90,7 @@
         self._check_no_forwarding([[start_label, end_label], ops])
         info, newops = self.optimizer.propagate_all_forward(
             start_label.getarglist()[:], ops, call_pure_results)
-        exported_state = self.export_state(start_label, end_label,
+        exported_state = self.export_state(start_label, end_label.getarglist(),
                                            info.inputargs)
         # we need to absolutely make sure that we've cleaned up all
         # the optimization info
@@ -137,25 +137,43 @@
             start_label.getarglist()[:], operations[:-1],
             call_pure_results, True)
         jump_op = operations[-1]
-        self.jump_to_existing_trace(jump_op, inline_short_preamble)
-        return info, self.optimizer._newoperations[:]
+        vs = self.jump_to_existing_trace(jump_op, inline_short_preamble)
+        if vs is None:
+            return info, self.optimizer._newoperations[:]
+        exported_state = self.export_state(start_label,
+                                           operations[-1].getarglist(),
+                                           info.inputargs)
+        self.optimizer._clean_optimization_info(self.optimizer._newoperations)
+        return exported_state, self.optimizer._newoperations
 
     def jump_to_existing_trace(self, jump_op, inline_short_preamble):
         jitcelltoken = jump_op.getdescr()
         args = [self.get_box_replacement(op) for op in jump_op.getarglist()]
-        target_token = jitcelltoken.target_tokens[0]
         virtual_state = self.get_virtual_state(args)
-        target_virtual_state = target_token.virtual_state
-        
-        short_preamble = target_token.short_preamble
-        extra = self.inline_short_preamble(args,
-            short_preamble[0].getarglist(), short_preamble[1:-1],
-            short_preamble[-1].getarglist(), self.optimizer.patchguardop)
-        self.send_extra_operation(jump_op.copy_and_change(rop.JUMP,
-                                  args=args + extra,
-                                  descr=jitcelltoken.target_tokens[0]))
+        infos = [self.optimizer.getinfo(arg) for arg in args]
+        for target_token in jitcelltoken.target_tokens:
+            target_virtual_state = target_token.virtual_state
+            if target_virtual_state is None:
+                continue
+            try:
+                extra_guards = target_virtual_state.generate_guards(
+                    virtual_state, args, infos, self.optimizer.cpu)
+                assert not extra_guards.extra_guards
+            except VirtualStatesCantMatch:
+                continue
+            short_preamble = target_token.short_preamble
+            extra = self.inline_short_preamble(args,
+                short_preamble[0].getarglist(), short_preamble[1:-1],
+                short_preamble[-1].getarglist(), self.optimizer.patchguardop)
+            self.send_extra_operation(jump_op.copy_and_change(rop.JUMP,
+                                      args=args + extra,
+                                      descr=target_token))
+            return None # explicit because the return can be non-None
+        return virtual_state
 
     def filter_extra_jump_args(self, label_args, jump_args):
+        label_args = [self.get_box_replacement(x) for x in label_args]
+        jump_args = [self.get_box_replacement(x) for x in jump_args]
         new_label_args = []
         new_jump_args = []
         assert len(label_args) == len(jump_args)
@@ -190,8 +208,7 @@
             op.set_forwarded(None)
         return res
 
-    def export_state(self, start_label, end_label, renamed_inputargs):
-        original_label_args = end_label.getarglist()
+    def export_state(self, start_label, original_label_args, 
renamed_inputargs):
         end_args = [self.get_box_replacement(a) for a in original_label_args]
         virtual_state = self.get_virtual_state(end_args)
         inparg_mapping = [(start_label.getarg(i), end_args[i])
@@ -222,13 +239,15 @@
     def import_state(self, targetop, exported_state):
         # the mapping between input args (from old label) and what we need
         # to actually emit. Update the info
-        for source, target in exported_state.inputarg_mapping:
-            if source is not target:
-                source.set_forwarded(target)
-            info = exported_state.exported_infos.get(target, None)
+        assert len(exported_state.inputarg_mapping) == 
len(targetop.getarglist())
+        for i, (s, target) in enumerate(exported_state.inputarg_mapping):
+            source = targetop.getarg(i)
+            assert source is not target
+            source.set_forwarded(target)
+            info = exported_state.exported_infos.get(source, None)
             if info is not None:
                 self.optimizer.setinfo_from_preamble(source, info,
-                                        exported_state.exported_infos)
+                                            exported_state.exported_infos)
         # import the optimizer state, starting from boxes that can be produced
         # by short preamble
         self.short_preamble_producer = ShortPreambleBuilder(
@@ -262,6 +281,9 @@
         self.short_preamble = short_preamble
         self.label_args = label_args
         self.extra_same_as = extra_same_as
+
+    def final(self):
+        return True
             
 class ExportedState(LoopInfo):
     """ Exported state consists of a few pieces of information:
@@ -289,3 +311,6 @@
         self.short_boxes = short_boxes
         self.renamed_inputargs = renamed_inputargs
         self.short_inputargs = short_inputargs
+
+    def final(self):
+        return False
diff --git a/rpython/jit/metainterp/optimizeopt/virtualstate.py 
b/rpython/jit/metainterp/optimizeopt/virtualstate.py
--- a/rpython/jit/metainterp/optimizeopt/virtualstate.py
+++ b/rpython/jit/metainterp/optimizeopt/virtualstate.py
@@ -127,6 +127,7 @@
             if box is not None:
                 fieldbox = opinfo._fields[self.fielddescrs[i].get_index()]
                 # must be there
+                xxx
                 fieldinfo = fieldbox.get_forwarded()
             else:
                 fieldbox = None
@@ -205,6 +206,7 @@
             if box is not None:
                 assert isinstance(opinfo, info.ArrayPtrInfo)
                 fieldbox = opinfo._items[i]
+                xxx
                 fieldinfo = fieldbox.get_forwarded()
             self.fieldstate[i].generate_guards(other.fieldstate[i],
                                             fieldbox, fieldinfo, state)
@@ -344,7 +346,8 @@
         if self.level == LEVEL_UNKNOWN:
             # confusingly enough, this is done also for pointers
             # which have the full range as the "bound", so it always works
-            return self._generate_guards_intbounds(other, box, extra_guards)
+            return self._generate_guards_intbounds(other, box, opinfo,
+                                                   extra_guards)
 
         # the following conditions often peek into the runtime value that the
         # box had when tracing. This value is only used as an educated guess.
@@ -412,13 +415,13 @@
                 raise VirtualStatesCantMatch("other not constant")
         assert 0, "unreachable"
 
-    def _generate_guards_intbounds(self, other, boxinfo, extra_guards):
+    def _generate_guards_intbounds(self, other, box, opinfo, extra_guards):
         if self.intbound is None:
             return
         if self.intbound.contains_bound(other.intbound):
             return
-        if (boxinfo is not None and isinstance(box, BoxInt) and
-                self.intbound.contains(box.getint())):
+        if (opinfo is not None and opinfo.is_constant() and
+                self.intbound.contains(opinfo.getint())):
             # this may generate a few more guards than needed, but they are
             # optimized away when emitting them
             self.intbound.make_guards(box, extra_guards)
@@ -502,11 +505,11 @@
             return False
         return True
 
-    def generate_guards(self, other, values, cpu):
-        assert len(self.state) == len(other.state) == len(values)
+    def generate_guards(self, other, boxes, infos, cpu):
+        assert len(self.state) == len(other.state) == len(boxes) == len(infos)
         state = GenerateGuardState(cpu)
         for i in range(len(self.state)):
-            self.state[i].generate_guards(other.state[i], values[i],
+            self.state[i].generate_guards(other.state[i], boxes[i], infos[i],
                                           state)
         return state
 
diff --git a/rpython/jit/metainterp/test/test_ajit.py 
b/rpython/jit/metainterp/test/test_ajit.py
--- a/rpython/jit/metainterp/test/test_ajit.py
+++ b/rpython/jit/metainterp/test/test_ajit.py
@@ -270,6 +270,7 @@
                 y -= 1
             return res
         res = self.meta_interp(f, [6, sys.maxint, 48])
+        self.check_trace_count(6)
         assert res == f(6, sys.maxint, 48)
 
     def test_loop_invariant_mul_bridge_ovf2(self):
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to