[pypy-commit] pypy stmgc-c7-rewindjmp: Kill the stm's jitdriver transformation
arigo
noreply at buildbot.pypy.org
Sun Aug 17 10:26:14 CEST 2014
Author: Armin Rigo <arigo at tunes.org>
Branch: stmgc-c7-rewindjmp
Changeset: r72839:987cc6fc0366
Date: 2014-08-16 17:05 +0200
http://bitbucket.org/pypy/pypy/changeset/987cc6fc0366/
Log: Kill the stm's jitdriver transformation
diff --git a/rpython/translator/stm/jitdriver.py b/rpython/translator/stm/jitdriver.py
deleted file mode 100644
--- a/rpython/translator/stm/jitdriver.py
+++ /dev/null
@@ -1,269 +0,0 @@
-from rpython.rtyper.lltypesystem import lltype, rclass
-from rpython.flowspace.model import checkgraph, copygraph
-from rpython.flowspace.model import Block, Link, SpaceOperation, Constant
-from rpython.translator.unsimplify import split_block, varoftype
-from rpython.annotator.model import s_Int
-from rpython.rtyper.llannotation import lltype_to_annotation
-from rpython.rtyper.annlowlevel import (MixLevelHelperAnnotator,
- cast_base_ptr_to_instance)
-from rpython.rlib import rstm
-from rpython.tool.sourcetools import compile2
-from rpython.translator.c.support import log
-
-def find_jit_merge_point(graph, relaxed=False):
- found = []
- for block in graph.iterblocks():
- for i in range(len(block.operations)):
- op = block.operations[i]
- if (op.opname == 'jit_marker'
- and op.args[0].value == 'jit_merge_point'):
- jitdriver = op.args[1].value
- if not jitdriver.autoreds:
- if jitdriver.stm_do_transaction_breaks:
- found.append((block, i))
- else:
- log.WARNING("ignoring non-stm jitdriver in %r" % (
- graph,))
- else:
- log.WARNING("ignoring jitdriver with autoreds in %r" % (
- graph,)) # XXX XXX!
-
- assert len(found) <= 1, "several jit_merge_point's in %r" % (graph,)
- if found:
- return found[0]
- else:
- return None
-
-def reorganize_around_jit_driver(stmtransformer, graph):
- location = find_jit_merge_point(graph)
- if location is not None:
- JitDriverSplitter(stmtransformer, graph).split(location)
-
-# ____________________________________________________________
-
-
-class JitDriverSplitter(object):
- #
- # def graph(..): | def graph(..):
- # stuff_before | stuff_before
- # while 1: ====> while 1:
- # jit_merge_point() | if should_break_transaction():
- # stuff_after | return invoke_stm(..)
- # | stuff_after
- # ----------------------------+
- #
- # def invoke_stm(..):
- # p = new container object
- # store (green args, red args) into p
- # perform_transaction(callback, p)
- # if p.got_exception: raise p.got_exception
- # return p.result_value
- #
- # (note that perform_transaction() itself will fill p.got_exception)
- #
- # def callback(p, retry_counter):
- # fish (green args, red args) from p
- # while 1:
- # stuff_after
- # if should_break_transaction():
- # store (green args, red args) into p
- # return 1 # causes perform_tr() to loop and call us again
- # p.result_value = result_value
- # return 0 # stop perform_tr() and returns
-
- def __init__(self, stmtransformer, graph):
- self.stmtransformer = stmtransformer
- self.main_graph = graph
- self.RESTYPE = graph.getreturnvar().concretetype
-
- def split(self, portal_location):
- self.check_jitdriver(portal_location)
- self.split_after_jit_merge_point(portal_location)
- self.make_container_type()
- #
- rtyper = self.stmtransformer.translator.rtyper
- self.mixlevelannotator = MixLevelHelperAnnotator(rtyper)
- self.make_callback_function()
- self.make_invoke_stm_function()
- self.rewrite_main_graph()
- self.mixlevelannotator.finish()
-
- def check_jitdriver(self, (portalblock, portalopindex)):
- op_jitmarker = portalblock.operations[portalopindex]
- assert op_jitmarker.opname == 'jit_marker'
- assert op_jitmarker.args[0].value == 'jit_merge_point'
- jitdriver = op_jitmarker.args[1].value
- assert not jitdriver.autoreds # fix me
-
- def split_after_jit_merge_point(self, (portalblock, portalopindex)):
- link = split_block(None, portalblock, portalopindex + 1)
- self.TYPES = [v.concretetype for v in link.args]
-
- def make_container_type(self):
- args = [('a%d' % i, self.TYPES[i]) for i in range(len(self.TYPES))]
- self.CONTAINER = lltype.GcStruct('StmArgs',
- ('result_value', self.RESTYPE),
- ('got_exception', rclass.OBJECTPTR),
- *args)
- self.CONTAINERP = lltype.Ptr(self.CONTAINER)
-
- def add_call_should_break_transaction(self, block):
- # add a should_break_transaction() call at the end of the block,
- # turn the following link into an "if False" link, add a new
- # "if True" link going to a fresh new block, and return this new
- # block.
- v2 = varoftype(lltype.Bool)
- block.operations.append(
- SpaceOperation('stm_should_break_transaction', [], v2))
- #
- assert block.exitswitch is None
- [link] = block.exits
- block.exitswitch = v2
- link.exitcase = False
- link.llexitcase = False
- newblock = Block([varoftype(v.concretetype) for v in link.args])
- otherlink = Link(link.args[:], newblock)
- otherlink.exitcase = True
- otherlink.llexitcase = True
- block.recloseblock(link, otherlink)
- return newblock
-
- def rewrite_main_graph(self):
- # add 'should_break_transaction()'
- main_graph = self.main_graph
- block1, i = find_jit_merge_point(main_graph, relaxed=True)
- assert i == len(block1.operations) - 1
- del block1.operations[i]
- blockf = self.add_call_should_break_transaction(block1)
- #
- # fill in blockf with a call to invoke_stm()
- v = varoftype(self.RESTYPE, 'result')
- op = SpaceOperation('direct_call',
- [self.c_invoke_stm_func] + blockf.inputargs, v)
- blockf.operations.append(op)
- blockf.closeblock(Link([v], main_graph.returnblock))
- #
- checkgraph(main_graph)
-
- def make_invoke_stm_function(self):
- CONTAINER = self.CONTAINER
- callback = self.callback_function
- perform_transaction = rstm.make_perform_transaction(callback,
- self.CONTAINERP)
- irange = range(len(self.TYPES))
- source = """if 1:
- def ll_invoke_stm(%s):
- p = lltype.malloc(CONTAINER)
- %s
- perform_transaction(p)
- if p.got_exception:
- raise cast_base_ptr_to_instance(Exception, p.got_exception)
- return p.result_value
-""" % (', '.join(['a%d' % i for i in irange]),
- '; '.join(['p.a%d = a%d' % (i, i) for i in irange]))
- d = {'CONTAINER': CONTAINER,
- 'lltype': lltype,
- 'perform_transaction': perform_transaction,
- 'cast_base_ptr_to_instance': cast_base_ptr_to_instance,
- }
- exec compile2(source) in d
- ll_invoke_stm = d['ll_invoke_stm']
- #
- mix = self.mixlevelannotator
- c_func = mix.constfunc(ll_invoke_stm,
- map(lltype_to_annotation, self.TYPES),
- lltype_to_annotation(self.RESTYPE))
- self.c_invoke_stm_func = c_func
-
- def container_var(self):
- return varoftype(self.CONTAINERP, 'stmargs')
-
- def make_callback_function(self):
- # make a copy of the 'main_graph'
- callback_graph = copygraph(self.main_graph)
- callback_graph.name += '_stm'
- self.callback_graph = callback_graph
- self.stmtransformer.translator.graphs.append(callback_graph)
- #for v1, v2 in zip(
- # self.main_graph.getargs() + [self.main_graph.getreturnvar()],
- # callback_graph.getargs() + [callback_graph.getreturnvar()]):
- # self.stmtransformer.translator.annotator.transfer_binding(v2, v1)
- #
- # make a new startblock
- v_p = self.container_var()
- v_retry_counter = varoftype(lltype.Signed, 'retry_counter')
- blockst = Block([v_retry_counter]) # 'v_p' inserted below
- renamed_p = {blockst: v_p}
- annotator = self.stmtransformer.translator.annotator
- annotator.setbinding(v_p, lltype_to_annotation(self.CONTAINERP))
- annotator.setbinding(v_retry_counter, s_Int)
- #
- # change the startblock of callback_graph to point just after the
- # jit_merge_point
- block1, i = find_jit_merge_point(callback_graph, relaxed=True)
- assert i == len(block1.operations) - 1
- del block1.operations[i]
- [link] = block1.exits
- callback_graph.startblock = blockst
- #
- # fill in the operations of blockst: getfields reading all live vars
- a_vars = []
- for i in range(len(self.TYPES)):
- c_a_i = Constant('a%d' % i, lltype.Void)
- v_a_i = varoftype(self.TYPES[i])
- blockst.operations.append(
- SpaceOperation('getfield', [v_p, c_a_i], v_a_i))
- a_vars.append(v_a_i)
- blockst.closeblock(Link(a_vars, link.target))
- #
- # hack at the regular return block, to set the result into
- # 'p.result_value' and return 0. Note that 'p.got_exception'
- # is already cleared.
- blockr = callback_graph.returnblock
- c_result_value = Constant('result_value', lltype.Void)
- v_p = self.container_var()
- renamed_p[blockr] = v_p
- blockr.operations = [
- SpaceOperation('setfield',
- [v_p, c_result_value, blockr.inputargs[0]],
- varoftype(lltype.Void)),
- ]
- v = varoftype(lltype.Signed)
- annotator.setbinding(v, s_Int)
- newblockr = Block([v])
- newblockr.operations = ()
- newblockr.closeblock()
- blockr.recloseblock(Link([Constant(0, lltype.Signed)], newblockr))
- callback_graph.returnblock = newblockr
- #
- # add 'should_break_transaction()' at the end of the loop
- blockf = self.add_call_should_break_transaction(block1)
- # store the variables again into v_p
- v_p = self.container_var()
- renamed_p[blockf] = v_p
- for i in range(len(self.TYPES)):
- c_a_i = Constant('a%d' % i, lltype.Void)
- v_a_i = blockf.inputargs[i]
- assert v_a_i.concretetype == self.TYPES[i]
- blockf.operations.append(
- SpaceOperation('setfield', [v_p, c_a_i, v_a_i],
- varoftype(lltype.Void)))
- blockf.closeblock(Link([Constant(1, lltype.Signed)], newblockr))
- #
- # now pass the original 'v_p' everywhere
- for block in callback_graph.iterblocks():
- if block.operations == (): # skip return and except blocks
- continue
- v_p = renamed_p.get(block, self.container_var())
- block.inputargs = [v_p] + block.inputargs
- for link in block.exits:
- if link.target.operations != (): # to return or except block
- link.args = [v_p] + link.args
- #
- checkgraph(callback_graph)
- #
- FUNCTYPE = lltype.FuncType([self.CONTAINERP, lltype.Signed],
- lltype.Signed)
- mix = self.mixlevelannotator
- self.callback_function = mix.graph2delayed(callback_graph,
- FUNCTYPE=FUNCTYPE)
diff --git a/rpython/translator/stm/test/test_jitdriver.py b/rpython/translator/stm/test/test_jitdriver.py
deleted file mode 100644
--- a/rpython/translator/stm/test/test_jitdriver.py
+++ /dev/null
@@ -1,59 +0,0 @@
-from rpython.rtyper.lltypesystem import lltype, rffi
-from rpython.translator.stm.test.transform_support import BaseTestTransform
-from rpython.rlib.jit import JitDriver
-from rpython.rlib import rstm
-
-
-class TestJitDriver(BaseTestTransform):
- do_jit_driver = True
-
- def test_loop_no_arg(self):
- class X:
- counter = 10
- x = X()
- myjitdriver = JitDriver(greens=[], reds=[],
- stm_do_transaction_breaks=True)
-
- def f1():
- while x.counter > 0:
- myjitdriver.jit_merge_point()
- if rstm.jit_stm_should_break_transaction(False):
- rstm.jit_stm_transaction_break_point()
- x.counter -= 1
- return 'X'
-
- res = self.interpret(f1, [])
- assert res == 'X'
-
- def test_loop_args(self):
- class X:
- counter = 100
- x = X()
- myjitdriver = JitDriver(greens=['a'], reds=['b', 'c'])
-
- def f1(a, b, c):
- while x.counter > 0:
- myjitdriver.jit_merge_point(a=a, b=b, c=c)
- x.counter -= (ord(a) + rffi.cast(lltype.Signed, b) + c)
- return 'X'
-
- res = self.interpret(f1, ['\x03', rffi.cast(rffi.SHORT, 4), 2])
- assert res == 'X'
-
- def test_loop_void_result(self):
- class X:
- counter = 10
- x = X()
- myjitdriver = JitDriver(greens=[], reds=[],
- stm_do_transaction_breaks=True)
-
- def f1():
- while x.counter > 0:
- myjitdriver.jit_merge_point()
- if rstm.jit_stm_should_break_transaction(False):
- rstm.jit_stm_transaction_break_point()
-
- x.counter -= 1
-
- res = self.interpret(f1, [])
- assert res == None
diff --git a/rpython/translator/stm/transform.py b/rpython/translator/stm/transform.py
--- a/rpython/translator/stm/transform.py
+++ b/rpython/translator/stm/transform.py
@@ -1,6 +1,5 @@
from rpython.translator.stm.inevitable import insert_turn_inevitable
from rpython.translator.stm.readbarrier import insert_stm_read_barrier
-from rpython.translator.stm.jitdriver import reorganize_around_jit_driver
from rpython.translator.c.support import log
@@ -12,7 +11,6 @@
def transform(self):
assert not hasattr(self.translator, 'stm_transformation_applied')
self.start_log(1)
- self.transform_jit_driver()
self.transform_turn_inevitable()
self.print_logs(1)
self.translator.stm_transformation_applied = True
@@ -35,10 +33,6 @@
for graph in self.translator.graphs:
insert_turn_inevitable(graph)
- def transform_jit_driver(self):
- for graph in self.translator.graphs:
- reorganize_around_jit_driver(self, graph)
-
def start_log(self, step):
log.info("Software Transactional Memory transformation, step %d"
% step)
More information about the pypy-commit
mailing list