1
from pypy.module.pypyjit.interp_jit import PORTAL
2
from pypy.module.pypyjit.newbool import NewBoolDesc
3
from pypy.translator.translator import graphof
4
from pypy.annotation.specialize import getuniquenondirectgraph
5
from pypy.jit.hintannotator.annotator import HintAnnotatorPolicy
7
class PyPyHintAnnotatorPolicy(HintAnnotatorPolicy):
8
novirtualcontainer = True
11
def __init__(self, timeshift_graphs):
12
self.timeshift_graphs = timeshift_graphs
14
def look_inside_graph(self, graph):
15
if graph in self.timeshift_graphs:
16
return self.timeshift_graphs[graph]
19
except AttributeError:
21
mod = func.__module__ or '?'
22
if mod.startswith('pypy.objspace'):
24
if '_geninterp_' in func.func_globals: # skip all geninterped stuff
26
if mod.startswith('pypy.interpreter.astcompiler'):
28
if mod.startswith('pypy.interpreter.pyparser'):
30
if mod.startswith('pypy.module.'):
31
if not mod.startswith('pypy.module.pypyjit.'):
33
if mod in forbidden_modules:
35
if func.__name__.startswith('_mm_') or '_mth_mm_' in func.__name__:
37
if func.__name__.startswith('fastfunc_'):
41
forbidden_modules = {'pypy.interpreter.gateway': True,
42
#'pypy.interpreter.baseobjspace': True,
43
'pypy.interpreter.typedef': True,
44
'pypy.interpreter.eval': True,
45
'pypy.interpreter.function': True,
46
'pypy.interpreter.pytraceback': True,
49
def enumerate_reachable_graphs(translator, startgraph):
50
from pypy.translator.backendopt.support import find_calls_from
51
pending = [(startgraph, None)]
53
seen = {startgraph: True}
55
yield None # hack: a separator meaning "length increases now"
60
for block, callee in find_calls_from(translator, head):
61
if callee not in seen:
62
newnode = callee, node
64
nextlengthlist.append(newnode)
65
nextseen[callee] = True
66
pending = nextlengthlist
70
def graphs_on_the_path_to(translator, startgraph, targetgraphs):
71
targetgraphs = targetgraphs.copy()
74
for node in enumerate_reachable_graphs(translator, startgraph):
75
if node is None: # hack: a separator meaning "length increases now"
77
del targetgraphs[graph]
81
elif node[0] in targetgraphs:
83
while node is not None:
87
raise Exception("did not reach all targets:\nmissing %r" % (
88
targetgraphs.keys(),))
91
def timeshift_graphs(t, portal_graph, log):
95
bk = t.annotator.bookkeeper
98
func = getattr(func, 'im_func', func)
99
desc = bk.getdesc(func)
100
return getuniquenondirectgraph(desc)
102
def seefunc(fromfunc, *tofuncs):
104
for tofunc in tofuncs:
105
targetgraphs[_graph(tofunc)] = True
106
graphs = graphs_on_the_path_to(t, _graph(fromfunc), targetgraphs)
108
if graph not in result_graphs:
109
log('including graph %s' % (graph,))
110
result_graphs[graph] = True
113
for i in range(1, len(path)):
114
seefunc(path[i-1], path[i])
116
def seegraph(func, look=True):
121
extra = " substituted with %s" % look
122
log('including graph %s%s' % (graph, extra))
124
log('excluding graph %s' % (graph,))
125
result_graphs[graph] = look
127
def seebinary(opname):
128
name2 = name1 = opname[:3].lower()
129
if name1 in ('and', 'or'):
131
descr_impl = getattr(pypy.objspace.descroperation.DescrOperation, name1)
132
obj_impl = getattr(pypy.objspace.std.intobject, name2 + '__Int_Int')
133
seepath(getattr(pypy.interpreter.pyframe.PyFrame, 'BINARY_'+ opname),
137
pypy.objspace.std.typeobject.W_TypeObject.is_heaptype)
138
descr_impl = getattr(pypy.objspace.descroperation.DescrOperation,
140
seepath(getattr(pypy.interpreter.pyframe.PyFrame, 'INPLACE_'+ opname),
144
pypy.objspace.std.typeobject.W_TypeObject.is_heaptype)
146
def seeunary(opname, name=None):
148
name = opname.lower()
149
descr_impl = getattr(pypy.objspace.descroperation.DescrOperation, name)
150
seepath(getattr(pypy.interpreter.pyframe.PyFrame, 'UNARY_' + opname),
152
getattr(pypy.objspace.std.intobject, name + '__Int'))
154
pypy.objspace.std.typeobject.W_TypeObject.is_heaptype)
157
descr_impl = getattr(pypy.objspace.descroperation.DescrOperation, name)
158
seepath(pypy.interpreter.pyframe.PyFrame.COMPARE_OP,
160
getattr(pypy.objspace.std.intobject, name +'__Int_Int'),
161
pypy.objspace.std.Space.newbool)
163
pypy.objspace.std.typeobject.W_TypeObject.is_heaptype)
165
# --------------------
166
for binop in 'ADD SUBTRACT MULTIPLY AND OR XOR'.split():
168
for cmpname in 'lt le eq ne ge gt'.split():
170
seepath(pypy.interpreter.pyframe.PyFrame.UNARY_NOT,
171
pypy.objspace.std.Space.not_)
173
seeunary('POSITIVE', 'pos')
174
seeunary('NEGATIVE', 'neg')
176
seepath(pypy.objspace.descroperation._invoke_binop,
177
pypy.objspace.descroperation._check_notimplemented)
178
seepath(pypy.objspace.std.intobject.add__Int_Int,
179
pypy.objspace.std.inttype.wrapint,
180
pypy.objspace.std.intobject.W_IntObject.__init__)
181
seepath(pypy.objspace.descroperation.DescrOperation.add,
182
pypy.objspace.std.Space.type,
183
pypy.objspace.std.Space.gettypeobject)
184
seepath(pypy.objspace.descroperation.DescrOperation.add,
185
pypy.objspace.std.Space.is_w)
186
seegraph(pypy.interpreter.pyframe.PyFrame.execute_frame, False)
187
# --------------------
188
# special timeshifting logic for newbool
189
seegraph(pypy.objspace.std.Space.newbool, NewBoolDesc)
190
seepath(pypy.interpreter.pyframe.PyFrame.JUMP_IF_TRUE,
191
pypy.objspace.std.Space.is_true)
192
seepath(pypy.interpreter.pyframe.PyFrame.JUMP_IF_FALSE,
193
pypy.objspace.std.Space.is_true)
196
seepath(pypy.interpreter.pyframe.PyFrame.CALL_FUNCTION,
197
pypy.interpreter.function.Function.funccall_valuestack)
198
seepath(pypy.interpreter.pyframe.PyFrame.CALL_FUNCTION,
199
pypy.interpreter.function.Function.funccall_obj_valuestack)
206
portal = getattr(PORTAL, 'im_func', PORTAL)
207
portal_graph = graphof(t, portal)
209
policy = PyPyHintAnnotatorPolicy(timeshift_graphs(t, portal_graph,
211
return portal, policy