def malloc_to_stack(t): adi = AbstractDataFlowInterpreter(t) for graph in t.graphs: if graph.startblock not in adi.flown_blocks: adi.schedule_function(graph) adi.complete() for graph in t.graphs: loop_blocks = support.find_loop_blocks(graph) for block, op in graph.iterblockops(): if op.opname == 'malloc': STRUCT = op.args[0].value # must not remove mallocs of structures that have a RTTI with a destructor try: destr_ptr = lltype.getRuntimeTypeInfo(STRUCT)._obj.destructor_funcptr if destr_ptr: continue except (ValueError, AttributeError), e: pass varstate = adi.getstate(op.result) assert len(varstate.creation_points) == 1 crep = varstate.creation_points.keys()[0] if not crep.escapes: if block not in loop_blocks: print "moving object from heap to stack %s in %s" % (op, graph.name) op.opname = 'flavored_malloc' op.args.insert(0, inputconst(lltype.Void, 'stack')) else: print "%s in %s is a non-escaping malloc in a loop" % (op, graph.name)
def malloc_to_stack(t): adi = AbstractDataFlowInterpreter(t) for graph in t.graphs: if graph.startblock not in adi.flown_blocks: adi.schedule_function(graph) adi.complete() for graph in t.graphs: loop_blocks = support.find_loop_blocks(graph) for block, op in graph.iterblockops(): if op.opname != 'malloc': continue STRUCT = op.args[0].value # must not remove mallocs of structures that have a RTTI with a destructor try: destr_ptr = lltype.getRuntimeTypeInfo(STRUCT)._obj.destructor_funcptr if destr_ptr: continue except (ValueError, AttributeError), e: pass varstate = adi.getstate(op.result) assert len(varstate.creation_points) == 1 crep = varstate.creation_points.keys()[0] if not crep.escapes: if block not in loop_blocks: print "moving object from heap to stack %s in %s" % (op, graph.name) flags = op.args[1].value assert flags == {'flavor': 'gc'} op.args[1] = Constant({'flavor': 'stack'}, lltype.Void) else: print "%s in %s is a non-escaping malloc in a loop" % (op, graph.name)
def test_find_loop_blocks_simple(): def f(a): if a <= 0: return 1 return f(a - 1) t = TranslationContext() t.buildannotator().build_types(f, [int]) t.buildrtyper().specialize() graph = graphof(t, f) backedges = find_backedges(graph) assert backedges == [] loop_blocks = find_loop_blocks(graph) assert len(loop_blocks) == 0
def test_find_loop_blocks(): def f(k): result = 0 for i in range(k): result += 1 for j in range(k): result += 1 return result t = TranslationContext() t.buildannotator().build_types(f, [int]) t.buildrtyper().specialize() graph = graphof(t, f) loop_blocks = find_loop_blocks(graph) assert len(loop_blocks) == 4
def measure_median_execution_cost(graph): blocks = [] blockmap = {} for block in graph.iterblocks(): blockmap[block] = len(blocks) blocks.append(block) loops = find_loop_blocks(graph) M = sparsemat.SparseMatrix(len(blocks)) vector = [] for i, block in enumerate(blocks): vector.append(block_weight(block)) M[i, i] = 1 if block.exits: if block not in loops: current_loop_start = None else: current_loop_start = loops[block] loop_exits = [] for link in block.exits: if (link.target in loops and loops[link.target] is current_loop_start): loop_exits.append(link) if len(loop_exits) and len(loop_exits) < len(block.exits): f = 0.3 / (len(block.exits) - len(loop_exits)) b = 0.7 / len(loop_exits) else: b = f = 1.0 / len(block.exits) for link in block.exits: if (link.target in loops and loops[link.target] is current_loop_start): M[i, blockmap[link.target]] -= b else: M[i, blockmap[link.target]] -= f try: Solution = M.solve(vector) except ValueError: return sys.maxint else: res = Solution[blockmap[graph.startblock]] assert res >= 0 return res
def test_find_loop_blocks2(): class A: pass def f(n): a1 = A() a1.x = 1 a2 = A() a2.x = 2 if n > 0: a = a1 else: a = a2 return a.x t = TranslationContext() t.buildannotator().build_types(f, [int]) t.buildrtyper().specialize() graph = graphof(t, f) backedges = find_backedges(graph) assert backedges == [] loop_blocks = find_loop_blocks(graph) assert len(loop_blocks) == 0
def test_find_loop_blocks3(): import os def ps(loops): return 42.0, 42.1 def f(loops): benchtime, stones = ps(abs(loops)) s = '' # annotator happiness if loops >= 0: s = ("RPystone(%s) time for %d passes = %f" % (23, loops, benchtime) + '\n' + ( "This machine benchmarks at %f pystones/second" % stones)) os.write(1, s) if loops == 12345: f(loops-1) t = TranslationContext() t.buildannotator().build_types(f, [int]) t.buildrtyper().specialize() graph = graphof(t, f) backedges = find_backedges(graph) assert backedges == [] loop_blocks = find_loop_blocks(graph) assert len(loop_blocks) == 0
def transform(self): assert not support.find_loop_blocks(self.graph) for i,var in enumerate(self.startblock.inputargs): self.vartonode[var] = ArgumentNode(i) self.transform_block(self.startblock) return self.get_node(self.returnblock.inputargs[0])