Author: Armin Rigo <ar...@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) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit