[pypy-svn] pypy arm-backend-2: Merge default and update moved compute_vars_longevity
bivab
commits-noreply at bitbucket.org
Fri Jan 14 12:55:44 CET 2011
Author: David Schneider <david.schneider at picle.org>
Branch: arm-backend-2
Changeset: r40665:a91dd51ccfca
Date: 2011-01-14 11:52 +0100
http://bitbucket.org/pypy/pypy/changeset/a91dd51ccfca/
Log: Merge default and update moved compute_vars_longevity
diff --git a/pypy/jit/backend/llsupport/regalloc.py b/pypy/jit/backend/llsupport/regalloc.py
--- a/pypy/jit/backend/llsupport/regalloc.py
+++ b/pypy/jit/backend/llsupport/regalloc.py
@@ -353,38 +353,45 @@
def compute_vars_longevity(inputargs, operations):
# compute a dictionary that maps variables to index in
# operations that is a "last-time-seen"
- longevity = {}
- start_live = {}
- for inputarg in inputargs:
- start_live[inputarg] = 0
- for i in range(len(operations)):
+ produced = {}
+ last_used = {}
+ for i in range(len(operations)-1, -1, -1):
op = operations[i]
- if op.result is not None:
- start_live[op.result] = i
+ if op.result:
+ if op.result not in last_used and op.has_no_side_effect():
+ continue
+ assert op.result not in produced
+ produced[op.result] = i
for j in range(op.numargs()):
arg = op.getarg(j)
- if isinstance(arg, Box):
- if arg not in start_live:
- not_implemented("Bogus arg in operation %d at %d" %
- (op.getopnum(), i))
-
- longevity[arg] = (start_live[arg], i)
+ if isinstance(arg, Box) and arg not in last_used:
+ last_used[arg] = i
if op.is_guard():
for arg in op.getfailargs():
if arg is None: # hole
continue
assert isinstance(arg, Box)
- if arg not in start_live:
- not_implemented("Bogus arg in guard %d at %d" %
- (op.getopnum(), i))
- longevity[arg] = (start_live[arg], i)
+ if arg not in last_used:
+ last_used[arg] = i
+
+ longevity = {}
+ for arg in produced:
+ if arg in last_used:
+ assert isinstance(arg, Box)
+ assert produced[arg] < last_used[arg]
+ longevity[arg] = (produced[arg], last_used[arg])
+ del last_used[arg]
for arg in inputargs:
- if arg not in longevity:
+ assert isinstance(arg, Box)
+ if arg not in last_used:
longevity[arg] = (-1, -1)
- for arg in longevity:
- assert isinstance(arg, Box)
+ else:
+ longevity[arg] = (0, last_used[arg])
+ del last_used[arg]
+ assert len(last_used) == 0
return longevity
+
def compute_loop_consts(inputargs, jump, looptoken):
if jump.getopnum() != rop.JUMP or jump.getdescr() is not looptoken:
loop_consts = {}
@@ -395,6 +402,7 @@
loop_consts[inputargs[i]] = i
return loop_consts
+
def not_implemented(msg):
os.write(2, '[llsupport/regalloc] %s\n' % msg)
raise NotImplementedError(msg)
diff --git a/pypy/module/pypyjit/test/test_pypy_c.py b/pypy/module/pypyjit/test/test_pypy_c.py
--- a/pypy/module/pypyjit/test/test_pypy_c.py
+++ b/pypy/module/pypyjit/test/test_pypy_c.py
@@ -1378,6 +1378,98 @@
i += 1
return sa
''', ops, ([a, b], r), count_debug_merge_point=False)
+
+ def test_revert_shift(self):
+ from sys import maxint
+ tests = []
+ for a in (1, 4, 8, 100):
+ for b in (-10, 10, -201, 201, -maxint/3, maxint/3):
+ for c in (-10, 10, -maxint/3, maxint/3):
+ tests.append(([a, b, c], long(4000*(a+b+c))))
+ self.run_source('''
+ def main(a, b, c):
+ from sys import maxint
+ i = sa = 0
+ while i < 2000:
+ if 0 < a < 10: pass
+ if -100 < b < 100: pass
+ if -maxint/2 < c < maxint/2: pass
+ sa += (a<<a)>>a
+ sa += (b<<a)>>a
+ sa += (c<<a)>>a
+ sa += (a<<100)>>100
+ sa += (b<<100)>>100
+ sa += (c<<100)>>100
+ i += 1
+ return long(sa)
+ ''', 93, count_debug_merge_point=False, *tests)
+
+ def test_division_to_rshift(self):
+ avalues = ('a', 'b', 7, -42, 8)
+ bvalues = ['b'] + range(-10, 0) + range(1,10)
+ code = ''
+ a1, b1, res1 = 10, 20, 0
+ a2, b2, res2 = 10, -20, 0
+ a3, b3, res3 = -10, -20, 0
+ def dd(a, b, aval, bval):
+ m = {'a': aval, 'b': bval}
+ if not isinstance(a, int):
+ a=m[a]
+ if not isinstance(b, int):
+ b=m[b]
+ return a/b
+ for a in avalues:
+ for b in bvalues:
+ code += ' sa += %s / %s\n' % (a, b)
+ res1 += dd(a, b, a1, b1)
+ res2 += dd(a, b, a2, b2)
+ res3 += dd(a, b, a3, b3)
+ self.run_source('''
+ def main(a, b):
+ i = sa = 0
+ while i < 2000:
+%s
+ i += 1
+ return sa
+ ''' % code, 179, ([a1, b1], 2000 * res1),
+ ([a2, b2], 2000 * res2),
+ ([a3, b3], 2000 * res3),
+ count_debug_merge_point=False)
+
+ def test_mod(self):
+ py.test.skip('Results are correct, but traces 1902 times (on trunk too).')
+ avalues = ('a', 'b', 7, -42, 8)
+ bvalues = ['b'] + range(-10, 0) + range(1,10)
+ code = ''
+ a1, b1, res1 = 10, 20, 0
+ a2, b2, res2 = 10, -20, 0
+ a3, b3, res3 = -10, -20, 0
+ def dd(a, b, aval, bval):
+ m = {'a': aval, 'b': bval}
+ if not isinstance(a, int):
+ a=m[a]
+ if not isinstance(b, int):
+ b=m[b]
+ return a % b
+ for a in avalues:
+ for b in bvalues:
+ code += ' sa += %s %% %s\n' % (a, b)
+ res1 += dd(a, b, a1, b1)
+ res2 += dd(a, b, a2, b2)
+ res3 += dd(a, b, a3, b3)
+ self.run_source('''
+ def main(a, b):
+ i = sa = 0
+ while i < 2000:
+ if a > 0: pass
+ if 1 < b < 2: pass
+%s
+ i += 1
+ return sa
+ ''' % code, 0, ([a1, b1], 2000 * res1),
+ ([a2, b2], 2000 * res2),
+ ([a3, b3], 2000 * res3),
+ count_debug_merge_point=False)
class AppTestJIT(PyPyCJITTests):
diff --git a/pypy/jit/backend/arm/arch.py b/pypy/jit/backend/arm/arch.py
--- a/pypy/jit/backend/arm/arch.py
+++ b/pypy/jit/backend/arm/arch.py
@@ -8,6 +8,7 @@
arm_int_div_sign = lltype.Ptr(lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed))
def arm_int_div(a, b):
+ print 'DIV'
return int(a/float(b))
arm_uint_div_sign = lltype.Ptr(lltype.FuncType([lltype.Unsigned, lltype.Unsigned], lltype.Unsigned))
diff --git a/pypy/jit/tool/showstats.py b/pypy/jit/tool/showstats.py
--- a/pypy/jit/tool/showstats.py
+++ b/pypy/jit/tool/showstats.py
@@ -10,7 +10,6 @@
def main(argv):
log = logparser.parse_log_file(argv[0])
- log_count_lines = open(argv[0] + '.count').readlines()
parts = logparser.extract_category(log, "jit-log-opt-")
for i, oplist in enumerate(parts):
loop = parse(oplist, no_namespace=True, nonstrict=True)
@@ -28,7 +27,6 @@
print "Loop #%d, length: %d, opcodes: %d, guards: %d" % (i, num_ops, num_dmp, num_guards)
else:
print "Loop #%d, length: %d, opcodes: %d, guards: %d, %f" % (i, num_ops, num_dmp, num_guards, num_ops/num_dmp)
- print loop.comment, "run", log_count_lines[i].split(":")[1].strip(), "times"
if __name__ == '__main__':
main(sys.argv[1:])
diff --git a/pypy/jit/metainterp/test/test_basic.py b/pypy/jit/metainterp/test/test_basic.py
--- a/pypy/jit/metainterp/test/test_basic.py
+++ b/pypy/jit/metainterp/test/test_basic.py
@@ -342,7 +342,7 @@
self.check_loop_count(1)
self.check_loops({'guard_true': 1,
'int_add': 2, 'int_sub': 1, 'int_gt': 1,
- 'int_mul': 1,
+ 'int_lshift': 1,
'jump': 1})
def test_loop_invariant_mul_bridge1(self):
diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py
--- a/pypy/jit/metainterp/optimizeopt/rewrite.py
+++ b/pypy/jit/metainterp/optimizeopt/rewrite.py
@@ -4,6 +4,9 @@
from pypy.jit.metainterp.optimizeutil import _findall
from pypy.jit.metainterp.resoperation import rop, ResOperation
from pypy.jit.codewriter.effectinfo import EffectInfo
+from pypy.jit.metainterp.optimizeopt.intutils import IntBound
+from pypy.rlib.rarithmetic import highest_bit
+
class OptRewrite(Optimization):
"""Rewrite operations into equivalent, cheaper operations.
@@ -141,6 +144,14 @@
(v2.is_constant() and v2.box.getint() == 0):
self.make_constant_int(op.result, 0)
else:
+ for lhs, rhs in [(v1, v2), (v2, v1)]:
+ # x & (x -1) == 0 is a quick test for power of 2
+ if (lhs.is_constant() and
+ (lhs.box.getint() & (lhs.box.getint() - 1)) == 0):
+ new_rhs = ConstInt(highest_bit(lhs.box.getint()))
+ op = op.copy_and_change(rop.INT_LSHIFT, args=[rhs.box, new_rhs])
+ break
+
self.emit_operation(op)
def optimize_CALL_PURE(self, op):
@@ -379,5 +390,17 @@
return True # 0-length arraycopy
return False
+ def optimize_INT_FLOORDIV(self, op):
+ v1 = self.getvalue(op.getarg(0))
+ v2 = self.getvalue(op.getarg(1))
+
+ if v1.intbound.known_ge(IntBound(0, 0)) and v2.is_constant():
+ val = v2.box.getint()
+ if val & (val - 1) == 0 and val > 0: # val == 2**shift
+ op = op.copy_and_change(rop.INT_RSHIFT,
+ args = [op.getarg(0), ConstInt(highest_bit(val))])
+ self.emit_operation(op)
+
+
optimize_ops = _findall(OptRewrite, 'optimize_')
optimize_guards = _findall(OptRewrite, 'optimize_', 'GUARD')
diff --git a/pypy/module/pypyjit/policy.py b/pypy/module/pypyjit/policy.py
--- a/pypy/module/pypyjit/policy.py
+++ b/pypy/module/pypyjit/policy.py
@@ -7,7 +7,8 @@
modname == '__builtin__.abstractinst' or
modname == '__builtin__.interp_classobj' or
modname == '__builtin__.functional' or
- modname == '__builtin__.descriptor'):
+ modname == '__builtin__.descriptor' or
+ modname == 'thread.os_local'):
return True
if '.' in modname:
modname, _ = modname.split('.', 1)
diff --git a/pypy/jit/metainterp/test/test_optimizeopt.py b/pypy/jit/metainterp/test/test_optimizeopt.py
--- a/pypy/jit/metainterp/test/test_optimizeopt.py
+++ b/pypy/jit/metainterp/test/test_optimizeopt.py
@@ -4035,8 +4035,110 @@
"""
self.optimize_loop(ops, expected, preamble)
-
-
+ def test_division_to_rshift(self):
+ ops = """
+ [i1, i2]
+ it = int_gt(i1, 0)
+ guard_true(it)[]
+ i3 = int_floordiv(i1, i2)
+ i4 = int_floordiv(2, i2)
+ i5 = int_floordiv(i1, 2)
+ i6 = int_floordiv(3, i2)
+ i7 = int_floordiv(i1, 3)
+ i8 = int_floordiv(4, i2)
+ i9 = int_floordiv(i1, 4)
+ i10 = int_floordiv(i1, 0)
+ i11 = int_floordiv(i1, 1)
+ i12 = int_floordiv(i2, 2)
+ i13 = int_floordiv(i2, 3)
+ i14 = int_floordiv(i2, 4)
+ jump(i5, i14)
+ """
+ expected = """
+ [i1, i2]
+ it = int_gt(i1, 0)
+ guard_true(it)[]
+ i3 = int_floordiv(i1, i2)
+ i4 = int_floordiv(2, i2)
+ i5 = int_rshift(i1, 1)
+ i6 = int_floordiv(3, i2)
+ i7 = int_floordiv(i1, 3)
+ i8 = int_floordiv(4, i2)
+ i9 = int_rshift(i1, 2)
+ i10 = int_floordiv(i1, 0)
+ i11 = int_rshift(i1, 0)
+ i12 = int_floordiv(i2, 2)
+ i13 = int_floordiv(i2, 3)
+ i14 = int_floordiv(i2, 4)
+ jump(i5, i14)
+ """
+ self.optimize_loop(ops, expected)
+
+ def test_mul_to_lshift(self):
+ ops = """
+ [i1, i2]
+ i3 = int_mul(i1, 2)
+ i4 = int_mul(2, i2)
+ i5 = int_mul(i1, 32)
+ i6 = int_mul(i1, i2)
+ jump(i5, i6)
+ """
+ expected = """
+ [i1, i2]
+ i3 = int_lshift(i1, 1)
+ i4 = int_lshift(i2, 1)
+ i5 = int_lshift(i1, 5)
+ i6 = int_mul(i1, i2)
+ jump(i5, i6)
+ """
+ self.optimize_loop(ops, expected)
+
+ def test_lshift_rshift(self):
+ ops = """
+ [i1, i2, i2b, i1b]
+ i3 = int_lshift(i1, i2)
+ i4 = int_rshift(i3, i2)
+ i5 = int_lshift(i1, 2)
+ i6 = int_rshift(i5, 2)
+ i7 = int_lshift(i1, 100)
+ i8 = int_rshift(i7, 100)
+ i9 = int_lt(i1b, 100)
+ guard_true(i9) []
+ i10 = int_gt(i1b, -100)
+ guard_true(i10) []
+ i13 = int_lshift(i1b, i2)
+ i14 = int_rshift(i13, i2)
+ i15 = int_lshift(i1b, 2)
+ i16 = int_rshift(i15, 2)
+ i17 = int_lshift(i1b, 100)
+ i18 = int_rshift(i17, 100)
+ i19 = int_eq(i1b, i16)
+ guard_true(i19) []
+ i20 = int_ne(i1b, i16)
+ guard_false(i20) []
+ jump(i2, i3, i1b, i2b)
+ """
+ expected = """
+ [i1, i2, i2b, i1b]
+ i3 = int_lshift(i1, i2)
+ i4 = int_rshift(i3, i2)
+ i5 = int_lshift(i1, 2)
+ i6 = int_rshift(i5, 2)
+ i7 = int_lshift(i1, 100)
+ i8 = int_rshift(i7, 100)
+ i9 = int_lt(i1b, 100)
+ guard_true(i9) []
+ i10 = int_gt(i1b, -100)
+ guard_true(i10) []
+ i13 = int_lshift(i1b, i2)
+ i14 = int_rshift(i13, i2)
+ i15 = int_lshift(i1b, 2)
+ i17 = int_lshift(i1b, 100)
+ i18 = int_rshift(i17, 100)
+ jump(i2, i3, i1b, i2b)
+ """
+ self.optimize_loop(ops, expected)
+
def test_subsub_ovf(self):
ops = """
[i0]
More information about the Pypy-commit
mailing list