Author: Armin Rigo <ar...@tunes.org> Branch: shadowstack-perf-2 Changeset: r84453:6ef16f41cbe6 Date: 2016-05-15 12:03 +0200 http://bitbucket.org/pypy/pypy/changeset/6ef16f41cbe6/
Log: fixes fixes fixes diff --git a/rpython/memory/gctransform/shadowcolor.py b/rpython/memory/gctransform/shadowcolor.py --- a/rpython/memory/gctransform/shadowcolor.py +++ b/rpython/memory/gctransform/shadowcolor.py @@ -213,9 +213,15 @@ if not regalloc: return + entrymap = mkentrymap(graph) + inputvars = {} # {inputvar: (its block, its index in inputargs)} + for block in graph.iterblocks(): + for i, v in enumerate(block.inputargs): + inputvars[v] = (block, i) + Plist = [] - for i in range(regalloc.numcolors): + for index in range(regalloc.numcolors): U = UnionFind() S = set() @@ -227,26 +233,61 @@ else: continue # no gc_pop_roots in this block for v in op.args: - if regalloc.getcolor(v) == i: + if regalloc.getcolor(v) == index: break else: continue # no variable goes into index i - lst = list(find_successors(graph, [(block, v)])) - U.union_list(lst) - S.update(lst) + + succ = set() + pending_succ = [(link1, v) for link1 in block.exits] + while pending_succ: + link1, v1 = pending_succ.pop() + for i2, v2 in enumerate(link1.args): + if v2 is v1: + block2 = link1.target + w2 = block2.inputargs[i2] + if w2 in succ: + continue + succ.add(w2) + # XXX renaming + for op2 in block2.operations: + if op2.opname in ('gc_save_root', 'gc_pop_roots'): + break + else: + for link2 in block2.exits: + pending_succ.append((link2, w2)) + U.union_list(list(succ)) + S.update(succ) G = defaultdict(set) for block in graph.iterblocks(): for op in block.operations: # XXX handle renames - if op.opname == 'gc_save_root' and op.args[0].value == i: + if op.opname == 'gc_save_root' and op.args[0].value == index: break else: continue # no matching gc_save_root in this block - lst = list(find_predecessors(graph, [(block, op.args[1])])) - U.union_list(lst) - for v1 in lst: - G[v1].add((block, op)) + + key = (block, op) + pred = set() + pending_pred = [(block, op.args[1])] + while pending_pred: + block1, v1 = pending_pred.pop() + if v1 not in block1.inputargs: + # XXX handle renames + pass + else: + pred.add(v1) + varindex = block1.inputargs.index(v1) + for link1 in entrymap[block1]: + prevblock1 = link1.prevblock + if prevblock1 is not None: + w1 = link1.args[varindex] + if w1 not in pred: + pending_pred.append((prevblock1, w1)) + U.union_list(list(pred)) + for v1 in pred: + G[v1].add(key) M = S.intersection(G) @@ -254,7 +295,7 @@ for v in M: vp = U.find_rep(v) if vp not in parts_target: - new_part = (i, set(), set()) + new_part = (index, set(), set()) # (index, # subset P of variables, # set of (block, gc_save_root)) @@ -266,12 +307,6 @@ #P.sort(...heuristic?) - entrymap = mkentrymap(graph) - inputvars = {} # {inputvar: (its block, its index in inputargs)} - for block in graph.iterblocks(): - for i, v in enumerate(block.inputargs): - inputvars[v] = (block, i) - variables_along_changes = set() for i, P, gcsaveroots in Plist: @@ -284,10 +319,7 @@ mark = [] for v in P: - try: - block, varindex = inputvars[v] - except KeyError: - continue + block, varindex = inputvars[v] for link in entrymap[block]: w = link.args[varindex] maybe_found = True # unless proven false @@ -296,6 +328,8 @@ maybe_found = False except KeyError: maybe_found = False + if link.prevblock is None: + maybe_found = False if maybe_found: for op in reversed(link.prevblock.operations): # XXX handle renames diff --git a/rpython/memory/gctransform/test/test_shadowcolor.py b/rpython/memory/gctransform/test/test_shadowcolor.py --- a/rpython/memory/gctransform/test/test_shadowcolor.py +++ b/rpython/memory/gctransform/test/test_shadowcolor.py @@ -311,7 +311,7 @@ assert list(expand_one_pop_roots(None, [])) == [] -def test_move_pushes_earlier(): +def test_move_pushes_earlier_1(): def g(a): return a - 1 def f(a, b): @@ -335,3 +335,30 @@ assert len(graph.startblock.operations) == 1 assert graph.startblock.operations[0].opname == 'gc_save_root' assert graph.startblock.operations[0].args[0].value == 0 + +def test_move_pushes_earlier_2(): + def g(a): + pass + def f(a, b): + llop.gc_push_roots(lltype.Void, b) + g(a) + llop.gc_pop_roots(lltype.Void, b) + while a > 10: + a -= 2 + llop.gc_push_roots(lltype.Void, b) + g(a) + llop.gc_pop_roots(lltype.Void, b) + return b + + graph = make_graph(f, [int, llmemory.GCREF]) + regalloc = allocate_registers(graph) + expand_push_roots(graph, regalloc) + move_pushes_earlier(graph, regalloc) + expand_pop_roots(graph, regalloc) + assert graphmodel.summary(graph) == { + 'gc_save_root': 1, + 'gc_restore_root': 2, + 'int_gt': 1, + 'int_sub': 1, + 'direct_call': 2, + } _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit