PageRenderTime 48ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/rpython/translator/backendopt/test/test_removenoops.py

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