PageRenderTime 52ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/rpython/jit/metainterp/optimizeopt/test/test_util.py

https://bitbucket.org/pypy/pypy/
Python | 673 lines | 667 code | 6 blank | 0 comment | 3 complexity | c1518f29bc459a3a83b3fcf7de55711a MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. import py, random, string
  2. from rpython.rlib.debug import debug_print
  3. from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
  4. from rpython.rtyper import rclass
  5. from rpython.rtyper.rclass import (
  6. OBJECT, OBJECT_VTABLE, FieldListAccessor, IR_QUASIIMMUTABLE)
  7. from rpython.jit.backend.llgraph import runner
  8. from rpython.jit.metainterp.history import (TreeLoop, AbstractDescr,
  9. JitCellToken, TargetToken)
  10. from rpython.jit.metainterp.optimizeopt.util import sort_descrs, equaloplists
  11. from rpython.jit.codewriter.effectinfo import EffectInfo, compute_bitstrings
  12. from rpython.jit.metainterp.logger import LogOperations
  13. from rpython.jit.tool.oparser import OpParser, pure_parse, convert_loop_to_trace
  14. from rpython.jit.metainterp.quasiimmut import QuasiImmutDescr
  15. from rpython.jit.metainterp import compile, resume, history
  16. from rpython.jit.metainterp.jitprof import EmptyProfiler
  17. from rpython.jit.metainterp.counter import DeterministicJitCounter
  18. from rpython.config.translationoption import get_combined_translation_config
  19. from rpython.jit.metainterp.resoperation import (rop, ResOperation,
  20. InputArgRef, AbstractValue, OpHelpers)
  21. from rpython.jit.metainterp.optimizeopt.util import args_dict
  22. from rpython.rlib.rjitlog import rjitlog as jl
  23. def test_sort_descrs():
  24. class PseudoDescr(AbstractDescr):
  25. def __init__(self, n):
  26. self.n = n
  27. def sort_key(self):
  28. return self.n
  29. for i in range(17):
  30. lst = [PseudoDescr(j) for j in range(i)]
  31. lst2 = lst[:]
  32. random.shuffle(lst2)
  33. sort_descrs(lst2)
  34. assert lst2 == lst
  35. def make_remap(inp1, inp2):
  36. remap = {}
  37. for a, b in zip(inp1, inp2):
  38. remap[b] = a
  39. return remap
  40. def test_equaloplists():
  41. ops = """
  42. [i0]
  43. i1 = int_add(i0, 1)
  44. i2 = int_add(i1, 1)
  45. guard_true(i1) [i2]
  46. jump(i1)
  47. """
  48. namespace = {}
  49. loop1 = pure_parse(ops, namespace=namespace)
  50. loop2 = pure_parse(ops, namespace=namespace)
  51. loop3 = pure_parse(ops.replace("i2 = int_add", "i2 = int_sub"),
  52. namespace=namespace)
  53. assert equaloplists(loop1.operations, loop2.operations,
  54. remap=make_remap(loop1.inputargs,
  55. loop2.inputargs))
  56. py.test.raises(AssertionError,
  57. "equaloplists(loop1.operations, loop3.operations,"
  58. "remap=make_remap(loop1.inputargs, loop3.inputargs))")
  59. def test_equaloplists_fail_args():
  60. ops = """
  61. [i0]
  62. i1 = int_add(i0, 1)
  63. i2 = int_add(i1, 1)
  64. guard_true(i1) [i2, i1]
  65. jump(i1)
  66. """
  67. namespace = {}
  68. loop1 = pure_parse(ops, namespace=namespace)
  69. loop2 = pure_parse(ops.replace("[i2, i1]", "[i1, i2]"),
  70. namespace=namespace)
  71. py.test.raises(AssertionError,
  72. "equaloplists(loop1.operations, loop2.operations,"
  73. "remap=make_remap(loop1.inputargs, loop2.inputargs))")
  74. assert equaloplists(loop1.operations, loop2.operations,
  75. remap=make_remap(loop1.inputargs, loop2.inputargs),
  76. strict_fail_args=False)
  77. loop3 = pure_parse(ops.replace("[i2, i1]", "[i2, i0]"),
  78. namespace=namespace)
  79. py.test.raises(AssertionError,
  80. "equaloplists(loop1.operations, loop3.operations,"
  81. " remap=make_remap(loop1.inputargs, loop3.inputargs))")
  82. # ____________________________________________________________
  83. class LLtypeMixin(object):
  84. def get_class_of_box(self, box):
  85. base = box.getref_base()
  86. return lltype.cast_opaque_ptr(rclass.OBJECTPTR, base).typeptr
  87. node_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
  88. node_vtable.name = rclass.alloc_array_name('node')
  89. node_vtable_adr = llmemory.cast_ptr_to_adr(node_vtable)
  90. node_vtable2 = lltype.malloc(OBJECT_VTABLE, immortal=True)
  91. node_vtable2.name = rclass.alloc_array_name('node2')
  92. node_vtable_adr2 = llmemory.cast_ptr_to_adr(node_vtable2)
  93. node_vtable3 = lltype.malloc(OBJECT_VTABLE, immortal=True)
  94. node_vtable3.name = rclass.alloc_array_name('node3')
  95. node_vtable_adr3 = llmemory.cast_ptr_to_adr(node_vtable3)
  96. cpu = runner.LLGraphCPU(None)
  97. NODE = lltype.GcForwardReference()
  98. S = lltype.GcForwardReference()
  99. NODE.become(lltype.GcStruct('NODE', ('parent', OBJECT),
  100. ('value', lltype.Signed),
  101. ('floatval', lltype.Float),
  102. ('charval', lltype.Char),
  103. ('nexttuple', lltype.Ptr(S)),
  104. ('next', lltype.Ptr(NODE))))
  105. S.become(lltype.GcStruct('TUPLE', ('a', lltype.Signed), ('abis', lltype.Signed),
  106. ('b', lltype.Ptr(NODE))))
  107. NODE2 = lltype.GcStruct('NODE2', ('parent', NODE),
  108. ('other', lltype.Ptr(NODE)))
  109. NODE3 = lltype.GcForwardReference()
  110. NODE3.become(lltype.GcStruct('NODE3', ('parent', OBJECT),
  111. ('value', lltype.Signed),
  112. ('next', lltype.Ptr(NODE3)),
  113. hints={'immutable': True}))
  114. big_fields = [('big' + i, lltype.Signed) for i in string.ascii_lowercase]
  115. BIG = lltype.GcForwardReference()
  116. BIG.become(lltype.GcStruct('BIG', *big_fields, hints={'immutable': True}))
  117. for field, _ in big_fields:
  118. locals()[field + 'descr'] = cpu.fielddescrof(BIG, field)
  119. node = lltype.malloc(NODE)
  120. node.value = 5
  121. node.next = node
  122. node.parent.typeptr = node_vtable
  123. nodeaddr = lltype.cast_opaque_ptr(llmemory.GCREF, node)
  124. #nodebox = InputArgRef(lltype.cast_opaque_ptr(llmemory.GCREF, node))
  125. node2 = lltype.malloc(NODE2)
  126. node2.parent.parent.typeptr = node_vtable2
  127. node2addr = lltype.cast_opaque_ptr(llmemory.GCREF, node2)
  128. myptr = lltype.cast_opaque_ptr(llmemory.GCREF, node)
  129. mynodeb = lltype.malloc(NODE)
  130. myarray = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(lltype.GcArray(lltype.Signed), 13, zero=True))
  131. mynodeb.parent.typeptr = node_vtable
  132. myptrb = lltype.cast_opaque_ptr(llmemory.GCREF, mynodeb)
  133. myptr2 = lltype.malloc(NODE2)
  134. myptr2.parent.parent.typeptr = node_vtable2
  135. myptr2 = lltype.cast_opaque_ptr(llmemory.GCREF, myptr2)
  136. nullptr = lltype.nullptr(llmemory.GCREF.TO)
  137. mynode3 = lltype.malloc(NODE3)
  138. mynode3.parent.typeptr = node_vtable3
  139. mynode3.value = 7
  140. mynode3.next = mynode3
  141. myptr3 = lltype.cast_opaque_ptr(llmemory.GCREF, mynode3) # a NODE2
  142. mynode4 = lltype.malloc(NODE3)
  143. mynode4.parent.typeptr = node_vtable3
  144. myptr4 = lltype.cast_opaque_ptr(llmemory.GCREF, mynode4) # a NODE3
  145. nullptr = lltype.nullptr(llmemory.GCREF.TO)
  146. #nodebox2 = InputArgRef(lltype.cast_opaque_ptr(llmemory.GCREF, node2))
  147. nodesize = cpu.sizeof(NODE, node_vtable)
  148. node_tid = nodesize.get_type_id()
  149. nodesize2 = cpu.sizeof(NODE2, node_vtable2)
  150. nodesize3 = cpu.sizeof(NODE3, node_vtable3)
  151. valuedescr = cpu.fielddescrof(NODE, 'value')
  152. floatdescr = cpu.fielddescrof(NODE, 'floatval')
  153. chardescr = cpu.fielddescrof(NODE, 'charval')
  154. nextdescr = cpu.fielddescrof(NODE, 'next')
  155. nexttupledescr = cpu.fielddescrof(NODE, 'nexttuple')
  156. otherdescr = cpu.fielddescrof(NODE2, 'other')
  157. valuedescr3 = cpu.fielddescrof(NODE3, 'value')
  158. nextdescr3 = cpu.fielddescrof(NODE3, 'next')
  159. assert valuedescr3.is_always_pure()
  160. assert nextdescr3.is_always_pure()
  161. accessor = FieldListAccessor()
  162. accessor.initialize(None, {'inst_field': IR_QUASIIMMUTABLE})
  163. QUASI = lltype.GcStruct('QUASIIMMUT', ('inst_field', lltype.Signed),
  164. ('mutate_field', rclass.OBJECTPTR),
  165. hints={'immutable_fields': accessor})
  166. quasisize = cpu.sizeof(QUASI, None)
  167. quasi = lltype.malloc(QUASI, immortal=True)
  168. quasi.inst_field = -4247
  169. quasifielddescr = cpu.fielddescrof(QUASI, 'inst_field')
  170. quasiptr = lltype.cast_opaque_ptr(llmemory.GCREF, quasi)
  171. quasiimmutdescr = QuasiImmutDescr(cpu, quasiptr, quasifielddescr,
  172. cpu.fielddescrof(QUASI, 'mutate_field'))
  173. NODEOBJ = lltype.GcStruct('NODEOBJ', ('parent', OBJECT),
  174. ('ref', lltype.Ptr(OBJECT)))
  175. nodeobj = lltype.malloc(NODEOBJ)
  176. nodeobjvalue = lltype.cast_opaque_ptr(llmemory.GCREF, nodeobj)
  177. refdescr = cpu.fielddescrof(NODEOBJ, 'ref')
  178. INTOBJ_NOIMMUT = lltype.GcStruct('INTOBJ_NOIMMUT', ('parent', OBJECT),
  179. ('intval', lltype.Signed))
  180. INTOBJ_IMMUT = lltype.GcStruct('INTOBJ_IMMUT', ('parent', OBJECT),
  181. ('intval', lltype.Signed),
  182. hints={'immutable': True})
  183. intobj_noimmut_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
  184. intobj_immut_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
  185. noimmut_intval = cpu.fielddescrof(INTOBJ_NOIMMUT, 'intval')
  186. immut_intval = cpu.fielddescrof(INTOBJ_IMMUT, 'intval')
  187. immut = lltype.malloc(INTOBJ_IMMUT, zero=True)
  188. immutaddr = lltype.cast_opaque_ptr(llmemory.GCREF, immut)
  189. noimmut_descr = cpu.sizeof(INTOBJ_NOIMMUT, intobj_noimmut_vtable)
  190. immut_descr = cpu.sizeof(INTOBJ_IMMUT, intobj_immut_vtable)
  191. PTROBJ_IMMUT = lltype.GcStruct('PTROBJ_IMMUT', ('parent', OBJECT),
  192. ('ptrval', lltype.Ptr(OBJECT)),
  193. hints={'immutable': True})
  194. ptrobj_immut_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
  195. ptrobj_immut_descr = cpu.sizeof(PTROBJ_IMMUT, ptrobj_immut_vtable)
  196. immut_ptrval = cpu.fielddescrof(PTROBJ_IMMUT, 'ptrval')
  197. arraydescr = cpu.arraydescrof(lltype.GcArray(lltype.Signed))
  198. int32arraydescr = cpu.arraydescrof(lltype.GcArray(rffi.INT))
  199. int16arraydescr = cpu.arraydescrof(lltype.GcArray(rffi.SHORT))
  200. float32arraydescr = cpu.arraydescrof(lltype.GcArray(lltype.SingleFloat))
  201. arraydescr_tid = arraydescr.get_type_id()
  202. array = lltype.malloc(lltype.GcArray(lltype.Signed), 15, zero=True)
  203. arrayref = lltype.cast_opaque_ptr(llmemory.GCREF, array)
  204. array2 = lltype.malloc(lltype.GcArray(lltype.Ptr(S)), 15, zero=True)
  205. array2ref = lltype.cast_opaque_ptr(llmemory.GCREF, array2)
  206. gcarraydescr = cpu.arraydescrof(lltype.GcArray(llmemory.GCREF))
  207. gcarraydescr_tid = gcarraydescr.get_type_id()
  208. floatarraydescr = cpu.arraydescrof(lltype.GcArray(lltype.Float))
  209. arrayimmutdescr = cpu.arraydescrof(lltype.GcArray(lltype.Signed, hints={"immutable": True}))
  210. immutarray = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(arrayimmutdescr.A, 13, zero=True))
  211. gcarrayimmutdescr = cpu.arraydescrof(lltype.GcArray(llmemory.GCREF, hints={"immutable": True}))
  212. floatarrayimmutdescr = cpu.arraydescrof(lltype.GcArray(lltype.Float, hints={"immutable": True}))
  213. # a GcStruct not inheriting from OBJECT
  214. tpl = lltype.malloc(S, zero=True)
  215. tupleaddr = lltype.cast_opaque_ptr(llmemory.GCREF, tpl)
  216. nodefull2 = lltype.malloc(NODE, zero=True)
  217. nodefull2addr = lltype.cast_opaque_ptr(llmemory.GCREF, nodefull2)
  218. ssize = cpu.sizeof(S, None)
  219. adescr = cpu.fielddescrof(S, 'a')
  220. abisdescr = cpu.fielddescrof(S, 'abis')
  221. bdescr = cpu.fielddescrof(S, 'b')
  222. #sbox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S)))
  223. arraydescr2 = cpu.arraydescrof(lltype.GcArray(lltype.Ptr(S)))
  224. T = lltype.GcStruct('TUPLE',
  225. ('c', lltype.Signed),
  226. ('d', lltype.Ptr(lltype.GcArray(lltype.Ptr(NODE)))))
  227. W_ROOT = lltype.GcStruct('W_ROOT', ('parent', OBJECT),
  228. ('inst_w_seq', llmemory.GCREF), ('inst_index', lltype.Signed),
  229. ('inst_w_list', llmemory.GCREF), ('inst_length', lltype.Signed),
  230. ('inst_start', lltype.Signed), ('inst_step', lltype.Signed))
  231. inst_w_seq = cpu.fielddescrof(W_ROOT, 'inst_w_seq')
  232. inst_index = cpu.fielddescrof(W_ROOT, 'inst_index')
  233. inst_length = cpu.fielddescrof(W_ROOT, 'inst_length')
  234. inst_start = cpu.fielddescrof(W_ROOT, 'inst_start')
  235. inst_step = cpu.fielddescrof(W_ROOT, 'inst_step')
  236. inst_w_list = cpu.fielddescrof(W_ROOT, 'inst_w_list')
  237. w_root_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
  238. tsize = cpu.sizeof(T, None)
  239. cdescr = cpu.fielddescrof(T, 'c')
  240. ddescr = cpu.fielddescrof(T, 'd')
  241. arraydescr3 = cpu.arraydescrof(lltype.GcArray(lltype.Ptr(NODE3)))
  242. U = lltype.GcStruct('U',
  243. ('parent', OBJECT),
  244. ('one', lltype.Ptr(lltype.GcArray(lltype.Ptr(NODE)))))
  245. u_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
  246. u_vtable_adr = llmemory.cast_ptr_to_adr(u_vtable)
  247. SIMPLE = lltype.GcStruct('simple',
  248. ('parent', OBJECT),
  249. ('value', lltype.Signed))
  250. simplevalue = cpu.fielddescrof(SIMPLE, 'value')
  251. simple_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
  252. simpledescr = cpu.sizeof(SIMPLE, simple_vtable)
  253. simple = lltype.malloc(SIMPLE, zero=True)
  254. simpleaddr = lltype.cast_opaque_ptr(llmemory.GCREF, simple)
  255. #usize = cpu.sizeof(U, ...)
  256. onedescr = cpu.fielddescrof(U, 'one')
  257. FUNC = lltype.FuncType([lltype.Signed], lltype.Signed)
  258. plaincalldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  259. EffectInfo.MOST_GENERAL)
  260. elidablecalldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  261. EffectInfo([valuedescr], [], [],
  262. [valuedescr], [], [],
  263. EffectInfo.EF_ELIDABLE_CANNOT_RAISE))
  264. elidable2calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  265. EffectInfo([valuedescr], [], [],
  266. [valuedescr], [], [],
  267. EffectInfo.EF_ELIDABLE_OR_MEMORYERROR))
  268. elidable3calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  269. EffectInfo([valuedescr], [], [],
  270. [valuedescr], [], [],
  271. EffectInfo.EF_ELIDABLE_CAN_RAISE))
  272. nonwritedescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  273. EffectInfo([], [], [], [], [], []))
  274. writeadescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  275. EffectInfo([], [], [], [adescr], [], []))
  276. writearraydescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  277. EffectInfo([], [], [], [adescr], [arraydescr],
  278. []))
  279. writevalue3descr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  280. EffectInfo([], [], [], [valuedescr3], [], []))
  281. readadescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  282. EffectInfo([adescr], [], [], [], [], []))
  283. mayforcevirtdescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  284. EffectInfo([nextdescr], [], [], [], [], [],
  285. EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE,
  286. can_invalidate=True))
  287. arraycopydescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  288. EffectInfo([], [arraydescr], [], [], [arraydescr], [],
  289. EffectInfo.EF_CANNOT_RAISE,
  290. oopspecindex=EffectInfo.OS_ARRAYCOPY))
  291. raw_malloc_descr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  292. EffectInfo([], [], [], [], [], [],
  293. EffectInfo.EF_CAN_RAISE,
  294. oopspecindex=EffectInfo.OS_RAW_MALLOC_VARSIZE_CHAR))
  295. raw_free_descr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  296. EffectInfo([], [], [], [], [], [],
  297. EffectInfo.EF_CANNOT_RAISE,
  298. oopspecindex=EffectInfo.OS_RAW_FREE))
  299. chararray = lltype.GcArray(lltype.Char)
  300. chararraydescr = cpu.arraydescrof(chararray)
  301. u2array = lltype.GcArray(rffi.USHORT)
  302. u2arraydescr = cpu.arraydescrof(u2array)
  303. nodefull = lltype.malloc(NODE2, zero=True)
  304. nodefull.parent.next = lltype.cast_pointer(lltype.Ptr(NODE), nodefull)
  305. nodefull.parent.nexttuple = tpl
  306. nodefulladdr = lltype.cast_opaque_ptr(llmemory.GCREF, nodefull)
  307. # array of structs (complex data)
  308. complexarray = lltype.GcArray(
  309. lltype.Struct("complex",
  310. ("real", lltype.Float),
  311. ("imag", lltype.Float),
  312. )
  313. )
  314. complexarraydescr = cpu.arraydescrof(complexarray)
  315. complexrealdescr = cpu.interiorfielddescrof(complexarray, "real")
  316. compleximagdescr = cpu.interiorfielddescrof(complexarray, "imag")
  317. complexarraycopydescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  318. EffectInfo([], [complexarraydescr], [], [], [complexarraydescr], [],
  319. EffectInfo.EF_CANNOT_RAISE,
  320. oopspecindex=EffectInfo.OS_ARRAYCOPY))
  321. rawarraydescr = cpu.arraydescrof(lltype.Array(lltype.Signed,
  322. hints={'nolength': True}))
  323. rawarraydescr_char = cpu.arraydescrof(lltype.Array(lltype.Char,
  324. hints={'nolength': True}))
  325. rawarraydescr_float = cpu.arraydescrof(lltype.Array(lltype.Float,
  326. hints={'nolength': True}))
  327. fc_array = lltype.GcArray(
  328. lltype.Struct(
  329. "floatchar", ("float", lltype.Float), ("char", lltype.Char)))
  330. fc_array_descr = cpu.arraydescrof(fc_array)
  331. fc_array_floatdescr = cpu.interiorfielddescrof(fc_array, "float")
  332. fc_array_chardescr = cpu.interiorfielddescrof(fc_array, "char")
  333. for _name, _os in [
  334. ('strconcatdescr', 'OS_STR_CONCAT'),
  335. ('strslicedescr', 'OS_STR_SLICE'),
  336. ('strequaldescr', 'OS_STR_EQUAL'),
  337. ('streq_slice_checknull_descr', 'OS_STREQ_SLICE_CHECKNULL'),
  338. ('streq_slice_nonnull_descr', 'OS_STREQ_SLICE_NONNULL'),
  339. ('streq_slice_char_descr', 'OS_STREQ_SLICE_CHAR'),
  340. ('streq_nonnull_descr', 'OS_STREQ_NONNULL'),
  341. ('streq_nonnull_char_descr', 'OS_STREQ_NONNULL_CHAR'),
  342. ('streq_checknull_char_descr', 'OS_STREQ_CHECKNULL_CHAR'),
  343. ('streq_lengthok_descr', 'OS_STREQ_LENGTHOK'),
  344. ]:
  345. if _name in ('strconcatdescr', 'strslicedescr'):
  346. _extra = EffectInfo.EF_ELIDABLE_OR_MEMORYERROR
  347. else:
  348. _extra = EffectInfo.EF_ELIDABLE_CANNOT_RAISE
  349. _oopspecindex = getattr(EffectInfo, _os)
  350. locals()[_name] = \
  351. cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  352. EffectInfo([], [], [], [], [], [], _extra,
  353. oopspecindex=_oopspecindex))
  354. #
  355. _oopspecindex = getattr(EffectInfo, _os.replace('STR', 'UNI'))
  356. locals()[_name.replace('str', 'unicode')] = \
  357. cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  358. EffectInfo([], [], [], [], [], [], _extra,
  359. oopspecindex=_oopspecindex))
  360. s2u_descr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  361. EffectInfo([], [], [], [], [], [], EffectInfo.EF_ELIDABLE_CAN_RAISE,
  362. oopspecindex=EffectInfo.OS_STR2UNICODE))
  363. #
  364. class LoopToken(AbstractDescr):
  365. pass
  366. asmdescr = LoopToken() # it can be whatever, it's not a descr though
  367. from rpython.jit.metainterp.virtualref import VirtualRefInfo
  368. class FakeWarmRunnerDesc:
  369. pass
  370. FakeWarmRunnerDesc.cpu = cpu
  371. vrefinfo = VirtualRefInfo(FakeWarmRunnerDesc)
  372. virtualtokendescr = vrefinfo.descr_virtual_token
  373. virtualforceddescr = vrefinfo.descr_forced
  374. FUNC = lltype.FuncType([], lltype.Void)
  375. ei = EffectInfo([], [], [], [], [], [], EffectInfo.EF_CANNOT_RAISE,
  376. can_invalidate=False,
  377. oopspecindex=EffectInfo.OS_JIT_FORCE_VIRTUALIZABLE)
  378. clear_vable = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, ei)
  379. jit_virtual_ref_vtable = vrefinfo.jit_virtual_ref_vtable
  380. jvr_vtable_adr = llmemory.cast_ptr_to_adr(jit_virtual_ref_vtable)
  381. vref_descr = cpu.sizeof(vrefinfo.JIT_VIRTUAL_REF, jit_virtual_ref_vtable)
  382. FUNC = lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed)
  383. ei = EffectInfo([], [], [], [], [], [], EffectInfo.EF_ELIDABLE_CANNOT_RAISE,
  384. can_invalidate=False,
  385. oopspecindex=EffectInfo.OS_INT_PY_DIV)
  386. int_py_div_descr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, ei)
  387. ei = EffectInfo([], [], [], [], [], [], EffectInfo.EF_ELIDABLE_CANNOT_RAISE,
  388. can_invalidate=False,
  389. oopspecindex=EffectInfo.OS_INT_UDIV)
  390. int_udiv_descr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, ei)
  391. ei = EffectInfo([], [], [], [], [], [], EffectInfo.EF_ELIDABLE_CANNOT_RAISE,
  392. can_invalidate=False,
  393. oopspecindex=EffectInfo.OS_INT_PY_MOD)
  394. int_py_mod_descr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, ei)
  395. namespace = locals()
  396. class FakeCallInfoCollection:
  397. def callinfo_for_oopspec(self, oopspecindex):
  398. calldescrtype = type(LLtypeMixin.strequaldescr)
  399. effectinfotype = type(LLtypeMixin.strequaldescr.get_extra_info())
  400. for value in LLtypeMixin.__dict__.values():
  401. if isinstance(value, calldescrtype):
  402. extra = value.get_extra_info()
  403. if (extra and isinstance(extra, effectinfotype) and
  404. extra.oopspecindex == oopspecindex):
  405. # returns 0 for 'func' in this test
  406. return value, 0
  407. raise AssertionError("not found: oopspecindex=%d" %
  408. oopspecindex)
  409. calldescr_udiv = LLtypeMixin.int_udiv_descr
  410. #calldescr_umod = LLtypeMixin.int_umod_descr
  411. LLtypeMixin.callinfocollection = FakeCallInfoCollection()
  412. # ____________________________________________________________
  413. class Fake(object):
  414. failargs_limit = 1000
  415. storedebug = None
  416. class FakeWarmState(object):
  417. vec = True # default is on
  418. vec_all = False
  419. vec_cost = 0
  420. def __init__(self, enable_opts):
  421. self.enable_opts = enable_opts
  422. class FakeJitDriverStaticData(object):
  423. vec = False
  424. class FakeMetaInterpStaticData(object):
  425. all_descrs = []
  426. def __init__(self, cpu):
  427. self.cpu = cpu
  428. self.profiler = EmptyProfiler()
  429. self.options = Fake()
  430. self.globaldata = Fake()
  431. self.config = get_combined_translation_config(translating=True)
  432. self.jitlog = jl.JitLogger()
  433. class logger_noopt:
  434. @classmethod
  435. def log_loop(*args, **kwds):
  436. pass
  437. @classmethod
  438. def log_loop_from_trace(*args, **kwds):
  439. pass
  440. class logger_ops:
  441. repr_of_resop = repr
  442. class warmrunnerdesc:
  443. class memory_manager:
  444. retrace_limit = 5
  445. max_retrace_guards = 15
  446. jitcounter = DeterministicJitCounter()
  447. def get_name_from_address(self, addr):
  448. # hack
  449. try:
  450. return "".join(addr.ptr.name.chars)
  451. except AttributeError:
  452. return ""
  453. class Info(object):
  454. def __init__(self, preamble, short_preamble=None, virtual_state=None):
  455. self.preamble = preamble
  456. self.short_preamble = short_preamble
  457. self.virtual_state = virtual_state
  458. class Storage(compile.ResumeGuardDescr):
  459. "for tests."
  460. def __init__(self, metainterp_sd=None, original_greenkey=None):
  461. self.metainterp_sd = metainterp_sd
  462. self.original_greenkey = original_greenkey
  463. def store_final_boxes(self, op, boxes, metainterp_sd):
  464. op.setfailargs(boxes)
  465. def __eq__(self, other):
  466. return True # screw this
  467. #return type(self) is type(other) # xxx obscure
  468. def _sortboxes(boxes):
  469. _kind2count = {history.INT: 1, history.REF: 2, history.FLOAT: 3}
  470. return sorted(boxes, key=lambda box: _kind2count[box.type])
  471. final_descr = history.BasicFinalDescr()
  472. class BaseTest(object):
  473. def parse(self, s, boxkinds=None, want_fail_descr=True, postprocess=None):
  474. AbstractValue._repr_memo.counter = 0
  475. self.oparse = OpParser(s, self.cpu, self.namespace, boxkinds,
  476. None, False, postprocess)
  477. return self.oparse.parse()
  478. def add_guard_future_condition(self, res):
  479. # invent a GUARD_FUTURE_CONDITION to not have to change all tests
  480. if res.operations[-1].getopnum() == rop.JUMP:
  481. guard = ResOperation(rop.GUARD_FUTURE_CONDITION, [])
  482. res.operations.insert(-1, guard)
  483. @staticmethod
  484. def assert_equal(optimized, expected, text_right=None):
  485. from rpython.jit.metainterp.optimizeopt.util import equaloplists
  486. assert len(optimized.inputargs) == len(expected.inputargs)
  487. remap = {}
  488. for box1, box2 in zip(optimized.inputargs, expected.inputargs):
  489. assert box1.type == box2.type
  490. remap[box2] = box1
  491. assert equaloplists(optimized.operations,
  492. expected.operations, False, remap, text_right)
  493. def _do_optimize_loop(self, compile_data):
  494. from rpython.jit.metainterp.optimizeopt import optimize_trace
  495. metainterp_sd = FakeMetaInterpStaticData(self.cpu)
  496. if hasattr(self, 'vrefinfo'):
  497. metainterp_sd.virtualref_info = self.vrefinfo
  498. if hasattr(self, 'callinfocollection'):
  499. metainterp_sd.callinfocollection = self.callinfocollection
  500. compute_bitstrings(self.cpu.fetch_all_descrs())
  501. #
  502. compile_data.enable_opts = self.enable_opts
  503. state = optimize_trace(metainterp_sd, None, compile_data)
  504. return state
  505. def _convert_call_pure_results(self, d):
  506. from rpython.jit.metainterp.optimizeopt.util import args_dict
  507. if d is None:
  508. return
  509. call_pure_results = args_dict()
  510. for k, v in d.items():
  511. call_pure_results[list(k)] = v
  512. return call_pure_results
  513. def convert_values(self, inpargs, values):
  514. from rpython.jit.metainterp.history import IntFrontendOp, RefFrontendOp
  515. if values:
  516. r = []
  517. for arg, v in zip(inpargs, values):
  518. if arg.type == 'i':
  519. n = IntFrontendOp(0)
  520. if v is not None:
  521. n.setint(v)
  522. else:
  523. n = RefFrontendOp(0)
  524. if v is not None:
  525. n.setref_base(v)
  526. assert arg.type == 'r'
  527. r.append(n)
  528. return r
  529. return inpargs
  530. def unroll_and_optimize(self, loop, call_pure_results=None,
  531. jump_values=None):
  532. self.add_guard_future_condition(loop)
  533. jump_op = loop.operations[-1]
  534. assert jump_op.getopnum() == rop.JUMP
  535. celltoken = JitCellToken()
  536. runtime_boxes = self.pack_into_boxes(jump_op, jump_values)
  537. jump_op.setdescr(celltoken)
  538. #start_label = ResOperation(rop.LABEL, loop.inputargs,
  539. # descr=jump_op.getdescr())
  540. #end_label = jump_op.copy_and_change(opnum=rop.LABEL)
  541. call_pure_results = self._convert_call_pure_results(call_pure_results)
  542. t = convert_loop_to_trace(loop, FakeMetaInterpStaticData(self.cpu))
  543. preamble_data = compile.LoopCompileData(t, runtime_boxes,
  544. call_pure_results)
  545. start_state, preamble_ops = self._do_optimize_loop(preamble_data)
  546. preamble_data.forget_optimization_info()
  547. loop_data = compile.UnrolledLoopData(preamble_data.trace,
  548. celltoken, start_state, call_pure_results)
  549. loop_info, ops = self._do_optimize_loop(loop_data)
  550. preamble = TreeLoop('preamble')
  551. preamble.inputargs = start_state.renamed_inputargs
  552. start_label = ResOperation(rop.LABEL, start_state.renamed_inputargs)
  553. preamble.operations = ([start_label] + preamble_ops +
  554. loop_info.extra_same_as + [loop_info.label_op])
  555. loop.inputargs = loop_info.label_op.getarglist()[:]
  556. loop.operations = [loop_info.label_op] + ops
  557. return Info(preamble, loop_info.target_token.short_preamble,
  558. start_state.virtual_state)
  559. def pack_into_boxes(self, jump_op, jump_values):
  560. assert jump_op.getopnum() == rop.JUMP
  561. r = []
  562. if jump_values is not None:
  563. assert len(jump_values) == len(jump_op.getarglist())
  564. for i, v in enumerate(jump_values):
  565. if v is not None:
  566. r.append(InputArgRef(v))
  567. else:
  568. r.append(None)
  569. else:
  570. for i, box in enumerate(jump_op.getarglist()):
  571. if box.type == 'r' and not box.is_constant():
  572. # NOTE: we arbitrarily set the box contents to a NODE2
  573. # object here. If you need something different, you
  574. # need to pass a 'jump_values' argument to e.g.
  575. # optimize_loop()
  576. r.append(InputArgRef(self.nodefulladdr))
  577. else:
  578. r.append(None)
  579. return r
  580. class FakeDescr(compile.ResumeGuardDescr):
  581. def clone_if_mutable(self):
  582. return FakeDescr()
  583. def __eq__(self, other):
  584. return isinstance(other, FakeDescr)
  585. def convert_old_style_to_targets(loop, jump):
  586. newloop = TreeLoop(loop.name)
  587. newloop.inputargs = loop.inputargs
  588. newloop.operations = [ResOperation(rop.LABEL, loop.inputargs, descr=FakeDescr())] + \
  589. loop.operations
  590. if not jump:
  591. assert newloop.operations[-1].getopnum() == rop.JUMP
  592. newloop.operations[-1] = newloop.operations[-1].copy_and_change(
  593. rop.LABEL)
  594. return newloop
  595. # ____________________________________________________________