[pypy-svn] r10247 - in pypy/dist/pypy/translator: . tool
arigo at codespeak.net
arigo at codespeak.net
Sat Apr 2 16:44:36 CEST 2005
Author: arigo
Date: Sat Apr 2 16:44:36 2005
New Revision: 10247
Added:
pypy/dist/pypy/translator/unsimplify.py (contents, props changed)
Modified:
pypy/dist/pypy/translator/genc_funcdef.py
pypy/dist/pypy/translator/geninterplevel.py
pypy/dist/pypy/translator/simplify.py
pypy/dist/pypy/translator/tool/graphpage.py
pypy/dist/pypy/translator/typer.py
Log:
A stupid bug prevented blocks with no operation from having their input/output
variables typed. Aaargh.
Also in this check-in:
* _temporarily_ moved remove_direct_loops() into "unsimplify.py", with a
copyvar() method taking a translator argument.
* type conversion of variables across links is delicate. It might be more
correct now.
* display the results of typer.py in the pygame graphs.
Modified: pypy/dist/pypy/translator/genc_funcdef.py
==============================================================================
--- pypy/dist/pypy/translator/genc_funcdef.py (original)
+++ pypy/dist/pypy/translator/genc_funcdef.py Sat Apr 2 16:44:36 2005
@@ -3,7 +3,7 @@
from pypy.objspace.flow.model import traverse, uniqueitems, checkgraph
from pypy.objspace.flow.model import Block, Link
from pypy.objspace.flow.model import last_exception, last_exc_value
-from pypy.translator.simplify import remove_direct_loops
+from pypy.translator.unsimplify import remove_direct_loops
from pypy.interpreter.pycode import CO_VARARGS
from types import FunctionType
@@ -44,8 +44,11 @@
self.wrapper_name = None # pyfn_xxx
self.globalobject_name = None # gfunc_xxx
self.localscope = namespace.localScope()
+
+ # get the flow graph, and ensure that there is no direct loop in it
+ # as we cannot generate valid code for this case.
self.graph = graph = genc.translator.getflowgraph(func)
- remove_direct_loops(graph) # this can introduce new vars! we need to declare them
+ remove_direct_loops(genc.translator, graph)
checkgraph(graph)
graph_args = graph.getargs()
Modified: pypy/dist/pypy/translator/geninterplevel.py
==============================================================================
--- pypy/dist/pypy/translator/geninterplevel.py (original)
+++ pypy/dist/pypy/translator/geninterplevel.py Sat Apr 2 16:44:36 2005
@@ -23,7 +23,6 @@
from pypy.objspace.flow.model import FunctionGraph, Block, Link
from pypy.objspace.flow.model import last_exception, last_exc_value
from pypy.objspace.flow.model import traverse, uniqueitems, checkgraph
-from pypy.translator.simplify import remove_direct_loops
from pypy.interpreter.pycode import CO_VARARGS, CO_VARKEYWORDS
from pypy.annotation import model as annmodel
from types import FunctionType, CodeType, ModuleType
Modified: pypy/dist/pypy/translator/simplify.py
==============================================================================
--- pypy/dist/pypy/translator/simplify.py (original)
+++ pypy/dist/pypy/translator/simplify.py Sat Apr 2 16:44:36 2005
@@ -3,8 +3,6 @@
'Syntactic-ish' simplifications on a flow graph.
simplify_graph() applies all simplifications defined in this file.
-See also remove_direct_loops(), which is a 'de-simplification' useful
-for code generators.
"""
from pypy.objspace.flow.model import *
@@ -103,21 +101,6 @@
link.prevblock.exitswitch = None
traverse(visit, graph)
-def remove_direct_loops(graph):
- """This is useful for code generators: it ensures that no link has
- common input and output variables, which could occur if a block's exit
- points back directly to the same block. It allows code generators to be
- simpler because they don't have to worry about overwriting input
- variables when generating a sequence of assignments."""
- def visit(link):
- if isinstance(link, Link) and link.prevblock is link.target:
- # insert an empty block with fresh variables.
- intermediate = [Variable() for a in link.args]
- b = Block(intermediate)
- b.closeblock(Link(intermediate, link.target))
- link.target = b
- traverse(visit, graph)
-
def transform_dead_op_vars(graph):
"""Remove dead operations and variables that are passed over a link
but not used in the target block. Input is a graph."""
Modified: pypy/dist/pypy/translator/tool/graphpage.py
==============================================================================
--- pypy/dist/pypy/translator/tool/graphpage.py (original)
+++ pypy/dist/pypy/translator/tool/graphpage.py Sat Apr 2 16:44:36 2005
@@ -1,5 +1,5 @@
import inspect
-from pypy.objspace.flow.model import traverse
+from pypy.objspace.flow.model import traverse, Block
from pypy.translator.tool.make_dot import DotGen, make_dot, make_dot_graphs
from pypy.interpreter.pycode import CO_VARARGS, CO_VARKEYWORDS
from pypy.annotation import model
@@ -124,6 +124,16 @@
self.annotator.binding_cause_history.get(var, []))
self.binding_history[var.name] = zip(history, cause_history)
+ def visit(node):
+ if isinstance(node, Block):
+ for var in node.getvariables():
+ if hasattr(var, 'type_cls'):
+ info = self.links.get(var.name, var.name)
+ info = '(%s) %s' % (var.type_cls.__name__, info)
+ self.links[var.name] = info
+ for graph in graphs:
+ traverse(visit, graph)
+
def followlink(self, varname):
# clicking on a variable name shows its binding history
cur_value = self.current_value[varname]
Modified: pypy/dist/pypy/translator/typer.py
==============================================================================
--- pypy/dist/pypy/translator/typer.py (original)
+++ pypy/dist/pypy/translator/typer.py Sat Apr 2 16:44:36 2005
@@ -1,6 +1,6 @@
import autopath
from pypy.objspace.flow.model import SpaceOperation, Variable, Constant
-from pypy.objspace.flow.model import Block, Link
+from pypy.objspace.flow.model import Block, Link, uniqueitems
class TypeMatch:
@@ -8,6 +8,9 @@
self.s_type = s_type
self.type_cls = type_cls
+class TyperError:
+ pass
+
class Specializer:
specializationdict = {}
@@ -28,12 +31,13 @@
def specialize(self):
for block in self.annotator.annotated:
- if block.operations:
+ if block.operations != ():
self.specialize_block(block)
def settype(self, a, type_cls):
"""Set the type_cls of a Variable or Constant."""
- assert not hasattr(a, 'type_cls')
+ if hasattr(a, 'type_cls') and a.type_cls != type_cls:
+ raise TyperError, "inconsitent type for %r" % (a,)
a.type_cls = type_cls
def setbesttype(self, a):
@@ -56,7 +60,12 @@
"""Get the operation(s) needed to convert 'v' to the given type."""
ops = []
if isinstance(v, Constant):
- self.settype(v, type_cls) # mark the concrete type of the Constant
+ try:
+ # mark the concrete type of the Constant
+ self.settype(v, type_cls)
+ except TyperError:
+ v = Constant(v.value) # need a copy of the Constant
+ self.settype(v, type_cls)
elif v.type_cls is not type_cls:
# XXX do we need better conversion paths?
@@ -123,6 +132,7 @@
# a2 in the inserted block before conversion
# a3 in the inserted block after conversion
# a4 in the original target block's inputargs
+ # warning, link.args may contain the same Variable multiple times!
convargs = []
convops = []
for i in range(len(link.args)):
@@ -135,9 +145,11 @@
# if there are conversion operations, they are inserted into
# a new block along this link
if convops:
+ vars = uniqueitems([a1 for a1 in link.args
+ if isinstance(a1, Variable)])
newblock = Block([])
mapping = {}
- for a1 in link.args:
+ for a1 in vars:
a2 = Variable()
a2.type_cls = a1.type_cls
newblock.inputargs.append(a2)
@@ -146,6 +158,9 @@
newblock.closeblock(Link(convargs, link.target))
newblock.renamevariables(mapping)
link.target = newblock
+ link.args[:] = vars
+ else:
+ link.args[:] = convargs # some Constants may have changed
def getspecializedop(self, op, bindings):
specializations = self.specializationdict.get(op.opname, ())
Added: pypy/dist/pypy/translator/unsimplify.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/unsimplify.py Sat Apr 2 16:44:36 2005
@@ -0,0 +1,27 @@
+from pypy.objspace.flow.model import *
+
+def copyvar(v):
+ """Make a copy of the Variable v, preserving annotations and type_cls."""
+ assert isinstance(v, Variable)
+ newvar = Variable(v)
+ annotator = translator.annotator
+ if annotator is not None and v in annotator.bindings:
+ annotator.bindings[newvar] = annotator.bindings[v]
+ if hasattr(v, 'type_cls'):
+ newvar.type_cls = v.type_cls
+ return newvar
+
+def remove_direct_loops(translator, graph):
+ """This is useful for code generators: it ensures that no link has
+ common input and output variables, which could occur if a block's exit
+ points back directly to the same block. It allows code generators to be
+ simpler because they don't have to worry about overwriting input
+ variables when generating a sequence of assignments."""
+ def visit(link):
+ if isinstance(link, Link) and link.prevblock is link.target:
+ # insert an empty block with fresh variables.
+ intermediate = [copyvar(a) for a in link.args]
+ b = Block(intermediate)
+ b.closeblock(Link(intermediate, link.target))
+ link.target = b
+ traverse(visit, graph)
More information about the Pypy-commit
mailing list