[pypy-svn] r35278 - in pypy/branch/jit-real-world/pypy/jit: hintannotator hintannotator/test timeshifter timeshifter/test
arigo at codespeak.net
arigo at codespeak.net
Tue Dec 5 02:02:01 CET 2006
Author: arigo
Date: Tue Dec 5 02:01:56 2006
New Revision: 35278
Modified:
pypy/branch/jit-real-world/pypy/jit/hintannotator/annotator.py
pypy/branch/jit-real-world/pypy/jit/hintannotator/bookkeeper.py
pypy/branch/jit-real-world/pypy/jit/hintannotator/model.py
pypy/branch/jit-real-world/pypy/jit/hintannotator/test/test_annotator.py
pypy/branch/jit-real-world/pypy/jit/timeshifter/hrtyper.py
pypy/branch/jit-real-world/pypy/jit/timeshifter/test/test_timeshift.py
Log:
(pedronis, arre on the earlier sweat part, arigo)
Don't use the RPython's normalization in the hint-annotator. It took
quite some sweat to discover that it was not a good idea. Instead, for
all the variables whose color is not fixed at the end of
hint-annotation, we proceed by assuming that they are all green and
forcing them to red as needed, in a fixpoint process again. The "needs"
is based on the dependencies captured by 'myorigin' and by the call
families, which produces the normalization effect.
Modified: pypy/branch/jit-real-world/pypy/jit/hintannotator/annotator.py
==============================================================================
--- pypy/branch/jit-real-world/pypy/jit/hintannotator/annotator.py (original)
+++ pypy/branch/jit-real-world/pypy/jit/hintannotator/annotator.py Tue Dec 5 02:01:56 2006
@@ -10,9 +10,12 @@
class HintAnnotatorPolicy(policy.AnnotatorPolicy):
- def __init__(self, novirtualcontainer=False, oopspec=False):
- self.novirtualcontainer = novirtualcontainer
- self.oopspec = oopspec
+ def __init__(self, novirtualcontainer = False,
+ oopspec = False,
+ entrypoint_returns_red = True):
+ self.novirtualcontainer = novirtualcontainer
+ self.oopspec = oopspec
+ self.entrypoint_returns_red = entrypoint_returns_red
def look_inside_graph(self, graph):
return True
Modified: pypy/branch/jit-real-world/pypy/jit/hintannotator/bookkeeper.py
==============================================================================
--- pypy/branch/jit-real-world/pypy/jit/hintannotator/bookkeeper.py (original)
+++ pypy/branch/jit-real-world/pypy/jit/hintannotator/bookkeeper.py Tue Dec 5 02:01:56 2006
@@ -25,12 +25,15 @@
# modify input_args_hs in-place to change their origin
for i in range(len(input_args_hs)):
- old = self.bookkeeper.enter((graph, i))
- try:
- input_args_hs[i] = hintmodel.reorigin(input_args_hs[i])
- finally:
- self.bookkeeper.leave(old)
-
+ hs_v1 = input_args_hs[i]
+ if isinstance(hs_v1, hintmodel.SomeLLAbstractConstant):
+ myorigin = self.bookkeeper.myinputargorigin(graph, i)
+ hs_v1 = hintmodel.SomeLLAbstractConstant(
+ hs_v1.concretetype, {myorigin: True},
+ eager_concrete = hs_v1.eager_concrete,
+ deepfrozen = hs_v1.deepfrozen,
+ myorigin = myorigin)
+ input_args_hs[i] = hs_v1
return graph
def cachedgraph(self, key, alt_name=None):
@@ -100,31 +103,80 @@
else:
self.position_key = old
+ def myinputargorigin(self, graph, i):
+ try:
+ origin = self.originflags[graph, i]
+ except KeyError:
+ origin = hintmodel.InputArgOriginFlags(self, graph, i)
+ self.originflags[graph, i] = origin
+ return origin
+
def myorigin(self):
try:
origin = self.originflags[self.position_key]
except KeyError:
- if len(self.position_key) == 3:
- graph, block, i = self.position_key
- spaceop = block.operations[i]
- spaceop = SpaceOperation(spaceop.opname,
- list(spaceop.args),
- spaceop.result)
- else:
- spaceop = None
+ assert len(self.position_key) == 3
+ graph, block, i = self.position_key
+ spaceop = block.operations[i]
+ spaceop = SpaceOperation(spaceop.opname,
+ list(spaceop.args),
+ spaceop.result)
origin = hintmodel.OriginFlags(self, spaceop)
self.originflags[self.position_key] = origin
return origin
def compute_at_fixpoint(self):
- pass
+ binding = self.annotator.binding
- def compute_after_normalization(self):
- # compute and cache the green-ness of OriginFlags objects
- # while we can do so (i.e. before the graphs are modified).
+ # for the entry point, we need to remove the 'myorigin' of
+ # the input arguments (otherwise they will always be green,
+ # as there is no call to the entry point to make them red)
+ tsgraph = self.annotator.translator.graphs[0]
+ for v in tsgraph.getargs():
+ hs_arg = binding(v)
+ if isinstance(hs_arg, hintmodel.SomeLLAbstractConstant):
+ hs_arg.myorigin = None
+ # for convenience, force the return var to be red too, as
+ # the timeshifter doesn't support anything else
+ if self.annotator.policy.entrypoint_returns_red:
+ v = tsgraph.getreturnvar()
+ hs_red = hintmodel.variableoftype(v.concretetype)
+ self.annotator.setbinding(v, hs_red)
+
+ # propagate the green/red constraints
+ log.event("Computing maximal green set...")
+ greenorigindependencies = {}
for origin in self.originflags.values():
- if origin.spaceop is not None:
- origin.greenargs_cached = origin.greenargs()
+ origin.greenargs = True
+ origin.record_dependencies(greenorigindependencies)
+
+ while True:
+ progress = False
+ for origin, deps in greenorigindependencies.items():
+ for v in deps:
+ if not binding(v).is_green():
+ # not green => force the origin to be red too
+ origin.greenargs = False
+ del greenorigindependencies[origin]
+ progress = True
+ break
+ if not progress:
+ break
+
+ for callfamily in self.tsgraph_maximal_call_families.infos():
+ if len(callfamily.tsgraphs) > 1:
+ # if at least one graph in the family returns a red,
+ # we force a red as the return of all of them
+ returns_red = False
+ for graph in callfamily.tsgraphs:
+ if not binding(graph.getreturnvar()).is_green():
+ returns_red = True
+ if returns_red:
+ for graph in callfamily.tsgraphs:
+ v = graph.getreturnvar()
+ hs_red = hintmodel.variableoftype(v.concretetype)
+ self.annotator.setbinding(v, hs_red)
+
# compute and cache the signature of the graphs before they are
# modified by further code
ha = self.annotator
@@ -249,8 +301,12 @@
hs_res = hintmodel.reorigin(hs_res, *deps_hs)
return hs_res
- def graph_family_call(self, graph_list, fixed, args_hs):
- tsgraphs = []
+ def graph_family_call(self, graph_list, fixed, args_hs,
+ tsgraphs_accum=None):
+ if tsgraphs_accum is None:
+ tsgraphs = []
+ else:
+ tsgraphs = tsgraphs_accum
results_hs = []
for graph in graph_list:
results_hs.append(self.graph_call(graph, fixed, args_hs, tsgraphs))
Modified: pypy/branch/jit-real-world/pypy/jit/hintannotator/model.py
==============================================================================
--- pypy/branch/jit-real-world/pypy/jit/hintannotator/model.py (original)
+++ pypy/branch/jit-real-world/pypy/jit/hintannotator/model.py Tue Dec 5 02:01:56 2006
@@ -33,22 +33,26 @@
pass
class OriginFlags(object):
-
fixed = False
read_positions = None
- greenargs_cached = None
- is_call_result = False
+ greenargs = False
def __init__(self, bookkeeper=None, spaceop=None):
self.bookkeeper = bookkeeper
self.spaceop = spaceop
def __repr__(self):
+ return '<%s %s>' % (getattr(self.spaceop, 'result', '?'),
+ self.reprstate())
+
+ def reprstate(self):
if self.fixed:
s = "fixed "
+ elif self.greenargs:
+ s = "green"
else:
s = ""
- return "<%sorigin>" % (s,)
+ return "%sorigin" % (s,)
def read_fixed(self):
if self.read_positions is None:
@@ -64,63 +68,66 @@
for p in self.read_positions:
annotator.reflowfromposition(p)
- def greenargs(self, frame=None):
- annotator = self.bookkeeper.annotator
- if frame is None:
- if self.greenargs_cached is not None:
- return self.greenargs_cached
- frame = GreenHandlerFrame(annotator)
- if self.is_call_result:
- return frame.greencallresult(self.spaceop)
+ def record_dependencies(self, greenorigindependencies):
+ deps = greenorigindependencies.setdefault(self, [])
+ deps.extend(self.spaceop.args)
+
+
+class CallOpOriginFlags(OriginFlags):
+
+ def record_dependencies(self, greenorigindependencies):
+ bk = self.bookkeeper
+ if self.spaceop.opname == 'direct_call':
+ args = self.spaceop.args[1:]
+ elif self.spaceop.opname == 'indirect_call':
+ args = self.spaceop.args[1:-1]
else:
- for v in self.spaceop.args:
- if not frame.greenvar(v):
- return False
- return True
-
-
-class GreenHandlerFrame(object):
-
- def __init__(self, annotator, parentframe=None):
- self.annotator = annotator
- self.parentframe = parentframe
- self.inputarg2actualarg = {} # {origin: annotation}
-
- def greenvar(self, v):
- hs = self.annotator.binding(v)
- if isinstance(hs, SomeLLAbstractConstant) and len(hs.origins) == 1:
- [o] = hs.origins.keys()
- if o in self.inputarg2actualarg:
- hs_actual = self.inputarg2actualarg[o]
- return hs_actual.is_green(self.parentframe)
- return hs.is_green(self)
-
- def greencallresult(self, spaceop):
-## print spaceop
-## if str(spaceop.result) == 'v58':
-## import pdb; pdb.set_trace()
- args_hs = [self.annotator.binding(v) for v in spaceop.args]
- hs_result = self.annotator.binding(spaceop.result)
- if not isinstance(hs_result, SomeLLAbstractConstant):
- return False # was generalized, e.g. to SomeLLAbstractVariable
- hs_f1 = args_hs.pop(0)
- fnobj = hs_f1.const._obj
- if (self.annotator.policy.oopspec and
- hasattr(fnobj._callable, 'oopspec')):
- assert False # XXX?
+ raise AssertionError(self.spaceop.opname)
- input_args_hs = list(args_hs)
- bk = self.annotator.bookkeeper
- graph = bk.get_graph_for_call(fnobj.graph,
- hs_result.is_fixed(),
- input_args_hs)
- newframe = GreenHandlerFrame(self.annotator, parentframe=self)
- for hs_inp_arg, hs_arg in zip(input_args_hs, args_hs):
- if isinstance(hs_arg, SomeLLAbstractConstant):
- assert len(hs_inp_arg.origins) == 1
- [o] = hs_inp_arg.origins.keys()
- newframe.inputarg2actualarg[o] = hs_arg
- return newframe.greenvar(graph.getreturnvar())
+ graph = self.any_called_graph
+ call_families = bk.tsgraph_maximal_call_families
+ _, repgraph, callfamily = call_families.find(graph)
+
+ # record the argument and return value dependencies
+ retdeps = greenorigindependencies.setdefault(self, [])
+ for graph in callfamily.tsgraphs:
+ retdeps.append(graph.getreturnvar())
+ for i, v in enumerate(args):
+ argorigin = bk.myinputargorigin(graph, i)
+ deps = greenorigindependencies.setdefault(argorigin, [])
+ deps.append(v)
+
+
+class InputArgOriginFlags(OriginFlags):
+
+ def __init__(self, bookkeeper, graph, i):
+ OriginFlags.__init__(self, bookkeeper)
+ self.graph = graph
+ self.i = i
+
+ def getarg(self):
+ return self.graph.getargs()[self.i]
+
+ def __repr__(self):
+ return '<%s %s>' % (self.getarg(), self.reprstate())
+
+ def record_dependencies(self, greenorigindependencies):
+ bk = self.bookkeeper
+ call_families = bk.tsgraph_maximal_call_families
+ _, repgraph, callfamily = call_families.find(self.graph)
+
+ # record the fact that each graph's input args should be as red
+ # as each other's
+ if self.graph is repgraph:
+ deps = greenorigindependencies.setdefault(self, [])
+ v = self.getarg()
+ for othergraph in callfamily.tsgraphs:
+ if othergraph is not repgraph:
+ deps.append(othergraph.getargs()[self.i])
+ otherorigin = bk.myinputargorigin(othergraph, self.i)
+ otherdeps = greenorigindependencies.setdefault(otherorigin,
+ [])
+ otherdeps.append(v)
# ____________________________________________________________
@@ -132,7 +139,7 @@
assert self.__class__ != SomeLLAbstractValue
self.deepfrozen = deepfrozen
- def is_green(self, frame=None):
+ def is_green(self):
return False
@@ -145,12 +152,11 @@
self.origins = origins
self.eager_concrete = eager_concrete
self.myorigin = myorigin
- assert myorigin is None or myorigin.spaceop is not None
def fmt_origins(self, origins):
counts = {}
for o in origins:
- x = repr(o)
+ x = o.reprstate()
counts[x] = counts.get(x, 0) + 1
items = counts.items()
items.sort()
@@ -167,7 +173,7 @@
if myorigin is None:
return None
else:
- return str(myorigin.spaceop.result)
+ return repr(myorigin)
def is_fixed(self):
for o in self.origins:
@@ -175,18 +181,19 @@
return False
return True
- def is_green(self, frame=None):
+ def is_green(self):
return (self.is_fixed() or self.eager_concrete or
self.concretetype is lltype.Void or
- (self.myorigin is not None and
- self.myorigin.greenargs(frame)))
+ (self.myorigin is not None and self.myorigin.greenargs))
def annotationcolor(self):
"""Compute the color of the variables with this annotation
for the pygame viewer
"""
try:
- if self.eager_concrete:
+ if self.concretetype is lltype.Void:
+ return annmodel.s_ImpossibleValue.annotationcolor
+ elif self.eager_concrete:
return (0,100,0) # green
elif self.is_green():
return (50,140,0) # green-dark-cyan
@@ -328,11 +335,16 @@
# cannot follow
return variableoftype(hs_v1.concretetype.TO.RESULT)
- fixed = bookkeeper.myorigin().read_fixed()
- hs_res = bookkeeper.graph_family_call(graph_list, fixed, args_hs)
+ myorigin = bookkeeper.myorigin()
+ myorigin.__class__ = CallOpOriginFlags # thud
+ fixed = myorigin.read_fixed()
+ tsgraphs_accum = []
+ hs_res = bookkeeper.graph_family_call(graph_list, fixed, args_hs,
+ tsgraphs_accum)
+ myorigin.any_called_graph = tsgraphs_accum[0]
if isinstance(hs_res, SomeLLAbstractConstant):
- hs_res.myorigin = bookkeeper.myorigin()
+ hs_res.myorigin = myorigin
# we need to make sure that hs_res does not become temporarily less
# general as a result of calling another specialized version of the
@@ -390,12 +402,17 @@
bookkeeper.annotator.translator.graphs[0]):
return variableoftype(lltype.typeOf(fnobj).RESULT)
- fixed = bookkeeper.myorigin().read_fixed()
- hs_res = bookkeeper.graph_call(fnobj.graph, fixed, args_hs)
+ myorigin = bookkeeper.myorigin()
+ myorigin.__class__ = CallOpOriginFlags # thud
+ fixed = myorigin.read_fixed()
+ tsgraphs_accum = []
+ hs_res = bookkeeper.graph_call(fnobj.graph, fixed, args_hs,
+ tsgraphs_accum)
+ myorigin.any_called_graph = tsgraphs_accum[0]
if isinstance(hs_res, SomeLLAbstractConstant):
- hs_res.myorigin = bookkeeper.myorigin()
- hs_res.myorigin.is_call_result = True
+ hs_res.myorigin = myorigin
+
## elif fnobj.graph.name.startswith('ll_stritem'):
## if isinstance(hs_res, SomeLLAbstractVariable):
## print hs_res
Modified: pypy/branch/jit-real-world/pypy/jit/hintannotator/test/test_annotator.py
==============================================================================
--- pypy/branch/jit-real-world/pypy/jit/hintannotator/test/test_annotator.py (original)
+++ pypy/branch/jit-real-world/pypy/jit/hintannotator/test/test_annotator.py Tue Dec 5 02:01:56 2006
@@ -10,12 +10,16 @@
from pypy.translator.backendopt.inline import auto_inlining
from pypy import conftest
-P_OOPSPEC = HintAnnotatorPolicy(oopspec=True)
+P_DEFAULT = HintAnnotatorPolicy(entrypoint_returns_red=False)
+P_OOPSPEC = HintAnnotatorPolicy(oopspec=True,
+ entrypoint_returns_red=False)
P_OOPSPEC_NOVIRTUAL = HintAnnotatorPolicy(oopspec=True,
- novirtualcontainer=True)
-P_NOVIRTUAL = HintAnnotatorPolicy(novirtualcontainer=True)
+ novirtualcontainer=True,
+ entrypoint_returns_red=False)
+P_NOVIRTUAL = HintAnnotatorPolicy(novirtualcontainer=True,
+ entrypoint_returns_red=False)
-def hannotate(func, argtypes, policy=None, annotator=False, inline=None,
+def hannotate(func, argtypes, policy=P_DEFAULT, annotator=False, inline=None,
backendoptimize=False):
# build the normal ll graphs for ll_function
t = TranslationContext()
Modified: pypy/branch/jit-real-world/pypy/jit/timeshifter/hrtyper.py
==============================================================================
--- pypy/branch/jit-real-world/pypy/jit/timeshifter/hrtyper.py (original)
+++ pypy/branch/jit-real-world/pypy/jit/timeshifter/hrtyper.py Tue Dec 5 02:01:56 2006
@@ -152,9 +152,9 @@
"""
Driver for running the timeshifter.
"""
- self.type_system.perform_normalizations(self)
+## self.type_system.perform_normalizations(self)
bk = self.annotator.bookkeeper
- bk.compute_after_normalization()
+## bk.compute_after_normalization()
entrygraph = self.annotator.translator.graphs[0]
self.origportalgraph = origportalgraph
if origportalgraph:
Modified: pypy/branch/jit-real-world/pypy/jit/timeshifter/test/test_timeshift.py
==============================================================================
--- pypy/branch/jit-real-world/pypy/jit/timeshifter/test/test_timeshift.py (original)
+++ pypy/branch/jit-real-world/pypy/jit/timeshifter/test/test_timeshift.py Tue Dec 5 02:01:56 2006
@@ -1134,15 +1134,15 @@
self.check_insns({})
def test_green_red_mismatch_in_call(self):
- py.test.skip("WIP")
+ #py.test.skip("WIP")
def add(a,b, u):
return a+b
def f(x, y, u):
r = add(x+1,y+1, u)
z = x+y
- hint(z, concrete=True)
+ z = hint(z, concrete=True) + r # this checks that 'r' is green
return hint(z, variable=True)
res = self.timeshift(f, [4, 5, 0], [], policy=P_NOVIRTUAL)
- assert res == 9
+ assert res == 20
More information about the pypy-svn
mailing list