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

« back to all changes in this revision

Viewing changes to pypy/translator/backendopt/test/test_removenoops.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.translator.backendopt.removenoops import remove_same_as, \
 
2
        remove_unaryops, remove_duplicate_casts, remove_superfluous_keep_alive
 
3
from pypy.translator.backendopt.inline import simple_inline_function
 
4
from pypy.translator.translator import TranslationContext, graphof
 
5
from pypy.rpython.memory.gctransform.test.test_transform import getops
 
6
from pypy.translator.test.snippet import simple_method
 
7
from pypy.translator.backendopt.all import backend_optimizations
 
8
from pypy.translator.backendopt.all import INLINE_THRESHOLD_FOR_TEST
 
9
from pypy.objspace.flow.model import checkgraph, flatten, Block
 
10
from pypy.rpython.lltypesystem import lltype
 
11
from pypy.rpython.lltypesystem.lloperation import llop
 
12
from pypy.rpython.llinterp import LLInterpreter
 
13
from pypy import conftest
 
14
 
 
15
import py
 
16
log = py.log.Producer('test_backendoptimization')
 
17
 
 
18
def get_graph(fn, signature, all_opts=True):
 
19
    t = TranslationContext()
 
20
    t.buildannotator().build_types(fn, signature)
 
21
    t.buildrtyper().specialize()
 
22
    if all_opts:
 
23
        backend_optimizations(t, inline_threshold=INLINE_THRESHOLD_FOR_TEST,
 
24
                              constfold=False,
 
25
                              raisingop2direct_call=False)
 
26
    graph = graphof(t, fn)
 
27
    if conftest.option.view:
 
28
        t.view()
 
29
    return graph, t
 
30
 
 
31
def check_graph(graph, args, expected_result, t):
 
32
    interp = LLInterpreter(t.rtyper)
 
33
    res = interp.eval_graph(graph, args)
 
34
    assert res == expected_result
 
35
 
 
36
def check_get_graph(fn, signature, args, expected_result):
 
37
    graph, t = get_graph(fn, signature)
 
38
    check_graph(graph, args, expected_result, t)
 
39
    return graph
 
40
 
 
41
 
 
42
def test_remove_same_as():
 
43
    def nothing(x):
 
44
        return x
 
45
    def f():
 
46
        nothing(False)
 
47
        if nothing(True):
 
48
            return 42
 
49
        else:
 
50
            return 666
 
51
    t = TranslationContext()
 
52
    t.buildannotator().build_types(f, [])
 
53
    t.buildrtyper().specialize()
 
54
    # now we make the 'if True' appear
 
55
    f_graph = graphof(t, f)
 
56
    simple_inline_function(t, nothing, f_graph)
 
57
    # here, the graph looks like  v21=same_as(True);  exitswitch: v21
 
58
    remove_same_as(f_graph)
 
59
    t.checkgraphs()
 
60
    # only one path should be left
 
61
    for block in f_graph.iterblocks():
 
62
        assert len(block.exits) <= 1
 
63
 
 
64
    interp = LLInterpreter(t.rtyper)
 
65
    result = interp.eval_graph(f_graph, [])
 
66
    assert result == 42
 
67
 
 
68
def test_remove_unaryops():
 
69
    # We really want to use remove_unaryops for things like ooupcast and
 
70
    # oodowncast in dynamically typed languages, but it's easier to test
 
71
    # it with operations on ints here.
 
72
    def f(x):
 
73
        i = llop.int_invert(lltype.Signed, x)
 
74
        i = llop.int_add(lltype.Signed, x, 1)
 
75
        return llop.int_neg(lltype.Signed, i)
 
76
    t = TranslationContext()
 
77
    t.buildannotator().build_types(f, [int])
 
78
    t.buildrtyper().specialize()
 
79
    f_graph = graphof(t, f)
 
80
    remove_unaryops(f_graph, ["int_neg", "int_invert"])
 
81
    t.checkgraphs()
 
82
 
 
83
    interp = LLInterpreter(t.rtyper)
 
84
    result = interp.eval_graph(f_graph, [-2])
 
85
    assert result == -1
 
86
 
 
87
def test_remove_keepalive():
 
88
    S = lltype.GcStruct("s", ("f", lltype.Signed))
 
89
    def f():
 
90
        s1 = lltype.malloc(S)
 
91
        llop.keepalive(lltype.Void, s1)
 
92
        s2 = lltype.malloc(S)
 
93
        llop.keepalive(lltype.Void, s1)
 
94
        llop.keepalive(lltype.Void, s2)
 
95
        return id(s1) + id(s2)
 
96
    graph, t = get_graph(f, [])
 
97
    remove_superfluous_keep_alive(graph)
 
98
    ops = getops(graph)
 
99
    assert len(ops['keepalive']) == 2
 
100
 
 
101
def test_remove_duplicate_casts():
 
102
    class A(object):
 
103
        def __init__(self, x, y):
 
104
            self.x = x
 
105
            self.y = y
 
106
        def getsum(self):
 
107
            return self.x + self.y
 
108
    class B(A):
 
109
        def __init__(self, x, y, z):
 
110
            A.__init__(self, x, y)
 
111
            self.z = z
 
112
        def getsum(self):
 
113
            return self.x + self.y + self.z
 
114
    def f(x, switch):
 
115
        a = A(x, x + 1)
 
116
        b = B(x, x + 1, x + 2)
 
117
        if switch:
 
118
            c = A(x, x + 1)
 
119
        else:
 
120
            c = B(x, x + 1, x + 2)
 
121
        return a.x + a.y + b.x + b.y + b.z + c.getsum()
 
122
    assert f(10, True) == 75
 
123
    graph, t = get_graph(f, [int, bool], all_opts=False)
 
124
    num_cast_pointer = len(getops(graph)['cast_pointer'])
 
125
    changed = remove_duplicate_casts(graph, t)
 
126
    assert changed
 
127
    ops = getops(graph)
 
128
    assert len(ops['cast_pointer']) < num_cast_pointer
 
129
    print len(ops['cast_pointer']), num_cast_pointer
 
130
    graph_getsum = graphof(t, B.getsum.im_func)
 
131
    num_cast_pointer = len(getops(graph_getsum)['cast_pointer'])
 
132
    changed = remove_duplicate_casts(graph_getsum, t)
 
133
    assert changed
 
134
    if conftest.option.view:
 
135
        t.view()
 
136
    check_graph(graph, [10, True], 75, t)
 
137
    ops = getops(graph_getsum)
 
138
    assert len(ops['cast_pointer']) < num_cast_pointer
 
139
    print len(ops['cast_pointer']), num_cast_pointer
 
140