[pypy-svn] r23549 - in pypy/dist/pypy/rpython: . lltypesystem lltypesystem/test
arigo at codespeak.net
arigo at codespeak.net
Tue Feb 21 15:10:25 CET 2006
Author: arigo
Date: Tue Feb 21 15:10:23 2006
New Revision: 23549
Added:
pypy/dist/pypy/rpython/lltypesystem/lloperation.py
pypy/dist/pypy/rpython/lltypesystem/test/test_lloperation.py
Modified:
pypy/dist/pypy/rpython/llinterp.py
Log:
A nice big table of all LL operations, with properties like side-effects-ness and constant-foldability.
Modified: pypy/dist/pypy/rpython/llinterp.py
==============================================================================
--- pypy/dist/pypy/rpython/llinterp.py (original)
+++ pypy/dist/pypy/rpython/llinterp.py Tue Feb 21 15:10:23 2006
@@ -657,6 +657,8 @@
""" % locals()).compile()
for opname in 'is_true', 'neg', 'abs', 'invert':
assert opname in opimpls
+ if typ is float and opname == 'invert':
+ continue
if typ is int and opname not in ops_returning_a_bool:
adjust_result = 'intmask'
else:
@@ -667,7 +669,7 @@
func = opimpls[%(opname)r]
return %(adjust_result)s(func(x))
""" % locals()).compile()
- if typ is int:
+ if typ is int and opname in ('neg', 'abs'):
opname += '_ovf'
exec py.code.Source("""
def op_%(opnameprefix)s_%(opname)s(self, x):
@@ -689,21 +691,21 @@
return func(x, y)
""" % locals()).compile()
- op_original_int_add = op_int_add
+ original_int_add = op_int_add
def op_int_add(self, x, y):
if isinstance(x, llmemory.AddressOffset) or isinstance(y, llmemory.AddressOffset) :
return x + y
else:
- return self.op_original_int_add(x, y)
+ return self.original_int_add(x, y)
- op_original_int_mul = op_int_mul
+ original_int_mul = op_int_mul
def op_int_mul(self, x, y):
if isinstance(x, llmemory.AddressOffset):
return x * y
else:
- return self.op_original_int_mul(x, y)
+ return self.original_int_mul(x, y)
def op_unichar_eq(self, x, y):
assert isinstance(x, unicode) and len(x) == 1
Added: pypy/dist/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/lltypesystem/lloperation.py Tue Feb 21 15:10:23 2006
@@ -0,0 +1,251 @@
+"""
+The table of all LL operations.
+"""
+
+class LLOp(object):
+
+ def __init__(self, sideeffects=True, canfold=False, canraise=(), pyobj=False):
+ if canfold:
+ sideeffects = False
+
+ # The operation has no side-effects: it can be removed
+ # if its result is not used
+ self.sideeffects = sideeffects
+
+ # Can be safely constant-folded: no side-effects
+ # and always gives the same result for given args
+ self.canfold = canfold
+
+ # Exceptions that can be raised
+ self.canraise = canraise
+
+ # The operation manipulates PyObjects
+ self.pyobj = pyobj
+
+# ____________________________________________________________
+#
+# This list corresponds to the operations implemented by the LLInterpreter.
+# XXX Some clean-ups are needed:
+# * many exception-raising operations are being replaced by calls to helpers
+# * there are still many _ovf operations that cannot really raise OverflowError
+# * the div/truediv/floordiv mess needs to be sorted out and reduced
+# * float_mod vs float_fmod ?
+# Run test_lloperation after changes. Feel free to clean up LLInterpreter too :-)
+
+LL_OPERATIONS = {
+
+ 'direct_call': LLOp(canraise=(Exception,)),
+ 'indirect_call': LLOp(canraise=(Exception,)),
+
+ # __________ numeric operations __________
+
+ 'bool_not': LLOp(canfold=True),
+
+ 'char_lt': LLOp(canfold=True),
+ 'char_le': LLOp(canfold=True),
+ 'char_eq': LLOp(canfold=True),
+ 'char_ne': LLOp(canfold=True),
+ 'char_gt': LLOp(canfold=True),
+ 'char_ge': LLOp(canfold=True),
+
+ 'unichar_eq': LLOp(canfold=True),
+ 'unichar_ne': LLOp(canfold=True),
+
+ 'int_is_true': LLOp(canfold=True),
+ 'int_neg': LLOp(canfold=True),
+ 'int_neg_ovf': LLOp(canfold=True, canraise=(OverflowError,)),
+ 'int_abs': LLOp(canfold=True),
+ 'int_abs_ovf': LLOp(canfold=True, canraise=(OverflowError,)),
+ 'int_invert': LLOp(canfold=True),
+
+ 'int_add': LLOp(canfold=True),
+ 'int_sub': LLOp(canfold=True),
+ 'int_mul': LLOp(canfold=True),
+ 'int_div': LLOp(canfold=True),
+ 'int_truediv': LLOp(canfold=True),
+ 'int_floordiv': LLOp(canfold=True),
+ 'int_mod': LLOp(canfold=True),
+ 'int_lt': LLOp(canfold=True),
+ 'int_le': LLOp(canfold=True),
+ 'int_eq': LLOp(canfold=True),
+ 'int_ne': LLOp(canfold=True),
+ 'int_gt': LLOp(canfold=True),
+ 'int_ge': LLOp(canfold=True),
+ 'int_and': LLOp(canfold=True),
+ 'int_or': LLOp(canfold=True),
+ 'int_lshift': LLOp(canfold=True),
+ 'int_rshift': LLOp(canfold=True),
+ 'int_xor': LLOp(canfold=True),
+ 'int_add_ovf': LLOp(canfold=True, canraise=(OverflowError,)),
+ 'int_sub_ovf': LLOp(canfold=True, canraise=(OverflowError,)),
+ 'int_mul_ovf': LLOp(canfold=True, canraise=(OverflowError,)),
+ 'int_div_ovf': LLOp(canfold=True, canraise=(OverflowError,)),
+ 'int_truediv_ovf': LLOp(canfold=True, canraise=(OverflowError,)),
+ 'int_floordiv_ovf': LLOp(canfold=True, canraise=(OverflowError,)),
+ 'int_mod_ovf': LLOp(canfold=True, canraise=(OverflowError,)),
+ 'int_lt_ovf': LLOp(canfold=True, canraise=(OverflowError,)),
+ 'int_le_ovf': LLOp(canfold=True, canraise=(OverflowError,)),
+ 'int_eq_ovf': LLOp(canfold=True, canraise=(OverflowError,)),
+ 'int_ne_ovf': LLOp(canfold=True, canraise=(OverflowError,)),
+ 'int_gt_ovf': LLOp(canfold=True, canraise=(OverflowError,)),
+ 'int_ge_ovf': LLOp(canfold=True, canraise=(OverflowError,)),
+ 'int_and_ovf': LLOp(canfold=True, canraise=(OverflowError,)),
+ 'int_or_ovf': LLOp(canfold=True, canraise=(OverflowError,)),
+ 'int_lshift_ovf': LLOp(canfold=True, canraise=(OverflowError,)),
+ 'int_rshift_ovf': LLOp(canfold=True, canraise=(OverflowError,)),
+ 'int_xor_ovf': LLOp(canfold=True, canraise=(OverflowError,)),
+ 'int_floordiv_ovf_zer': LLOp(canfold=True, canraise=(OverflowError, ZeroDivisionError)),
+ 'int_mod_ovf_zer': LLOp(canfold=True, canraise=(OverflowError, ZeroDivisionError)),
+
+ 'uint_is_true': LLOp(canfold=True),
+ 'uint_neg': LLOp(canfold=True),
+ 'uint_abs': LLOp(canfold=True),
+ 'uint_invert': LLOp(canfold=True),
+
+ 'uint_add': LLOp(canfold=True),
+ 'uint_sub': LLOp(canfold=True),
+ 'uint_mul': LLOp(canfold=True),
+ 'uint_div': LLOp(canfold=True),
+ 'uint_truediv': LLOp(canfold=True),
+ 'uint_floordiv': LLOp(canfold=True),
+ 'uint_mod': LLOp(canfold=True),
+ 'uint_lt': LLOp(canfold=True),
+ 'uint_le': LLOp(canfold=True),
+ 'uint_eq': LLOp(canfold=True),
+ 'uint_ne': LLOp(canfold=True),
+ 'uint_gt': LLOp(canfold=True),
+ 'uint_ge': LLOp(canfold=True),
+ 'uint_and': LLOp(canfold=True),
+ 'uint_or': LLOp(canfold=True),
+ 'uint_lshift': LLOp(canfold=True),
+ 'uint_rshift': LLOp(canfold=True),
+ 'uint_xor': LLOp(canfold=True),
+
+ 'float_is_true': LLOp(canfold=True),
+ 'float_neg': LLOp(canfold=True),
+ 'float_abs': LLOp(canfold=True),
+
+ 'float_add': LLOp(canfold=True),
+ 'float_sub': LLOp(canfold=True),
+ 'float_mul': LLOp(canfold=True),
+ 'float_div': LLOp(canfold=True),
+ 'float_truediv': LLOp(canfold=True),
+ 'float_floordiv': LLOp(canfold=True),
+ 'float_mod': LLOp(canfold=True),
+ 'float_lt': LLOp(canfold=True),
+ 'float_le': LLOp(canfold=True),
+ 'float_eq': LLOp(canfold=True),
+ 'float_ne': LLOp(canfold=True),
+ 'float_gt': LLOp(canfold=True),
+ 'float_ge': LLOp(canfold=True),
+ 'float_floor': LLOp(canfold=True),
+ 'float_fmod': LLOp(canfold=True),
+
+ 'llong_is_true': LLOp(canfold=True),
+ 'llong_neg': LLOp(canfold=True),
+ 'llong_abs': LLOp(canfold=True),
+ 'llong_invert': LLOp(canfold=True),
+
+ 'llong_add': LLOp(canfold=True),
+ 'llong_sub': LLOp(canfold=True),
+ 'llong_mul': LLOp(canfold=True),
+ 'llong_div': LLOp(canfold=True),
+ 'llong_truediv': LLOp(canfold=True),
+ 'llong_floordiv': LLOp(canfold=True),
+ 'llong_mod': LLOp(canfold=True),
+ 'llong_lt': LLOp(canfold=True),
+ 'llong_le': LLOp(canfold=True),
+ 'llong_eq': LLOp(canfold=True),
+ 'llong_ne': LLOp(canfold=True),
+ 'llong_gt': LLOp(canfold=True),
+ 'llong_ge': LLOp(canfold=True),
+
+ 'ullong_is_true': LLOp(canfold=True),
+ 'ullong_neg': LLOp(canfold=True),
+ 'ullong_abs': LLOp(canfold=True),
+ 'ullong_invert': LLOp(canfold=True),
+
+ 'ullong_add': LLOp(canfold=True),
+ 'ullong_sub': LLOp(canfold=True),
+ 'ullong_mul': LLOp(canfold=True),
+ 'ullong_div': LLOp(canfold=True),
+ 'ullong_truediv': LLOp(canfold=True),
+ 'ullong_floordiv': LLOp(canfold=True),
+ 'ullong_mod': LLOp(canfold=True),
+ 'ullong_lt': LLOp(canfold=True),
+ 'ullong_le': LLOp(canfold=True),
+ 'ullong_eq': LLOp(canfold=True),
+ 'ullong_ne': LLOp(canfold=True),
+ 'ullong_gt': LLOp(canfold=True),
+ 'ullong_ge': LLOp(canfold=True),
+
+ 'cast_bool_to_int': LLOp(canfold=True),
+ 'cast_bool_to_uint': LLOp(canfold=True),
+ 'cast_bool_to_float': LLOp(canfold=True),
+ 'cast_char_to_int': LLOp(canfold=True),
+ 'cast_unichar_to_int': LLOp(canfold=True),
+ 'cast_int_to_char': LLOp(canfold=True),
+ 'cast_int_to_unichar': LLOp(canfold=True),
+ 'cast_int_to_uint': LLOp(canfold=True),
+ 'cast_int_to_float': LLOp(canfold=True),
+ 'cast_int_to_longlong': LLOp(canfold=True),
+ 'cast_uint_to_int': LLOp(canfold=True),
+ 'cast_float_to_int': LLOp(canfold=True),
+ 'cast_float_to_uint': LLOp(canfold=True),
+ 'truncate_longlong_to_int':LLOp(canfold=True),
+
+ # __________ pointer operations __________
+
+ 'malloc': LLOp(canraise=(MemoryError,)),
+ 'malloc_varsize': LLOp(canraise=(MemoryError,)),
+ 'flavored_malloc': LLOp(canraise=(MemoryError,)),
+ 'flavored_free': LLOp(),
+ 'getfield': LLOp(sideeffects=False),
+ 'getarrayitem': LLOp(sideeffects=False),
+ 'getarraysize': LLOp(canfold=True),
+ 'getsubstruct': LLOp(canfold=True),
+ 'getarraysubstruct': LLOp(canfold=True),
+ 'setfield': LLOp(),
+ 'setarrayitem': LLOp(),
+ 'cast_pointer': LLOp(canfold=True),
+ 'ptr_eq': LLOp(canfold=True),
+ 'ptr_ne': LLOp(canfold=True),
+ 'ptr_nonzero': LLOp(canfold=True),
+ 'ptr_iszero': LLOp(canfold=True),
+ 'cast_ptr_to_int': LLOp(sideeffects=False),
+
+ # __________ address operations __________
+
+ 'raw_malloc': LLOp(canraise=(MemoryError,)),
+ 'raw_free': LLOp(),
+ 'raw_memcopy': LLOp(),
+ 'raw_load': LLOp(sideeffects=False),
+ 'raw_store': LLOp(),
+ 'adr_add': LLOp(canfold=True),
+ 'adr_sub': LLOp(canfold=True),
+ 'adr_delta': LLOp(canfold=True),
+ 'adr_lt': LLOp(canfold=True),
+ 'adr_le': LLOp(canfold=True),
+ 'adr_eq': LLOp(canfold=True),
+ 'adr_ne': LLOp(canfold=True),
+ 'adr_gt': LLOp(canfold=True),
+ 'adr_ge': LLOp(canfold=True),
+ 'cast_ptr_to_adr': LLOp(canfold=True),
+ 'cast_adr_to_ptr': LLOp(canfold=True),
+
+ # __________ misc operations __________
+
+ 'keepalive': LLOp(),
+ 'same_as': LLOp(canfold=True),
+ 'hint': LLOp(),
+}
+
+ # __________ operations on PyObjects __________
+
+from pypy.objspace.flow.operation import FunctionByName
+opimpls = FunctionByName.copy()
+opimpls['is_true'] = True
+opimpls['simple_call'] = True
+for opname in opimpls:
+ LL_OPERATIONS[opname] = LLOp(canraise=(Exception,), pyobj=True)
+del opname, opimpls, FunctionByName
Added: pypy/dist/pypy/rpython/lltypesystem/test/test_lloperation.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_lloperation.py Tue Feb 21 15:10:23 2006
@@ -0,0 +1,22 @@
+from pypy.rpython.lltypesystem.lloperation import LL_OPERATIONS
+from pypy.rpython.llinterp import LLFrame
+
+# This tests that the LLInterpreter and the LL_OPERATIONS tables are in sync.
+
+LL_INTERP_OPERATIONS = [name[3:] for name in LLFrame.__dict__.keys()
+ if name.startswith('op_')
+# Ignore OO operations for now
+ and not (name == 'op_new' or
+ name == 'op_subclassof' or
+ name == 'op_instanceof' or
+ name == 'op_classof' or
+ name.startswith('op_oo'))]
+
+
+def test_table_complete():
+ for opname in LL_INTERP_OPERATIONS:
+ assert opname in LL_OPERATIONS
+
+def test_llinterp_complete():
+ for opname in LL_OPERATIONS:
+ assert opname in LL_INTERP_OPERATIONS
More information about the Pypy-commit
mailing list