[pypy-svn] r43640 - in pypy/dist/pypy/lang/prolog: builtin interpreter interpreter/test
cfbolz at codespeak.net
cfbolz at codespeak.net
Fri May 25 18:11:45 CEST 2007
Author: cfbolz
Date: Fri May 25 18:11:45 2007
New Revision: 43640
Modified:
pypy/dist/pypy/lang/prolog/builtin/arithmeticbuiltin.py
pypy/dist/pypy/lang/prolog/builtin/formatting.py
pypy/dist/pypy/lang/prolog/builtin/register.py
pypy/dist/pypy/lang/prolog/interpreter/arithmetic.py
pypy/dist/pypy/lang/prolog/interpreter/engine.py
pypy/dist/pypy/lang/prolog/interpreter/helper.py
pypy/dist/pypy/lang/prolog/interpreter/portal.py
pypy/dist/pypy/lang/prolog/interpreter/term.py
pypy/dist/pypy/lang/prolog/interpreter/test/test_jit.py
Log:
attempt to jit some of the integer arithmetic functions. requires some
rewriting.
Modified: pypy/dist/pypy/lang/prolog/builtin/arithmeticbuiltin.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/builtin/arithmeticbuiltin.py (original)
+++ pypy/dist/pypy/lang/prolog/builtin/arithmeticbuiltin.py Fri May 25 18:11:45 2007
@@ -27,6 +27,7 @@
def impl_is(engine, var, num):
var.unify(num, engine.heap)
+impl_is._look_inside_me_ = True
expose_builtin(impl_is, "is", unwrap_spec=["raw", "arithmetic"])
for ext, prolog, python in [("eq", "=:=", "=="),
@@ -43,7 +44,7 @@
eq = num1.num %s num2.num
elif isinstance(num1, term.Float):
if isinstance(num2, term.Float):
- eq = num1.num %s num2.num
+ eq = num1.floatval %s num2.floatval
if not eq:
raise error.UnificationFailed()""" % (ext, python, python)).compile()
expose_builtin(globals()["impl_arith_%s" % (ext, )], prolog,
Modified: pypy/dist/pypy/lang/prolog/builtin/formatting.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/builtin/formatting.py (original)
+++ pypy/dist/pypy/lang/prolog/builtin/formatting.py Fri May 25 18:11:45 2007
@@ -73,7 +73,7 @@
return str(num.num)
def format_float(self, num):
- return str(num.num)
+ return str(num.floatval)
def format_var(self, var):
return "_G%s" % (var.index, )
Modified: pypy/dist/pypy/lang/prolog/builtin/register.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/builtin/register.py (original)
+++ pypy/dist/pypy/lang/prolog/builtin/register.py Fri May 25 18:11:45 2007
@@ -87,7 +87,7 @@
signature = "%s/%s" % (name, len(unwrap_spec))
b = Builtin(miniglobals[funcname])
builtins[signature] = b
- if signature == ",/2":
+ if signature in [",/2", "is/2"]:
builtins_list.insert(0, (signature, b))
else:
builtins_list.append((signature, b))
Modified: pypy/dist/pypy/lang/prolog/interpreter/arithmetic.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/interpreter/arithmetic.py (original)
+++ pypy/dist/pypy/lang/prolog/interpreter/arithmetic.py Fri May 25 18:11:45 2007
@@ -4,10 +4,12 @@
from pypy.lang.prolog.interpreter import engine, helper, term, error
from pypy.lang.prolog.interpreter.error import UnificationFailed, FunctionNotFound
from pypy.rlib.rarithmetic import intmask
+from pypy.rlib.jit import we_are_jitted, hint
+from pypy.rlib.unroll import unrolling_iterable
arithmetic_functions = {}
+arithmetic_functions_list = []
-pattern_to_function = {}
class CodeCollector(object):
def __init__(self):
@@ -85,29 +87,15 @@
code.end_block("def")
miniglobals = globals().copy()
exec py.code.Source(code.tostring()).compile() in miniglobals
- return miniglobals["prolog_" + name]
+ result = miniglobals["prolog_" + name]
+ result._look_inside_me_ = True
+ return result
wrap_builtin_operation._annspecialcase_ = 'specialize:memo'
def eval_arithmetic(engine, query):
- query = query.getvalue(engine.heap)
- if isinstance(query, term.Number):
- return query
- if isinstance(query, term.Float):
- return norm_float(query)
- if isinstance(query, term.Atom):
- #XXX beautify that
- if query.name == "pi":
- return term.Float(math.pi)
- if query.name == "e":
- return term.Float(math.e)
- error.throw_type_error("evaluable", query.get_prolog_signature())
- if isinstance(query, term.Term):
- func = arithmetic_functions.get(query.signature, None)
- if func is None:
- error.throw_type_error("evaluable", query.get_prolog_signature())
- return func(engine, query)
- raise error.UncatchableError("not implemented")
+ return query.eval_arithmetic(engine)
+eval_arithmetic._look_inside_me_ = True
def norm_float(obj):
v = obj.floatval
@@ -121,7 +109,7 @@
("-", ["expr", "expr"], "v0 - v1", True, True),
("*", ["expr", "expr"], "v0 * v1", True, True),
("//", ["int", "int"], "v0 / v1", True, False),
- ("**", ["expr", "expr"], "v0 ** v1", True, True),
+ ("**", ["expr", "expr"], "float(v0) ** float(v1)", True, False),
(">>", ["int", "int"], "v0 >> v1", False, False),
("<<", ["int", "int"], "intmask(v0 << v1)", False,
False),
@@ -134,9 +122,9 @@
("max", ["expr", "expr"], "max(v0, v1)", False, True),
("min", ["expr", "expr"], "min(v0, v1)", False, True),
("round", ["expr"], "int(v0 + 0.5)", False, False),
- ("floor", ["expr"], "math.floor(v0)", False, True), #XXX
- ("ceiling", ["expr"], "math.ceil(v0)", False, True), #XXX
- ("float_fractional_part", ["expr"], "v0 - int(v0)", False, True), #XXX
+ ("floor", ["expr"], "math.floor(v0)", False, False), #XXX
+ ("ceiling", ["expr"], "math.ceil(v0)", False, False), #XXX
+ ("float_fractional_part", ["expr"], "v0 - int(v0)", False, False), #XXX
("float_integer_part", ["expr"], "int(v0)", False, True),
]
@@ -151,3 +139,6 @@
intversion)
signature = "%s/%s" % (prolog_name, len(unwrap_spec))
arithmetic_functions[signature] = f
+ arithmetic_functions_list.append((signature, f))
+
+arithmetic_functions_list = unrolling_iterable(arithmetic_functions_list)
Modified: pypy/dist/pypy/lang/prolog/interpreter/engine.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/interpreter/engine.py (original)
+++ pypy/dist/pypy/lang/prolog/interpreter/engine.py Fri May 25 18:11:45 2007
@@ -334,7 +334,7 @@
continuation)
raise
else:
- inline = False #XXX rule.body is None # inline facts
+ inline = rule.body is None # inline facts
try:
# for the last rule (rulechain is None), this will always
# return, because choice_point is False
Modified: pypy/dist/pypy/lang/prolog/interpreter/helper.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/interpreter/helper.py (original)
+++ pypy/dist/pypy/lang/prolog/interpreter/helper.py Fri May 25 18:11:45 2007
@@ -3,8 +3,10 @@
from pypy.lang.prolog.interpreter import term
from pypy.lang.prolog.interpreter import error
+emptylist = term.Atom.newatom("[]")
+
def wrap_list(python_list):
- curr = term.Atom.newatom("[]")
+ curr = emptylist
for i in range(len(python_list) - 1, -1, -1):
curr = term.Term(".", [python_list[i], curr])
return curr
@@ -23,6 +25,7 @@
def is_callable(var, engine):
return isinstance(var, term.Callable)
+is_callable._look_inside_me_ = True
def ensure_callable(var):
if isinstance(var, term.Var):
@@ -31,6 +34,7 @@
return var
else:
error.throw_type_error("callable", var)
+ensure_callable._look_inside_me_ = True
def unwrap_int(obj):
if isinstance(obj, term.Number):
@@ -45,6 +49,7 @@
if isinstance(obj, term.Atom):
return obj.name
error.throw_type_error('atom', obj)
+unwrap_atom._look_inside_me_ = True
def unwrap_predicate_indicator(predicate):
if not isinstance(predicate, term.Term):
Modified: pypy/dist/pypy/lang/prolog/interpreter/portal.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/interpreter/portal.py (original)
+++ pypy/dist/pypy/lang/prolog/interpreter/portal.py Fri May 25 18:11:45 2007
@@ -1,5 +1,5 @@
from pypy.jit.hintannotator.policy import ManualGraphPolicy
-from pypy.lang.prolog.interpreter import term, engine
+from pypy.lang.prolog.interpreter import term, engine, helper
from pypy.translator.translator import graphof
from pypy.annotation.specialize import getuniquenondirectgraph
@@ -27,7 +27,7 @@
def fill_timeshift_graphs(self, t, portal_graph):
import pypy
- for cls in [term.Var, term.Term, term.Number, term.Float, term.Atom]:
+ for cls in [term.Var, term.Term, term.Number, term.Atom]:
self.seegraph(cls.copy)
self.seegraph(cls.__init__)
self.seegraph(cls.copy_and_unify)
@@ -37,6 +37,7 @@
self.seegraph(cls.copy_and_basic_unify)
for cls in [term.Var, term.Term, term.Number, term.Atom]:
self.seegraph(cls.get_unify_hash)
+ self.seegraph(cls.eval_arithmetic)
for cls in [term.Callable, term.Atom, term.Term]:
self.seegraph(cls.get_prolog_signature)
self.seegraph(cls.unify_hash_of_children)
@@ -58,6 +59,8 @@
for cls in [engine.Continuation, engine.LimitedScopeContinuation,
pypy.lang.prolog.builtin.control.AndContinuation]:
self.seegraph(cls._call)
+ for function in "".split():
+ self.seegraph(getattr(helper, function))
def get_portal(drv):
t = drv.translator
Modified: pypy/dist/pypy/lang/prolog/interpreter/term.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/interpreter/term.py (original)
+++ pypy/dist/pypy/lang/prolog/interpreter/term.py Fri May 25 18:11:45 2007
@@ -2,8 +2,10 @@
from pypy.rlib.objectmodel import we_are_translated, UnboxedValue
from pypy.rlib.rarithmetic import intmask
from pypy.lang.prolog.interpreter.error import UnificationFailed, UncatchableError
+from pypy.lang.prolog.interpreter import error
from pypy.rlib.jit import hint
from pypy.rlib.objectmodel import specialize
+from pypy.rlib.jit import we_are_jitted, hint, purefunction
DEBUG = False
@@ -71,6 +73,8 @@
# for testing
return not (self == other)
+ def eval_arithmetic(self, engine):
+ error.throw_type_error("evaluable", self)
class Var(PrologObject):
TAG = 0
@@ -169,13 +173,20 @@
return (self.__class__ == other.__class__ and
self.index == other.index)
+ @staticmethod
+ @purefunction
def newvar(index):
result = Var.cache.get(index, None)
if result is not None:
return result
Var.cache[index] = result = Var(index)
return result
- newvar = staticmethod(newvar)
+
+ def eval_arithmetic(self, engine):
+ self = self.dereference(engine.heap)
+ if isinstance(self, Var):
+ error.throw_instantiation_error()
+ return self.eval_arithmetic(engine)
class NonVar(PrologObject):
@@ -271,13 +282,22 @@
def get_prolog_signature(self):
return Term("/", [self, NUMBER_0])
+ @staticmethod
+ @purefunction
def newatom(name):
result = Atom.cache.get(name, None)
if result is not None:
return result
Atom.cache[name] = result = Atom(name)
return result
- newatom = staticmethod(newatom)
+
+ def eval_arithmetic(self, engine):
+ #XXX beautify that
+ if self.name == "pi":
+ return Float.pi
+ if self.name == "e":
+ return Float.e
+ error.throw_type_error("evaluable", self.get_prolog_signature())
class Number(NonVar):
@@ -312,6 +332,9 @@
def get_unify_hash(self, heap):
return intmask(self.num << TAGBITS | self.TAG)
+ def eval_arithmetic(self, engine):
+ return self
+
NUMBER_0 = Number(0)
class Float(NonVar):
@@ -349,6 +372,14 @@
def __repr__(self):
return "Float(%r)" % (self.floatval, )
+ def eval_arithmetic(self, engine):
+ from pypy.lang.prolog.interpreter.arithmetic import norm_float
+ return norm_float(self)
+
+Float.e = Float(math.e)
+Float.pi = Float(math.pi)
+
+
class BlackBox(NonVar):
# meant to be subclassed
TAG = tag()
@@ -376,6 +407,7 @@
return intmask(id(self) << TAGBITS | self.TAG)
+
# helper functions for various Term methods
def _clone(obj, offset):
@@ -490,6 +522,20 @@
return True
return False
+ def eval_arithmetic(self, engine):
+ from pypy.lang.prolog.interpreter.arithmetic import arithmetic_functions
+ from pypy.lang.prolog.interpreter.arithmetic import arithmetic_functions_list
+ if we_are_jitted():
+ signature = hint(self.signature, promote=True)
+ func = None
+ for sig, func in arithmetic_functions_list:
+ if sig == signature:
+ break
+ else:
+ func = arithmetic_functions.get(self.signature, None)
+ if func is None:
+ error.throw_type_error("evaluable", self.get_prolog_signature())
+ return func(engine, self)
class Rule(object):
_immutable_ = True
Modified: pypy/dist/pypy/lang/prolog/interpreter/test/test_jit.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/interpreter/test/test_jit.py (original)
+++ pypy/dist/pypy/lang/prolog/interpreter/test/test_jit.py Fri May 25 18:11:45 2007
@@ -133,23 +133,26 @@
def test_loop(self):
e = get_engine("""
- f(X) :- h(X).
- f(a).
- h(X) :- h(X).
+ f(X) :- h(X, _).
+ f(50).
+ h(0, _).
+ h(X, Y) :- Y is X - 1, h(Y, _).
""")
- X = e.heap.newvar()
+ num = term.Number(50)
def main(n):
e.heap.reset()
if n == 0:
- e.call(term.Term("f", [X]))
- return isinstance(X.dereference(e.heap), term.Atom)
+ e.call(term.Term("f", [num]))
+ return True
else:
return False
+ res = main(0)
+ assert res
res = self.timeshift_from_portal(main, portal.PORTAL,
[0], policy=POLICY,
backendoptimize=True,
inline=0.0)
- assert res == True
+ assert res
More information about the Pypy-commit
mailing list