File: policy.py

package info (click to toggle)
pypy 5.6.0%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 97,040 kB
  • ctags: 185,069
  • sloc: python: 1,147,862; ansic: 49,642; cpp: 5,245; asm: 5,169; makefile: 529; sh: 481; xml: 232; lisp: 45
file content (120 lines) | stat: -rw-r--r-- 4,875 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
from rpython.jit.metainterp import history
from rpython.tool.udir import udir
from rpython.tool.ansi_print import AnsiLogger

log = AnsiLogger('jitcodewriter')


class JitPolicy(object):
    def __init__(self, jithookiface=None):
        self.unsafe_loopy_graphs = set()
        self.supports_floats = False
        self.supports_longlong = False
        self.supports_singlefloats = False
        if jithookiface is None:
            from rpython.rlib.jit import JitHookInterface
            jithookiface = JitHookInterface()
        self.jithookiface = jithookiface

    def set_supports_floats(self, flag):
        self.supports_floats = flag

    def set_supports_longlong(self, flag):
        self.supports_longlong = flag

    def set_supports_singlefloats(self, flag):
        self.supports_singlefloats = flag

    def dump_unsafe_loops(self):
        f = udir.join("unsafe-loops.txt").open('w')
        strs = [str(graph) for graph in self.unsafe_loopy_graphs]
        strs.sort()
        for graph in strs:
            print >> f, graph
        f.close()

    def look_inside_function(self, func):
        return True # look into everything by default

    def _reject_function(self, func):
        # explicitly elidable functions are always opaque
        if getattr(func, '_elidable_function_', False):
            return True
        # rpython.rtyper.module.* are opaque helpers
        mod = func.__module__ or '?'
        if mod.startswith('rpython.rtyper.module.'):
            return True
        return False

    def look_inside_graph(self, graph):
        from rpython.translator.backendopt.support import find_backedges
        contains_loop = bool(find_backedges(graph))
        try:
            func = graph.func
        except AttributeError:
            see_function = True
        else:
            if hasattr(func, '_jit_look_inside_'):
                see_function = func._jit_look_inside_   # override guessing
            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 contains_unsupported_variable_type(graph,
                            self.supports_floats,
                            self.supports_longlong,
                            self.supports_singlefloats)
        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 contains_unsupported_variable_type(graph, supports_floats,
                                              supports_longlong,
                                              supports_singlefloats):
    getkind = history.getkind
    try:
        for block in graph.iterblocks():
            for v in block.inputargs:
                getkind(v.concretetype, supports_floats,
                                        supports_longlong,
                                        supports_singlefloats)
            for op in block.operations:
                for v in op.args:
                    getkind(v.concretetype, supports_floats,
                                            supports_longlong,
                                            supports_singlefloats)
                v = op.result
                getkind(v.concretetype, supports_floats,
                                        supports_longlong,
                                        supports_singlefloats)
    except NotImplementedError as e:
        log.WARNING('%s, ignoring graph' % (e,))
        log.WARNING('  %s' % (graph,))
        return True
    return False

# ____________________________________________________________

class StopAtXPolicy(JitPolicy):
    def __init__(self, *funcs):
        JitPolicy.__init__(self)
        self.funcs = funcs

    def look_inside_function(self, func):
        return func not in self.funcs