def look_inside_graph(self, graph): from pypy.translator.backendopt.support import find_backedges contains_loop = bool(find_backedges(graph)) try: func = graph.func except AttributeError: see_function = True else: see_function = (self.look_inside_function(func) and not self._reject_function(func)) contains_loop = contains_loop and not getattr( func, '_jit_unroll_safe_', False) unsupported = contains_unsupported_variable_type(graph, self.supports_floats, self.supports_longlong, self.supports_singlefloats) res = see_function and not unsupported if res and contains_loop: self.unsafe_loopy_graphs.add(graph) res = res and not contains_loop if (see_function and not res and getattr(graph, "access_directly", False)): # This happens when we have a function which has an argument with # the access_directly flag, and the annotator has determined we will # see the function. (See # pypy/annotation/specialize.py:default_specialize) However, # look_inside_graph just decided that we will not see it. (It has a # loop or unsupported variables.) If we return False, the call will # be turned into a residual call, but the graph is access_directly! # If such a function is called and accesses a virtualizable, the JIT # will not notice, and the virtualizable will fall out of sync. So, # we fail loudly now. raise ValueError("access_directly on a function which we don't see %s" % graph) return res
def look_inside_graph(self, graph): from pypy.translator.backendopt.support import find_backedges contains_loop = bool(find_backedges(graph)) try: func = graph.func except AttributeError: see_function = True else: see_function = (self.look_inside_function(func) and not self._reject_function(func)) contains_loop = contains_loop and not getattr( func, '_jit_unroll_safe_', False) unsupported = contains_unsupported_variable_type( graph, self.supports_floats, self.supports_longlong, self.supports_singlefloats) res = see_function and not unsupported if res and contains_loop: self.unsafe_loopy_graphs.add(graph) res = res and not contains_loop if (see_function and not res and getattr(graph, "access_directly", False)): # This happens when we have a function which has an argument with # the access_directly flag, and the annotator has determined we will # see the function. (See # pypy/annotation/specialize.py:default_specialize) However, # look_inside_graph just decided that we will not see it. (It has a # loop or unsupported variables.) If we return False, the call will # be turned into a residual call, but the graph is access_directly! # If such a function is called and accesses a virtualizable, the JIT # will not notice, and the virtualizable will fall out of sync. So, # we fail loudly now. raise ValueError( "access_directly on a function which we don't see %s" % graph) return res
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_backedges(): 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) backedges = find_backedges(graph) assert len(backedges) == 2
def look_inside_graph(self, graph): from pypy.translator.backendopt.support import find_backedges contains_loop = bool(find_backedges(graph)) unsupported = contains_unsupported_variable_type(graph, self.supports_floats) try: func = graph.func except AttributeError: see_function = True else: see_function = self.look_inside_function(func) and not self._reject_function(func) contains_loop = contains_loop and not getattr(func, "_jit_unroll_safe_", False) res = see_function and not unsupported if res and contains_loop: self.unsafe_loopy_graphs.add(graph) return res and not contains_loop
def look_inside_graph(self, graph): from pypy.translator.backendopt.support import find_backedges contains_loop = bool(find_backedges(graph)) unsupported = contains_unsupported_variable_type( graph, self.supports_floats) try: func = graph.func except AttributeError: see_function = True else: see_function = (self.look_inside_function(func) and not self._reject_function(func)) contains_loop = contains_loop and not getattr( func, '_jit_unroll_safe_', False) res = see_function and not unsupported if res and contains_loop: self.unsafe_loopy_graphs.add(graph) return res and not contains_loop
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