PageRenderTime 41ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/rpython/jit/backend/arm/test/test_runner.py

https://bitbucket.org/pypy/pypy/
Python | 301 lines | 287 code | 12 blank | 2 comment | 7 complexity | fb93ce19d00b3e3238665727ca53071b MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. import py
  2. from rpython.jit.backend.detect_cpu import getcpuclass
  3. from rpython.jit.backend.test.runner_test import LLtypeBackendTest,\
  4. boxfloat, constfloat
  5. from rpython.jit.metainterp.history import BasicFailDescr, BasicFinalDescr
  6. from rpython.jit.metainterp.resoperation import (ResOperation, rop,
  7. InputArgInt)
  8. from rpython.jit.tool.oparser import parse
  9. from rpython.rtyper.lltypesystem import lltype, llmemory
  10. from rpython.rtyper import rclass
  11. from rpython.rtyper.annlowlevel import llhelper
  12. from rpython.jit.codewriter.effectinfo import EffectInfo
  13. from rpython.jit.metainterp.history import JitCellToken, TargetToken
  14. from rpython.jit.backend.arm.detect import detect_arch_version
  15. from rpython.jit.codewriter import longlong
  16. CPU = getcpuclass()
  17. class FakeStats(object):
  18. pass
  19. class TestARM(LLtypeBackendTest):
  20. # for the individual tests see
  21. # ====> ../../test/runner_test.py
  22. add_loop_instructions = 'ldr; adds; cmp; beq; b;'
  23. arch_version = detect_arch_version()
  24. if arch_version == 7:
  25. bridge_loop_instructions = ('ldr; movw; nop; cmp; bge; '
  26. 'push; movw; movt; push; movw; movt; '
  27. 'blx; movw; movt; bx;')
  28. else:
  29. bridge_loop_instructions = ('ldr; mov; nop; nop; nop; cmp; bge; '
  30. 'push; ldr; mov; '
  31. '[^;]+; ' # inline constant
  32. 'push; ldr; mov; '
  33. '[^;]+; ' # inline constant
  34. 'blx; ldr; mov; '
  35. '[^;]+; ' # inline constant
  36. 'bx;')
  37. def get_cpu(self):
  38. cpu = CPU(rtyper=None, stats=FakeStats())
  39. cpu.setup_once()
  40. return cpu
  41. def test_result_is_spilled(self):
  42. cpu = self.cpu
  43. inp = [InputArgInt(i) for i in range(1, 15)]
  44. looptoken = JitCellToken()
  45. targettoken = TargetToken()
  46. operations = [
  47. ResOperation(rop.LABEL, inp, descr=targettoken),
  48. ResOperation(rop.INT_ADD, [inp[0], inp[1]]),
  49. ResOperation(rop.INT_ADD, [inp[2], inp[3]]),
  50. ResOperation(rop.INT_ADD, [inp[4], inp[5]]),
  51. ResOperation(rop.INT_ADD, [inp[6], inp[7]]),
  52. ResOperation(rop.INT_ADD, [inp[8], inp[9]]),
  53. ResOperation(rop.INT_ADD, [inp[10], inp[11]]),
  54. ResOperation(rop.INT_ADD, [inp[12], inp[13]]),
  55. ResOperation(rop.INT_ADD, [inp[0], inp[1]]),
  56. ResOperation(rop.INT_ADD, [inp[2], inp[3]]),
  57. ResOperation(rop.INT_ADD, [inp[4], inp[5]]),
  58. ResOperation(rop.INT_ADD, [inp[6], inp[7]]),
  59. ResOperation(rop.INT_ADD, [inp[8], inp[9]]),
  60. ResOperation(rop.INT_ADD, [inp[10], inp[11]]),
  61. ResOperation(rop.INT_ADD, [inp[12], inp[13]]),
  62. ResOperation(rop.GUARD_FALSE, [inp[1]], descr=BasicFailDescr(1)),
  63. ResOperation(rop.FINISH, [inp[1]], descr=BasicFinalDescr(1)),
  64. ]
  65. operations[-2].setfailargs(operations[1:15])
  66. cpu.compile_loop(inp, operations, looptoken)
  67. args = [i for i in range(1, 15)]
  68. deadframe = self.cpu.execute_token(looptoken, *args)
  69. output = [self.cpu.get_int_value(deadframe, i - 1) for i in range(1, 15)]
  70. expected = [3, 7, 11, 15, 19, 23, 27, 3, 7, 11, 15, 19, 23, 27]
  71. assert output == expected
  72. def test_redirect_call_assembler2(self):
  73. def assembler_helper(deadframe, virtualizable):
  74. x = self.cpu.get_int_value(deadframe, 0)
  75. assert x == 11
  76. return 7
  77. FUNCPTR = lltype.Ptr(lltype.FuncType([llmemory.GCREF, llmemory.GCREF],
  78. lltype.Signed))
  79. class FakeJitDriverSD:
  80. index_of_virtualizable = -1
  81. _assembler_helper_ptr = llhelper(FUNCPTR, assembler_helper)
  82. assembler_helper_adr = llmemory.cast_ptr_to_adr(
  83. _assembler_helper_ptr)
  84. FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof(
  85. lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed)),
  86. [lltype.Signed], lltype.Signed, EffectInfo.MOST_GENERAL)
  87. lt1, lt2, lt3 = [JitCellToken() for x in range(3)]
  88. lt2.outermost_jitdriver_sd = FakeJitDriverSD()
  89. loop1 = parse('''
  90. [i0]
  91. i1 = call_assembler_i(i0, descr=lt2)
  92. guard_not_forced()[]
  93. finish(i1)
  94. ''', namespace=locals())
  95. loop2 = parse('''
  96. [i0]
  97. i1 = int_add(i0, 1)
  98. finish(i1)
  99. ''')
  100. loop3 = parse('''
  101. [i0]
  102. i1 = int_sub(i0, 1)
  103. finish(i1)
  104. ''')
  105. self.cpu.compile_loop(loop2.inputargs, loop2.operations, lt2)
  106. self.cpu.compile_loop(loop3.inputargs, loop3.operations, lt3)
  107. self.cpu.compile_loop(loop1.inputargs, loop1.operations, lt1)
  108. df = self.cpu.execute_token(lt1, 10)
  109. assert self.cpu.get_int_value(df, 0) == 7
  110. self.cpu.redirect_call_assembler(lt2, lt3)
  111. df = self.cpu.execute_token(lt1, 12)
  112. assert self.cpu.get_int_value(df, 0) == 7
  113. SFloat = lltype.GcForwardReference()
  114. SFloat.become(lltype.GcStruct('SFloat', ('parent', rclass.OBJECT),
  115. ('v1', lltype.Signed), ('v2', lltype.Signed),
  116. ('v3', lltype.Signed), ('v4', lltype.Signed),
  117. ('v5', lltype.Signed), ('v6', lltype.Signed),
  118. ('v7', lltype.Signed), ('v8', lltype.Signed),
  119. ('v9', lltype.Signed), ('v10', lltype.Signed),
  120. ('v11', lltype.Signed), ('v12', lltype.Signed),
  121. ('v13', lltype.Signed), ('v14', lltype.Signed),
  122. ('v15', lltype.Signed), ('v16', lltype.Signed),
  123. ('v17', lltype.Signed), ('v18', lltype.Signed),
  124. ('v19', lltype.Signed), ('v20', lltype.Signed),
  125. ('w1', lltype.Signed), ('w2', lltype.Signed),
  126. ('w3', lltype.Signed), ('w4', lltype.Signed),
  127. ('w5', lltype.Signed), ('w6', lltype.Signed),
  128. ('w7', lltype.Signed), ('w8', lltype.Signed),
  129. ('w9', lltype.Signed), ('w10', lltype.Signed),
  130. ('w11', lltype.Signed), ('w12', lltype.Signed),
  131. ('w13', lltype.Signed), ('w14', lltype.Signed),
  132. ('w15', lltype.Signed), ('w16', lltype.Signed),
  133. ('w17', lltype.Signed), ('w18', lltype.Signed),
  134. ('w19', lltype.Signed), ('w20', lltype.Signed),
  135. ('x1', lltype.Signed), ('x2', lltype.Signed),
  136. ('x3', lltype.Signed), ('x4', lltype.Signed),
  137. ('x5', lltype.Signed), ('x6', lltype.Signed),
  138. ('x7', lltype.Signed), ('x8', lltype.Signed),
  139. ('x9', lltype.Signed), ('x10', lltype.Signed),
  140. ('x11', lltype.Signed), ('x12', lltype.Signed),
  141. ('x13', lltype.Signed), ('x14', lltype.Signed),
  142. ('x15', lltype.Signed), ('x16', lltype.Signed),
  143. ('x17', lltype.Signed), ('x18', lltype.Signed),
  144. ('x19', lltype.Signed), ('x20', lltype.Signed),
  145. ('y1', lltype.Signed), ('y2', lltype.Signed),
  146. ('y3', lltype.Signed), ('y4', lltype.Signed),
  147. ('y5', lltype.Signed), ('y6', lltype.Signed),
  148. ('y7', lltype.Signed), ('y8', lltype.Signed),
  149. ('y9', lltype.Signed), ('y10', lltype.Signed),
  150. ('y11', lltype.Signed), ('y12', lltype.Signed),
  151. ('y13', lltype.Signed), ('y14', lltype.Signed),
  152. ('y15', lltype.Signed), ('y16', lltype.Signed),
  153. ('y17', lltype.Signed), ('y18', lltype.Signed),
  154. ('y19', lltype.Signed), ('y20', lltype.Signed),
  155. ('float', lltype.Float)))
  156. TFloat = lltype.GcStruct('TFloat', ('parent', SFloat),
  157. ('next', lltype.Ptr(SFloat)))
  158. def test_float_field(self):
  159. if not self.cpu.supports_floats:
  160. py.test.skip('requires floats')
  161. t_box, T_box, _ = self.alloc_instance(self.TFloat)
  162. floatdescr = self.cpu.fielddescrof(self.SFloat, 'float')
  163. self.execute_operation(rop.SETFIELD_GC, [t_box, boxfloat(3.4)],
  164. 'void', descr=floatdescr)
  165. res = self.execute_operation(rop.GETFIELD_GC_F, [t_box],
  166. 'float', descr=floatdescr)
  167. assert longlong.getrealfloat(res) == 3.4
  168. #
  169. self.execute_operation(rop.SETFIELD_GC, [t_box, constfloat(-3.6)],
  170. 'void', descr=floatdescr)
  171. res = self.execute_operation(rop.GETFIELD_GC_F, [t_box],
  172. 'float', descr=floatdescr)
  173. assert longlong.getrealfloat(res) == -3.6
  174. def test_compile_loop_many_int_args(self):
  175. for numargs in range(2, 30):
  176. ops = []
  177. arglist = "[%s]\n" % ", ".join(["i%d" % i for i in range(numargs)])
  178. ops.append(arglist)
  179. arg1 = 0
  180. arg2 = 1
  181. res = numargs
  182. for i in range(numargs - 1):
  183. op = "i%d = int_add(i%d, i%d)\n" % (res, arg1, arg2)
  184. arg1 = res
  185. res += 1
  186. arg2 += 1
  187. ops.append(op)
  188. ops.append("finish(i%d)" % (res - 1))
  189. ops = "".join(ops)
  190. loop = parse(ops)
  191. looptoken = JitCellToken()
  192. self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
  193. ARGS = [lltype.Signed] * numargs
  194. RES = lltype.Signed
  195. args = [i+1 for i in range(numargs)]
  196. deadframe = self.cpu.execute_token(looptoken, *args)
  197. assert self.cpu.get_int_value(deadframe, 0) == sum(args)
  198. def test_debugger_on(self):
  199. py.test.skip("I don't care for now")
  200. from rpython.rlib import debug
  201. targettoken, preambletoken = TargetToken(), TargetToken()
  202. loop = """
  203. [i0]
  204. label(i0, descr=preambletoken)
  205. debug_merge_point('xyz', 0)
  206. i1 = int_add(i0, 1)
  207. i2 = int_ge(i1, 10)
  208. guard_false(i2) []
  209. label(i1, descr=targettoken)
  210. debug_merge_point('xyz', 0)
  211. i11 = int_add(i1, 1)
  212. i12 = int_ge(i11, 10)
  213. guard_false(i12) []
  214. jump(i11, descr=targettoken)
  215. """
  216. ops = parse(loop, namespace={'targettoken': targettoken,
  217. 'preambletoken': preambletoken})
  218. debug._log = dlog = debug.DebugLog()
  219. try:
  220. self.cpu.assembler.set_debug(True)
  221. looptoken = JitCellToken()
  222. self.cpu.compile_loop(ops.inputargs, ops.operations, looptoken)
  223. self.cpu.execute_token(looptoken, 0)
  224. # check debugging info
  225. struct = self.cpu.assembler.loop_run_counters[0]
  226. assert struct.i == 1
  227. struct = self.cpu.assembler.loop_run_counters[1]
  228. assert struct.i == 1
  229. struct = self.cpu.assembler.loop_run_counters[2]
  230. assert struct.i == 9
  231. self.cpu.finish_once()
  232. finally:
  233. debug._log = None
  234. l0 = ('debug_print', 'entry -1:1')
  235. l1 = ('debug_print', preambletoken.repr_of_descr() + ':1')
  236. l2 = ('debug_print', targettoken.repr_of_descr() + ':9')
  237. assert ('jit-backend-counts', [l0, l1, l2]) in dlog
  238. def test_label_float_in_reg_and_on_stack(self):
  239. targettoken = TargetToken()
  240. ops = """
  241. [i0, f3]
  242. i2 = same_as_i(i0) # but forced to be in a register
  243. force_spill(i2)
  244. force_spill(f3)
  245. f4 = float_add(f3, 5.0)
  246. label(f3, f4, descr=targettoken)
  247. force_spill(f3)
  248. f5 = same_as_f(f3) # but forced to be in a register
  249. finish(f5)
  250. """
  251. faildescr = BasicFailDescr(2)
  252. loop = parse(ops, self.cpu, namespace=locals())
  253. looptoken = JitCellToken()
  254. info = self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
  255. ops2 = """
  256. [i0, f1]
  257. i1 = same_as_i(i0)
  258. f2 = same_as_f(f1)
  259. f3 = float_add(f1, 10.0)
  260. force_spill(f3)
  261. force_spill(i1)
  262. f4 = float_add(f3, f1)
  263. jump(f3, f4, descr=targettoken)
  264. """
  265. loop2 = parse(ops2, self.cpu, namespace=locals())
  266. looptoken2 = JitCellToken()
  267. info = self.cpu.compile_loop(loop2.inputargs, loop2.operations, looptoken2)
  268. deadframe = self.cpu.execute_token(looptoken, -9, longlong.getfloatstorage(-13.5))
  269. res = longlong.getrealfloat(self.cpu.get_float_value(deadframe, 0))
  270. assert res == -13.5
  271. #
  272. deadframe = self.cpu.execute_token(looptoken2, -9, longlong.getfloatstorage(-13.5))
  273. res = longlong.getrealfloat(self.cpu.get_float_value(deadframe, 0))
  274. assert res == -3.5