[pypy-svn] r21037 - in pypy/dist/pypy/jit: . test
arigo at codespeak.net
arigo at codespeak.net
Sun Dec 11 13:27:05 CET 2005
Author: arigo
Date: Sun Dec 11 13:27:03 2005
New Revision: 21037
Modified:
pypy/dist/pypy/jit/llabstractinterp.py
pypy/dist/pypy/jit/test/test_llabstractinterp.py
Log:
* Bug fix & test: forgot to create the exitcase and llexitcase on the new
links!
* Added caching of specializations for the tests, similar to test_llinterp.
Modified: pypy/dist/pypy/jit/llabstractinterp.py
==============================================================================
--- pypy/dist/pypy/jit/llabstractinterp.py (original)
+++ pypy/dist/pypy/jit/llabstractinterp.py Sun Dec 11 13:27:03 2005
@@ -52,7 +52,7 @@
def with_fresh_variables(self, memo):
return self
- def match(self, other):
+ def match(self, other, memo):
return isinstance(other, LLConcreteValue) and self.value == other.value
@@ -92,7 +92,7 @@
def with_fresh_variables(self, memo):
return LLRuntimeValue(self.getconcretetype())
- def match(self, other):
+ def match(self, other, memo):
# Note: the meaning of match() is actually to see if calling
# with_fresh_variables() on both 'self' and 'other' would give the
# same result. This is why any two LLRuntimeValues match each other.
@@ -222,14 +222,18 @@
result.extend(self.getfield(name).getruntimevars(memo))
return result
- def match(self, other):
- if self is other:
- return True
+ def match(self, other, memo):
+ if (False, self) in memo:
+ return other is memo[False, self]
+ if (True, other) in memo:
+ return self is memo[True, other]
+ memo[False, self] = other
+ memo[True, other] = self
assert self.T == other.T
for name in self.T._names:
a1 = self.getfield(name)
a2 = other.getfield(name)
- if not a1.match(a2):
+ if not a1.match(a2, memo):
return False
else:
return True
@@ -258,9 +262,9 @@
def with_fresh_variables(self, memo):
return LLVirtualPtr(self.containerobj.copy(memo))
- def match(self, other):
+ def match(self, other, memo):
if isinstance(other, LLVirtualPtr):
- return self.containerobj.match(other.containerobj)
+ return self.containerobj.match(other.containerobj, memo)
else:
return False
@@ -278,8 +282,9 @@
def match(self, args_a):
# simple for now
+ memo = {}
for a1, a2 in zip(self.args_a, args_a):
- if not a1.match(a2):
+ if not a1.match(a2, memo):
return False
else:
return True
@@ -468,6 +473,9 @@
for origlink in links:
args_a = [builder.binding(v) for v in origlink.args]
newlink = self.interp.schedule(args_a, origlink.target)
+ if newexitswitch is not None:
+ newlink.exitcase = origlink.exitcase
+ newlink.llexitcase = origlink.llexitcase
newlinks.append(newlink)
else:
# copies of return and except blocks are *normal* blocks currently;
Modified: pypy/dist/pypy/jit/test/test_llabstractinterp.py
==============================================================================
--- pypy/dist/pypy/jit/test/test_llabstractinterp.py (original)
+++ pypy/dist/pypy/jit/test/test_llabstractinterp.py Sun Dec 11 13:27:03 2005
@@ -15,23 +15,38 @@
t = annmodel.lltype_to_annotation(T)
return a.typeannotation(t)
-def abstrinterp(ll_function, argvalues, arghints):
+_lastinterpreted = []
+def get_and_residualize_graph(ll_function, argvalues, arghints):
+ key = ll_function, tuple(arghints), tuple([argvalues[n] for n in arghints])
+ for key1, value1 in _lastinterpreted: # 'key' is not hashable
+ if key1 == key:
+ return value1
+ if len(_lastinterpreted) >= 3:
+ del _lastinterpreted[0]
+ # build the normal ll graphs for ll_function
t = TranslationContext()
a = t.buildannotator()
argtypes = [annotation(a, value) for value in argvalues]
graph1 = annotate_lowlevel_helper(a, ll_function, argtypes)
rtyper = t.buildrtyper()
rtyper.specialize()
+ # build the residual ll graphs by propagating the hints
interp = LLAbstractInterp()
hints = {}
- argvalues2 = argvalues[:]
- lst = list(arghints)
- lst.sort()
- lst.reverse()
- for hint in lst:
- hints[graph1.getargs()[hint]] = argvalues2[hint]
- del argvalues2[hint]
+ for hint in arghints:
+ hints[graph1.getargs()[hint]] = argvalues[hint]
graph2 = interp.eval(graph1, hints)
+ # cache and return the original and the residual ll graph
+ result = t, interp, graph1, graph2
+ _lastinterpreted.append((key, result))
+ return result
+
+def abstrinterp(ll_function, argvalues, arghints):
+ t, interp, graph1, graph2 = get_and_residualize_graph(
+ ll_function, argvalues, arghints)
+ argvalues2 = [argvalues[n] for n in range(len(argvalues))
+ if n not in arghints]
+ rtyper = t.rtyper
# check the result by running it
llinterp = LLInterpreter(rtyper)
result1 = llinterp.eval_graph(graph1, argvalues)
@@ -95,6 +110,8 @@
return y
graph2, insns = abstrinterp(ll_function, [6, 42], [])
assert insns == {'int_is_true': 1, 'int_add': 2}
+ graph2, insns = abstrinterp(ll_function, [0, 42], [])
+ assert insns == {'int_is_true': 1, 'int_add': 2}
def test_unrolling_loop():
def ll_function(x, y):
More information about the Pypy-commit
mailing list