[pypy-svn] r74457 - in pypy/branch/blackhole-improvement/pypy: jit/codewriter jit/codewriter/test objspace/flow
arigo at codespeak.net
arigo at codespeak.net
Mon May 10 11:56:52 CEST 2010
Author: arigo
Date: Mon May 10 11:56:50 2010
New Revision: 74457
Added:
pypy/branch/blackhole-improvement/pypy/jit/codewriter/jtransform.py
- copied, changed from r74453, pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitter.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jtransform.py
- copied, changed from r74453, pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitter.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_policy.py (contents, props changed)
Removed:
pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitter.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitter.py
Modified:
pypy/branch/blackhole-improvement/pypy/jit/codewriter/assembler.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/call.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/codewriter.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitcode.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/support.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_call.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_codewriter.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py
pypy/branch/blackhole-improvement/pypy/objspace/flow/model.py
Log:
Rename 'jitter' into 'jtransform'. Add policy tests.
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/assembler.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/assembler.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/assembler.py Mon May 10 11:56:50 2010
@@ -13,14 +13,24 @@
self.insns = {}
self.descrs = []
self._descr_dict = {}
+ self._count_jitcodes = 0
- def assemble(self, ssarepr):
+ def assemble(self, ssarepr, jitcode=None):
+ """Take the 'ssarepr' representation of the code and assemble
+ it inside the 'jitcode'. If jitcode is None, make a new one.
+ """
self.setup()
for insn in ssarepr.insns:
self.write_insn(insn)
self.fix_labels()
self.check_result()
- return self.make_jitcode(ssarepr)
+ if jitcode is None:
+ jitcode = JitCode(ssarepr.name)
+ self.make_jitcode(jitcode)
+ if self._count_jitcodes < 20: # stop if we have a lot of them
+ jitcode._dump = format_assembler(ssarepr)
+ self._count_jitcodes += 1
+ return jitcode
def setup(self):
self.code = []
@@ -163,8 +173,7 @@
assert self.count_regs['ref'] + len(self.constants_r) <= 256
assert self.count_regs['float'] + len(self.constants_f) <= 256
- def make_jitcode(self, ssarepr):
- jitcode = JitCode(ssarepr.name, assembler=self)
+ def make_jitcode(self, jitcode):
jitcode.setup(''.join(self.code),
self.constants_i,
self.constants_r,
@@ -172,8 +181,5 @@
self.count_regs['int'],
self.count_regs['ref'],
self.count_regs['float'],
- liveness=self.liveness)
- #if self._count_jitcodes < 50: # stop if we have a lot of them
- # jitcode._dump = format_assembler(ssarepr)
- #self._count_jitcodes += 1
- return jitcode
+ liveness=self.liveness,
+ assembler=self)
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/call.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/call.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/call.py Mon May 10 11:56:50 2010
@@ -5,19 +5,23 @@
from pypy.jit.codewriter import support
from pypy.translator.simplify import get_funcobj
+from pypy.jit.codewriter.jitcode import JitCode
class CallControl(object):
- def __init__(self, rtyper=None, portal_runner_obj=None):
+ def __init__(self, rtyper=None, portal_graph=None):
self.rtyper = rtyper
- self.portal_runner_obj = portal_runner_obj
+ self.portal_graph = portal_graph
+ self.jitcodes = {} # map {graph: jitcode}
+ self.unfinished_graphs = [] # list of graphs with pending jitcodes
- def find_all_graphs(self, portal_graph, policy):
+ def find_all_graphs(self, policy):
def is_candidate(graph):
return policy.look_inside_graph(graph)
-
- todo = [portal_graph]
+
+ assert self.portal_graph is not None
+ todo = [self.portal_graph]
candidate_graphs = set(todo)
def callers():
@@ -94,9 +98,9 @@
funcobj = get_funcobj(funcptr)
if getattr(funcobj, 'graph', None) is None:
return 'residual'
- if funcobj is self.portal_runner_obj:
- return 'recursive'
targetgraph = funcobj.graph
+ if targetgraph is self.portal_graph:
+ return 'recursive'
if (hasattr(targetgraph, 'func') and
hasattr(targetgraph.func, 'oopspec')):
return 'builtin'
@@ -111,3 +115,18 @@
def is_candidate(self, graph):
# used only after find_all_graphs()
return graph in self.candidate_graphs
+
+ def enum_pending_graphs(self):
+ while self.unfinished_graphs:
+ graph = self.unfinished_graphs.pop()
+ yield graph, self.jitcodes[graph]
+
+ def get_jitcode(self, graph, called_from=None):
+ # 'called_from' is only one of the callers, used for debugging.
+ try:
+ return self.jitcodes[graph]
+ except KeyError:
+ jitcode = JitCode(graph.name, called_from=called_from)
+ self.jitcodes[graph] = jitcode
+ self.unfinished_graphs.append(graph)
+ return jitcode
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 Mon May 10 11:56:50 2010
@@ -2,14 +2,17 @@
from pypy.jit.codewriter.regalloc import perform_register_allocation
from pypy.jit.codewriter.flatten import flatten_graph, KINDS
from pypy.jit.codewriter.assembler import Assembler, JitCode
-from pypy.jit.codewriter.jitter import transform_graph
+from pypy.jit.codewriter.jtransform import transform_graph
from pypy.jit.codewriter.format import format_assembler
from pypy.jit.codewriter.liveness import compute_liveness
+from pypy.jit.codewriter.call import CallControl
from pypy.jit.codewriter.policy import log
+from pypy.objspace.flow.model import copygraph
from pypy.tool.udir import udir
class CodeWriter(object):
+ callcontrol = None # for tests
def __init__(self, cpu=None):
self.cpu = cpu
@@ -19,17 +22,19 @@
"""For testing."""
rtyper = support.annotate(func, values, type_system=type_system)
graph = rtyper.annotator.translator.graphs[0]
- return self.transform_graph_to_jitcode(graph, True, True)
+ jitcode = JitCode("test")
+ self.transform_graph_to_jitcode(graph, jitcode, True, True)
+ return jitcode
- def transform_graph_to_jitcode(self, graph, portal, verbose):
+ def transform_graph_to_jitcode(self, graph, jitcode, portal, verbose):
"""Transform a graph into a JitCode containing the same bytecode
- in a different format. Note that the original 'graph' is mangled
- by the process and should not be used any more.
+ in a different format.
"""
+ graph = copygraph(graph, shallowvars=True)
#
# step 1: mangle the graph so that it contains the final instructions
# that we want in the JitCode, but still as a control flow graph
- transform_graph(graph, self.cpu, portal)
+ transform_graph(graph, self.cpu, self.callcontrol, portal)
#
# step 2a: perform register allocation on it
regallocs = {}
@@ -52,12 +57,16 @@
# of bytes and lists of constants. It's during this step that
# constants are cast to their normalized type (Signed, GCREF or
# Float).
- jitcode = self.assembler.assemble(ssarepr)
- return jitcode
+ self.assembler.assemble(ssarepr, jitcode)
- def make_jitcodes(self, maingraph, verbose=False):
- self.portal_graph = maingraph
- return self.transform_graph_to_jitcode(maingraph, True, verbose)
+ def make_jitcodes(self, maingraph, policy, verbose=False):
+ self.callcontrol = CallControl(self.cpu.rtyper, maingraph)
+ self.callcontrol.find_all_graphs(policy)
+ mainjitcode = self.callcontrol.get_jitcode(maingraph)
+ for graph, jitcode in self.callcontrol.enum_pending_graphs():
+ self.transform_graph_to_jitcode(graph, jitcode,
+ graph is maingraph, verbose)
+ return mainjitcode
def print_ssa_repr(self, ssarepr, portal, verbose):
if verbose:
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitcode.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitcode.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitcode.py Mon May 10 11:56:50 2010
@@ -1,23 +1,21 @@
-from pypy.jit.metainterp.history import AbstractValue, AbstractDescr
+from pypy.jit.metainterp.history import AbstractDescr
from pypy.rlib.objectmodel import we_are_translated
-class JitCode(AbstractValue):
+class JitCode(AbstractDescr):
_empty_i = []
_empty_r = []
_empty_f = []
- def __init__(self, name, fnaddr=None, calldescr=None, called_from=None,
- assembler=None):
+ def __init__(self, name, fnaddr=None, calldescr=None, called_from=None):
self.name = name
self.fnaddr = fnaddr
self.calldescr = calldescr
self._called_from = called_from # debugging
- self._assembler = assembler # debugging
def setup(self, code='', constants_i=[], constants_r=[], constants_f=[],
num_regs_i=256, num_regs_r=256, num_regs_f=256,
- liveness=None):
+ liveness=None, assembler=None):
self.code = code
# if the following lists are empty, use a single shared empty list
self.constants_i = constants_i or self._empty_i
@@ -28,6 +26,7 @@
(num_regs_r << 9) |
(num_regs_f << 0))
self.liveness = liveness
+ self._assembler = assembler # debugging
def num_regs_i(self):
return self.num_regs_encoded >> 18
@@ -98,6 +97,13 @@
raise KeyError("missing liveness[%d], corresponding to %r" % (
pc, insn))
+ def __repr__(self):
+ return '<JitCode %r>' % self.name
+
class SwitchDictDescr(AbstractDescr):
"Get a 'dict' attribute mapping integer values to bytecode positions."
+
+ def __repr__(self):
+ dict = getattr(self, 'dict', '?')
+ return '<SwitchDictDescr %s>' % (dict,)
Copied: pypy/branch/blackhole-improvement/pypy/jit/codewriter/jtransform.py (from r74453, 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/jtransform.py Mon May 10 11:56:50 2010
@@ -7,11 +7,11 @@
from pypy.jit.codewriter import support, heaptracker
-def transform_graph(graph, cpu=None, portal=True):
+def transform_graph(graph, cpu=None, callcontrol=None, portal=True):
"""Transform a control flow graph to make it suitable for
being flattened in a JitCode.
"""
- t = Transformer(cpu)
+ t = Transformer(cpu, callcontrol)
t.transform(graph, portal)
@@ -21,8 +21,9 @@
class Transformer(object):
- def __init__(self, cpu=None):
+ def __init__(self, cpu=None, callcontrol=None):
self.cpu = cpu
+ self.callcontrol = callcontrol
def transform(self, graph, portal):
self.graph = graph
@@ -173,10 +174,21 @@
rewrite_op_float_gt = _rewrite_symmetric
rewrite_op_float_ge = _rewrite_symmetric
+ # ----------
+ # Various kinds of calls
+
def rewrite_op_direct_call(self, op):
+ kind = self.callcontrol.guess_call_kind(op)
+ return getattr(self, 'handle_%s_call' % kind)(op)
+
+ def rewrite_op_indirect_call(self, op):
+ kind = self.callcontrol.guess_call_kind(op)
+ return getattr(self, 'handle_%s_indirect_call' % kind)(op)
+
+ def rewrite_call(self, op, namebase, initialargs):
"""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}'."""
+ into 'i0 = xxx_call_ir_i(fn, descr, [i1,i2], [ref1,ref2])'.
+ The name is one of '{residual,direct}_call_{r,ir,irf}_{i,r,f,v}'."""
args_i = []
args_r = []
args_f = []
@@ -190,16 +202,8 @@
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]
- FUNC = op.args[0].concretetype.TO
- NONVOIDARGS = tuple([ARG for ARG in FUNC.ARGS if ARG != lltype.Void])
- calldescr = self.cpu.calldescrof(FUNC, NONVOIDARGS, FUNC.RESULT)
- return SpaceOperation('G_residual_call_%s_%s' % (kinds, reskind),
- [op.args[0], calldescr] + sublists,
- op.result)
-
- def rewrite_op_indirect_call(self, op):
- op1 = SpaceOperation('direct_call', op.args[:-1], op.result)
- return self.rewrite_op_direct_call(op1)
+ return SpaceOperation('G_%s_call_%s_%s' % (namebase, kinds, reskind),
+ initialargs + sublists, op.result)
def add_in_correct_list(self, v, lst_i, lst_r, lst_f):
kind = getkind(v.concretetype)
@@ -210,6 +214,25 @@
else: raise AssertionError(kind)
lst.append(v)
+ def handle_residual_call(self, op):
+ """A direct_call turns into the operation 'residual_call_xxx' if it
+ is calling a function that we don't want to JIT. The initial args
+ of 'residual_call_xxx' are the constant function to call, and its
+ calldescr."""
+ FUNC = op.args[0].concretetype.TO
+ NONVOIDARGS = tuple([ARG for ARG in FUNC.ARGS if ARG != lltype.Void])
+ calldescr = self.cpu.calldescrof(FUNC, NONVOIDARGS, FUNC.RESULT)
+ return self.rewrite_call(op, 'residual', [op.args[0], calldescr])
+
+ def handle_regular_call(self, op):
+ """A direct_call turns into the operation 'inline_call_xxx' if it
+ is calling a function that we want to JIT. The initial arg of
+ 'inline_call_xxx' is the JitCode of the called function."""
+ [targetgraph] = self.callcontrol.graphs_from(op)
+ jitcode = self.callcontrol.get_jitcode(targetgraph,
+ called_from=self.graph)
+ return self.rewrite_call(op, 'inline', [jitcode])
+
def _do_builtin_call(self, op, oopspec_name=None, args=None, extra=None):
if oopspec_name is None: oopspec_name = op.opname
if args is None: args = op.args
@@ -230,6 +253,9 @@
rewrite_op_int_lshift_ovf = _do_builtin_call
rewrite_op_gc_identityhash = _do_builtin_call
+ # ----------
+ # getfield/setfield/mallocs etc.
+
def rewrite_op_hint(self, op):
hints = op.args[1].value
if hints.get('promote') and op.args[0].concretetype is not lltype.Void:
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/support.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/support.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/support.py Mon May 10 11:56:50 2010
@@ -55,6 +55,10 @@
# t.view()
return rtyper
+def getgraph(func, values):
+ rtyper = annotate(func, values)
+ return rtyper.annotator.translator.graphs[0]
+
def split_before_jit_merge_point(graph, portalblock, portalopindex):
"""Find the block with 'jit_merge_point' and split just before,
making sure the input args are in the canonical order.
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_call.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_call.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_call.py Mon May 10 11:56:50 2010
@@ -4,7 +4,10 @@
from pypy.rlib import jit
from pypy.jit.codewriter.call import CallControl
from pypy.jit.codewriter import support
-from pypy.jit.codewriter.policy import JitPolicy
+
+class FakePolicy:
+ def look_inside_graph(self, graph):
+ return True
def test_graphs_from_direct_call():
@@ -49,106 +52,30 @@
# ____________________________________________________________
def test_find_all_graphs():
- def f(x):
- if x < 0:
- return f(-x)
- return x + 1
- @jit.purefunction
def g(x):
return x + 2
- @jit.dont_look_inside
- def h(x):
- return x + 3
- def i(x):
- return f(x) * g(x) * h(x)
-
- rtyper = support.annotate(i, [7])
- cc = CallControl()
- jitpolicy = JitPolicy()
- res = cc.find_all_graphs(rtyper.annotator.translator.graphs[0],
- jitpolicy)
- translator = rtyper.annotator.translator
-
- funcs = set([graph.func for graph in res])
- assert funcs == set([i, f])
-
-def test_find_all_graphs_without_floats():
- def g(x):
- return int(x * 12.5)
def f(x):
return g(x) + 1
rtyper = support.annotate(f, [7])
- cc = CallControl()
- jitpolicy = JitPolicy()
- jitpolicy.set_supports_floats(True)
- translator = rtyper.annotator.translator
- res = cc.find_all_graphs(translator.graphs[0], jitpolicy)
+ cc = CallControl(portal_graph=rtyper.annotator.translator.graphs[0])
+ res = cc.find_all_graphs(FakePolicy())
funcs = set([graph.func for graph in res])
assert funcs == set([f, g])
- cc = CallControl()
- jitpolicy.set_supports_floats(False)
- res = cc.find_all_graphs(translator.graphs[0], jitpolicy)
- funcs = [graph.func for graph in res]
- assert funcs == [f]
-
-def test_find_all_graphs_loops():
+def test_find_all_graphs_without_g():
def g(x):
- i = 0
- while i < x:
- i += 1
- return i
- @jit.unroll_safe
- def h(x):
- i = 0
- while i < x:
- i += 1
- return i
-
+ return x + 2
def f(x):
- i = 0
- while i < x*x:
- i += g(x) + h(x)
- return i
-
+ return g(x) + 1
rtyper = support.annotate(f, [7])
- cc = CallControl()
- jitpolicy = JitPolicy()
- translator = rtyper.annotator.translator
- res = cc.find_all_graphs(translator.graphs[0], jitpolicy)
- funcs = set([graph.func for graph in res])
- assert funcs == set([f, h])
-
-def test_unroll_safe_and_inline():
- @jit.unroll_safe
- def h(x):
- i = 0
- while i < x:
- i += 1
- return i
- h._always_inline_ = True
-
- def g(x):
- return h(x)
-
- rtyper = support.annotate(g, [7])
- cc = CallControl()
- jitpolicy = JitPolicy()
- translator = rtyper.annotator.translator
- res = cc.find_all_graphs(translator.graphs[0], jitpolicy)
- funcs = set([graph.func for graph in res])
- assert funcs == set([g, h])
-
-def test_find_all_graphs_str_join():
- def i(x, y):
- return "hello".join([str(x), str(y), "bye"])
-
- rtyper = support.annotate(i, [7, 100])
- cc = CallControl()
- jitpolicy = JitPolicy()
- translator = rtyper.annotator.translator
- # does not explode
- cc.find_all_graphs(translator.graphs[0], jitpolicy)
+ cc = CallControl(portal_graph=rtyper.annotator.translator.graphs[0])
+ class CustomFakePolicy:
+ def look_inside_graph(self, graph):
+ assert graph.name == 'g'
+ return False
+ res = cc.find_all_graphs(CustomFakePolicy())
+ funcs = [graph.func for graph in res]
+ assert funcs == [f]
# ____________________________________________________________
@@ -157,7 +84,7 @@
graph = object()
g = object()
g1 = object()
- cc = CallControl(portal_runner_obj=portal_runner_obj)
+ cc = CallControl(portal_graph=portal_runner_obj.graph)
cc.candidate_graphs = [g, g1]
op = SpaceOperation('direct_call', [Constant(portal_runner_obj)],
@@ -206,3 +133,15 @@
res = cc.graphs_from(op)
assert res is None
assert cc.guess_call_kind(op) == 'residual'
+
+# ____________________________________________________________
+
+def test_get_jitcode():
+ cc = CallControl()
+ class somegraph:
+ name = "foo"
+ jitcode = cc.get_jitcode(somegraph)
+ assert jitcode is cc.get_jitcode(somegraph) # caching
+ assert jitcode.name == "foo"
+ pending = list(cc.enum_pending_graphs())
+ assert pending == [(somegraph, jitcode)]
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_codewriter.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_codewriter.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_codewriter.py Mon May 10 11:56:50 2010
@@ -1,5 +1,13 @@
import py
from pypy.jit.codewriter.codewriter import CodeWriter
+from pypy.jit.codewriter import support
+
+class FakeCPU:
+ rtyper = None
+
+class FakePolicy:
+ def look_inside_graph(self, graph):
+ return True
def test_loop():
@@ -27,6 +35,23 @@
for i in range(1, len(jitcode.code)):
py.test.raises(KeyError, jitcode._live_vars, i)
+def test_call():
+ def ggg(x):
+ return x * 2
+ def fff(a, b):
+ return ggg(b) - ggg(a)
+ rtyper = support.annotate(fff, [35, 42])
+ maingraph = rtyper.annotator.translator.graphs[0]
+ cw = CodeWriter(FakeCPU())
+ jitcode = cw.make_jitcodes(maingraph, FakePolicy(), verbose=True)
+ print jitcode._dump
+ [jitcode2] = cw.assembler.descrs
+ print jitcode2._dump
+ assert jitcode is not jitcode2
+ assert jitcode.name == 'fff'
+ assert jitcode2.name == 'ggg'
+ assert 'ggg' in jitcode._dump
+
def test_integration():
from pypy.jit.metainterp.blackhole import BlackholeInterpBuilder
def f(a, b):
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py Mon May 10 11:56:50 2010
@@ -43,6 +43,10 @@
def fielddescrof(self, STRUCT, name):
return FakeDescr()
+class FakePolicy:
+ def guess_call_kind(self, op):
+ return 'residual'
+
def fake_regallocs():
return {'int': FakeRegAlloc(),
'ref': FakeRegAlloc(),
@@ -76,8 +80,8 @@
transform=False, liveness=False):
graphs = self.make_graphs(func, args)
if transform:
- from pypy.jit.codewriter.jitter import transform_graph
- transform_graph(graphs[0], FakeCPU())
+ from pypy.jit.codewriter.jtransform import transform_graph
+ transform_graph(graphs[0], FakeCPU(), FakePolicy())
if liveness:
from pypy.jit.codewriter.liveness import compute_liveness
compute_liveness(graphs[0])
Copied: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jtransform.py (from r74453, 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_jtransform.py Mon May 10 11:56:50 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.jitter import Transformer
+from pypy.jit.codewriter.jtransform import Transformer
from pypy.jit.metainterp.history import getkind
from pypy.rpython.lltypesystem import lltype, rclass, rstr
from pypy.translator.unsimplify import varoftype
@@ -27,6 +27,20 @@
def __init__(self, exitcase):
self.exitcase = self.llexitcase = exitcase
+class FakeResidualCallControl:
+ def guess_call_kind(self, op):
+ return 'residual'
+
+class FakeRegularCallControl:
+ def guess_call_kind(self, op):
+ return 'regular'
+ def graphs_from(self, op):
+ return ['somegraph']
+ def get_jitcode(self, graph, called_from=None):
+ assert graph == 'somegraph'
+ return 'somejitcode'
+
+
def test_optimize_goto_if_not():
v1 = Variable()
v2 = Variable()
@@ -127,7 +141,7 @@
assert op1.result == v3
assert op1.opname == name2[0]
-def test_residual_call():
+def test_calls():
for RESTYPE in [lltype.Signed, rclass.OBJECTPTR,
lltype.Float, lltype.Void]:
for with_void in [False, True]:
@@ -144,6 +158,7 @@
elif with_i: expectedkind = 'ir' # integers and references
else: expectedkind = 'r' # only references
yield residual_call_test, ARGS, RESTYPE, expectedkind
+ yield direct_call_test, ARGS, RESTYPE, expectedkind
def get_direct_call_op(argtypes, restype):
FUNC = lltype.FuncType(argtypes, restype)
@@ -156,7 +171,8 @@
def residual_call_test(argtypes, restype, expectedkind):
op = get_direct_call_op(argtypes, restype)
- op1 = Transformer(FakeCPU()).rewrite_operation(op)
+ tr = Transformer(FakeCPU(), FakeResidualCallControl())
+ op1 = tr.rewrite_operation(op)
reskind = getkind(restype)[0]
assert op1.opname == 'G_residual_call_%s_%s' % (expectedkind, reskind)
assert op1.result == op.result
@@ -173,6 +189,24 @@
kind = getkind(v.concretetype)
assert kind == 'void' or kind[0] in expectedkind
+def direct_call_test(argtypes, restype, expectedkind):
+ op = get_direct_call_op(argtypes, restype)
+ tr = Transformer(FakeCPU(), FakeRegularCallControl())
+ tr.graph = 'someinitialgraph'
+ op1 = tr.rewrite_operation(op)
+ reskind = getkind(restype)[0]
+ assert op1.opname == 'G_inline_call_%s_%s' % (expectedkind, reskind)
+ assert op1.result == op.result
+ assert op1.args[0] == 'somejitcode'
+ assert len(op1.args) == 1 + len(expectedkind)
+ for sublist, kind1 in zip(op1.args[1:], expectedkind):
+ assert sublist.kind.startswith(kind1)
+ assert list(sublist) == [v for v in op.args[1:]
+ if getkind(v.concretetype) == sublist.kind]
+ for v in op.args[1:]:
+ kind = getkind(v.concretetype)
+ assert kind == 'void' or kind[0] in expectedkind
+
def test_getfield():
# XXX a more compact encoding would be possible, something along
# the lines of getfield_gc_r %r0, $offset, %r1
@@ -272,7 +306,8 @@
v = varoftype(lltype.Ptr(S))
op = SpaceOperation('malloc', [Constant(S, lltype.Void),
Constant({'flavor': 'gc'}, lltype.Void)], v)
- op1 = Transformer(FakeCPU()).rewrite_operation(op)
+ tr = Transformer(FakeCPU(), FakeResidualCallControl())
+ op1 = tr.rewrite_operation(op)
assert op1.opname == 'G_residual_call_r_r'
assert op1.args[0].value == 'alloc_with_del' # pseudo-function as a str
assert list(op1.args[2]) == []
Added: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_policy.py
==============================================================================
--- (empty file)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_policy.py Mon May 10 11:56:50 2010
@@ -0,0 +1,98 @@
+from pypy.jit.codewriter.policy import contains_unsupported_variable_type
+from pypy.jit.codewriter.policy import JitPolicy
+from pypy.jit.codewriter import support
+from pypy.rlib.rarithmetic import r_singlefloat
+from pypy.rlib import jit
+
+def test_contains_unsupported_variable_type():
+ def f(x):
+ return x
+ graph = support.getgraph(f, [5])
+ assert not contains_unsupported_variable_type(graph, True)
+ assert not contains_unsupported_variable_type(graph, False)
+ #
+ graph = support.getgraph(f, [5.5])
+ assert not contains_unsupported_variable_type(graph, True)
+ assert contains_unsupported_variable_type(graph, False)
+ #
+ graph = support.getgraph(f, [r_singlefloat(5.5)])
+ assert contains_unsupported_variable_type(graph, True)
+ assert contains_unsupported_variable_type(graph, False)
+
+
+def test_regular_function():
+ graph = support.getgraph(lambda x: x+3, [5])
+ assert JitPolicy().look_inside_graph(graph)
+
+def test_without_floats():
+ graph = support.getgraph(lambda x: x+3.2, [5.4])
+ policy = JitPolicy()
+ policy.set_supports_floats(True)
+ assert policy.look_inside_graph(graph)
+ policy = JitPolicy()
+ policy.set_supports_floats(False)
+ assert not policy.look_inside_graph(graph)
+
+def test_purefunction():
+ @jit.purefunction
+ def g(x):
+ return x + 2
+ graph = support.getgraph(g, [5])
+ assert not JitPolicy().look_inside_graph(graph)
+
+def test_dont_look_inside():
+ @jit.dont_look_inside
+ def h(x):
+ return x + 3
+ graph = support.getgraph(h, [5])
+ assert not JitPolicy().look_inside_graph(graph)
+
+def test_loops():
+ def g(x):
+ i = 0
+ while i < x:
+ i += 1
+ return i
+ graph = support.getgraph(g, [5])
+ assert not JitPolicy().look_inside_graph(graph)
+
+def test_unroll_safe():
+ @jit.unroll_safe
+ def h(x):
+ i = 0
+ while i < x:
+ i += 1
+ return i
+ graph = support.getgraph(h, [5])
+ assert JitPolicy().look_inside_graph(graph)
+
+def test_unroll_safe_and_inline():
+ @jit.unroll_safe
+ def h(x):
+ i = 0
+ while i < x:
+ i += 1
+ return i
+ h._always_inline_ = True
+
+ def g(x):
+ return h(x)
+
+ graph = support.getgraph(h, [5])
+ assert JitPolicy().look_inside_graph(graph)
+
+def test_str_join():
+ def f(x, y):
+ return "hello".join([str(x), str(y), "bye"])
+
+ graph = support.getgraph(f, [5, 83])
+ for block in graph.iterblocks():
+ for op in block.operations:
+ if op.opname == 'direct_call':
+ funcptr = op.args[0].value
+ called_graph = funcptr._obj.graph
+ if JitPolicy().look_inside_graph(called_graph):
+ # the calls to join() and str() should be residual
+ mod = called_graph.func.__module__
+ assert (mod == 'pypy.rpython.rlist' or
+ mod == 'pypy.rpython.lltypesystem.rlist')
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py Mon May 10 11:56:50 2010
@@ -3,7 +3,6 @@
from pypy.jit.codewriter.regalloc import perform_register_allocation
from pypy.jit.codewriter.flatten import flatten_graph, ListOfKind
from pypy.jit.codewriter.format import format_assembler
-from pypy.jit.codewriter.jitter import transform_graph
from pypy.objspace.flow.model import Variable, Constant, SpaceOperation
from pypy.objspace.flow.model import FunctionGraph, Block, Link
from pypy.objspace.flow.model import c_last_exception
@@ -22,6 +21,7 @@
# graphs must first be transformed by jitter.py before they can be
# subjected to register allocation and flattening.
if transform:
+ from pypy.jit.codewriter.jtransform import transform_graph
transform_graph(graph)
regalloc = perform_register_allocation(graph, 'int')
ssarepr = flatten_graph(graph, {'int': regalloc})
Modified: pypy/branch/blackhole-improvement/pypy/objspace/flow/model.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/objspace/flow/model.py (original)
+++ pypy/branch/blackhole-improvement/pypy/objspace/flow/model.py Mon May 10 11:56:50 2010
@@ -414,13 +414,14 @@
lst.append(link)
return result
-def copygraph(graph, shallow=False, varmap={}):
+def copygraph(graph, shallow=False, varmap={}, shallowvars=False):
"Make a copy of a flow graph."
blockmap = {}
varmap = varmap.copy()
+ shallowvars = shallowvars or shallow
def copyvar(v):
- if shallow:
+ if shallowvars:
return v
try:
return varmap[v]
More information about the Pypy-commit
mailing list