[pypy-svn] r42363 - in pypy/dist/pypy: config objspace/flow translator/backendopt translator/cli translator/cli/test translator/oosupport
antocuni at codespeak.net
antocuni at codespeak.net
Thu Apr 26 21:22:47 CEST 2007
Author: antocuni
Date: Thu Apr 26 21:22:46 2007
New Revision: 42363
Modified:
pypy/dist/pypy/config/translationoption.py
pypy/dist/pypy/objspace/flow/model.py
pypy/dist/pypy/translator/backendopt/all.py
pypy/dist/pypy/translator/cli/function.py
pypy/dist/pypy/translator/cli/test/runtest.py
pypy/dist/pypy/translator/cli/test/test_snippet.py
pypy/dist/pypy/translator/oosupport/function.py
pypy/dist/pypy/translator/oosupport/treebuilder.py
Log:
A backend optimization for gencli, which turns SSI graphs into
stack-based machine friendly graphs.
Modified: pypy/dist/pypy/config/translationoption.py
==============================================================================
--- pypy/dist/pypy/config/translationoption.py (original)
+++ pypy/dist/pypy/config/translationoption.py Thu Apr 26 21:22:46 2007
@@ -17,6 +17,7 @@
ChoiceOption("type_system", "Type system to use when RTyping",
["lltype", "ootype"], cmdline=None,
requires={
+ "lltype": [("translation.backendopt.stack_optimization", False)],
"ootype": [("translation.backendopt.raisingop2direct_call", False),
("translation.backendopt.constfold", False),
("translation.backendopt.heap2stack", False),
@@ -30,10 +31,14 @@
("translation.gc", "boehm"),
("translation.backendopt.raisingop2direct_call", True)],
"cli": [("translation.type_system", "ootype")],
- "jvm": [("translation.type_system", "ootype")],
- "js": [("translation.type_system", "ootype")],
- "squeak": [("translation.type_system", "ootype")],
- "cl": [("translation.type_system", "ootype")],
+ "jvm": [("translation.type_system", "ootype"),
+ ("translation.backendopt.stack_optimization", False)],
+ "js": [("translation.type_system", "ootype"),
+ ("translation.backendopt.stack_optimization", False)],
+ "squeak": [("translation.type_system", "ootype"),
+ ("translation.backendopt.stack_optimization", False)],
+ "cl": [("translation.type_system", "ootype"),
+ ("translation.backendopt.stack_optimization", False)],
},
cmdline="-b --backend"),
BoolOption("llvm_via_c", "compile llvm via C",
@@ -166,6 +171,14 @@
"which lets the C optimizer remove the asserts",
default=False),
+ BoolOption("stack_optimization",
+ "Tranform graphs in SSI form into graphs tailored for "
+ "stack based virtual machines",
+ default=True,
+ cmdline="--stackopt",
+ requires=[("translation.type_system", "ootype"),
+ ("translation.backend", "cli")]),
+
BoolOption("none",
"Do not run any backend optimizations",
requires=[('translation.backendopt.inline', False),
Modified: pypy/dist/pypy/objspace/flow/model.py
==============================================================================
--- pypy/dist/pypy/objspace/flow/model.py (original)
+++ pypy/dist/pypy/objspace/flow/model.py Thu Apr 26 21:22:46 2007
@@ -573,6 +573,8 @@
def checkgraph(graph):
"Check the consistency of a flow graph."
+
+ from pypy.translator.oosupport.treebuilder import SubOperation
if not __debug__:
return
try:
@@ -608,19 +610,24 @@
if in_link is not None:
assert vars[v] is None or vars[v] is in_link
- for v in block.inputargs:
- definevar(v)
-
- for op in block.operations:
+ def checkop(op):
for v in op.args:
- assert isinstance(v, (Constant, Variable))
- if isinstance(v, Variable):
+ assert isinstance(v, (Constant, Variable, SubOperation))
+ if isinstance(v, SubOperation):
+ checkop(v.op)
+ elif isinstance(v, Variable):
usevar(v)
else:
assert v.value is not last_exception
#assert v.value != last_exc_value
if op.opname == 'direct_call':
assert isinstance(op.args[0], Constant)
+
+ for v in block.inputargs:
+ definevar(v)
+
+ for op in block.operations:
+ checkop(op)
definevar(op.result)
exc_links = {}
Modified: pypy/dist/pypy/translator/backendopt/all.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/all.py (original)
+++ pypy/dist/pypy/translator/backendopt/all.py Thu Apr 26 21:22:46 2007
@@ -11,6 +11,8 @@
from pypy.translator.backendopt.removeassert import remove_asserts
from pypy.translator.backendopt.support import log
from pypy.translator.backendopt.checkvirtual import check_virtual_methods
+from pypy.translator.backendopt.ssa import SSI_to_SSA
+from pypy.translator.oosupport.treebuilder import build_trees
from pypy.objspace.flow.model import checkgraph
INLINE_THRESHOLD_FOR_TEST = 33
@@ -125,6 +127,11 @@
print "after if-to-switch:"
print_statistics(translator.graphs[0], translator)
+ if config.stack_optimization:
+ for graph in graphs:
+ SSI_to_SSA(graph)
+ build_trees(graph)
+
for graph in graphs:
checkgraph(graph)
Modified: pypy/dist/pypy/translator/cli/function.py
==============================================================================
--- pypy/dist/pypy/translator/cli/function.py (original)
+++ pypy/dist/pypy/translator/cli/function.py Thu Apr 26 21:22:46 2007
@@ -6,6 +6,7 @@
from pypy.objspace.flow import model as flowmodel
from pypy.rpython.lltypesystem.lltype import Void
from pypy.rpython.ootypesystem import ootype
+from pypy.translator.oosupport.treebuilder import SubOperation
from pypy.translator.oosupport.function import Function as OOFunction
from pypy.translator.oosupport.constant import push_constant
from pypy.translator.cli.option import getoption
@@ -127,17 +128,18 @@
else:
self.ilasm.opcode('br', self._get_block_name(self.return_block))
-
def _render_op(self, op):
- from pypy.rpython.ootypesystem import ootype
- instr_list = self.db.genoo.opcodes.get(op.opname, None)
- assert instr_list is not None, 'Unknown opcode: %s ' % op
- assert isinstance(instr_list, InstructionList)
- instr_list.render(self.generator, op)
+ OOFunction._render_op(self, op)
if op.opname in ('direct_call', 'oosend', 'indirect_call') and not self.in_try:
self._premature_return()
- def _premature_return(self):
+ def _render_sub_op(self, sub_op):
+ OOFunction._render_sub_op(self, sub_op)
+ if sub_op.op.opname in ('direct_call', 'oosend', 'indirect_call') and not self.in_try:
+ self._premature_return(need_pop=sub_op.op.result is not ootype.Void)
+
+
+ def _premature_return(self, need_pop=False):
try:
return_block = self._get_block_name(self.graph.returnblock)
except KeyError:
@@ -205,6 +207,23 @@
self.load(return_var)
self.ilasm.opcode('ret')
+ # XXX: this method should be moved into oosupport, but other
+ # backends are not ready :-(
+ def render_bool_switch(self, block):
+ assert len(block.exits) == 2
+ for link in block.exits:
+ if link.exitcase:
+ link_true = link
+ else:
+ link_false = link
+
+ true_label = self.next_label('link_true')
+ self.generator.load(block.exitswitch)
+ self.generator.branch_conditionally(link.exitcase, true_label)
+ self._follow_link(link_false) # if here, the exitswitch is false
+ self.set_label(true_label)
+ self._follow_link(link_true) # if here, the exitswitch is true
+
def render_numeric_switch(self, block):
if block.exitswitch.concretetype in (ootype.SignedLongLong, ootype.UnsignedLongLong):
# TODO: it could be faster to check is the values fit in
@@ -269,7 +288,8 @@
self.ilasm.load_arg(v)
else:
self.ilasm.load_local(v)
-
+ elif isinstance(v, SubOperation):
+ self._render_sub_op(v)
else:
super(Function, self).load(v)
Modified: pypy/dist/pypy/translator/cli/test/runtest.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/runtest.py (original)
+++ pypy/dist/pypy/translator/cli/test/runtest.py Thu Apr 26 21:22:46 2007
@@ -166,16 +166,7 @@
t.buildrtyper(type_system="ootype").specialize()
check_virtual_methods(ootype.ROOT)
- backend_opt_default = dict(
- raisingop2direct_call=False,
- inline_threshold=1,
- mallocs=True,
- merge_if_blocks=True,
- constfold=True,
- heap2stack=False,
- clever_malloc_removal=False)
- backend_opt_default.update(backend_opt)
- #backend_optimizations(t, **backend_opt_default)
+ backend_optimizations(t)
main_graph = t.graphs[0]
Modified: pypy/dist/pypy/translator/cli/test/test_snippet.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/test_snippet.py (original)
+++ pypy/dist/pypy/translator/cli/test/test_snippet.py Thu Apr 26 21:22:46 2007
@@ -2,5 +2,14 @@
from pypy.translator.oosupport.test_template.snippets import BaseTestSnippets
class TestSnippets(BaseTestSnippets, CliTest):
- pass
+ def test_link_SSA(self):
+ def fn():
+ lst = [42, 43, 44]
+ for i in range(len(lst)):
+ item = lst[i]
+ if i < 10:
+ lst[i] = item+10
+ return lst
+ res = self.ll_to_list(self.interpret(fn, []))
+ assert res == [52, 53, 54]
Modified: pypy/dist/pypy/translator/oosupport/function.py
==============================================================================
--- pypy/dist/pypy/translator/oosupport/function.py (original)
+++ pypy/dist/pypy/translator/oosupport/function.py Thu Apr 26 21:22:46 2007
@@ -5,7 +5,8 @@
from pypy.objspace.flow import model as flowmodel
from pypy.rpython.ootypesystem import ootype
-from pypy.translator.oosupport.metavm import InstructionList
+from pypy.translator.oosupport.treebuilder import SubOperation
+from pypy.translator.oosupport.metavm import InstructionList, StoreResult
class Function(object):
@@ -194,6 +195,8 @@
else:
assert False, 'Unknonw exitswitch type: %s' % block.exitswitch.concretetype
+ # XXX: soon or later we should use the implementation in
+ # cli/function.py, but at the moment jvm and js fail with it.
def render_bool_switch(self, block):
for link in block.exits:
self._setup_link(link)
@@ -221,15 +224,21 @@
self.generator.load(block.exitswitch)
self.generator.branch_if_equal(target_label)
+ def _follow_link(self, link):
+ target_label = self._get_block_name(link.target)
+ self._setup_link(link)
+ self.generator.branch_unconditionally(target_label)
+
def _setup_link(self, link):
- self.generator.add_comment("Setup link")
target = link.target
for to_load, to_store in zip(link.args, target.inputargs):
- if to_load.concretetype is not ootype.Void:
- self.generator.add_comment(" to_load=%r to_store=%r" % (
- to_load, to_store))
- self.generator.load(to_load)
- self.generator.store(to_store)
+ if isinstance(to_load, flowmodel.Variable) and to_load.name == to_store.name:
+ continue
+ if to_load.concretetype is ootype.Void:
+ continue
+ self.generator.add_comment("%r --> %r" % (to_load, to_store))
+ self.generator.load(to_load)
+ self.generator.store(to_store)
def _render_op(self, op):
instr_list = self.db.genoo.opcodes.get(op.opname, None)
@@ -237,6 +246,16 @@
assert isinstance(instr_list, InstructionList)
instr_list.render(self.generator, op)
+ def _render_sub_op(self, sub_op):
+ op = sub_op.op
+ instr_list = self.db.genoo.opcodes.get(op.opname, None)
+ assert instr_list is not None, 'Unknown opcode: %s ' % op
+ assert isinstance(instr_list, InstructionList)
+ assert instr_list[-1] is StoreResult, "Cannot inline an operation that doesn't store the result"
+ instr_list = InstructionList(instr_list[:-1]) # leave the value on the stack if this is a sub-op
+ instr_list.render(self.generator, op)
+ # now the value is on the stack
+
# ---------------------------------------------------------#
# These methods are quite backend independent, but not #
# used in all backends. Invoke them from your __init__ if #
Modified: pypy/dist/pypy/translator/oosupport/treebuilder.py
==============================================================================
--- pypy/dist/pypy/translator/oosupport/treebuilder.py (original)
+++ pypy/dist/pypy/translator/oosupport/treebuilder.py Thu Apr 26 21:22:46 2007
@@ -50,7 +50,7 @@
if can_be_inlined(sub_op):
op.args[i] = SubOperation(sub_op)
block.operations[sub_i] = None
- block.operations = [op for op in block.operations if op is not None]
+ block.operations = [op for op in block.operations if op is not None] or ()
def build_trees(graph):
if not getattr(graph, 'tree_built', False):
More information about the Pypy-commit
mailing list