[pypy-commit] pypy jit-targets: Improve randomness: generates a LABEL that is not always the very first

arigo noreply at buildbot.pypy.org
Thu Nov 24 18:43:58 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: jit-targets
Changeset: r49744:40325623b256
Date: 2011-11-24 15:59 +0100
http://bitbucket.org/pypy/pypy/changeset/40325623b256/

Log:	Improve randomness: generates a LABEL that is not always the very
	first operation in the loop, but only when it we can safely move it
	down. It is nevertheless enough to trigger a bug in the x86 backend:
	run it with --random-seed 1260.

diff --git a/pypy/jit/backend/test/test_random.py b/pypy/jit/backend/test/test_random.py
--- a/pypy/jit/backend/test/test_random.py
+++ b/pypy/jit/backend/test/test_random.py
@@ -525,31 +525,53 @@
                     startvars.append(BoxFloat(r.random_float_storage()))
                 else:
                     startvars.append(BoxInt(r.random_integer()))
+            allow_delay = True
+        else:
+            allow_delay = False
         assert len(dict.fromkeys(startvars)) == len(startvars)
         self.startvars = startvars
         self.prebuilt_ptr_consts = []
         self.r = r
-        self.build_random_loop(cpu, builder_factory, r, startvars)
+        self.build_random_loop(cpu, builder_factory, r, startvars, allow_delay)
 
-    def build_random_loop(self, cpu, builder_factory, r, startvars):
+    def build_random_loop(self, cpu, builder_factory, r, startvars, allow_delay):
 
         loop = TreeLoop('test_random_function')
         loop.inputargs = startvars[:]
         loop.operations = []
         loop._jitcelltoken = JitCellToken()
-        loop._targettoken = TargetToken()
-        loop.operations.append(ResOperation(rop.LABEL, loop.inputargs, None,
-                                            loop._targettoken))
         builder = builder_factory(cpu, loop, startvars[:])
-        self.generate_ops(builder, r, loop, startvars)
+        if allow_delay:
+            needs_a_label = True
+        else:
+            self.insert_label(loop, 0, r)
+            needs_a_label = False
+        self.generate_ops(builder, r, loop, startvars, needs_a_label=needs_a_label)
         self.builder = builder
         self.loop = loop
+        dump(loop)
         cpu.compile_loop(loop.inputargs, loop.operations, loop._jitcelltoken)
 
-    def generate_ops(self, builder, r, loop, startvars):
+    def insert_label(self, loop, position, r):
+        assert not hasattr(loop, '_targettoken')
+        for i in range(position):
+            op = loop.operations[i]
+            if (not op.has_no_side_effect()
+                    or not isinstance(op.result, (BoxInt, BoxFloat))):
+                position = i
+                break       # cannot move the LABEL later
+            randompos = r.randrange(0, len(self.startvars)+1)
+            self.startvars.insert(randompos, op.result)
+        loop._targettoken = TargetToken()
+        loop.operations.insert(position, ResOperation(rop.LABEL, self.startvars, None,
+                                                      loop._targettoken))
+
+    def generate_ops(self, builder, r, loop, startvars, needs_a_label=False):
         block_length = pytest.config.option.block_length
+        istart = 0
 
         for i in range(block_length):
+            istart = len(loop.operations)
             try:
                 op = r.choice(builder.OPERATIONS)
                 op.filter(builder)
@@ -558,6 +580,12 @@
                 pass
             if builder.should_fail_by is not None:
                 break
+            if needs_a_label and r.random() < 0.2:
+                self.insert_label(loop, istart, r)
+                needs_a_label = False
+        if needs_a_label:
+            self.insert_label(loop, istart, r)
+
         endvars = []
         used_later = {}
         for op in loop.operations:
@@ -685,6 +713,7 @@
             args = [x.clonebox() for x in subset]
             rl = RandomLoop(self.builder.cpu, self.builder.fork,
                                      r, args)
+            dump(rl.loop)
             self.cpu.compile_loop(rl.loop.inputargs, rl.loop.operations,
                                   rl.loop._jitcelltoken)
             # done
@@ -702,11 +731,19 @@
             self.dont_generate_more = True
         if r.random() < .05:
             return False
+        dump(subloop)
         self.builder.cpu.compile_bridge(fail_descr, fail_args,
                                         subloop.operations,
                                         self.loop._jitcelltoken)
         return True
 
+def dump(loop):
+    print >> sys.stderr, loop
+    if hasattr(loop, 'inputargs'):
+        print >> sys.stderr, '\t', loop.inputargs
+    for op in loop.operations:
+        print >> sys.stderr, '\t', op
+
 def check_random_function(cpu, BuilderClass, r, num=None, max=None):
     loop = RandomLoop(cpu, BuilderClass, r)
     while True:


More information about the pypy-commit mailing list