[pypy-svn] r37394 - in pypy/dist/pypy: jit/codegen jit/codegen/i386 jit/codegen/i386/demo jit/codegen/i386/test objspace/flow
arigo at codespeak.net
arigo at codespeak.net
Fri Jan 26 16:11:40 CET 2007
Author: arigo
Date: Fri Jan 26 16:11:37 2007
New Revision: 37394
Modified:
pypy/dist/pypy/jit/codegen/graph2rgenop.py
pypy/dist/pypy/jit/codegen/i386/demo/support.py
pypy/dist/pypy/jit/codegen/i386/demo/test_factorial.py
pypy/dist/pypy/jit/codegen/i386/operation.py
pypy/dist/pypy/jit/codegen/i386/test/test_operation.py
pypy/dist/pypy/objspace/flow/objspace.py
Log:
Some more bugs found by test_random_function().
Modified: pypy/dist/pypy/jit/codegen/graph2rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/graph2rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/graph2rgenop.py Fri Jan 26 16:11:37 2007
@@ -17,17 +17,16 @@
t.buildannotator(policy=policy).build_types(entrypoint, argtypes)
t.buildrtyper().specialize()
- #from pypy.translator.backendopt.all import backend_optimizations
- #backend_optimizations(t)
+ # note that backend optimizations will constant-fold simple operations,
+ # which is required by some backends that don't accept calls like
+ # genop1("add", constant, constant).
+ from pypy.translator.backendopt.all import backend_optimizations
+ backend_optimizations(t)
if conftest.option.view:
t.view()
- from pypy.translator.c.genc import CStandaloneBuilder
- cbuild = CStandaloneBuilder(t, entrypoint, config=t.config)
- db = cbuild.generate_graphs_for_llinterp()
- entrypointptr = cbuild.getentrypointptr()
- entrygraph = entrypointptr._obj.graph
+ entrygraph = t._graphof(entrypoint)
return compile_graph(rgenop, entrygraph, random_seed=random_seed)
Modified: pypy/dist/pypy/jit/codegen/i386/demo/support.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/demo/support.py (original)
+++ pypy/dist/pypy/jit/codegen/i386/demo/support.py Fri Jan 26 16:11:37 2007
@@ -26,8 +26,6 @@
seed = demo_conftest.option.randomseed
benchmark = bench_conftest.option.benchmark
- expected = entrypoint(*args)
-
logfile = str(udir.join('%s.log' % (entrypoint.__name__,)))
try:
os.unlink(logfile)
@@ -58,20 +56,22 @@
random_seed=seed)
machine_code_dumper._freeze_() # clean up state
- fp = cast(c_void_p(gv_entrypoint.value),
- CFUNCTYPE(c_int, *[c_int] * nb_args))
-
print
- print 'Random seed value was %d.' % (seed,)
+ print 'Random seed value: %d' % (seed,)
print
+ expected = entrypoint(*args)
+
print 'Running %s(%s)...' % (entrypoint.__name__,
', '.join(map(repr, args)))
+ fp = cast(c_void_p(gv_entrypoint.value),
+ CFUNCTYPE(c_int, *[c_int] * nb_args))
res = fp(*args)
print '===>', res
print
if res != expected:
- raise AssertionError("expected return value is %s, got %s" % (
- expected, res))
+ raise AssertionError(
+ "expected return value is %s, got %s\nseed = %s" % (
+ expected, res, seed))
if view:
from pypy.jit.codegen.i386.viewcode import World
Modified: pypy/dist/pypy/jit/codegen/i386/demo/test_factorial.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/demo/test_factorial.py (original)
+++ pypy/dist/pypy/jit/codegen/i386/demo/test_factorial.py Fri Jan 26 16:11:37 2007
@@ -48,14 +48,13 @@
#rundemo(f1, 2117)
rundemo(f1, 217)
-def test_random_function():
- py.test.skip("in-progress (e.g. --seed=225 shows a backend crash)")
- from pypy.rlib.unroll import SpecTag
- blocklabels = range(15)
+def test_random_function(nb_blocks=15, max_block_length=20):
+ py.test.skip("in-progress")
+ blocklabels = range(nb_blocks)
r = Random()
vars = list("abcdefghijklmnopqrstuvwxyz")
varlist = ', '.join(vars)
- magicsum = '+'.join(['%s^%d' % (v, hash(v)) for v in vars])
+ magicsum = '+'.join(['%s*%d' % (v, hash(v)) for v in vars])
operations = ['%s + %s',
'%s + %s',
'%s - %s',
@@ -64,8 +63,8 @@
'%s & %s',
'%s | %s',
'%s ^ %s',
- '%s << abs(%s)',
- '%s >> abs(%s)',
+ '%s << (%s & 0x1234567f)',
+ '%s >> (%s & 0x1234567f)',
'abs(%s)',
'-%s',
'~%s',
@@ -84,14 +83,13 @@
'!%s > %s',
'!%s >= %s',
]
- lines = ["def dummyfn(%(varlist)s):" % locals(),
- " goto = blocktag0",
- " counter = 10000",
- " while counter > 0:",
- " counter -= 1"]
+ lines = ["def dummyfn(counter, %(varlist)s):" % locals(),
+ " goto = 0",
+ " while True:",
+ ]
for i in blocklabels:
- lines.append(" if goto is blocktag%d:" % i)
- for j in range(r.randrange(0, 20)):
+ lines.append(" if goto == %d:" % i)
+ for j in range(r.randrange(0, max_block_length)):
v1 = r.choice(vars)
constbytes = r.randrange(-15, 5)
if constbytes <= 0:
@@ -113,19 +111,19 @@
constant = constant << 8 | r.randrange(0, 256)
lines.append(" %s = %d" % (v1, constant))
v1 = r.choice(vars)
- lines.append(" if %s: goto = blocktag%d" %
- (v1, r.choice(blocklabels)))
- lines.append(" else: goto = blocktag%d" %
- (r.choice(blocklabels),))
- lines.append(" del goto")
+ for line in [" if %s:" % v1,
+ " else:"]:
+ lines.append(line)
+ j = r.choice(blocklabels)
+ if j <= i:
+ lines.append(" counter -= 1")
+ lines.append(" if not counter: break")
+ lines.append(" goto = %d" % j)
lines.append(" return intmask(%(magicsum)s)" % locals())
- miniglobals = {'intmask': intmask}
- for i in blocklabels:
- miniglobals['blocktag%d' % i] = SpecTag()
src = py.code.Source('\n'.join(lines))
- exec src.compile() in miniglobals
- dummyfn = miniglobals['dummyfn']
+ print src
+ exec src.compile()
args = [r.randrange(-99, 100) for v1 in vars]
- rundemo(dummyfn, *args)
+ rundemo(dummyfn, 100, *args)
Modified: pypy/dist/pypy/jit/codegen/i386/operation.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/operation.py (original)
+++ pypy/dist/pypy/jit/codegen/i386/operation.py Fri Jan 26 16:11:37 2007
@@ -53,11 +53,20 @@
class UnaryOp(Op1):
def generate(self, allocator):
try:
- loc = allocator.var2loc[self]
+ dstop = allocator.get_operand(self)
except KeyError:
return # simple operation whose result is not used anyway
- op = allocator.load_location_with(loc, self.x)
- self.emit(allocator.mc, op)
+ srcop = allocator.get_operand(self.x)
+ mc = allocator.mc
+ if srcop != dstop:
+ try:
+ mc.MOV(dstop, srcop)
+ except FailedToImplement:
+ mc.MOV(ecx, srcop)
+ self.emit(mc, ecx)
+ mc.MOV(dstop, ecx)
+ return
+ self.emit(mc, dstop)
class OpIntNeg(UnaryOp):
opname = 'int_neg'
@@ -214,6 +223,8 @@
mc.MOV(dstop, tmpop)
class MulOrDivOp(Op2):
+ extra_scratch = mem(esp)
+
def generate3(self, mc, dstop, op1, op2):
# not very efficient but not very common operations either
if dstop != eax:
@@ -223,6 +234,9 @@
if op1 != eax:
mc.MOV(eax, op1)
if self.input_is_64bits:
+ if op2 == edx:
+ mc.PUSH(edx)
+ op2 = MulOrDivOp.extra_scratch
if self.unsigned:
mc.XOR(edx, edx)
else:
@@ -234,6 +248,8 @@
self.emit(mc, ecx)
if dstop != self.reg_containing_result:
mc.MOV(dstop, self.reg_containing_result)
+ if op2 is MulOrDivOp.extra_scratch:
+ mc.ADD(esp, imm8(WORD))
if dstop != edx:
mc.POP(edx)
if dstop != eax:
Modified: pypy/dist/pypy/jit/codegen/i386/test/test_operation.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/test/test_operation.py (original)
+++ pypy/dist/pypy/jit/codegen/i386/test/test_operation.py Fri Jan 26 16:11:37 2007
@@ -77,3 +77,15 @@
[v4] = args_gv
builder1.finish_and_return(rgenop.sigToken(FUNC0), v4)
builder0.end()
+
+ def test_idiv_bug(self):
+ def fn(x, y):
+ return (x+1) // (-y) + x + y # generated a bogus "idiv edx"
+ fp = self.rgen(fn, [int, int])
+ assert fp(5, 7) == fn(5, 7)
+
+ def test_imod_bug(self):
+ def fn(x, y):
+ return (x+1) % (-y) + x + y
+ fp = self.rgen(fn, [int, int])
+ assert fp(5, 7) == fn(5, 7)
Modified: pypy/dist/pypy/objspace/flow/objspace.py
==============================================================================
--- pypy/dist/pypy/objspace/flow/objspace.py (original)
+++ pypy/dist/pypy/objspace/flow/objspace.py Fri Jan 26 16:11:37 2007
@@ -623,12 +623,17 @@
raise flowcontext.OperationThatShouldNotBePropagatedError(
self.wrap(etype), self.wrap(msg))
else:
- try:
- return self.wrap(result)
- except WrapException:
- # type cannot sanely appear in flow graph,
- # store operation with variable result instead
- pass
+ # don't try to constant-fold operations giving a 'long'
+ # result. The result is probably meant to be sent to
+ # an intmask(), but the 'long' constant confuses the
+ # annotator a lot.
+ if type(result) is not long:
+ try:
+ return self.wrap(result)
+ except WrapException:
+ # type cannot sanely appear in flow graph,
+ # store operation with variable result instead
+ pass
#print >> sys.stderr, 'Variable operation', name, args_w
w_result = self.do_operation_with_implicit_exceptions(name, *args_w)
More information about the Pypy-commit
mailing list