PageRenderTime 57ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://bitbucket.org/bwesterb/pypy
Python | 5123 lines | 5095 code | 19 blank | 9 comment | 9 complexity | 882b7981b9a491d59c33b30576936cd5 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. import py
  2. from rpython.rlib.objectmodel import instantiate
  3. from rpython.jit.metainterp.optimizeopt.test.test_util import (
  4. LLtypeMixin, BaseTest, FakeMetaInterpStaticData, convert_old_style_to_targets)
  5. from rpython.jit.metainterp.history import TargetToken, JitCellToken
  6. from rpython.jit.metainterp.test.test_compile import FakeLogger
  7. import rpython.jit.metainterp.optimizeopt.optimizer as optimizeopt
  8. import rpython.jit.metainterp.optimizeopt.virtualize as virtualize
  9. from rpython.jit.metainterp.optimize import InvalidLoop
  10. from rpython.jit.metainterp.history import AbstractDescr, ConstInt, BoxInt, get_const_ptr_for_string
  11. from rpython.jit.metainterp import executor, compile, resume, history
  12. from rpython.jit.metainterp.resoperation import rop, opname, ResOperation
  13. from rpython.rlib.rarithmetic import LONG_BIT
  14. def test_store_final_boxes_in_guard():
  15. from rpython.jit.metainterp.compile import ResumeGuardDescr
  16. from rpython.jit.metainterp.resume import tag, TAGBOX
  17. b0 = BoxInt()
  18. b1 = BoxInt()
  19. opt = optimizeopt.Optimizer(FakeMetaInterpStaticData(LLtypeMixin.cpu),
  20. None)
  21. fdescr = ResumeGuardDescr()
  22. op = ResOperation(rop.GUARD_TRUE, ['dummy'], None, descr=fdescr)
  23. # setup rd data
  24. fi0 = resume.FrameInfo(None, "code0", 11)
  25. fdescr.rd_frame_info_list = resume.FrameInfo(fi0, "code1", 33)
  26. snapshot0 = resume.Snapshot(None, [b0])
  27. fdescr.rd_snapshot = resume.Snapshot(snapshot0, [b1])
  28. #
  29. opt.store_final_boxes_in_guard(op)
  30. if op.getfailargs() == [b0, b1]:
  31. assert list(fdescr.rd_numb.nums) == [tag(1, TAGBOX)]
  32. assert list(fdescr.rd_numb.prev.nums) == [tag(0, TAGBOX)]
  33. else:
  34. assert op.getfailargs() == [b1, b0]
  35. assert list(fdescr.rd_numb.nums) == [tag(0, TAGBOX)]
  36. assert list(fdescr.rd_numb.prev.nums) == [tag(1, TAGBOX)]
  37. assert fdescr.rd_virtuals is None
  38. assert fdescr.rd_consts == []
  39. def test_sharing_field_lists_of_virtual():
  40. class FakeOptimizer(object):
  41. class optimizer(object):
  42. class cpu(object):
  43. pass
  44. opt = FakeOptimizer()
  45. virt1 = virtualize.AbstractVirtualStructValue(opt, None)
  46. lst1 = virt1._get_field_descr_list()
  47. assert lst1 == []
  48. lst2 = virt1._get_field_descr_list()
  49. assert lst1 is lst2
  50. virt1.setfield(LLtypeMixin.valuedescr, optimizeopt.OptValue(None))
  51. lst3 = virt1._get_field_descr_list()
  52. assert lst3 == [LLtypeMixin.valuedescr]
  53. lst4 = virt1._get_field_descr_list()
  54. assert lst3 is lst4
  55. virt2 = virtualize.AbstractVirtualStructValue(opt, None)
  56. lst5 = virt2._get_field_descr_list()
  57. assert lst5 is lst1
  58. virt2.setfield(LLtypeMixin.valuedescr, optimizeopt.OptValue(None))
  59. lst6 = virt1._get_field_descr_list()
  60. assert lst6 is lst3
  61. def test_reuse_vinfo():
  62. class FakeVInfo(object):
  63. def set_content(self, fieldnums):
  64. self.fieldnums = fieldnums
  65. def equals(self, fieldnums):
  66. return self.fieldnums == fieldnums
  67. class FakeVirtualValue(virtualize.AbstractVirtualValue):
  68. def _make_virtual(self, *args):
  69. return FakeVInfo()
  70. v1 = FakeVirtualValue(None, None)
  71. vinfo1 = v1.make_virtual_info(None, [1, 2, 4])
  72. vinfo2 = v1.make_virtual_info(None, [1, 2, 4])
  73. assert vinfo1 is vinfo2
  74. vinfo3 = v1.make_virtual_info(None, [1, 2, 6])
  75. assert vinfo3 is not vinfo2
  76. vinfo4 = v1.make_virtual_info(None, [1, 2, 6])
  77. assert vinfo3 is vinfo4
  78. def test_descrlist_dict():
  79. from rpython.jit.metainterp.optimizeopt import util as optimizeutil
  80. h1 = optimizeutil.descrlist_hash([])
  81. h2 = optimizeutil.descrlist_hash([LLtypeMixin.valuedescr])
  82. h3 = optimizeutil.descrlist_hash(
  83. [LLtypeMixin.valuedescr, LLtypeMixin.nextdescr])
  84. assert h1 != h2
  85. assert h2 != h3
  86. assert optimizeutil.descrlist_eq([], [])
  87. assert not optimizeutil.descrlist_eq([], [LLtypeMixin.valuedescr])
  88. assert optimizeutil.descrlist_eq([LLtypeMixin.valuedescr],
  89. [LLtypeMixin.valuedescr])
  90. assert not optimizeutil.descrlist_eq([LLtypeMixin.valuedescr],
  91. [LLtypeMixin.nextdescr])
  92. assert optimizeutil.descrlist_eq([LLtypeMixin.valuedescr, LLtypeMixin.nextdescr],
  93. [LLtypeMixin.valuedescr, LLtypeMixin.nextdescr])
  94. assert not optimizeutil.descrlist_eq([LLtypeMixin.nextdescr, LLtypeMixin.valuedescr],
  95. [LLtypeMixin.valuedescr, LLtypeMixin.nextdescr])
  96. # descrlist_eq should compare by identity of the descrs, not by the result
  97. # of sort_key
  98. class FakeDescr(object):
  99. def sort_key(self):
  100. return 1
  101. assert not optimizeutil.descrlist_eq([FakeDescr()], [FakeDescr()])
  102. # ____________________________________________________________
  103. class BaseTestBasic(BaseTest):
  104. enable_opts = "intbounds:rewrite:virtualize:string:earlyforce:pure:heap"
  105. def optimize_loop(self, ops, optops, call_pure_results=None):
  106. loop = self.parse(ops)
  107. token = JitCellToken()
  108. loop.operations = [ResOperation(rop.LABEL, loop.inputargs, None, descr=TargetToken(token))] + \
  109. loop.operations
  110. if loop.operations[-1].getopnum() == rop.JUMP:
  111. loop.operations[-1].setdescr(token)
  112. expected = convert_old_style_to_targets(self.parse(optops), jump=True)
  113. self._do_optimize_loop(loop, call_pure_results)
  114. print '\n'.join([str(o) for o in loop.operations])
  115. self.assert_equal(loop, expected)
  116. def setup_method(self, meth=None):
  117. class FailDescr(compile.ResumeGuardDescr):
  118. oparse = None
  119. def _oparser_uses_descr_of_guard(self, oparse, fail_args):
  120. # typically called 3 times: once when parsing 'ops',
  121. # once when parsing 'preamble', once when parsing 'expected'.
  122. self.oparse = oparse
  123. self.rd_frame_info_list, self.rd_snapshot = snapshot(fail_args)
  124. def _clone_if_mutable(self):
  125. assert self is fdescr
  126. return fdescr2
  127. def __repr__(self):
  128. if self is fdescr:
  129. return 'fdescr'
  130. if self is fdescr2:
  131. return 'fdescr2'
  132. return compile.ResumeGuardDescr.__repr__(self)
  133. #
  134. def snapshot(fail_args, got=[]):
  135. if not got: # only the first time, i.e. when parsing 'ops'
  136. rd_frame_info_list = resume.FrameInfo(None, "code", 11)
  137. rd_snapshot = resume.Snapshot(None, fail_args)
  138. got.append(rd_frame_info_list)
  139. got.append(rd_snapshot)
  140. return got
  141. #
  142. fdescr = instantiate(FailDescr)
  143. self.namespace['fdescr'] = fdescr
  144. fdescr2 = instantiate(FailDescr)
  145. self.namespace['fdescr2'] = fdescr2
  146. def teardown_method(self, meth):
  147. self.namespace.pop('fdescr', None)
  148. self.namespace.pop('fdescr2', None)
  149. class BaseTestOptimizeBasic(BaseTestBasic):
  150. def test_simple(self):
  151. ops = """
  152. [i]
  153. i0 = int_sub(i, 1)
  154. guard_value(i0, 0) [i0]
  155. jump(i)
  156. """
  157. expected = """
  158. [i]
  159. i0 = int_sub(i, 1)
  160. guard_value(i0, 0) [i0]
  161. jump(1)
  162. """
  163. self.optimize_loop(ops, expected)
  164. def test_constant_propagate(self):
  165. ops = """
  166. []
  167. i0 = int_add(2, 3)
  168. i1 = int_is_true(i0)
  169. guard_true(i1) []
  170. i2 = int_is_zero(i1)
  171. guard_false(i2) []
  172. guard_value(i0, 5) []
  173. jump()
  174. """
  175. expected = """
  176. []
  177. jump()
  178. """
  179. self.optimize_loop(ops, expected)
  180. def test_constant_propagate_ovf(self):
  181. ops = """
  182. []
  183. i0 = int_add_ovf(2, 3)
  184. guard_no_overflow() []
  185. i1 = int_is_true(i0)
  186. guard_true(i1) []
  187. i2 = int_is_zero(i1)
  188. guard_false(i2) []
  189. guard_value(i0, 5) []
  190. jump()
  191. """
  192. expected = """
  193. []
  194. jump()
  195. """
  196. self.optimize_loop(ops, expected)
  197. # ----------
  198. def test_remove_guard_class_1(self):
  199. ops = """
  200. [p0]
  201. guard_class(p0, ConstClass(node_vtable)) []
  202. guard_class(p0, ConstClass(node_vtable)) []
  203. jump(p0)
  204. """
  205. expected = """
  206. [p0]
  207. guard_class(p0, ConstClass(node_vtable)) []
  208. jump(p0)
  209. """
  210. self.optimize_loop(ops, expected)
  211. def test_remove_guard_class_2(self):
  212. ops = """
  213. [i0]
  214. p0 = new_with_vtable(ConstClass(node_vtable))
  215. escape(p0)
  216. guard_class(p0, ConstClass(node_vtable)) []
  217. jump(i0)
  218. """
  219. expected = """
  220. [i0]
  221. p0 = new_with_vtable(ConstClass(node_vtable))
  222. escape(p0)
  223. jump(i0)
  224. """
  225. self.optimize_loop(ops, expected)
  226. def test_remove_guard_class_constant(self):
  227. ops = """
  228. [i0]
  229. p0 = same_as(ConstPtr(myptr))
  230. guard_class(p0, ConstClass(node_vtable)) []
  231. jump(i0)
  232. """
  233. expected = """
  234. [i0]
  235. jump(i0)
  236. """
  237. self.optimize_loop(ops, expected)
  238. def test_constant_boolrewrite_lt(self):
  239. ops = """
  240. [i0]
  241. i1 = int_lt(i0, 0)
  242. guard_true(i1) []
  243. i2 = int_ge(i0, 0)
  244. guard_false(i2) []
  245. jump(i0)
  246. """
  247. expected = """
  248. [i0]
  249. i1 = int_lt(i0, 0)
  250. guard_true(i1) []
  251. jump(i0)
  252. """
  253. self.optimize_loop(ops, expected)
  254. def test_constant_boolrewrite_gt(self):
  255. ops = """
  256. [i0]
  257. i1 = int_gt(i0, 0)
  258. guard_true(i1) []
  259. i2 = int_le(i0, 0)
  260. guard_false(i2) []
  261. jump(i0)
  262. """
  263. expected = """
  264. [i0]
  265. i1 = int_gt(i0, 0)
  266. guard_true(i1) []
  267. jump(i0)
  268. """
  269. self.optimize_loop(ops, expected)
  270. def test_constant_boolrewrite_reflex(self):
  271. ops = """
  272. [i0]
  273. i1 = int_gt(i0, 0)
  274. guard_true(i1) []
  275. i2 = int_lt(0, i0)
  276. guard_true(i2) []
  277. jump(i0)
  278. """
  279. expected = """
  280. [i0]
  281. i1 = int_gt(i0, 0)
  282. guard_true(i1) []
  283. jump(i0)
  284. """
  285. self.optimize_loop(ops, expected)
  286. def test_constant_boolrewrite_reflex_invers(self):
  287. ops = """
  288. [i0]
  289. i1 = int_gt(i0, 0)
  290. guard_true(i1) []
  291. i2 = int_ge(0, i0)
  292. guard_false(i2) []
  293. jump(i0)
  294. """
  295. expected = """
  296. [i0]
  297. i1 = int_gt(i0, 0)
  298. guard_true(i1) []
  299. jump(i0)
  300. """
  301. self.optimize_loop(ops, expected)
  302. def test_remove_consecutive_guard_value_constfold(self):
  303. ops = """
  304. []
  305. i0 = escape()
  306. guard_value(i0, 0) []
  307. i1 = int_add(i0, 1)
  308. guard_value(i1, 1) []
  309. i2 = int_add(i1, 2)
  310. escape(i2)
  311. jump()
  312. """
  313. expected = """
  314. []
  315. i0 = escape()
  316. guard_value(i0, 0) []
  317. escape(3)
  318. jump()
  319. """
  320. self.optimize_loop(ops, expected)
  321. def test_remove_guard_value_if_constant(self):
  322. ops = """
  323. [p1]
  324. guard_value(p1, ConstPtr(myptr)) []
  325. jump(ConstPtr(myptr))
  326. """
  327. expected = """
  328. []
  329. jump()
  330. """
  331. py.test.skip("XXX")
  332. self.optimize_loop(ops, 'Constant(myptr)', expected)
  333. def test_ooisnull_oononnull_1(self):
  334. ops = """
  335. [p0]
  336. guard_class(p0, ConstClass(node_vtable)) []
  337. guard_nonnull(p0) []
  338. jump(p0)
  339. """
  340. expected = """
  341. [p0]
  342. guard_class(p0, ConstClass(node_vtable)) []
  343. jump(p0)
  344. """
  345. self.optimize_loop(ops, expected)
  346. def test_int_is_true_1(self):
  347. ops = """
  348. [i0]
  349. i1 = int_is_true(i0)
  350. guard_true(i1) []
  351. i2 = int_is_true(i0)
  352. guard_true(i2) []
  353. jump(i0)
  354. """
  355. expected = """
  356. [i0]
  357. i1 = int_is_true(i0)
  358. guard_true(i1) []
  359. jump(i0)
  360. """
  361. self.optimize_loop(ops, expected)
  362. def test_int_is_true_is_zero(self):
  363. py.test.skip("XXX implement me")
  364. ops = """
  365. [i0]
  366. i1 = int_is_true(i0)
  367. guard_true(i1) []
  368. i2 = int_is_zero(i0)
  369. guard_false(i2) []
  370. jump(i0)
  371. """
  372. expected = """
  373. [i0]
  374. i1 = int_is_true(i0)
  375. guard_true(i1) []
  376. jump(i0)
  377. """
  378. self.optimize_loop(ops, expected)
  379. def test_int_is_zero_int_is_true(self):
  380. ops = """
  381. [i0]
  382. i1 = int_is_zero(i0)
  383. guard_true(i1) []
  384. i2 = int_is_true(i0)
  385. guard_false(i2) []
  386. jump(i0)
  387. """
  388. expected = """
  389. [i0]
  390. i1 = int_is_zero(i0)
  391. guard_true(i1) []
  392. jump(0)
  393. """
  394. self.optimize_loop(ops, expected)
  395. def test_ooisnull_oononnull_2(self):
  396. ops = """
  397. [p0]
  398. guard_nonnull(p0) []
  399. guard_nonnull(p0) []
  400. jump(p0)
  401. """
  402. expected = """
  403. [p0]
  404. guard_nonnull(p0) []
  405. jump(p0)
  406. """
  407. self.optimize_loop(ops, expected)
  408. def test_ooisnull_on_null_ptr_1(self):
  409. ops = """
  410. []
  411. p0 = escape()
  412. guard_isnull(p0) []
  413. guard_isnull(p0) []
  414. jump()
  415. """
  416. expected = """
  417. []
  418. p0 = escape()
  419. guard_isnull(p0) []
  420. jump()
  421. """
  422. self.optimize_loop(ops, expected)
  423. def test_ooisnull_oononnull_via_virtual(self):
  424. ops = """
  425. [p0]
  426. pv = new_with_vtable(ConstClass(node_vtable))
  427. setfield_gc(pv, p0, descr=valuedescr)
  428. guard_nonnull(p0) []
  429. p1 = getfield_gc(pv, descr=valuedescr)
  430. guard_nonnull(p1) []
  431. jump(p0)
  432. """
  433. expected = """
  434. [p0]
  435. guard_nonnull(p0) []
  436. jump(p0)
  437. """
  438. self.optimize_loop(ops, expected)
  439. def test_oois_1(self):
  440. ops = """
  441. [p0]
  442. guard_class(p0, ConstClass(node_vtable)) []
  443. i0 = instance_ptr_ne(p0, NULL)
  444. guard_true(i0) []
  445. i1 = instance_ptr_eq(p0, NULL)
  446. guard_false(i1) []
  447. i2 = instance_ptr_ne(NULL, p0)
  448. guard_true(i0) []
  449. i3 = instance_ptr_eq(NULL, p0)
  450. guard_false(i1) []
  451. jump(p0)
  452. """
  453. expected = """
  454. [p0]
  455. guard_class(p0, ConstClass(node_vtable)) []
  456. jump(p0)
  457. """
  458. self.optimize_loop(ops, expected)
  459. def test_nonnull_1(self):
  460. ops = """
  461. [p0]
  462. setfield_gc(p0, 5, descr=valuedescr) # forces p0 != NULL
  463. i0 = ptr_ne(p0, NULL)
  464. guard_true(i0) []
  465. i1 = ptr_eq(p0, NULL)
  466. guard_false(i1) []
  467. i2 = ptr_ne(NULL, p0)
  468. guard_true(i0) []
  469. i3 = ptr_eq(NULL, p0)
  470. guard_false(i1) []
  471. guard_nonnull(p0) []
  472. jump(p0)
  473. """
  474. expected = """
  475. [p0]
  476. setfield_gc(p0, 5, descr=valuedescr)
  477. jump(p0)
  478. """
  479. self.optimize_loop(ops, expected)
  480. def test_const_guard_value(self):
  481. ops = """
  482. []
  483. i = int_add(5, 3)
  484. guard_value(i, 8) []
  485. jump()
  486. """
  487. expected = """
  488. []
  489. jump()
  490. """
  491. self.optimize_loop(ops, expected)
  492. def test_constptr_guard_value(self):
  493. ops = """
  494. []
  495. p1 = escape()
  496. guard_value(p1, ConstPtr(myptr)) []
  497. jump()
  498. """
  499. self.optimize_loop(ops, ops)
  500. def test_guard_value_to_guard_true(self):
  501. ops = """
  502. [i]
  503. i1 = int_lt(i, 3)
  504. guard_value(i1, 1) [i]
  505. jump(i)
  506. """
  507. expected = """
  508. [i]
  509. i1 = int_lt(i, 3)
  510. guard_true(i1) [i]
  511. jump(i)
  512. """
  513. self.optimize_loop(ops, expected)
  514. def test_guard_value_to_guard_false(self):
  515. ops = """
  516. [i]
  517. i1 = int_is_true(i)
  518. guard_value(i1, 0) [i]
  519. jump(i)
  520. """
  521. expected = """
  522. [i]
  523. i1 = int_is_true(i)
  524. guard_false(i1) [i]
  525. jump(i)
  526. """
  527. self.optimize_loop(ops, expected)
  528. def test_guard_value_on_nonbool(self):
  529. ops = """
  530. [i]
  531. i1 = int_add(i, 3)
  532. guard_value(i1, 0) [i]
  533. jump(i)
  534. """
  535. expected = """
  536. [i]
  537. i1 = int_add(i, 3)
  538. guard_value(i1, 0) [i]
  539. jump(-3)
  540. """
  541. self.optimize_loop(ops, expected)
  542. def test_int_is_true_of_bool(self):
  543. ops = """
  544. [i0, i1]
  545. i2 = int_gt(i0, i1)
  546. i3 = int_is_true(i2)
  547. i4 = int_is_true(i3)
  548. guard_value(i4, 0) [i0, i1]
  549. jump(i0, i1)
  550. """
  551. expected = """
  552. [i0, i1]
  553. i2 = int_gt(i0, i1)
  554. guard_false(i2) [i0, i1]
  555. jump(i0, i1)
  556. """
  557. self.optimize_loop(ops, expected)
  558. def test_p123_simple(self):
  559. ops = """
  560. [i1, p2, p3]
  561. i3 = getfield_gc(p3, descr=valuedescr)
  562. escape(i3)
  563. p1 = new_with_vtable(ConstClass(node_vtable))
  564. setfield_gc(p1, i1, descr=valuedescr)
  565. jump(i1, p1, p2)
  566. """
  567. # We cannot track virtuals that survive for more than two iterations.
  568. self.optimize_loop(ops, ops)
  569. def test_p123_nested(self):
  570. ops = """
  571. [i1, p2, p3]
  572. i3 = getfield_gc(p3, descr=valuedescr)
  573. escape(i3)
  574. p1 = new_with_vtable(ConstClass(node_vtable))
  575. p1sub = new_with_vtable(ConstClass(node_vtable2))
  576. setfield_gc(p1sub, i1, descr=valuedescr)
  577. setfield_gc(p1, i1, descr=valuedescr)
  578. setfield_gc(p1, p1sub, descr=nextdescr)
  579. jump(i1, p1, p2)
  580. """
  581. # The same as test_p123_simple, but with a virtual containing another
  582. # virtual.
  583. self.optimize_loop(ops, ops)
  584. def test_p123_anti_nested(self):
  585. ops = """
  586. [i1, p2, p3]
  587. p3sub = getfield_gc(p3, descr=nextdescr)
  588. i3 = getfield_gc(p3sub, descr=valuedescr)
  589. escape(i3)
  590. p1 = new_with_vtable(ConstClass(node_vtable))
  591. p2sub = new_with_vtable(ConstClass(node_vtable2))
  592. setfield_gc(p2sub, i1, descr=valuedescr)
  593. setfield_gc(p2, p2sub, descr=nextdescr)
  594. jump(i1, p1, p2)
  595. """
  596. # The same as test_p123_simple, but in the end the "old" p2 contains
  597. # a "young" virtual p2sub. Make sure it is all forced.
  598. self.optimize_loop(ops, ops)
  599. # ----------
  600. def test_keep_guard_no_exception(self):
  601. ops = """
  602. [i1]
  603. i2 = call(i1, descr=nonwritedescr)
  604. guard_no_exception() [i1, i2]
  605. jump(i2)
  606. """
  607. self.optimize_loop(ops, ops)
  608. def test_keep_guard_no_exception_with_call_pure_that_is_not_folded(self):
  609. ops = """
  610. [i1]
  611. i2 = call_pure(123456, i1, descr=nonwritedescr)
  612. guard_no_exception() [i1, i2]
  613. jump(i2)
  614. """
  615. expected = """
  616. [i1]
  617. i2 = call(123456, i1, descr=nonwritedescr)
  618. guard_no_exception() [i1, i2]
  619. jump(i2)
  620. """
  621. self.optimize_loop(ops, expected)
  622. def test_remove_guard_no_exception_with_call_pure_on_constant_args(self):
  623. arg_consts = [ConstInt(i) for i in (123456, 81)]
  624. call_pure_results = {tuple(arg_consts): ConstInt(5)}
  625. ops = """
  626. [i1]
  627. i3 = same_as(81)
  628. i2 = call_pure(123456, i3, descr=nonwritedescr)
  629. guard_no_exception() [i1, i2]
  630. jump(i2)
  631. """
  632. expected = """
  633. [i1]
  634. jump(5)
  635. """
  636. self.optimize_loop(ops, expected, call_pure_results)
  637. def test_remove_guard_no_exception_with_duplicated_call_pure(self):
  638. ops = """
  639. [i1]
  640. i2 = call_pure(123456, i1, descr=nonwritedescr)
  641. guard_no_exception() [i1, i2]
  642. i3 = call_pure(123456, i1, descr=nonwritedescr)
  643. guard_no_exception() [i1, i2, i3]
  644. jump(i3)
  645. """
  646. expected = """
  647. [i1]
  648. i2 = call(123456, i1, descr=nonwritedescr)
  649. guard_no_exception() [i1, i2]
  650. jump(i2)
  651. """
  652. self.optimize_loop(ops, expected)
  653. # ----------
  654. def test_call_loopinvariant(self):
  655. ops = """
  656. [i1]
  657. i2 = call_loopinvariant(1, i1, descr=nonwritedescr)
  658. guard_no_exception() []
  659. guard_value(i2, 1) []
  660. i3 = call_loopinvariant(1, i1, descr=nonwritedescr)
  661. guard_no_exception() []
  662. guard_value(i3, 1) []
  663. i4 = call_loopinvariant(1, i1, descr=nonwritedescr)
  664. guard_no_exception() []
  665. guard_value(i4, 1) []
  666. jump(i1)
  667. """
  668. expected = """
  669. [i1]
  670. i2 = call(1, i1, descr=nonwritedescr)
  671. guard_no_exception() []
  672. guard_value(i2, 1) []
  673. jump(i1)
  674. """
  675. self.optimize_loop(ops, expected)
  676. # ----------
  677. def test_virtual_1(self):
  678. ops = """
  679. [i, p0]
  680. i0 = getfield_gc(p0, descr=valuedescr)
  681. i1 = int_add(i0, i)
  682. setfield_gc(p0, i1, descr=valuedescr)
  683. jump(i, p0)
  684. """
  685. expected = """
  686. [i, i2]
  687. i1 = int_add(i2, i)
  688. jump(i, i1)
  689. """
  690. py.test.skip("XXX")
  691. self.optimize_loop(ops, 'Not, Virtual(node_vtable, valuedescr=Not)',
  692. expected)
  693. def test_virtual_float(self):
  694. ops = """
  695. [f, p0]
  696. f0 = getfield_gc(p0, descr=floatdescr)
  697. f1 = float_add(f0, f)
  698. setfield_gc(p0, f1, descr=floatdescr)
  699. jump(f, p0)
  700. """
  701. expected = """
  702. [f, f2]
  703. f1 = float_add(f2, f)
  704. jump(f, f1)
  705. """
  706. py.test.skip("XXX")
  707. self.optimize_loop(ops, 'Not, Virtual(node_vtable, floatdescr=Not)',
  708. expected)
  709. def test_virtual_2(self):
  710. ops = """
  711. [i, p0]
  712. i0 = getfield_gc(p0, descr=valuedescr)
  713. i1 = int_add(i0, i)
  714. p1 = new_with_vtable(ConstClass(node_vtable))
  715. setfield_gc(p1, i1, descr=valuedescr)
  716. jump(i, p1)
  717. """
  718. expected = """
  719. [i, i2]
  720. i1 = int_add(i2, i)
  721. jump(i, i1)
  722. """
  723. py.test.skip("XXX")
  724. self.optimize_loop(ops, 'Not, Virtual(node_vtable, valuedescr=Not)',
  725. expected)
  726. def test_virtual_oois(self):
  727. ops = """
  728. [p0, p1, p2]
  729. guard_nonnull(p0) []
  730. i3 = ptr_ne(p0, NULL)
  731. guard_true(i3) []
  732. i4 = ptr_eq(p0, NULL)
  733. guard_false(i4) []
  734. i5 = ptr_ne(NULL, p0)
  735. guard_true(i5) []
  736. i6 = ptr_eq(NULL, p0)
  737. guard_false(i6) []
  738. i7 = ptr_ne(p0, p1)
  739. guard_true(i7) []
  740. i8 = ptr_eq(p0, p1)
  741. guard_false(i8) []
  742. i9 = ptr_ne(p0, p2)
  743. guard_true(i9) []
  744. i10 = ptr_eq(p0, p2)
  745. guard_false(i10) []
  746. i11 = ptr_ne(p2, p1)
  747. guard_true(i11) []
  748. i12 = ptr_eq(p2, p1)
  749. guard_false(i12) []
  750. jump(p0, p1, p2)
  751. """
  752. expected = """
  753. [p2]
  754. # all constant-folded :-)
  755. jump(p2)
  756. """
  757. py.test.skip("XXX")
  758. self.optimize_loop(ops, '''Virtual(node_vtable),
  759. Virtual(node_vtable),
  760. Not''',
  761. expected)
  762. #
  763. # to be complete, we also check the no-opt case where most comparisons
  764. # are not removed. The exact set of comparisons removed depends on
  765. # the details of the algorithm...
  766. expected2 = """
  767. [p0, p1, p2]
  768. guard_nonnull(p0) []
  769. i7 = ptr_ne(p0, p1)
  770. guard_true(i7) []
  771. i9 = ptr_ne(p0, p2)
  772. guard_true(i9) []
  773. i11 = ptr_ne(p2, p1)
  774. guard_true(i11) []
  775. jump(p0, p1, p2)
  776. """
  777. self.optimize_loop(ops, expected2)
  778. def test_virtual_default_field(self):
  779. ops = """
  780. [p0]
  781. i0 = getfield_gc(p0, descr=valuedescr)
  782. guard_value(i0, 0) []
  783. p1 = new_with_vtable(ConstClass(node_vtable))
  784. # the field 'value' has its default value of 0
  785. jump(p1)
  786. """
  787. expected = """
  788. [i]
  789. guard_value(i, 0) []
  790. jump(0)
  791. """
  792. # the 'expected' is sub-optimal, but it should be done by another later
  793. # optimization step. See test_find_nodes_default_field() for why.
  794. py.test.skip("XXX")
  795. self.optimize_loop(ops, 'Virtual(node_vtable, valuedescr=Not)',
  796. expected)
  797. def test_virtual_3(self):
  798. ops = """
  799. [i]
  800. p1 = new_with_vtable(ConstClass(node_vtable))
  801. setfield_gc(p1, i, descr=valuedescr)
  802. i0 = getfield_gc(p1, descr=valuedescr)
  803. i1 = int_add(i0, 1)
  804. jump(i1)
  805. """
  806. expected = """
  807. [i]
  808. i1 = int_add(i, 1)
  809. jump(i1)
  810. """
  811. self.optimize_loop(ops, expected)
  812. def test_virtual_4(self):
  813. ops = """
  814. [i0, p0]
  815. guard_class(p0, ConstClass(node_vtable)) []
  816. i1 = getfield_gc(p0, descr=valuedescr)
  817. i2 = int_sub(i1, 1)
  818. i3 = int_add(i0, i1)
  819. p1 = new_with_vtable(ConstClass(node_vtable))
  820. setfield_gc(p1, i2, descr=valuedescr)
  821. jump(i3, p1)
  822. """
  823. expected = """
  824. [i0, i1]
  825. i2 = int_sub(i1, 1)
  826. i3 = int_add(i0, i1)
  827. jump(i3, i2)
  828. """
  829. py.test.skip("XXX")
  830. self.optimize_loop(ops, 'Not, Virtual(node_vtable, valuedescr=Not)',
  831. expected)
  832. def test_virtual_5(self):
  833. ops = """
  834. [i0, p0]
  835. guard_class(p0, ConstClass(node_vtable)) []
  836. i1 = getfield_gc(p0, descr=valuedescr)
  837. i2 = int_sub(i1, 1)
  838. i3 = int_add(i0, i1)
  839. p2 = new_with_vtable(ConstClass(node_vtable2))
  840. setfield_gc(p2, i1, descr=valuedescr)
  841. p1 = new_with_vtable(ConstClass(node_vtable))
  842. setfield_gc(p1, i2, descr=valuedescr)
  843. setfield_gc(p1, p2, descr=nextdescr)
  844. jump(i3, p1)
  845. """
  846. expected = """
  847. [i0, i1, i1bis]
  848. i2 = int_sub(i1, 1)
  849. i3 = int_add(i0, i1)
  850. jump(i3, i2, i1)
  851. """
  852. py.test.skip("XXX")
  853. self.optimize_loop(ops,
  854. '''Not, Virtual(node_vtable,
  855. valuedescr=Not,
  856. nextdescr=Virtual(node_vtable2,
  857. valuedescr=Not))''',
  858. expected)
  859. def test_virtual_constant_isnull(self):
  860. ops = """
  861. [i0]
  862. p0 = new_with_vtable(ConstClass(node_vtable))
  863. setfield_gc(p0, NULL, descr=nextdescr)
  864. p2 = getfield_gc(p0, descr=nextdescr)
  865. i1 = ptr_eq(p2, NULL)
  866. jump(i1)
  867. """
  868. expected = """
  869. [i0]
  870. jump(1)
  871. """
  872. self.optimize_loop(ops, expected)
  873. def test_virtual_constant_isnonnull(self):
  874. ops = """
  875. [i0]
  876. p0 = new_with_vtable(ConstClass(node_vtable))
  877. setfield_gc(p0, ConstPtr(myptr), descr=nextdescr)
  878. p2 = getfield_gc(p0, descr=nextdescr)
  879. i1 = ptr_eq(p2, NULL)
  880. jump(i1)
  881. """
  882. expected = """
  883. [i0]
  884. jump(0)
  885. """
  886. self.optimize_loop(ops, expected)
  887. def test_virtual_array_of_struct(self):
  888. ops = """
  889. [f0, f1, f2, f3]
  890. p0 = new_array(2, descr=complexarraydescr)
  891. setinteriorfield_gc(p0, 0, f1, descr=compleximagdescr)
  892. setinteriorfield_gc(p0, 0, f0, descr=complexrealdescr)
  893. setinteriorfield_gc(p0, 1, f3, descr=compleximagdescr)
  894. setinteriorfield_gc(p0, 1, f2, descr=complexrealdescr)
  895. f4 = getinteriorfield_gc(p0, 0, descr=complexrealdescr)
  896. f5 = getinteriorfield_gc(p0, 1, descr=complexrealdescr)
  897. f6 = float_mul(f4, f5)
  898. f7 = getinteriorfield_gc(p0, 0, descr=compleximagdescr)
  899. f8 = getinteriorfield_gc(p0, 1, descr=compleximagdescr)
  900. f9 = float_mul(f7, f8)
  901. f10 = float_add(f6, f9)
  902. finish(f10)
  903. """
  904. expected = """
  905. [f0, f1, f2, f3]
  906. f4 = float_mul(f0, f2)
  907. f5 = float_mul(f1, f3)
  908. f6 = float_add(f4, f5)
  909. finish(f6)
  910. """
  911. self.optimize_loop(ops, expected)
  912. def test_virtual_array_of_struct_forced(self):
  913. ops = """
  914. [f0, f1]
  915. p0 = new_array(1, descr=complexarraydescr)
  916. setinteriorfield_gc(p0, 0, f0, descr=complexrealdescr)
  917. setinteriorfield_gc(p0, 0, f1, descr=compleximagdescr)
  918. f2 = getinteriorfield_gc(p0, 0, descr=complexrealdescr)
  919. f3 = getinteriorfield_gc(p0, 0, descr=compleximagdescr)
  920. f4 = float_mul(f2, f3)
  921. i0 = escape(f4, p0)
  922. finish(i0)
  923. """
  924. expected = """
  925. [f0, f1]
  926. f2 = float_mul(f0, f1)
  927. p0 = new_array(1, descr=complexarraydescr)
  928. setinteriorfield_gc(p0, 0, f1, descr=compleximagdescr)
  929. setinteriorfield_gc(p0, 0, f0, descr=complexrealdescr)
  930. i0 = escape(f2, p0)
  931. finish(i0)
  932. """
  933. self.optimize_loop(ops, expected)
  934. def test_nonvirtual_1(self):
  935. ops = """
  936. [i]
  937. p1 = new_with_vtable(ConstClass(node_vtable))
  938. setfield_gc(p1, i, descr=valuedescr)
  939. i0 = getfield_gc(p1, descr=valuedescr)
  940. i1 = int_add(i0, 1)
  941. escape(p1)
  942. escape(p1)
  943. jump(i1)
  944. """
  945. expected = """
  946. [i]
  947. i1 = int_add(i, 1)
  948. p1 = new_with_vtable(ConstClass(node_vtable))
  949. setfield_gc(p1, i, descr=valuedescr)
  950. escape(p1)
  951. escape(p1)
  952. jump(i1)
  953. """
  954. self.optimize_loop(ops, expected)
  955. def test_nonvirtual_2(self):
  956. ops = """
  957. [i, p0]
  958. i0 = getfield_gc(p0, descr=valuedescr)
  959. escape(p0)
  960. i1 = int_add(i0, i)
  961. p1 = new_with_vtable(ConstClass(node_vtable))
  962. setfield_gc(p1, i1, descr=valuedescr)
  963. jump(i, p1)
  964. """
  965. expected = ops
  966. self.optimize_loop(ops, expected)
  967. def test_nonvirtual_later(self):
  968. ops = """
  969. [i]
  970. p1 = new_with_vtable(ConstClass(node_vtable))
  971. setfield_gc(p1, i, descr=valuedescr)
  972. i1 = getfield_gc(p1, descr=valuedescr)
  973. escape(p1)
  974. i2 = getfield_gc(p1, descr=valuedescr)
  975. i3 = int_add(i1, i2)
  976. jump(i3)
  977. """
  978. expected = """
  979. [i]
  980. p1 = new_with_vtable(ConstClass(node_vtable))
  981. setfield_gc(p1, i, descr=valuedescr)
  982. escape(p1)
  983. i2 = getfield_gc(p1, descr=valuedescr)
  984. i3 = int_add(i, i2)
  985. jump(i3)
  986. """
  987. self.optimize_loop(ops, expected)
  988. def test_nonvirtual_dont_write_null_fields_on_force(self):
  989. ops = """
  990. [i]
  991. p1 = new_with_vtable(ConstClass(node_vtable))
  992. setfield_gc(p1, i, descr=valuedescr)
  993. i1 = getfield_gc(p1, descr=valuedescr)
  994. setfield_gc(p1, 0, descr=valuedescr)
  995. escape(p1)
  996. i2 = getfield_gc(p1, descr=valuedescr)
  997. jump(i2)
  998. """
  999. expected = """
  1000. [i]
  1001. p1 = new_with_vtable(ConstClass(node_vtable))
  1002. escape(p1)
  1003. i2 = getfield_gc(p1, descr=valuedescr)
  1004. jump(i2)
  1005. """
  1006. self.optimize_loop(ops, expected)
  1007. def test_getfield_gc_pure_1(self):
  1008. ops = """
  1009. [i]
  1010. p1 = new_with_vtable(ConstClass(node_vtable))
  1011. setfield_gc(p1, i, descr=valuedescr)
  1012. i1 = getfield_gc_pure(p1, descr=valuedescr)
  1013. jump(i1)
  1014. """
  1015. expected = """
  1016. [i]
  1017. jump(i)
  1018. """
  1019. self.optimize_loop(ops, expected)
  1020. def test_getfield_gc_pure_2(self):
  1021. ops = """
  1022. [i]
  1023. i1 = getfield_gc_pure(ConstPtr(myptr), descr=valuedescr)
  1024. jump(i1)
  1025. """
  1026. expected = """
  1027. [i]
  1028. jump(5)
  1029. """
  1030. self.node.value = 5
  1031. self.optimize_loop(ops, expected)
  1032. def test_getfield_gc_nonpure_2(self):
  1033. ops = """
  1034. [i]
  1035. i1 = getfield_gc(ConstPtr(myptr), descr=valuedescr)
  1036. jump(i1)
  1037. """
  1038. expected = ops
  1039. self.optimize_loop(ops, expected)
  1040. def test_varray_1(self):
  1041. ops = """
  1042. [i1]
  1043. p1 = new_array(3, descr=arraydescr)
  1044. i3 = arraylen_gc(p1, descr=arraydescr)
  1045. guard_value(i3, 3) []
  1046. setarrayitem_gc(p1, 1, i1, descr=arraydescr)
  1047. setarrayitem_gc(p1, 0, 25, descr=arraydescr)
  1048. i2 = getarrayitem_gc(p1, 1, descr=arraydescr)
  1049. jump(i2)
  1050. """
  1051. expected = """
  1052. [i1]
  1053. jump(i1)
  1054. """
  1055. self.optimize_loop(ops, expected)
  1056. def test_varray_alloc_and_set(self):
  1057. ops = """
  1058. [i1]
  1059. p1 = new_array(2, descr=arraydescr)
  1060. setarrayitem_gc(p1, 0, 25, descr=arraydescr)
  1061. i2 = getarrayitem_gc(p1, 1, descr=arraydescr)
  1062. jump(i2)
  1063. """
  1064. expected = """
  1065. [i1]
  1066. jump(0)
  1067. """
  1068. self.optimize_loop(ops, expected)
  1069. def test_varray_float(self):
  1070. ops = """
  1071. [f1]
  1072. p1 = new_array(3, descr=floatarraydescr)
  1073. i3 = arraylen_gc(p1, descr=floatarraydescr)
  1074. guard_value(i3, 3) []
  1075. setarrayitem_gc(p1, 1, f1, descr=floatarraydescr)
  1076. setarrayitem_gc(p1, 0, 3.5, descr=floatarraydescr)
  1077. f2 = getarrayitem_gc(p1, 1, descr=floatarraydescr)
  1078. jump(f2)
  1079. """
  1080. expected = """
  1081. [f1]
  1082. jump(f1)
  1083. """
  1084. self.optimize_loop(ops, expected)
  1085. def test_array_non_optimized(self):
  1086. ops = """
  1087. [i1, p0]
  1088. setarrayitem_gc(p0, 0, i1, descr=arraydescr)
  1089. guard_nonnull(p0) []
  1090. p1 = new_array(i1, descr=arraydescr)
  1091. jump(i1, p1)
  1092. """
  1093. expected = """
  1094. [i1, p0]
  1095. p1 = new_array(i1, descr=arraydescr)
  1096. setarrayitem_gc(p0, 0, i1, descr=arraydescr)
  1097. jump(i1, p1)
  1098. """
  1099. self.optimize_loop(ops, expected)
  1100. def test_nonvirtual_array_dont_write_null_fields_on_force(self):
  1101. ops = """
  1102. [i1]
  1103. p1 = new_array(5, descr=arraydescr)
  1104. setarrayitem_gc(p1, 0, i1, descr=arraydescr)
  1105. setarrayitem_gc(p1, 1, 0, descr=arraydescr)
  1106. escape(p1)
  1107. jump(i1)
  1108. """
  1109. expected = """
  1110. [i1]
  1111. p1 = new_array(5, descr=arraydescr)
  1112. setarrayitem_gc(p1, 0, i1, descr=arraydescr)
  1113. escape(p1)
  1114. jump(i1)
  1115. """
  1116. self.optimize_loop(ops, expected)
  1117. def test_varray_2(self):
  1118. ops = """
  1119. [i0, p1]
  1120. i1 = getarrayitem_gc(p1, 0, descr=arraydescr)
  1121. i2 = getarrayitem_gc(p1, 1, descr=arraydescr)
  1122. i3 = int_sub(i1, i2)
  1123. guard_value(i3, 15) []
  1124. p2 = new_array(2, descr=arraydescr)
  1125. setarrayitem_gc(p2, 1, i0, descr=arraydescr)
  1126. setarrayitem_gc(p2, 0, 20, descr=arraydescr)
  1127. jump(i0, p2)
  1128. """
  1129. expected = """
  1130. [i0, i1, i2]
  1131. i3 = int_sub(i1, i2)
  1132. guard_value(i3, 15) []
  1133. jump(i0, 20, i0)
  1134. """
  1135. py.test.skip("XXX")
  1136. self.optimize_loop(ops, 'Not, VArray(arraydescr, Not, Not)', expected)
  1137. def test_p123_array(self):
  1138. ops = """
  1139. [i1, p2, p3]
  1140. i3 = getarrayitem_gc(p3, 0, descr=arraydescr)
  1141. escape(i3)
  1142. p1 = new_array(1, descr=arraydescr)
  1143. setarrayitem_gc(p1, 0, i1, descr=arraydescr)
  1144. jump(i1, p1, p2)
  1145. """
  1146. # We cannot track virtuals that survive for more than two iterations.
  1147. self.optimize_loop(ops, ops)
  1148. def test_varray_forced_1(self):
  1149. ops = """
  1150. []
  1151. p2 = new_with_vtable(ConstClass(node_vtable))
  1152. setfield_gc(p2, 3, descr=valuedescr)
  1153. i1 = getfield_gc(p2, descr=valuedescr) # i1 = const 3
  1154. p1 = new_array(i1, descr=arraydescr)
  1155. escape(p1)
  1156. i2 = arraylen_gc(p1)
  1157. escape(i2)
  1158. jump()
  1159. """
  1160. expected = """
  1161. []
  1162. p1 = new_array(3, descr=arraydescr)
  1163. escape(p1)
  1164. i2 = arraylen_gc(p1)
  1165. escape(i2)
  1166. jump()
  1167. """
  1168. self.optimize_loop(ops, expected)
  1169. def test_vstruct_1(self):
  1170. ops = """
  1171. [i1, p2]
  1172. i2 = getfield_gc(p2, descr=adescr)
  1173. escape(i2)
  1174. p3 = new(descr=ssize)
  1175. setfield_gc(p3, i1, descr=adescr)
  1176. jump(i1, p3)
  1177. """
  1178. expected = """
  1179. [i1, i2]
  1180. escape(i2)
  1181. jump(i1, i1)
  1182. """
  1183. py.test.skip("XXX")
  1184. self.optimize_loop(ops, 'Not, VStruct(ssize, adescr=Not)', expected)
  1185. def test_p123_vstruct(self):
  1186. ops = """
  1187. [i1, p2, p3]
  1188. i3 = getfield_gc(p3, descr=adescr)
  1189. escape(i3)
  1190. p1 = new(descr=ssize)
  1191. setfield_gc(p1, i1, descr=adescr)
  1192. jump(i1, p1, p2)
  1193. """
  1194. # We cannot track virtuals that survive for more than two iterations.
  1195. self.optimize_loop(ops, ops)
  1196. def test_duplicate_getfield_1(self):
  1197. ops = """
  1198. [p1, p2]
  1199. i1 = getfield_gc(p1, descr=valuedescr)
  1200. i2 = getfield_gc(p2, descr=valuedescr)
  1201. i3 = getfield_gc(p1, descr=valuedescr)
  1202. i4 = getfield_gc(p2, descr=valuedescr)
  1203. escape(i1)
  1204. escape(i2)
  1205. escape(i3)
  1206. escape(i4)
  1207. jump(p1, p2)
  1208. """
  1209. expected = """
  1210. [p1, p2]
  1211. i1 = getfield_gc(p1, descr=valuedescr)
  1212. i2 = getfield_gc(p2, descr=valuedescr)
  1213. escape(i1)
  1214. escape(i2)
  1215. escape(i1)
  1216. escape(i2)
  1217. jump(p1, p2)
  1218. """
  1219. self.optimize_loop(ops, expected)
  1220. def test_getfield_after_setfield(self):
  1221. ops = """
  1222. [p1, i1]
  1223. setfield_gc(p1, i1, descr=valuedescr)
  1224. i2 = getfield_gc(p1, descr=valuedescr)
  1225. escape(i2)
  1226. jump(p1, i1)
  1227. """
  1228. expected = """
  1229. [p1, i1]
  1230. setfield_gc(p1, i1, descr=valuedescr)
  1231. escape(i1)
  1232. jump(p1, i1)
  1233. """
  1234. self.optimize_loop(ops, expected)
  1235. def test_setfield_of_different_type_does_not_clear(self):
  1236. ops = """
  1237. [p1, p2, i1]
  1238. setfield_gc(p1, i1, descr=valuedescr)
  1239. setfield_gc(p2, p1, descr=nextdescr)
  1240. i2 = getfield_gc(p1, descr=valuedescr)
  1241. escape(i2)
  1242. jump(p1, p2, i1)
  1243. """
  1244. expected = """
  1245. [p1, p2, i1]
  1246. setfield_gc(p1, i1, descr=valuedescr)
  1247. setfield_gc(p2, p1, descr=nextdescr)
  1248. escape(i1)
  1249. jump(p1, p2, i1)
  1250. """
  1251. self.optimize_loop(ops, expected)
  1252. def test_setfield_of_same_type_clears(self):
  1253. ops = """
  1254. [p1, p2, i1, i2]
  1255. setfield_gc(p1, i1, descr=valuedescr)
  1256. setfield_gc(p2, i2, descr=valuedescr)
  1257. i3 = getfield_gc(p1, descr=valuedescr)
  1258. escape(i3)
  1259. jump(p1, p2, i1, i3)
  1260. """
  1261. self.optimize_loop(ops, ops)
  1262. def test_duplicate_getfield_mergepoint_has_no_side_effects(self):
  1263. ops = """
  1264. [p1]
  1265. i1 = getfield_gc(p1, descr=valuedescr)
  1266. debug_merge_point(15, 0)
  1267. i2 = getfield_gc(p1, descr=valuedescr)
  1268. escape(i1)
  1269. escape(i2)
  1270. jump(p1)
  1271. """
  1272. expected = """
  1273. [p1]
  1274. i1 = getfield_gc(p1, descr=valuedescr)
  1275. debug_merge_point(15, 0)
  1276. escape(i1)
  1277. escape(i1)
  1278. jump(p1)
  1279. """
  1280. self.optimize_loop(ops, expected)
  1281. def test_duplicate_getfield_ovf_op_does_not_clear(self):
  1282. ops = """
  1283. [p1]
  1284. i1 = getfield_gc(p1, descr=valuedescr)
  1285. i2 = int_add_ovf(i1, 14)
  1286. guard_no_overflow() []
  1287. i3 = getfield_gc(p1, descr=valuedescr)
  1288. escape(i2)
  1289. escape(i3)
  1290. jump(p1)
  1291. """
  1292. expected = """
  1293. [p1]
  1294. i1 = getfield_gc(p1, descr=valuedescr)
  1295. i2 = int_add_ovf(i1, 14)
  1296. guard_no_overflow() []
  1297. escape(i2)
  1298. escape(i1)
  1299. jump(p1)
  1300. """
  1301. self.optimize_loop(ops, expected)
  1302. def test_duplicate_getfield_setarrayitem_does_not_clear(self):
  1303. ops = """
  1304. [p1, p2]
  1305. i1 = getfield_gc(p1, descr=valuedescr)
  1306. setarrayitem_gc(p2, 0, p1, descr=arraydescr2)
  1307. i3 = getfield_gc(p1, descr=valuedescr)
  1308. escape(i1)
  1309. escape(i3)
  1310. jump(p1, p2)
  1311. """
  1312. expected = """
  1313. [p1, p2]
  1314. i1 = getfield_gc(p1, descr=valuedescr)
  1315. setarrayitem_gc(p2, 0, p1, descr=arraydescr2)
  1316. escape(i1)
  1317. escape(i1)
  1318. jump(p1, p2)
  1319. """
  1320. self.optimize_loop(ops, expected)
  1321. def test_duplicate_getfield_constant(self):
  1322. ops = """
  1323. []
  1324. i1 = getfield_gc(ConstPtr(myptr), descr=valuedescr)
  1325. i2 = getfield_gc(ConstPtr(myptr), descr=valuedescr)
  1326. escape(i1)
  1327. escape(i2)
  1328. jump()
  1329. """
  1330. expected = """
  1331. []
  1332. i1 = getfield_gc(ConstPtr(myptr), descr=valuedescr)
  1333. escape(i1)
  1334. escape(i1)
  1335. jump()
  1336. """
  1337. self.optimize_loop(ops, expected)
  1338. def test_duplicate_getfield_guard_value_const(self):
  1339. ops = """
  1340. [p1]
  1341. guard_value(p1, ConstPtr(myptr)) []
  1342. i1 = getfield_gc(p1, descr=valuedescr)
  1343. i2 = getfield_gc(ConstPtr(myptr), descr=valuedescr)
  1344. escape(i1)
  1345. escape(i2)
  1346. jump(p1)
  1347. """
  1348. expected = """
  1349. []
  1350. i1 = getfield_gc(ConstPtr(myptr), descr=valuedescr)
  1351. escape(i1)
  1352. escape(i1)
  1353. jump()
  1354. """
  1355. py.test.skip("XXX")
  1356. self.optimize_loop(ops, 'Constant(myptr)', expected)
  1357. def test_duplicate_getfield_sideeffects_1(self):
  1358. ops = """
  1359. [p1]
  1360. i1 = getfield_gc(p1, descr=valuedescr)
  1361. escape()
  1362. i2 = getfield_gc(p1, descr=valuedescr)
  1363. escape(i1)
  1364. escape(i2)
  1365. jump(p1)
  1366. """
  1367. self.optimize_loop(ops, ops)
  1368. def test_duplicate_getfield_sideeffects_2(self):
  1369. ops = """
  1370. [p1, i1]
  1371. setfield_gc(p1, i1, descr=valuedescr)
  1372. escape()
  1373. i2 = getfield_gc(p1, descr=valuedescr)
  1374. escape(i2)
  1375. jump(p1, i1)
  1376. """
  1377. self.optimize_loop(ops, ops)
  1378. def test_duplicate_setfield_1(self):
  1379. ops = """
  1380. [p1, i1, i2]
  1381. setfield_gc(p1, i1, descr=valuedescr)
  1382. setfield_gc(p1, i2, descr=valuedescr)
  1383. jump(p1, i1, i2)
  1384. """
  1385. expected = """
  1386. [p1, i1, i2]
  1387. setfield_gc(p1, i2, descr=valuedescr)
  1388. jump(p1, i1, i2)
  1389. """
  1390. self.optimize_loop(ops, expected)
  1391. def test_duplicate_setfield_2(self):
  1392. ops = """
  1393. [p1, i1, i3]
  1394. setfield_gc(p1, i1, descr=valuedescr)
  1395. i2 = getfield_gc(p1, descr=valuedescr)
  1396. setfield_gc(p1, i3, descr=valuedescr)
  1397. escape(i2)
  1398. jump(p1, i1, i3)
  1399. """
  1400. expected = """
  1401. [p1, i1, i3]
  1402. setfield_gc(p1, i3, descr=valuedescr)
  1403. escape(i1)
  1404. jump(p1, i1, i3)
  1405. """
  1406. self.optimize_loop(ops, expected)
  1407. def test_duplicate_setfield_3(self):
  1408. ops = """
  1409. [p1, p2, i1, i3]
  1410. setfield_gc(p1, i1, descr=valuedescr)
  1411. i2 = getfield_gc(p2, descr=valuedescr)
  1412. setfield_gc(p1, i3, descr=valuedescr)
  1413. escape(i2)
  1414. jump(p1, p2, i1, i3)
  1415. """
  1416. # potential aliasing of p1 and p2 means that we cannot kill the
  1417. # the setfield_gc
  1418. self.optimize_loop(ops, ops)
  1419. def test_duplicate_setfield_4(self):
  1420. ops = """
  1421. [p1, i1, i2, p3]
  1422. setfield_gc(p1, i1, descr=valuedescr)
  1423. #
  1424. # some operations on which the above setfield_gc cannot have effect
  1425. i3 = getarrayitem_gc_pure(p3, 1, descr=arraydescr)
  1426. i4 = getarrayitem_gc(p3, i3, descr=arraydescr)
  1427. i5 = int_add(i3, i4)
  1428. setarrayitem_gc(p3, 0, i5, descr=arraydescr)
  1429. setfield_gc(p1, i4, descr=nextdescr)
  1430. #
  1431. setfield_gc(p1, i2, descr=valuedescr)
  1432. jump(p1, i1, i2, p3)
  1433. """
  1434. expected = """
  1435. [p1, i1, i2, p3]
  1436. #
  1437. i3 = getarrayitem_gc_pure(p3, 1, descr=arraydescr)
  1438. i4 = getarrayitem_gc(p3, i3, descr=arraydescr)
  1439. i5 = int_add(i3, i4)
  1440. #
  1441. setfield_gc(p1, i2, descr=valuedescr)
  1442. setarrayitem_gc(p3, 0, i5, descr=arraydescr)
  1443. setfield_gc(p1, i4, descr=nextdescr)
  1444. jump(p1, i1, i2, p3)
  1445. """
  1446. self.optimize_loop(ops, expected)
  1447. def test_duplicate_setfield_5(self):
  1448. ops = """
  1449. [p0, i1]
  1450. p1 = new_with_vtable(ConstClass(node_vtable))
  1451. setfield_gc(p1, i1, descr=valuedescr)
  1452. setfield_gc(p0, p1, descr=nextdescr)
  1453. setfield_raw(i1, i1, descr=valuedescr) # random op with side-effects
  1454. p2 = getfield_gc(p0, descr=nextdescr)
  1455. i2 = getfield_gc(p2, descr=valuedescr)
  1456. setfield_gc(p0, NULL, descr=nextdescr)
  1457. escape(i2)
  1458. jump(p0, i1)
  1459. """
  1460. expected = """
  1461. [p0, i1]
  1462. setfield_raw(i1, i1, descr=valuedescr)
  1463. setfield_gc(p0, NULL, descr=nextdescr)
  1464. escape(i1)
  1465. jump(p0, i1)
  1466. """
  1467. self.optimize_loop(ops, expected)
  1468. def test_duplicate_setfield_sideeffects_1(self):
  1469. ops = """
  1470. [p1, i1, i2]
  1471. setfield_gc(p1, i1, descr=valuedescr)
  1472. escape()
  1473. setfield_gc(p1, i2, descr=valuedescr)
  1474. jump(p1, i1, i2)
  1475. """
  1476. self.optimize_loop(ops, ops)
  1477. def test_duplicate_setfield_residual_guard_1(self):
  1478. ops = """
  1479. [p1, i1, i2, i3]
  1480. setfield_gc(p1, i1, descr=valuedescr)
  1481. guard_true(i3) []
  1482. i4 = int_neg(i2)
  1483. setfield_gc(p1, i2, descr=valuedescr)
  1484. jump(p1, i1, i2, i4)
  1485. """
  1486. self.optimize_loop(ops, ops)
  1487. def test_duplicate_setfield_residual_guard_2(self):
  1488. # the difference with the previous test is that the field value is
  1489. # a virtual, which we try hard to keep virtual
  1490. ops = """
  1491. [p1, i2, i3]
  1492. p2 = new_with_vtable(ConstClass(node_vtable))
  1493. setfield_gc(p1, p2, descr=nextdescr)
  1494. guard_true(i3) []
  1495. i4 = int_neg(i2)
  1496. setfield_gc(p1, NULL, descr=nextdescr)
  1497. jump(p1, i2, i4)
  1498. """
  1499. expected = """
  1500. [p1, i2, i3]
  1501. guard_true(i3) [p1]
  1502. i4 = int_neg(i2)
  1503. setfield_gc(p1, NULL, descr=nextdescr)
  1504. jump(p1, i2, i4)
  1505. """
  1506. self.optimize_loop(ops, expected)
  1507. def test_duplicate_setfield_residual_guard_3(self):
  1508. ops = """
  1509. [p1, i2, i3]
  1510. p2 = new_with_vtable(ConstClass(node_vtable))
  1511. setfield_gc(p2, i2, descr=valuedescr)
  1512. setfield_gc(p1, p2, descr=nextdescr)
  1513. guard_true(i3) []
  1514. i4 = int_neg(i2)
  1515. setfield_gc(p1, NULL, descr=nextdescr)
  1516. jump(p1, i2, i4)
  1517. """
  1518. expected = """
  1519. [p1, i2, i3]
  1520. guard_true(i3) [i2, p1]
  1521. i4 = int_neg(i2)
  1522. setfield_gc(p1, NULL, descr=nextdescr)
  1523. jump(p1, i2, i4)
  1524. """
  1525. self.optimize_loop(ops, expected)
  1526. def test_duplicate_setfield_residual_guard_4(self):
  1527. # test that the setfield_gc does not end up between int_eq and
  1528. # the following guard_true
  1529. ops = """
  1530. [p1, i1, i2, i3]
  1531. setfield_gc(p1, i1, descr=valuedescr)
  1532. i5 = int_eq(i3, 5)
  1533. guard_true(i5) []
  1534. i4 = int_neg(i2)
  1535. setfield_gc(p1, i2, descr=valuedescr)
  1536. jump(p1, i1, i2, i4)
  1537. """
  1538. self.optimize_loop(ops, ops)
  1539. def test_duplicate_setfield_aliasing(self):
  1540. # a case where aliasing issues (and not enough cleverness) mean
  1541. # that we fail to remove any setfield_gc
  1542. ops = """
  1543. [p1, p2, i1, i2, i3]
  1544. setfield_gc(p1, i1, descr=valuedescr)
  1545. setfield_gc(p2, i2, descr=valuedescr)
  1546. setfield_gc(p1, i3, descr=valuedescr)
  1547. jump(p1, p2, i1, i2, i3)
  1548. """
  1549. self.optimize_loop(ops, ops)
  1550. def test_duplicate_setfield_guard_value_const(self):
  1551. ops = """
  1552. [p1, i1, i2]
  1553. guard_value(p1, ConstPtr(myptr)) []
  1554. setfield_gc(p1, i1, descr=valuedescr)
  1555. setfield_gc(ConstPtr(myptr), i2, descr=valuedescr)
  1556. jump(p1, i1, i2)
  1557. """
  1558. expected = """
  1559. [i1, i2]
  1560. setfield_gc(ConstPtr(myptr), i2, descr=valuedescr)
  1561. jump(i1, i2)
  1562. """
  1563. py.test.skip("XXX")
  1564. self.optimize_loop(ops, 'Constant(myptr), Not, Not', expected)
  1565. def test_duplicate_getarrayitem_1(self):
  1566. ops = """
  1567. [p1]
  1568. p2 = getarrayitem_gc(p1, 0, descr=arraydescr2)
  1569. p3 = getarrayitem_gc(p1, 1, descr=arraydescr2)
  1570. p4 = getarrayitem_gc(p1, 0, descr=arraydescr2)
  1571. p5 = getarrayitem_gc(p1, 1, descr=arraydescr2)
  1572. escape(p2)
  1573. escape(p3)
  1574. escape(p4)
  1575. escape(p5)
  1576. jump(p1)
  1577. """
  1578. expected = """
  1579. [p1]
  1580. p2 = getarrayitem_gc(p1, 0, descr=arraydescr2)
  1581. p3 = getarrayitem_gc(p1, 1, descr=arraydescr2)
  1582. escape(p2)
  1583. escape(p3)
  1584. escape(p2)
  1585. escape(p3)
  1586. jump(p1)
  1587. """
  1588. self.optimize_loop(ops, expected)
  1589. def test_duplicate_getarrayitem_after_setarrayitem_1(self):
  1590. ops = """
  1591. [p1, p2]
  1592. setarrayitem_gc(p1, 0, p2, descr=arraydescr2)
  1593. p3 = getarrayitem_gc(p1, 0, descr=arraydescr2)
  1594. escape(p3)
  1595. jump(p1, p3)
  1596. """
  1597. expected = """
  1598. [p1, p2]
  1599. setarrayitem_gc(p1, 0, p2, descr=arraydescr2)
  1600. escape(p2)
  1601. jump(p1, p2)
  1602. """
  1603. self.optimize_loop(ops, expected)
  1604. def test_duplicate_getarrayitem_after_setarrayitem_2(self):
  1605. py.test.skip("setarrayitem with variable index")
  1606. ops = """
  1607. [p1, p2, p3, i1]
  1608. setarrayitem_gc(p1, 0, p2, descr=arraydescr2)
  1609. setarrayitem_gc(p1, i1, p3, descr=arraydesc

Large files files are truncated, but you can click here to view the full file