[pypy-svn] r74019 - in pypy/branch/blackhole-improvement/pypy/jit/codewriter: . test
arigo at codespeak.net
arigo at codespeak.net
Fri Apr 23 15:19:48 CEST 2010
Author: arigo
Date: Fri Apr 23 15:19:46 2010
New Revision: 74019
Modified:
pypy/branch/blackhole-improvement/pypy/jit/codewriter/codewriter.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitter.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitter.py
Log:
Put the functions from jitter.py in a class, in order to give
them access to the cpu.
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/codewriter.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/codewriter.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/codewriter.py Fri Apr 23 15:19:46 2010
@@ -8,8 +8,8 @@
class CodeWriter(object):
- def __init__(self, rtyper=None):
- self.rtyper = rtyper
+ def __init__(self, cpu=None):
+ self.cpu = cpu
self.assembler = Assembler()
def transform_func_to_jitcode(self, func, values, type_system='lltype'):
@@ -19,7 +19,7 @@
return self.transform_graph_to_jitcode(graph)
def transform_graph_to_jitcode(self, graph, verbose=False):
- transform_graph(graph)
+ transform_graph(graph, self.cpu)
regallocs = {}
for kind in KINDS:
regallocs[kind] = perform_register_allocation(graph, kind)
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitter.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitter.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitter.py Fri Apr 23 15:19:46 2010
@@ -4,98 +4,110 @@
from pypy.jit.codewriter.flatten import ListOfKind
-def transform_graph(graph):
+def transform_graph(graph, cpu=None):
"""Transform a control flow graph to make it suitable for
being flattened in a JitCode.
"""
- for block in graph.iterblocks():
- rename = {}
- newoperations = []
- for op in block.operations:
- if is_noop_operation(op):
- rename[op.result] = rename.get(op.args[0], op.args[0])
- else:
- for i, v in enumerate(op.args):
- if v in rename:
- op = SpaceOperation(op.opname, op.args[:], op.result)
- op.args[i] = rename[v]
- newoperations.append(rewrite_operation(op))
- block.operations = newoperations
- optimize_goto_if_not(block)
-
-
-def optimize_goto_if_not(block):
- """Replace code like 'v = int_gt(x,y); exitswitch = v'
- with just 'exitswitch = ('int_gt',x,y)'."""
- if len(block.exits) != 2:
- return False
- v = block.exitswitch
- if v.concretetype != lltype.Bool:
+ t = Transformer(cpu)
+ t.transform(graph)
+
+
+class Transformer(object):
+
+ def __init__(self, cpu=None):
+ self.cpu = cpu
+
+ def transform(self, graph):
+ for block in graph.iterblocks():
+ rename = {}
+ newoperations = []
+ for op in block.operations:
+ if self.is_noop_operation(op):
+ rename[op.result] = rename.get(op.args[0], op.args[0])
+ else:
+ for i, v in enumerate(op.args):
+ if v in rename:
+ op = SpaceOperation(op.opname, op.args[:],
+ op.result)
+ op.args[i] = rename[v]
+ newoperations.append(self.rewrite_operation(op))
+ block.operations = newoperations
+ self.optimize_goto_if_not(block)
+
+ # ----------
+
+ def optimize_goto_if_not(self, block):
+ """Replace code like 'v = int_gt(x,y); exitswitch = v'
+ with just 'exitswitch = ('int_gt',x,y)'."""
+ if len(block.exits) != 2:
+ return False
+ v = block.exitswitch
+ if v.concretetype != lltype.Bool:
+ return False
+ for link in block.exits:
+ if v in link.args:
+ return False # variable escapes to next block
+ for op in block.operations[::-1]:
+ if v in op.args:
+ return False # variable is also used in cur block
+ if v is op.result:
+ if op.opname not in ('int_lt', 'int_le', 'int_eq', 'int_ne',
+ 'int_gt', 'int_ge'):
+ return False # not a supported operation
+ # ok! optimize this case
+ block.operations.remove(op)
+ block.exitswitch = (op.opname,) + tuple(op.args)
+ return True
return False
- for link in block.exits:
- if v in link.args:
- return False # variable escapes to next block
- for op in block.operations[::-1]:
- if v in op.args:
- return False # variable is also used in cur block
- if v is op.result:
- if op.opname not in ('int_lt', 'int_le', 'int_eq', 'int_ne',
- 'int_gt', 'int_ge'):
- return False # not a supported operation
- # ok! optimize this case
- block.operations.remove(op)
- block.exitswitch = (op.opname,) + tuple(op.args)
- return True
- return False
-# ____________________________________________________________
+ # ----------
-def is_noop_operation(op):
- return op.opname in _noop_operations
+ def is_noop_operation(self, op):
+ return op.opname in self._noop_operations
-_noop_operations = {'same_as': True,
- 'cast_int_to_char': True,
- 'cast_char_to_int': True}
-
-def rewrite_operation(op):
- try:
- return _rewrite_ops[op.opname](op)
- except KeyError:
- return op
-
-def rewrite_op_direct_call(op):
- """Turn 'i0 = direct_call(fn, i1, i2, ref1, ref2)'
- into e.g. 'i0 = residual_call_ir_i(fn, [i1, i2], [ref1, ref2])'.
- The name is one of 'residual_call_{r,ir,irf}_{i,r,f,v}'."""
- args_i = []
- args_r = []
- args_f = []
- for v in op.args[1:]:
- add_in_correct_list(v, args_i, args_r, args_f)
- if args_f: kinds = 'irf'
- elif args_i: kinds = 'ir'
- else: kinds = 'r'
- sublists = []
- if 'i' in kinds: sublists.append(ListOfKind('int', args_i))
- if 'r' in kinds: sublists.append(ListOfKind('ref', args_r))
- if 'f' in kinds: sublists.append(ListOfKind('float', args_f))
- reskind = getkind(op.result.concretetype)[0]
- return SpaceOperation('residual_call_%s_%s' % (kinds, reskind),
- [op.args[0]] + sublists,
- op.result)
-
-def add_in_correct_list(v, lst_i, lst_r, lst_f):
- kind = getkind(v.concretetype)
- if kind == 'void': return
- elif kind == 'int': lst = lst_i
- elif kind == 'ref': lst = lst_r
- elif kind == 'float': lst = lst_f
- else: raise AssertionError(kind)
- lst.append(v)
+ _noop_operations = {'same_as': True,
+ 'cast_int_to_char': True,
+ 'cast_char_to_int': True}
+
+ def rewrite_operation(self, op):
+ try:
+ return _rewrite_ops[op.opname](self, op)
+ except KeyError:
+ return op
+
+ def rewrite_op_direct_call(self, op):
+ """Turn 'i0 = direct_call(fn, i1, i2, ref1, ref2)'
+ into e.g. 'i0 = residual_call_ir_i(fn, [i1, i2], [ref1, ref2])'.
+ The name is one of 'residual_call_{r,ir,irf}_{i,r,f,v}'."""
+ args_i = []
+ args_r = []
+ args_f = []
+ for v in op.args[1:]:
+ self.add_in_correct_list(v, args_i, args_r, args_f)
+ if args_f: kinds = 'irf'
+ elif args_i: kinds = 'ir'
+ else: kinds = 'r'
+ sublists = []
+ if 'i' in kinds: sublists.append(ListOfKind('int', args_i))
+ if 'r' in kinds: sublists.append(ListOfKind('ref', args_r))
+ if 'f' in kinds: sublists.append(ListOfKind('float', args_f))
+ reskind = getkind(op.result.concretetype)[0]
+ return SpaceOperation('residual_call_%s_%s' % (kinds, reskind),
+ [op.args[0]] + sublists,
+ op.result)
+
+ def add_in_correct_list(self, v, lst_i, lst_r, lst_f):
+ kind = getkind(v.concretetype)
+ if kind == 'void': return
+ elif kind == 'int': lst = lst_i
+ elif kind == 'ref': lst = lst_r
+ elif kind == 'float': lst = lst_f
+ else: raise AssertionError(kind)
+ lst.append(v)
# ____________________________________________________________
_rewrite_ops = {}
-for _name, _func in globals().items():
+for _name in dir(Transformer):
if _name.startswith('rewrite_op_'):
- _rewrite_ops[_name[len('rewrite_op_'):]] = _func
+ _rewrite_ops[_name[len('rewrite_op_'):]] = getattr(Transformer, _name)
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitter.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitter.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitter.py Fri Apr 23 15:19:46 2010
@@ -1,7 +1,7 @@
import random
from pypy.objspace.flow.model import FunctionGraph, Block, Link
from pypy.objspace.flow.model import SpaceOperation, Variable, Constant
-from pypy.jit.codewriter import jitter
+from pypy.jit.codewriter.jitter import Transformer
from pypy.jit.metainterp.history import getkind
from pypy.rpython.lltypesystem import lltype, rclass, rstr
from pypy.translator.unsimplify import varoftype
@@ -19,7 +19,7 @@
block.operations = [sp1, SpaceOperation('int_gt', [v1, v2], v3), sp2]
block.exitswitch = v3
block.exits = exits = [FakeLink(), FakeLink()]
- res = jitter.optimize_goto_if_not(block)
+ res = Transformer().optimize_goto_if_not(block)
assert res == True
assert block.operations == [sp1, sp2]
assert block.exitswitch == ('int_gt', v1, v2)
@@ -30,7 +30,7 @@
block = Block([v1])
block.exitswitch = v1
block.exits = [FakeLink(), FakeLink()]
- assert not jitter.optimize_goto_if_not(block)
+ assert not Transformer().optimize_goto_if_not(block)
def test_optimize_goto_if_not__exit():
v1 = Variable()
@@ -41,7 +41,7 @@
block.exitswitch = v3
block.exits = [FakeLink(), FakeLink()]
block.exits[1].args = [v3]
- assert not jitter.optimize_goto_if_not(block)
+ assert not Transformer().optimize_goto_if_not(block)
def test_optimize_goto_if_not__unknownop():
v3 = Variable(); v3.concretetype = lltype.Bool
@@ -49,7 +49,7 @@
block.operations = [SpaceOperation('foobar', [], v3)]
block.exitswitch = v3
block.exits = [FakeLink(), FakeLink()]
- assert not jitter.optimize_goto_if_not(block)
+ assert not Transformer().optimize_goto_if_not(block)
def test_residual_call():
for RESTYPE in [lltype.Signed, rclass.OBJECTPTR,
@@ -78,7 +78,7 @@
def residual_call_test(argtypes, restype, expectedkind):
op = get_direct_call_op(argtypes, restype)
- op1 = jitter.rewrite_operation(op)
+ op1 = Transformer().rewrite_operation(op)
reskind = getkind(restype)[0]
assert op1.opname == 'residual_call_%s_%s' % (expectedkind, reskind)
assert op1.result == op.result
More information about the Pypy-commit
mailing list