forked from nawalgupta/PythonBuddy
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpolicy.py
More file actions
120 lines (105 loc) · 4.76 KB
/
Copy pathpolicy.py
File metadata and controls
120 lines (105 loc) · 4.76 KB
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