~ubuntu-branches/ubuntu/karmic/pypy/karmic

« back to all changes in this revision

Viewing changes to pypy/module/pypyjit/portal.py

  • Committer: Bazaar Package Importer
  • Author(s): Alexandre Fayolle
  • Date: 2007-04-13 09:33:09 UTC
  • Revision ID: james.westby@ubuntu.com-20070413093309-yoojh4jcoocu2krz
Tags: upstream-1.0.0
ImportĀ upstreamĀ versionĀ 1.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
6
 
 
7
class PyPyHintAnnotatorPolicy(HintAnnotatorPolicy):
 
8
    novirtualcontainer = True
 
9
    oopspec = True
 
10
 
 
11
    def __init__(self, timeshift_graphs):
 
12
        self.timeshift_graphs = timeshift_graphs
 
13
 
 
14
    def look_inside_graph(self, graph):
 
15
        if graph in self.timeshift_graphs:
 
16
            return self.timeshift_graphs[graph]
 
17
        try:
 
18
            func = graph.func
 
19
        except AttributeError:
 
20
            return True
 
21
        mod = func.__module__ or '?'
 
22
        if mod.startswith('pypy.objspace'):
 
23
            return False
 
24
        if '_geninterp_' in func.func_globals: # skip all geninterped stuff
 
25
            return False
 
26
        if mod.startswith('pypy.interpreter.astcompiler'):
 
27
            return False
 
28
        if mod.startswith('pypy.interpreter.pyparser'):
 
29
            return False
 
30
        if mod.startswith('pypy.module.'):
 
31
            if not mod.startswith('pypy.module.pypyjit.'):
 
32
                return False
 
33
        if mod in forbidden_modules:
 
34
            return False
 
35
        if func.__name__.startswith('_mm_') or '_mth_mm_' in func.__name__:
 
36
            return False
 
37
        if func.__name__.startswith('fastfunc_'):
 
38
            return False
 
39
        return True
 
40
 
 
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,
 
47
                     }
 
48
 
 
49
def enumerate_reachable_graphs(translator, startgraph):
 
50
    from pypy.translator.backendopt.support import find_calls_from
 
51
    pending = [(startgraph, None)]
 
52
    yield pending[0]
 
53
    seen = {startgraph: True}
 
54
    while pending:
 
55
        yield None     # hack: a separator meaning "length increases now"
 
56
        nextlengthlist = []
 
57
        nextseen = {}
 
58
        for node in pending:
 
59
            head, tail = node
 
60
            for block, callee in find_calls_from(translator, head):
 
61
                if callee not in seen:
 
62
                    newnode = callee, node
 
63
                    yield newnode
 
64
                    nextlengthlist.append(newnode)
 
65
                    nextseen[callee] = True
 
66
        pending = nextlengthlist
 
67
        seen.update(nextseen)
 
68
    yield None
 
69
 
 
70
def graphs_on_the_path_to(translator, startgraph, targetgraphs):
 
71
    targetgraphs = targetgraphs.copy()
 
72
    result = {}
 
73
    found = {}
 
74
    for node in enumerate_reachable_graphs(translator, startgraph):
 
75
        if node is None:  # hack: a separator meaning "length increases now"
 
76
            for graph in found:
 
77
                del targetgraphs[graph]
 
78
            found.clear()
 
79
            if not targetgraphs:
 
80
                return result
 
81
        elif node[0] in targetgraphs:
 
82
            found[node[0]] = True
 
83
            while node is not None:
 
84
                head, tail = node
 
85
                result[head] = True
 
86
                node = tail
 
87
    raise Exception("did not reach all targets:\nmissing %r" % (
 
88
        targetgraphs.keys(),))
 
89
 
 
90
 
 
91
def timeshift_graphs(t, portal_graph, log):
 
92
    import pypy
 
93
    result_graphs = {}
 
94
 
 
95
    bk = t.annotator.bookkeeper
 
96
 
 
97
    def _graph(func):
 
98
        func = getattr(func, 'im_func', func)
 
99
        desc = bk.getdesc(func)
 
100
        return getuniquenondirectgraph(desc)
 
101
 
 
102
    def seefunc(fromfunc, *tofuncs):
 
103
        targetgraphs = {}
 
104
        for tofunc in tofuncs:
 
105
            targetgraphs[_graph(tofunc)] = True
 
106
        graphs = graphs_on_the_path_to(t, _graph(fromfunc), targetgraphs)
 
107
        for graph in graphs:
 
108
            if graph not in result_graphs:
 
109
                log('including graph %s' % (graph,))
 
110
            result_graphs[graph] = True
 
111
 
 
112
    def seepath(*path):
 
113
        for i in range(1, len(path)):
 
114
            seefunc(path[i-1], path[i])
 
115
 
 
116
    def seegraph(func, look=True):
 
117
        graph = _graph(func)
 
118
        if look:
 
119
            extra = ""
 
120
            if look != True:
 
121
                extra = " substituted with %s" % look
 
122
            log('including graph %s%s' % (graph, extra))
 
123
        else:
 
124
            log('excluding graph %s' % (graph,))
 
125
        result_graphs[graph] = look
 
126
 
 
127
    def seebinary(opname):
 
128
        name2 = name1 = opname[:3].lower()
 
129
        if name1 in ('and', 'or'):
 
130
            name1 += '_'
 
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),
 
134
                descr_impl,
 
135
                obj_impl)
 
136
        seepath(descr_impl,
 
137
                pypy.objspace.std.typeobject.W_TypeObject.is_heaptype)
 
138
        descr_impl = getattr(pypy.objspace.descroperation.DescrOperation,
 
139
                             'inplace_' + name2)
 
140
        seepath(getattr(pypy.interpreter.pyframe.PyFrame, 'INPLACE_'+ opname),
 
141
                descr_impl,
 
142
                obj_impl)
 
143
        seepath(descr_impl,
 
144
                pypy.objspace.std.typeobject.W_TypeObject.is_heaptype)
 
145
        
 
146
    def seeunary(opname, name=None):
 
147
        if name is None:
 
148
            name = opname.lower()
 
149
        descr_impl = getattr(pypy.objspace.descroperation.DescrOperation, name)
 
150
        seepath(getattr(pypy.interpreter.pyframe.PyFrame, 'UNARY_' + opname),
 
151
                descr_impl,
 
152
                getattr(pypy.objspace.std.intobject, name + '__Int'))
 
153
        seepath(descr_impl,
 
154
                pypy.objspace.std.typeobject.W_TypeObject.is_heaptype)
 
155
 
 
156
    def seecmp(name):
 
157
        descr_impl = getattr(pypy.objspace.descroperation.DescrOperation, name)
 
158
        seepath(pypy.interpreter.pyframe.PyFrame.COMPARE_OP,
 
159
                descr_impl,
 
160
                getattr(pypy.objspace.std.intobject, name +'__Int_Int'),
 
161
                pypy.objspace.std.Space.newbool)
 
162
        seepath(descr_impl,
 
163
                pypy.objspace.std.typeobject.W_TypeObject.is_heaptype)
 
164
 
 
165
    # --------------------
 
166
    for binop in 'ADD SUBTRACT MULTIPLY AND OR XOR'.split():
 
167
        seebinary(binop)
 
168
    for cmpname in 'lt le eq ne ge gt'.split():
 
169
        seecmp(cmpname)
 
170
    seepath(pypy.interpreter.pyframe.PyFrame.UNARY_NOT,
 
171
            pypy.objspace.std.Space.not_)
 
172
    seeunary('INVERT')
 
173
    seeunary('POSITIVE', 'pos')
 
174
    seeunary('NEGATIVE', 'neg')
 
175
 
 
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)
 
194
 
 
195
    #
 
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)
 
200
 
 
201
    return result_graphs
 
202
 
 
203
 
 
204
def get_portal(drv):
 
205
    t = drv.translator
 
206
    portal = getattr(PORTAL, 'im_func', PORTAL)
 
207
    portal_graph = graphof(t, portal)
 
208
 
 
209
    policy = PyPyHintAnnotatorPolicy(timeshift_graphs(t, portal_graph,
 
210
                                                      drv.log))
 
211
    return portal, policy