PageRenderTime 58ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

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

https://bitbucket.org/pypy/pypy/
Python | 9385 lines | 9382 code | 2 blank | 1 comment | 6 complexity | b4c3685e7aa08298a029ba818824dc06 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0

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

  1. import py, sys
  2. from rpython.rlib.objectmodel import instantiate
  3. from rpython.rlib.rarithmetic import intmask
  4. from rpython.rtyper.lltypesystem import lltype
  5. from rpython.jit.metainterp import compile, resume
  6. from rpython.jit.metainterp.history import AbstractDescr, ConstInt, TreeLoop
  7. from rpython.jit.metainterp.optimize import InvalidLoop
  8. from rpython.jit.metainterp.optimizeopt import build_opt_chain
  9. from rpython.jit.metainterp.optimizeopt.test.test_util import (
  10. LLtypeMixin, BaseTest, convert_old_style_to_targets)
  11. from rpython.jit.metainterp.optimizeopt.test.test_optimizebasic import \
  12. FakeMetaInterpStaticData
  13. from rpython.jit.metainterp.resoperation import rop, opname, oparity,\
  14. InputArgInt
  15. def test_build_opt_chain():
  16. def check(chain, expected_names):
  17. names = [opt.__class__.__name__ for opt in chain]
  18. assert names == expected_names
  19. #
  20. metainterp_sd = FakeMetaInterpStaticData(None)
  21. chain, _ = build_opt_chain(metainterp_sd, "")
  22. check(chain, ["OptSimplify"])
  23. #
  24. chain, _ = build_opt_chain(metainterp_sd, "")
  25. check(chain, ["OptSimplify"])
  26. #
  27. chain, _ = build_opt_chain(metainterp_sd, "")
  28. check(chain, ["OptSimplify"])
  29. #
  30. chain, _ = build_opt_chain(metainterp_sd, "heap:intbounds")
  31. check(chain, ["OptIntBounds", "OptHeap", "OptSimplify"])
  32. #
  33. chain, unroll = build_opt_chain(metainterp_sd, "unroll")
  34. check(chain, ["OptSimplify"])
  35. assert unroll
  36. #
  37. chain, _ = build_opt_chain(metainterp_sd, "aaa:bbb")
  38. check(chain, ["OptSimplify"])
  39. # ____________________________________________________________
  40. class BaseTestWithUnroll(BaseTest):
  41. enable_opts = "intbounds:rewrite:virtualize:string:earlyforce:pure:heap:unroll"
  42. def optimize_loop(self, ops, expected, expected_preamble=None,
  43. call_pure_results=None, expected_short=None,
  44. jump_values=None):
  45. loop = self.parse(ops)
  46. if expected != "crash!":
  47. expected = self.parse(expected)
  48. if expected_preamble:
  49. expected_preamble = self.parse(expected_preamble)
  50. if expected_short:
  51. # the short preamble doesn't have fail descrs, they are patched in when it is used
  52. expected_short = self.parse(expected_short, want_fail_descr=False)
  53. info = self.unroll_and_optimize(loop, call_pure_results, jump_values)
  54. preamble = info.preamble
  55. preamble.check_consistency(check_descr=False)
  56. #
  57. print
  58. print "Preamble:"
  59. if preamble.operations:
  60. print '\n'.join([str(o) for o in preamble.operations])
  61. else:
  62. print 'Failed!'
  63. print
  64. print "Loop:"
  65. print '\n'.join([str(o) for o in loop.operations])
  66. print
  67. if expected_short:
  68. print "Short Preamble:"
  69. short = info.short_preamble
  70. print '\n'.join([str(o) for o in short])
  71. print
  72. assert expected != "crash!", "should have raised an exception"
  73. loop.check_consistency(check_descr=False)
  74. self.assert_equal(loop, convert_old_style_to_targets(expected, jump=True))
  75. assert loop.operations[0].getdescr() == loop.operations[-1].getdescr()
  76. if expected_preamble:
  77. self.assert_equal(preamble, convert_old_style_to_targets(expected_preamble, jump=False),
  78. text_right='expected preamble')
  79. if expected_short:
  80. short_preamble = TreeLoop('short preamble')
  81. assert short[0].getopnum() == rop.LABEL
  82. short_preamble.inputargs = short[0].getarglist()
  83. short_preamble.operations = short
  84. self.assert_equal(short_preamble, convert_old_style_to_targets(expected_short, jump=True),
  85. text_right='expected short preamble')
  86. #assert short[-1].getdescr() == loop.operations[0].getdescr()
  87. # XXX not sure what to do about that one
  88. return loop
  89. def raises(self, e, fn, *args):
  90. return py.test.raises(e, fn, *args).value
  91. class OptimizeOptTest(BaseTestWithUnroll):
  92. def test_simple(self):
  93. ops = """
  94. []
  95. f = escape_f()
  96. f0 = float_sub(f, 1.0)
  97. guard_value(f0, 0.0) [f0]
  98. escape_n(f)
  99. jump()
  100. """
  101. self.optimize_loop(ops, ops)
  102. def test_constant_propagate(self):
  103. ops = """
  104. []
  105. i0 = int_add(2, 3)
  106. i1 = int_is_true(i0)
  107. guard_true(i1) []
  108. i2 = int_is_zero(i1)
  109. guard_false(i2) []
  110. guard_value(i0, 5) []
  111. jump()
  112. """
  113. expected = """
  114. []
  115. jump()
  116. """
  117. self.optimize_loop(ops, expected)
  118. def test_constant_propagate_ovf(self):
  119. ops = """
  120. []
  121. i0 = int_add_ovf(2, 3)
  122. guard_no_overflow() []
  123. i1 = int_is_true(i0)
  124. guard_true(i1) []
  125. i2 = int_is_zero(i1)
  126. guard_false(i2) []
  127. guard_value(i0, 5) []
  128. jump()
  129. """
  130. expected = """
  131. []
  132. jump()
  133. """
  134. self.optimize_loop(ops, expected)
  135. def test_constfold_all(self):
  136. from rpython.jit.metainterp.executor import _execute_arglist
  137. import random
  138. for opnum in range(rop.INT_ADD, rop.SAME_AS_I+1):
  139. try:
  140. op = opname[opnum]
  141. except KeyError:
  142. continue
  143. if 'FLOAT' in op:
  144. continue
  145. if 'VEC' in op:
  146. continue
  147. args = []
  148. for _ in range(oparity[opnum]):
  149. args.append(random.randrange(1, 20))
  150. if opnum == rop.INT_SIGNEXT:
  151. # 2nd arg is number of bytes to extend from ---
  152. # must not be too random
  153. args[-1] = random.choice([1, 2] if sys.maxint < 2**32 else
  154. [1, 2, 4])
  155. ops = """
  156. []
  157. i1 = %s(%s)
  158. escape_n(i1)
  159. jump()
  160. """ % (op.lower(), ', '.join(map(str, args)))
  161. argboxes = [InputArgInt(a) for a in args]
  162. expected_value = _execute_arglist(self.cpu, None, opnum, argboxes)
  163. expected = """
  164. []
  165. escape_n(%d)
  166. jump()
  167. """ % expected_value
  168. self.optimize_loop(ops, expected)
  169. def test_reverse_of_cast_1(self):
  170. ops = """
  171. [i0]
  172. p0 = cast_int_to_ptr(i0)
  173. i1 = cast_ptr_to_int(p0)
  174. jump(i1)
  175. """
  176. expected = """
  177. [i0]
  178. jump(i0)
  179. """
  180. short = """
  181. [i2]
  182. p3 = cast_int_to_ptr(i2)
  183. jump()
  184. """
  185. self.optimize_loop(ops, expected, expected_short=short)
  186. def test_reverse_of_cast_2(self):
  187. ops = """
  188. [p0]
  189. i1 = cast_ptr_to_int(p0)
  190. p1 = cast_int_to_ptr(i1)
  191. jump(p1)
  192. """
  193. expected = """
  194. [p0]
  195. jump(p0)
  196. """
  197. self.optimize_loop(ops, expected)
  198. # ----------
  199. def test_remove_guard_class_1(self):
  200. ops = """
  201. [p0]
  202. guard_class(p0, ConstClass(node_vtable)) []
  203. guard_class(p0, ConstClass(node_vtable)) []
  204. jump(p0)
  205. """
  206. preamble = """
  207. [p0]
  208. guard_class(p0, ConstClass(node_vtable)) []
  209. jump(p0)
  210. """
  211. expected = """
  212. [p0]
  213. jump(p0)
  214. """
  215. self.optimize_loop(ops, expected, expected_preamble=preamble)
  216. def test_remove_guard_class_2(self):
  217. ops = """
  218. [i0]
  219. p0 = new_with_vtable(descr=nodesize)
  220. escape_n(p0)
  221. guard_class(p0, ConstClass(node_vtable)) []
  222. jump(i0)
  223. """
  224. expected = """
  225. [i0]
  226. p0 = new_with_vtable(descr=nodesize)
  227. escape_n(p0)
  228. jump(i0)
  229. """
  230. self.optimize_loop(ops, expected)
  231. def test_remove_guard_class_constant(self):
  232. ops = """
  233. [i0]
  234. p0 = same_as_r(ConstPtr(myptr))
  235. guard_class(p0, ConstClass(node_vtable)) []
  236. jump(i0)
  237. """
  238. expected = """
  239. [i0]
  240. jump(i0)
  241. """
  242. self.optimize_loop(ops, expected)
  243. def test_constant_boolrewrite_lt(self):
  244. ops = """
  245. [i0]
  246. i1 = int_lt(i0, 0)
  247. guard_true(i1) []
  248. i2 = int_ge(i0, 0)
  249. guard_false(i2) []
  250. jump(i0)
  251. """
  252. preamble = """
  253. [i0]
  254. i1 = int_lt(i0, 0)
  255. guard_true(i1) []
  256. jump(i0)
  257. """
  258. expected = """
  259. [i0]
  260. jump(i0)
  261. """
  262. self.optimize_loop(ops, expected, expected_preamble=preamble)
  263. def test_constant_boolrewrite_gt(self):
  264. ops = """
  265. [i0]
  266. i1 = int_gt(i0, 0)
  267. guard_true(i1) []
  268. i2 = int_le(i0, 0)
  269. guard_false(i2) []
  270. jump(i0)
  271. """
  272. preamble = """
  273. [i0]
  274. i1 = int_gt(i0, 0)
  275. guard_true(i1) []
  276. jump(i0)
  277. """
  278. expected = """
  279. [i0]
  280. jump(i0)
  281. """
  282. self.optimize_loop(ops, expected, expected_preamble=preamble)
  283. def test_constant_boolrewrite_reflex(self):
  284. ops = """
  285. [i0]
  286. i1 = int_gt(i0, 0)
  287. guard_true(i1) []
  288. i2 = int_lt(0, i0)
  289. guard_true(i2) []
  290. jump(i0)
  291. """
  292. preamble = """
  293. [i0]
  294. i1 = int_gt(i0, 0)
  295. guard_true(i1) []
  296. jump(i0)
  297. """
  298. expected = """
  299. [i0]
  300. jump(i0)
  301. """
  302. self.optimize_loop(ops, expected, expected_preamble=preamble)
  303. def test_constant_boolrewrite_reflex_invers(self):
  304. ops = """
  305. [i0]
  306. i1 = int_gt(i0, 0)
  307. guard_true(i1) []
  308. i2 = int_ge(0, i0)
  309. guard_false(i2) []
  310. jump(i0)
  311. """
  312. preamble = """
  313. [i0]
  314. i1 = int_gt(i0, 0)
  315. guard_true(i1) []
  316. jump(i0)
  317. """
  318. expected = """
  319. [i0]
  320. jump(i0)
  321. """
  322. self.optimize_loop(ops, expected, expected_preamble=preamble)
  323. def test_remove_consecutive_guard_value_constfold(self):
  324. ops = """
  325. []
  326. i0 = escape_i()
  327. guard_value(i0, 0) []
  328. i1 = int_add(i0, 1)
  329. guard_value(i1, 1) []
  330. i2 = int_add(i1, 2)
  331. escape_n(i2)
  332. jump()
  333. """
  334. expected = """
  335. []
  336. i0 = escape_i()
  337. guard_value(i0, 0) []
  338. escape_n(3)
  339. jump()
  340. """
  341. self.optimize_loop(ops, expected)
  342. def test_remove_guard_value_if_constant(self):
  343. ops = """
  344. [p1]
  345. guard_value(p1, ConstPtr(myptr)) []
  346. jump(p1)
  347. """
  348. expected = """
  349. []
  350. jump()
  351. """
  352. self.optimize_loop(ops, expected)
  353. def test_ooisnull_oononnull_1(self):
  354. ops = """
  355. [p0]
  356. guard_class(p0, ConstClass(node_vtable)) []
  357. guard_nonnull(p0) []
  358. jump(p0)
  359. """
  360. preamble = """
  361. [p0]
  362. guard_class(p0, ConstClass(node_vtable)) []
  363. jump(p0)
  364. """
  365. expected = """
  366. [p0]
  367. jump(p0)
  368. """
  369. self.optimize_loop(ops, expected, preamble)
  370. def test_guard_nonnull_class_1(self):
  371. ops = """
  372. [p0]
  373. guard_class(p0, ConstClass(node_vtable)) []
  374. guard_nonnull(p0) []
  375. guard_nonnull_class(p0, ConstClass(node_vtable)) []
  376. jump(p0)
  377. """
  378. preamble = """
  379. [p0]
  380. guard_class(p0, ConstClass(node_vtable)) []
  381. jump(p0)
  382. """
  383. expected = """
  384. [p0]
  385. jump(p0)
  386. """
  387. self.optimize_loop(ops, expected, preamble)
  388. def test_guard_nonnull_class_2(self):
  389. ops = """
  390. [p0]
  391. guard_nonnull_class(p0, ConstClass(node_vtable)) []
  392. jump(p0)
  393. """
  394. preamble = """
  395. [p0]
  396. guard_nonnull_class(p0, ConstClass(node_vtable)) []
  397. jump(p0)
  398. """
  399. expected = """
  400. [p0]
  401. jump(p0)
  402. """
  403. self.optimize_loop(ops, expected, preamble)
  404. def test_int_is_true_1(self):
  405. ops = """
  406. [i0]
  407. i1 = int_is_true(i0)
  408. guard_true(i1) []
  409. i2 = int_is_true(i0)
  410. guard_true(i2) []
  411. jump(i0)
  412. """
  413. preamble = """
  414. [i0]
  415. i1 = int_is_true(i0)
  416. guard_true(i1) []
  417. jump(i0)
  418. """
  419. expected = """
  420. [i0]
  421. jump(i0)
  422. """
  423. short = """
  424. [i0]
  425. i1 = int_is_true(i0)
  426. guard_value(i1, 1) []
  427. jump()
  428. """
  429. self.optimize_loop(ops, expected, preamble, expected_short=short)
  430. def test_bound_int_is_true(self):
  431. ops = """
  432. [i0]
  433. i1 = int_add(i0, 1)
  434. i2 = int_gt(i1, 0)
  435. guard_true(i2) []
  436. i3 = int_is_true(i1)
  437. guard_true(i3) []
  438. jump(i1)
  439. """
  440. expected = """
  441. [i0]
  442. i1 = int_add(i0, 1)
  443. i2 = int_gt(i1, 0)
  444. guard_true(i2) []
  445. jump(i1)
  446. """
  447. self.optimize_loop(ops, expected, expected)
  448. def test_int_is_true_is_zero(self):
  449. py.test.skip("in-progress")
  450. ops = """
  451. [i0]
  452. i1 = int_add(i0, 1)
  453. i2 = int_is_true(i1)
  454. guard_true(i2) []
  455. i3 = int_is_zero(i1)
  456. guard_false(i3) []
  457. jump(i1)
  458. """
  459. expected = """
  460. [i0]
  461. i1 = int_add(i0, 1)
  462. i2 = int_is_true(i1)
  463. guard_true(i2) []
  464. jump(i1)
  465. """
  466. self.optimize_loop(ops, expected)
  467. def test_ooisnull_oononnull_2(self):
  468. ops = """
  469. [p0]
  470. guard_nonnull(p0) []
  471. guard_nonnull(p0) []
  472. jump(p0)
  473. """
  474. preamble = """
  475. [p0]
  476. guard_nonnull(p0) []
  477. jump(p0)
  478. """
  479. expected = """
  480. [p0]
  481. jump(p0)
  482. """
  483. self.optimize_loop(ops, expected, preamble)
  484. def test_ooisnull_on_null_ptr_1(self):
  485. ops = """
  486. []
  487. p0 = escape_r()
  488. guard_isnull(p0) []
  489. guard_isnull(p0) []
  490. jump()
  491. """
  492. expected = """
  493. []
  494. p0 = escape_r()
  495. guard_isnull(p0) []
  496. jump()
  497. """
  498. self.optimize_loop(ops, expected)
  499. def test_ooisnull_oononnull_via_virtual(self):
  500. ops = """
  501. [p0]
  502. pv = new_with_vtable(descr=nodesize)
  503. setfield_gc(pv, p0, descr=valuedescr)
  504. guard_nonnull(p0) []
  505. p1 = getfield_gc_r(pv, descr=valuedescr)
  506. guard_nonnull(p1) []
  507. jump(p0)
  508. """
  509. preamble = """
  510. [p0]
  511. guard_nonnull(p0) []
  512. jump(p0)
  513. """
  514. expected = """
  515. [p0]
  516. jump(p0)
  517. """
  518. self.optimize_loop(ops, expected, preamble)
  519. def test_oois_1(self):
  520. ops = """
  521. [p0]
  522. guard_class(p0, ConstClass(node_vtable)) []
  523. i0 = ptr_ne(p0, NULL)
  524. guard_true(i0) []
  525. i1 = ptr_eq(p0, NULL)
  526. guard_false(i1) []
  527. i2 = ptr_ne(NULL, p0)
  528. guard_true(i0) []
  529. i3 = ptr_eq(NULL, p0)
  530. guard_false(i1) []
  531. jump(p0)
  532. """
  533. preamble = """
  534. [p0]
  535. guard_class(p0, ConstClass(node_vtable)) []
  536. jump(p0)
  537. """
  538. expected = """
  539. [p0]
  540. jump(p0)
  541. """
  542. self.optimize_loop(ops, expected, preamble)
  543. def test_nonnull_1(self):
  544. ops = """
  545. [p0]
  546. setfield_gc(p0, 5, descr=valuedescr) # forces p0 != NULL
  547. i0 = ptr_ne(p0, NULL)
  548. guard_true(i0) []
  549. i1 = ptr_eq(p0, NULL)
  550. guard_false(i1) []
  551. i2 = ptr_ne(NULL, p0)
  552. guard_true(i2) []
  553. i3 = ptr_eq(NULL, p0)
  554. guard_false(i3) []
  555. guard_nonnull(p0) []
  556. jump(p0)
  557. """
  558. preamble = """
  559. [p0]
  560. setfield_gc(p0, 5, descr=valuedescr)
  561. jump(p0)
  562. """
  563. expected = """
  564. [p0]
  565. jump(p0)
  566. """
  567. self.optimize_loop(ops, expected, preamble)
  568. def test_nonnull_2(self):
  569. ops = """
  570. []
  571. p0 = new_array(5, descr=arraydescr) # forces p0 != NULL
  572. i0 = ptr_ne(p0, NULL)
  573. guard_true(i0) []
  574. i1 = ptr_eq(p0, NULL)
  575. guard_false(i1) []
  576. i2 = ptr_ne(NULL, p0)
  577. guard_true(i2) []
  578. i3 = ptr_eq(NULL, p0)
  579. guard_false(i3) []
  580. guard_nonnull(p0) []
  581. escape_r(p0)
  582. jump()
  583. """
  584. expected = """
  585. []
  586. p0 = new_array(5, descr=arraydescr)
  587. escape_r(p0)
  588. jump()
  589. """
  590. self.optimize_loop(ops, expected)
  591. def test_const_guard_value(self):
  592. ops = """
  593. []
  594. i = int_add(5, 3)
  595. guard_value(i, 8) []
  596. jump()
  597. """
  598. expected = """
  599. []
  600. jump()
  601. """
  602. self.optimize_loop(ops, expected)
  603. def test_constptr_guard_value(self):
  604. ops = """
  605. []
  606. p1 = escape_r()
  607. guard_value(p1, ConstPtr(myptr)) []
  608. jump()
  609. """
  610. self.optimize_loop(ops, ops)
  611. def test_guard_value_to_guard_true(self):
  612. ops = """
  613. [i]
  614. i1 = int_lt(i, 3)
  615. guard_value(i1, 1) [i]
  616. jump(i)
  617. """
  618. preamble = """
  619. [i]
  620. i1 = int_lt(i, 3)
  621. guard_true(i1) [i]
  622. jump(i)
  623. """
  624. expected = """
  625. [i]
  626. jump(i)
  627. """
  628. self.optimize_loop(ops, expected, preamble)
  629. def test_guard_value_to_guard_false(self):
  630. ops = """
  631. [i]
  632. i1 = int_is_true(i)
  633. guard_value(i1, 0) [i]
  634. jump(i)
  635. """
  636. preamble = """
  637. [i]
  638. i1 = int_is_true(i)
  639. guard_false(i1) [i]
  640. jump()
  641. """
  642. expected = """
  643. []
  644. jump()
  645. """
  646. self.optimize_loop(ops, expected, preamble)
  647. def test_guard_value_on_nonbool(self):
  648. ops = """
  649. [i]
  650. i1 = int_add(i, 3)
  651. guard_value(i1, 0) [i]
  652. jump(i)
  653. """
  654. preamble = """
  655. [i]
  656. i1 = int_add(i, 3)
  657. guard_value(i1, 0) [i]
  658. jump()
  659. """
  660. expected = """
  661. []
  662. jump()
  663. """
  664. self.optimize_loop(ops, expected, preamble)
  665. def test_int_is_true_of_bool(self):
  666. ops = """
  667. [i0, i1]
  668. i2 = int_gt(i0, i1)
  669. i3 = int_is_true(i2)
  670. i4 = int_is_true(i3)
  671. guard_value(i4, 0) [i0, i1]
  672. jump(i0, i1)
  673. """
  674. preamble = """
  675. [i0, i1]
  676. i2 = int_gt(i0, i1)
  677. guard_false(i2) [i0, i1]
  678. jump(i0, i1)
  679. """
  680. expected = """
  681. [i0, i1]
  682. jump(i0, i1)
  683. """
  684. self.optimize_loop(ops, expected, preamble)
  685. def test_compare_with_itself(self):
  686. ops = """
  687. []
  688. i0 = escape_i()
  689. i1 = int_lt(i0, i0)
  690. guard_false(i1) []
  691. i2 = int_le(i0, i0)
  692. guard_true(i2) []
  693. i3 = int_eq(i0, i0)
  694. guard_true(i3) []
  695. i4 = int_ne(i0, i0)
  696. guard_false(i4) []
  697. i5 = int_gt(i0, i0)
  698. guard_false(i5) []
  699. i6 = int_ge(i0, i0)
  700. guard_true(i6) []
  701. jump()
  702. """
  703. expected = """
  704. []
  705. i0 = escape_i()
  706. jump()
  707. """
  708. self.optimize_loop(ops, expected)
  709. def test_compare_with_itself_uint(self):
  710. py.test.skip("implement me")
  711. ops = """
  712. []
  713. i0 = escape_i()
  714. i7 = uint_lt(i0, i0)
  715. guard_false(i7) []
  716. i8 = uint_le(i0, i0)
  717. guard_true(i8) []
  718. i9 = uint_gt(i0, i0)
  719. guard_false(i9) []
  720. i10 = uint_ge(i0, i0)
  721. guard_true(i10) []
  722. jump()
  723. """
  724. expected = """
  725. []
  726. i0 = escape_i()
  727. jump()
  728. """
  729. self.optimize_loop(ops, expected)
  730. def test_p123_simple(self):
  731. ops = """
  732. [i1, p2, p3]
  733. i3 = getfield_gc_i(p3, descr=valuedescr)
  734. escape_n(i3)
  735. p1 = new_with_vtable(descr=nodesize)
  736. setfield_gc(p1, i1, descr=valuedescr)
  737. jump(i1, p1, p2)
  738. """
  739. preamble = """
  740. [i1, p2, p3]
  741. i3 = getfield_gc_i(p3, descr=valuedescr)
  742. escape_n(i3)
  743. jump(i1, p2)
  744. """
  745. expected = """
  746. [i1, p2]
  747. i3 = getfield_gc_i(p2, descr=valuedescr)
  748. escape_n(i3)
  749. p3 = new_with_vtable(descr=nodesize)
  750. setfield_gc(p3, i1, descr=valuedescr)
  751. jump(i1, p3)
  752. """
  753. # We cannot track virtuals that survive for more than two iterations.
  754. self.optimize_loop(ops, expected, preamble,
  755. jump_values=[None, self.nodefulladdr, None])
  756. def test_p123_nested(self):
  757. ops = """
  758. [i1, p2, p3]
  759. i3 = getfield_gc_i(p3, descr=valuedescr)
  760. escape_n(i3)
  761. p1 = new_with_vtable(descr=nodesize)
  762. setfield_gc(p1, i1, descr=valuedescr)
  763. p1sub = new_with_vtable(descr=nodesize2)
  764. setfield_gc(p1sub, i1, descr=valuedescr)
  765. setfield_gc(p1, p1sub, descr=nextdescr)
  766. jump(i1, p1, p2)
  767. """
  768. # The same as test_p123_simple, but with a virtual containing another
  769. # virtual.
  770. preamble = """
  771. [i1, p2, p3]
  772. i3 = getfield_gc_i(p3, descr=valuedescr)
  773. escape_n(i3)
  774. jump(i1, p2)
  775. """
  776. expected = """
  777. [i1, p2]
  778. i3 = getfield_gc_i(p2, descr=valuedescr)
  779. escape_n(i3)
  780. p4 = new_with_vtable(descr=nodesize)
  781. p1sub = new_with_vtable(descr=nodesize2)
  782. setfield_gc(p1sub, i1, descr=valuedescr)
  783. setfield_gc(p4, i1, descr=valuedescr)
  784. setfield_gc(p4, p1sub, descr=nextdescr)
  785. jump(i1, p4)
  786. """
  787. self.optimize_loop(ops, expected, preamble,
  788. jump_values=[None, self.nodefulladdr, self.nodefulladdr])
  789. def test_p123_anti_nested(self):
  790. ops = """
  791. [i1, p2, p3]
  792. p3sub = getfield_gc_r(p3, descr=nextdescr)
  793. i3 = getfield_gc_i(p3sub, descr=valuedescr)
  794. escape_n(i3)
  795. p1 = new_with_vtable(descr=nodesize)
  796. p2sub = new_with_vtable(descr=nodesize2)
  797. setfield_gc(p2sub, i1, descr=valuedescr)
  798. setfield_gc(p2, p2sub, descr=nextdescr)
  799. jump(i1, p1, p2)
  800. """
  801. # The same as test_p123_simple, but in the end the "old" p2 contains
  802. # a "young" virtual p2sub. Make sure it is all forced.
  803. preamble = """
  804. [i1, p2, p3]
  805. p3sub = getfield_gc_r(p3, descr=nextdescr)
  806. i3 = getfield_gc_i(p3sub, descr=valuedescr)
  807. escape_n(i3)
  808. p2sub = new_with_vtable(descr=nodesize2)
  809. setfield_gc(p2sub, i1, descr=valuedescr)
  810. setfield_gc(p2, p2sub, descr=nextdescr)
  811. jump(i1, p2, p2sub)
  812. """
  813. expected = """
  814. [i1, p2, p10]
  815. i3 = getfield_gc_i(p10, descr=valuedescr)
  816. escape_n(i3)
  817. p1 = new_with_vtable(descr=nodesize)
  818. p3sub = new_with_vtable(descr=nodesize2)
  819. setfield_gc(p3sub, i1, descr=valuedescr)
  820. setfield_gc(p1, p3sub, descr=nextdescr)
  821. jump(i1, p1, p3sub)
  822. """
  823. self.optimize_loop(ops, expected, preamble,
  824. jump_values=[None, self.nodefulladdr, self.nodefulladdr])
  825. def test_dont_delay_setfields(self):
  826. ops = """
  827. [p1, p2]
  828. i1 = getfield_gc_i(p1, descr=valuedescr)
  829. i2 = int_sub(i1, 1)
  830. i2b = int_is_true(i2)
  831. guard_true(i2b) []
  832. setfield_gc(p2, i2, descr=valuedescr)
  833. p3 = new_with_vtable(descr=nodesize)
  834. jump(p2, p3)
  835. """
  836. short = """
  837. [p1, p2]
  838. guard_nonnull(p1) []
  839. guard_is_object(p1) []
  840. guard_subclass(p1, ConstClass(node_vtable)) []
  841. i1 = getfield_gc_i(p1, descr=valuedescr)
  842. jump(i1)
  843. """
  844. preamble = """
  845. [p1, p2]
  846. i1 = getfield_gc_i(p1, descr=valuedescr)
  847. i2 = int_sub(i1, 1)
  848. i2b = int_is_true(i2)
  849. guard_true(i2b) []
  850. setfield_gc(p2, i2, descr=valuedescr)
  851. jump(p2, i2)
  852. """
  853. expected = """
  854. [p2, i1]
  855. i2 = int_sub(i1, 1)
  856. i2b = int_is_true(i2)
  857. guard_true(i2b) []
  858. p3 = new_with_vtable(descr=nodesize)
  859. setfield_gc(p3, i2, descr=valuedescr)
  860. jump(p3, i2)
  861. """
  862. self.optimize_loop(ops, expected, preamble, expected_short=short,
  863. jump_values=[None, self.nodefulladdr])
  864. # ----------
  865. def test_fold_guard_no_exception(self):
  866. ops = """
  867. [i]
  868. guard_no_exception() []
  869. i1 = int_add(i, 3)
  870. i2 = call_i(i1, descr=nonwritedescr)
  871. guard_no_exception() [i1, i2]
  872. i3 = call_i(i2, descr=nonwritedescr)
  873. jump(i1) # the exception is considered lost when we loop back
  874. """
  875. preamble = """
  876. [i]
  877. guard_no_exception() [] # occurs at the start of bridges, so keep it
  878. i1 = int_add(i, 3)
  879. i2 = call_i(i1, descr=nonwritedescr)
  880. guard_no_exception() [i1, i2]
  881. i3 = call_i(i2, descr=nonwritedescr)
  882. jump(i1)
  883. """
  884. expected = """
  885. [i]
  886. guard_no_exception() [] # occurs at the start of bridges, so keep it
  887. i1 = int_add(i, 3)
  888. i2 = call_i(i1, descr=nonwritedescr)
  889. guard_no_exception() [i1, i2]
  890. i3 = call_i(i2, descr=nonwritedescr)
  891. jump(i1)
  892. """
  893. self.optimize_loop(ops, expected, preamble)
  894. def test_bug_guard_no_exception(self):
  895. ops = """
  896. []
  897. i0 = call_i(123, descr=nonwritedescr)
  898. p0 = call_r(0, "xy", descr=s2u_descr) # string -> unicode
  899. guard_no_exception() []
  900. escape_n(p0)
  901. jump()
  902. """
  903. expected = """
  904. []
  905. i0 = call_i(123, descr=nonwritedescr)
  906. escape_n(u"xy")
  907. jump()
  908. """
  909. self.optimize_loop(ops, expected)
  910. # ----------
  911. def test_call_loopinvariant(self):
  912. ops = """
  913. [i1]
  914. i2 = call_loopinvariant_i(1, i1, descr=nonwritedescr)
  915. guard_no_exception() []
  916. guard_value(i2, 1) []
  917. i3 = call_loopinvariant_i(1, i1, descr=nonwritedescr)
  918. guard_no_exception() []
  919. guard_value(i3, 1) []
  920. i4 = call_loopinvariant_i(1, i1, descr=nonwritedescr)
  921. guard_no_exception() []
  922. guard_value(i4, 1) []
  923. jump(i1)
  924. """
  925. preamble = """
  926. [i1]
  927. i2 = call_i(1, i1, descr=nonwritedescr)
  928. guard_no_exception() []
  929. guard_value(i2, 1) []
  930. jump(i1)
  931. """
  932. expected = """
  933. [i1]
  934. jump(i1)
  935. """
  936. self.optimize_loop(ops, expected, preamble)
  937. # ----------
  938. def test_virtual_1(self):
  939. ops = """
  940. [i, p0]
  941. i0 = getfield_gc_i(p0, descr=valuedescr)
  942. i1 = int_add(i0, i)
  943. p1 = new_with_vtable(descr=nodesize)
  944. setfield_gc(p1, i1, descr=valuedescr)
  945. jump(i, p1)
  946. """
  947. preamble = """
  948. [i, p0]
  949. i0 = getfield_gc_i(p0, descr=valuedescr)
  950. i1 = int_add(i0, i)
  951. jump(i, i1)
  952. """
  953. expected = """
  954. [i, i2]
  955. i1 = int_add(i2, i)
  956. jump(i, i1)
  957. """
  958. self.optimize_loop(ops, expected, preamble,
  959. jump_values=[None, self.nodefulladdr])
  960. def test_virtual_float(self):
  961. ops = """
  962. [f, p0]
  963. f0 = getfield_gc_f(p0, descr=floatdescr)
  964. f1 = float_add(f0, f)
  965. p1 = new_with_vtable(descr=nodesize)
  966. setfield_gc(p1, f1, descr=floatdescr)
  967. jump(f, p1)
  968. """
  969. preamble = """
  970. [f, p0]
  971. f2 = getfield_gc_f(p0, descr=floatdescr)
  972. f1 = float_add(f2, f)
  973. jump(f, f1)
  974. """
  975. expected = """
  976. [f, f2]
  977. f1 = float_add(f2, f)
  978. jump(f, f1)
  979. """
  980. self.optimize_loop(ops, expected, preamble)
  981. def test_virtual_oois(self):
  982. ops = """
  983. [p0, p1, p2]
  984. guard_nonnull(p0) []
  985. i3 = ptr_ne(p0, NULL)
  986. guard_true(i3) []
  987. i4 = ptr_eq(p0, NULL)
  988. guard_false(i4) []
  989. i5 = ptr_ne(NULL, p0)
  990. guard_true(i5) []
  991. i6 = ptr_eq(NULL, p0)
  992. guard_false(i6) []
  993. i7 = ptr_ne(p0, p1)
  994. guard_true(i7) []
  995. i8 = ptr_eq(p0, p1)
  996. guard_false(i8) []
  997. i9 = ptr_ne(p0, p2)
  998. guard_true(i9) []
  999. i10 = ptr_eq(p0, p2)
  1000. guard_false(i10) []
  1001. i11 = ptr_ne(p2, p1)
  1002. guard_true(i11) []
  1003. i12 = ptr_eq(p2, p1)
  1004. guard_false(i12) []
  1005. jump(p0, p1, p2)
  1006. """
  1007. expected = """
  1008. [p0, p1, p2]
  1009. # all constant-folded :-)
  1010. jump(p0, p1, p2)
  1011. """
  1012. #
  1013. # to be complete, we also check the no-opt case where most comparisons
  1014. # are not removed. The exact set of comparisons removed depends on
  1015. # the details of the algorithm...
  1016. expected2 = """
  1017. [p0, p1, p2]
  1018. guard_nonnull(p0) []
  1019. i7 = ptr_ne(p0, p1)
  1020. guard_true(i7) []
  1021. i9 = ptr_ne(p0, p2)
  1022. guard_true(i9) []
  1023. i11 = ptr_ne(p2, p1)
  1024. guard_true(i11) []
  1025. jump(p0, p1, p2)
  1026. """
  1027. self.optimize_loop(ops, expected, expected2)
  1028. def test_virtual_default_field(self):
  1029. ops = """
  1030. [p0]
  1031. i0 = getfield_gc_i(p0, descr=valuedescr)
  1032. guard_value(i0, 0) []
  1033. p1 = new_with_vtable(descr=nodesize)
  1034. # the field 'value' has its default value of 0
  1035. jump(p1)
  1036. """
  1037. preamble = """
  1038. [p0]
  1039. i0 = getfield_gc_i(p0, descr=valuedescr)
  1040. guard_value(i0, 0) []
  1041. jump()
  1042. """
  1043. expected = """
  1044. []
  1045. jump()
  1046. """
  1047. self.optimize_loop(ops, expected, preamble)
  1048. def test_virtual_3(self):
  1049. ops = """
  1050. [i]
  1051. p1 = new_with_vtable(descr=nodesize)
  1052. setfield_gc(p1, i, descr=valuedescr)
  1053. i0 = getfield_gc_i(p1, descr=valuedescr)
  1054. i1 = int_add(i0, 1)
  1055. jump(i1)
  1056. """
  1057. expected = """
  1058. [i]
  1059. i1 = int_add(i, 1)
  1060. jump(i1)
  1061. """
  1062. self.optimize_loop(ops, expected)
  1063. def test_virtual_4(self):
  1064. ops = """
  1065. [i0, p0]
  1066. guard_class(p0, ConstClass(node_vtable)) []
  1067. i1 = getfield_gc_i(p0, descr=valuedescr)
  1068. i2 = int_sub(i1, 1)
  1069. i3 = int_add(i0, i1)
  1070. p1 = new_with_vtable(descr=nodesize)
  1071. setfield_gc(p1, i2, descr=valuedescr)
  1072. jump(i3, p1)
  1073. """
  1074. preamble = """
  1075. [i0, p0]
  1076. guard_class(p0, ConstClass(node_vtable)) []
  1077. i1 = getfield_gc_i(p0, descr=valuedescr)
  1078. i2 = int_sub(i1, 1)
  1079. i3 = int_add(i0, i1)
  1080. jump(i3, i2)
  1081. """
  1082. expected = """
  1083. [i0, i1]
  1084. i2 = int_sub(i1, 1)
  1085. i3 = int_add(i0, i1)
  1086. jump(i3, i2)
  1087. """
  1088. self.optimize_loop(ops, expected, preamble)
  1089. def test_virtual_5(self):
  1090. ops = """
  1091. [i0, p0]
  1092. guard_class(p0, ConstClass(node_vtable)) []
  1093. i1 = getfield_gc_i(p0, descr=valuedescr)
  1094. i2 = int_sub(i1, 1)
  1095. i3 = int_add(i0, i1)
  1096. p2 = new_with_vtable(descr=nodesize2)
  1097. setfield_gc(p2, i1, descr=valuedescr)
  1098. p1 = new_with_vtable(descr=nodesize)
  1099. setfield_gc(p1, i2, descr=valuedescr)
  1100. setfield_gc(p1, p2, descr=nextdescr)
  1101. jump(i3, p1)
  1102. """
  1103. preamble = """
  1104. [i0, p0]
  1105. guard_class(p0, ConstClass(node_vtable)) []
  1106. i1 = getfield_gc_i(p0, descr=valuedescr)
  1107. i2 = int_sub(i1, 1)
  1108. i3 = int_add(i0, i1)
  1109. jump(i3, i2, i1)
  1110. """
  1111. expected = """
  1112. [i0, i1bis, i1]
  1113. i2 = int_sub(i1bis, 1)
  1114. i3 = int_add(i0, i1bis)
  1115. jump(i3, i2, i1bis)
  1116. """
  1117. self.optimize_loop(ops, expected, preamble)
  1118. def test_virtual_recursive(self):
  1119. ops = """
  1120. [p0]
  1121. p41 = getfield_gc_r(p0, descr=nextdescr)
  1122. i0 = getfield_gc_i(p41, descr=valuedescr)
  1123. p1 = new_with_vtable(descr=nodesize2)
  1124. p2 = new_with_vtable(descr=nodesize2)
  1125. setfield_gc(p2, p1, descr=nextdescr)
  1126. setfield_gc(p1, p2, descr=nextdescr)
  1127. i1 = int_add(i0, 1)
  1128. setfield_gc(p2, i1, descr=valuedescr)
  1129. jump(p1)
  1130. """
  1131. preamble = """
  1132. [p0]
  1133. p41 = getfield_gc_r(p0, descr=nextdescr)
  1134. i0 = getfield_gc_i(p41, descr=valuedescr)
  1135. i3 = int_add(i0, 1)
  1136. jump(i3)
  1137. """
  1138. expected = """
  1139. [i0]
  1140. i1 = int_add(i0, 1)
  1141. jump(i1)
  1142. """
  1143. self.optimize_loop(ops, expected, preamble)
  1144. def test_virtual_recursive_forced(self):
  1145. ops = """
  1146. [p0]
  1147. p41 = getfield_gc_r(p0, descr=nextdescr)
  1148. i0 = getfield_gc_i(p41, descr=valuedescr)
  1149. p1 = new_with_vtable(descr=nodesize2)
  1150. p2 = new_with_vtable(descr=nodesize2)
  1151. setfield_gc(p2, p1, descr=nextdescr)
  1152. setfield_gc(p1, p2, descr=nextdescr)
  1153. i1 = int_add(i0, 1)
  1154. setfield_gc(p2, i1, descr=valuedescr)
  1155. setfield_gc(p0, p1, descr=nextdescr)
  1156. jump(p1)
  1157. """
  1158. preamble = """
  1159. [p0]
  1160. p41 = getfield_gc_r(p0, descr=nextdescr)
  1161. i0 = getfield_gc_i(p41, descr=valuedescr)
  1162. i1 = int_add(i0, 1)
  1163. p1 = new_with_vtable(descr=nodesize2)
  1164. p2 = new_with_vtable(descr=nodesize2)
  1165. setfield_gc(p2, i1, descr=valuedescr)
  1166. setfield_gc(p2, p1, descr=nextdescr)
  1167. setfield_gc(p1, p2, descr=nextdescr)
  1168. setfield_gc(p0, p1, descr=nextdescr)
  1169. jump(p1)
  1170. """
  1171. loop = """
  1172. [p0]
  1173. p41 = getfield_gc_r(p0, descr=nextdescr)
  1174. i0 = getfield_gc_i(p41, descr=valuedescr)
  1175. i1 = int_add(i0, 1)
  1176. p1 = new_with_vtable(descr=nodesize2)
  1177. p2 = new_with_vtable(descr=nodesize2)
  1178. setfield_gc(p2, i1, descr=valuedescr)
  1179. setfield_gc(p2, p1, descr=nextdescr)
  1180. setfield_gc(p0, p1, descr=nextdescr)
  1181. setfield_gc(p1, p2, descr=nextdescr)
  1182. jump(p1)
  1183. """
  1184. self.optimize_loop(ops, loop, preamble)
  1185. def test_virtual_constant_isnull(self):
  1186. ops = """
  1187. [i0]
  1188. p0 = new_with_vtable(descr=nodesize)
  1189. setfield_gc(p0, NULL, descr=nextdescr)
  1190. p2 = getfield_gc_r(p0, descr=nextdescr)
  1191. i1 = ptr_eq(p2, NULL)
  1192. jump(i1)
  1193. """
  1194. preamble = """
  1195. [i0]
  1196. jump()
  1197. """
  1198. expected = """
  1199. []
  1200. jump()
  1201. """
  1202. self.optimize_loop(ops, expected, preamble)
  1203. def test_virtual_constant_isnonnull(self):
  1204. ops = """
  1205. [i0]
  1206. p0 = new_with_vtable(descr=nodesize)
  1207. setfield_gc(p0, ConstPtr(myptr), descr=nextdescr)
  1208. p2 = getfield_gc_r(p0, descr=nextdescr)
  1209. i1 = ptr_eq(p2, NULL)
  1210. jump(i1)
  1211. """
  1212. expected = """
  1213. []
  1214. jump()
  1215. """
  1216. self.optimize_loop(ops, expected)
  1217. def test_virtual_field_forced_by_lazy_setfield(self):
  1218. ops = """
  1219. [i0, p1, p3]
  1220. i28 = int_add(i0, 1)
  1221. p30 = new_with_vtable(descr=nodesize)
  1222. setfield_gc(p30, i28, descr=valuedescr)
  1223. setfield_gc(p3, p30, descr=nextdescr)
  1224. p45 = getfield_gc_r(p3, descr=nextdescr)
  1225. i29 = int_add(i28, 1)
  1226. jump(i29, p45, p3)
  1227. """
  1228. preamble = """
  1229. [i0, p1, p3]
  1230. i28 = int_add(i0, 1)
  1231. i29 = int_add(i28, 1)
  1232. p30 = new_with_vtable(descr=nodesize)
  1233. setfield_gc(p30, i28, descr=valuedescr)
  1234. setfield_gc(p3, p30, descr=nextdescr)
  1235. #p46 = same_as(p30) # This same_as should be killed by backend
  1236. jump(i29, p30, p3)
  1237. """
  1238. expected = """
  1239. [i0, p1, p3]
  1240. i28 = int_add(i0, 1)
  1241. i29 = int_add(i28, 1)
  1242. p30 = new_with_vtable(descr=nodesize)
  1243. setfield_gc(p30, i28, descr=valuedescr)
  1244. setfield_gc(p3, p30, descr=nextdescr)
  1245. jump(i29, p30, p3)
  1246. """
  1247. self.optimize_loop(ops, expected, preamble)
  1248. def test_nonvirtual_1(self):
  1249. ops = """
  1250. [i]
  1251. p1 = new_with_vtable(descr=nodesize)
  1252. setfield_gc(p1, i, descr=valuedescr)
  1253. i0 = getfield_gc_i(p1, descr=valuedescr)
  1254. i1 = int_add(i0, 1)
  1255. escape_n(p1)
  1256. escape_n(p1)
  1257. jump(i1)
  1258. """
  1259. expected = """
  1260. [i]
  1261. i1 = int_add(i, 1)
  1262. p1 = new_with_vtable(descr=nodesize)
  1263. setfield_gc(p1, i, descr=valuedescr)
  1264. escape_n(p1)
  1265. escape_n(p1)
  1266. jump(i1)
  1267. """
  1268. self.optimize_loop(ops, expected)
  1269. def test_nonvirtual_2(self):
  1270. ops = """
  1271. [i, p0]
  1272. i0 = getfield_gc_i(p0, descr=valuedescr)
  1273. escape_n(p0)
  1274. i1 = int_add(i0, i)
  1275. p1 = new_with_vtable(descr=nodesize)
  1276. setfield_gc(p1, i1, descr=valuedescr)
  1277. jump(i, p1)
  1278. """
  1279. preamble = """
  1280. [i, p0]
  1281. i0 = getfield_gc_i(p0, descr=valuedescr)
  1282. escape_n(p0)
  1283. i1 = int_add(i0, i)
  1284. jump(i, i1)
  1285. """
  1286. expected = """
  1287. [i, i1]
  1288. p1 = new_with_vtable(descr=nodesize)
  1289. setfield_gc(p1, i1, descr=valuedescr)
  1290. escape_n(p1)
  1291. i2 = int_add(i1, i)
  1292. jump(i, i2)
  1293. """
  1294. self.optimize_loop(ops, expected, preamble)
  1295. def test_nonvirtual_later(self):
  1296. ops = """
  1297. [i]
  1298. p1 = new_with_vtable(descr=nodesize)
  1299. setfield_gc(p1, i, descr=valuedescr)
  1300. i1 = getfield_gc_i(p1, descr=valuedescr)
  1301. escape_n(p1)
  1302. i2 = getfield_gc_i(p1, descr=valuedescr)
  1303. i3 = int_add(i1, i2)
  1304. jump(i3)
  1305. """
  1306. expected = """
  1307. [i]
  1308. p1 = new_with_vtable(descr=nodesize)
  1309. setfield_gc(p1, i, descr=valuedescr)
  1310. escape_n(p1)
  1311. i2 = getfield_gc_i(p1, descr=valuedescr)
  1312. i3 = int_add(i, i2)
  1313. jump(i3)
  1314. """
  1315. self.optimize_loop(ops, expected)
  1316. def test_nonvirtual_write_null_fields_on_force(self):
  1317. ops = """
  1318. [i]
  1319. p1 = new_with_vtable(descr=nodesize)
  1320. setfield_gc(p1, i, descr=valuedescr)
  1321. i1 = getfield_gc_i(p1, descr=valuedescr)
  1322. setfield_gc(p1, 0, descr=valuedescr)
  1323. escape_n(p1)
  1324. i2 = getfield_gc_i(p1, descr=valuedescr)
  1325. jump(i2)
  1326. """
  1327. expected = """
  1328. [i]
  1329. p1 = new_with_vtable(descr=nodesize)
  1330. setfield_gc(p1, 0, descr=valuedescr)
  1331. escape_n(p1)
  1332. i2 = getfield_gc_i(p1, descr=valuedescr)
  1333. jump(i2)
  1334. """
  1335. self.optimize_loop(ops, expected)
  1336. def test_pure_getfield_gc_1(self):
  1337. ops = """
  1338. [i]
  1339. p1 = new_with_vtable(descr=nodesize)
  1340. setfield_gc(p1, i, descr=valuedescr)
  1341. i1 = getfield_gc_i(p1, descr=valuedescr)
  1342. jump(i1)
  1343. """
  1344. expected = """
  1345. [i]
  1346. jump(i)
  1347. """
  1348. self.optimize_loop(ops, expected)
  1349. def test_pure_getfield_gc_2(self):
  1350. ops = """
  1351. [i]
  1352. i1 = getfield_gc_i(ConstPtr(myptr3), descr=valuedescr3)
  1353. jump(i1)
  1354. """
  1355. expected = """
  1356. []
  1357. jump()
  1358. """
  1359. self.node.value = 5
  1360. self.optimize_loop(ops, expected)
  1361. def test_pure_getfield_gc_3(self):
  1362. ops = """
  1363. []
  1364. p1 = escape_r()
  1365. p2 = getfield_gc_r(p1, descr=nextdescr3)
  1366. escape_n(p2)
  1367. p3 = getfield_gc_r(p1, descr=nextdescr3)
  1368. escape_n(p3)
  1369. jump()
  1370. """
  1371. expected = """
  1372. []
  1373. p1 = escape_r()
  1374. p2 = getfield_gc_r(p1, descr=nextdescr3)
  1375. escape_n(p2)
  1376. escape_n(p2)
  1377. jump()
  1378. """
  1379. self.optimize_loop(ops, expected)
  1380. def test_getfield_gc_nonpure_2(self):
  1381. ops = """
  1382. [i]
  1383. i1 = getfield_gc_i(ConstPtr(myptr), descr=valuedescr)
  1384. call_n(i1, descr=nonwritedescr)
  1385. jump(i)
  1386. """
  1387. preamble = """
  1388. [i]
  1389. i1 = getfield_gc_i(ConstPtr(myptr), descr=valuedescr)
  1390. call_n(i1, descr=nonwritedescr)
  1391. jump(i, i1)
  1392. """
  1393. expected = """
  1394. [i, i1]
  1395. call_n(i1, descr=nonwritedescr)
  1396. jump(i, i1)
  1397. """
  1398. self.optimize_loop(ops, expected, preamble)
  1399. def test_varray_boxed1(self):
  1400. ops = """
  1401. [p0, p8]
  1402. p11 = getfield_gc_r(p0, descr=otherdescr)
  1403. guard_nonnull(p11) [p0, p8]
  1404. guard_class(p11, ConstClass(node_vtable2)) [p0, p8]
  1405. p14 = getfield_gc_r(p11, descr=otherdescr)
  1406. guard_isnull(p14) [p0, p8]
  1407. p18 = getfield_gc_r(ConstPtr(myptr), descr=otherdescr)
  1408. guard_isnull(p18) [p0, p8]
  1409. p31 = new(descr=ssize)
  1410. setfield_gc(p31, 0, descr=adescr)
  1411. p33 = new_array(0, descr=arraydescr)
  1412. setfield_gc(p31, p33, descr=bdescr)
  1413. p35 = new_with_vtable(descr=nodesize)
  1414. setfield_gc(p35, p31, descr=nexttupledescr)
  1415. jump(p0, p35)
  1416. """
  1417. expected = """
  1418. [p0, p1]
  1419. jump(p0, p1)
  1420. """
  1421. self.optimize_loop(ops, expected)
  1422. def test_varray_boxed_simplified(self):
  1423. ops = """
  1424. [p0, p8]
  1425. p18 = getfield_gc_r(ConstPtr(myptr), descr=otherdescr)
  1426. guard_isnull(p18) [p0, p8]
  1427. p31 = new(descr=ssize)
  1428. p35 = new_with_vtable(descr=nodesize)
  1429. setfield_gc(p35, p31, descr=nexttupledescr)
  1430. jump(p0, p35)
  1431. """
  1432. expected = """
  1433. [p0]
  1434. jump(p0)
  1435. """
  1436. self.optimize_loop(ops, expected)
  1437. def test_varray_boxed_noconst(self):
  1438. ops = """
  1439. [p0, p8, p18, p19]
  1440. guard_isnull(p18) [p0, p8]
  1441. p31 = new(descr=ssize)
  1442. p35 = new_with_vtable(descr=nodesize)
  1443. setfield_gc(p35, p31, descr=nexttupledescr)
  1444. jump(p0, p35, p19, p18)
  1445. """
  1446. expected = """
  1447. [p0, p19]
  1448. guard_isnull(p19) [p0]
  1449. jump(p0, NULL)
  1450. """
  1451. self.optimize_loop(ops, expected)
  1452. def test_varray_1(self):
  1453. ops = """
  1454. [i1]
  1455. p1 = new_array(3, descr=arraydescr)
  1456. i3 = arraylen_gc(p1, descr=arraydescr)
  1457. guard_value(i3, 3) []
  1458. setarrayitem_gc(p1, 1, i1, descr=arraydescr)
  1459. setarrayitem_gc(p1, 0, 25, descr=arraydescr)
  1460. i2 = getarrayitem_gc_i(p1, 1, descr=arraydescr)
  1461. jump(i2)
  1462. """
  1463. expected = """
  1464. [i1]
  1465. jump(i1)
  1466. """
  1467. self.optimize_loop(ops, expected)
  1468. def test_varray_clear_unroll_bug(self):
  1469. ops = """
  1470. [p0]
  1471. i0 = getarrayitem_gc_i(p0, 0, descr=arraydescr)
  1472. i1 = getarrayitem_gc_i(p0, 1, descr=arraydescr)
  1473. i2 = getarrayitem_gc_i(p0, 2, descr=arraydescr)
  1474. i3 = int_add(i0, i1)
  1475. i4 = int_add(i3, i2)
  1476. p1 = new_array_clear(3, descr=arraydescr)
  1477. setarrayitem_gc(p1, 1, i4, descr=arraydescr)
  1478. setarrayitem_gc(p1, 0, 25, descr=arraydescr)
  1479. jump(p1)
  1480. """
  1481. expected = """
  1482. [i1]
  1483. i2 = int_add(25, i1)
  1484. jump(i2)
  1485. """
  1486. jump_values = [self.arrayref]
  1487. self.optimize_loop(ops, expected, jump_values=jump_values)
  1488. def test_varray_alloc_and_set(self):
  1489. ops = """
  1490. [i1]
  1491. p1 = new_array(2, descr=arraydescr)
  1492. setarrayitem_gc(p1, 0, 25, descr=arraydescr)
  1493. i2 = getarrayitem_gc_i(p1, 0, descr=arraydescr)
  1494. jump(i2)
  1495. """
  1496. preamble = """
  1497. [i1]
  1498. jump()
  1499. """
  1500. expected = """
  1501. []
  1502. jump()
  1503. """
  1504. self.optimize_loop(ops, expected, preamble)
  1505. def test_varray_float(self):
  1506. ops = """
  1507. [f1]
  1508. p1 = new_array(3, descr=floatarraydescr)
  1509. i3 = arraylen_gc(p1, descr=floatarraydescr)
  1510. guard_value(i3, 3) []
  1511. setarrayitem_gc(p1, 1, f1, descr=floatarraydescr)
  1512. setarrayitem_gc(p1, 0, 3.5, descr=floatarraydescr)
  1513. f2 = getarrayitem_gc_f(p1, 1, descr=floatarraydescr)
  1514. jump(f2)
  1515. """
  1516. expected = """
  1517. [f1]
  1518. jump(f1)
  1519. """
  1520. self.optimize_loop(ops, expected)
  1521. def test_array_non_optimized(self):
  1522. ops = """
  1523. [i1, p0]
  1524. setarrayitem_gc(p0, 0, i1, descr=arraydescr)
  1525. guard_nonnull(p0) []
  1526. p1 = new_array(i1, descr=arraydescr)
  1527. jump(i1, p1)
  1528. """
  1529. expected = """
  1530. [i1, p0]
  1531. p1 = new_array(i1, descr=arraydescr)
  1532. setarrayitem_gc(p0, 0, i1, descr=arraydescr)
  1533. jump(i1, p1)
  1534. """
  1535. self.optimize_loop(ops, expected)
  1536. def test_nonvirtual_array_write_null_fields_on_force(self):
  1537. ops = """
  1538. [i1]
  1539. p1 = new_array(5, descr=arraydescr)
  1540. setarrayitem_gc(p1, 0, i1, descr=arraydescr)
  1541. setarrayitem_gc(p1, 1, 0, descr=arraydescr)
  1542. escape_n(p1)
  1543. jump(i1)
  1544. """
  1545. expected = """
  1546. [i1]
  1547. p1 = new_array(5, descr=arraydescr)
  1548. setarrayitem_gc(p1, 0, i1, descr=arraydescr)
  1549. setarrayitem_gc(p1, 1, 0, descr=arraydescr)
  1550. escape_n(p1)
  1551. jump(i1)
  1552. """
  1553. self.optimize_loop(ops, expected)
  1554. def test_varray_2(self):
  1555. ops = """
  1556. [i0, p1]
  1557. i1 = getarrayitem_gc_i(p1, 0, descr=arraydescr)
  1558. i2 = getarrayitem_gc_i(p1, 1, descr=arraydescr)
  1559. i3 = int_sub(i1, i2)
  1560. guard_value(i3, 15) []
  1561. p2 = new_array(2, descr=arraydescr)
  1562. setarrayitem_gc(p2, 1, i0, descr=arraydescr)
  1563. setarrayitem_gc(p2, 0, 20, descr=arraydescr)
  1564. jump(i0, p2)
  1565. """
  1566. preamble = """
  1567. [i0, p1]
  1568. i1 = getarrayitem_gc_i(p1, 0, descr=arraydescr)
  1569. i2 = getarrayitem_gc_i(p1, 1, descr=arraydescr)
  1570. i3 = int_sub(i1, i2)
  1571. guard_value(i3, 15) []
  1572. jump(i0)
  1573. """
  1574. expected = """
  1575. [i0]
  1576. i3 = int_sub(20, i0)
  1577. guard_value(i3, 15) []
  1578. jump(5)
  1579. """
  1580. self.optimize_loop(ops, expected, preamble,
  1581. jump_values=[None, self.arrayref])
  1582. def test_p123_array(self):
  1583. ops = """
  1584. [i1, p2, p3]
  1585. i3 = getarrayitem_gc_i(p3, 0, descr=arraydescr)
  1586. escape_n(i3)
  1587. p1 = new_array(1, descr=arraydescr)
  1588. setarrayitem_gc(p1, 0, i1, descr=arraydescr)
  1589. jump(i1, p1, p2)
  1590. """
  1591. preamble = """
  1592. [i1, p2, p3]
  1593. i3 = getarrayitem_gc_i(p3, 0, descr=arraydescr)
  1594. escape_n(i3)
  1595. jump(i1, p2)
  1596. """
  1597. expected = """
  1598. [i1, p2]
  1599. i3 = getarrayitem_gc_i(p2, 0, descr=arraydescr)
  1600. escape_n(i3)
  1601. p1 = new_array(1, descr=arraydescr)
  1602. setarrayitem_gc(p1, 0, i1, descr=arraydescr)
  1603. jump(i1, p1)
  1604. """
  1605. # We cannot track virtuals that survive for more than two iterations.
  1606. self.optimize_loop(ops, expected, preamble,
  1607. jump_values=[None, self.arrayref, None])
  1608. def test_varray_forced_1(self):
  1609. ops = """
  1610. []
  1611. p2 = new_with_vtable(descr=nodesize)
  1612. setfield_gc(p2, 3, descr=valuedescr)
  1613. i1 = getfield_gc_i(p2, descr=valuedescr) # i1 = const 3
  1614. p1 = new_array(i1, descr=arraydescr)
  1615. escape_n(p1)
  1616. i2 = arraylen_gc(p1)
  1617. escape_n(i2)
  1618. jump()
  1619. """
  1620. expected = """
  1621. []
  1622. p1 = new_array(3, descr=arraydescr)
  1623. escape_n(p1)
  1624. escape_n(3)
  1625. jump()
  1626. """
  1627. self.optimize_loop(ops, expected)
  1628. def test_vstruct_1(self):
  1629. ops = """
  1630. [i1, p2]
  1631. i2 = getfield_gc_i(p2, descr=adescr)
  1632. escape_n(i2)
  1633. p3 = new(descr=ssize)
  1634. setfield_gc(p3, i1, descr=adescr)
  1635. jump(i1, p3)
  1636. """
  1637. preamble = """
  1638. [i1, p2]
  1639. i2 = getfield_gc_i(p2, descr=adescr)
  1640. escape_n(i2)
  1641. jump(i1)
  1642. """
  1643. expected = """
  1644. [i1]
  1645. escape_n(i1)
  1646. jump(i1)
  1647. """
  1648. self.optimize_loop(ops, expected, preamble,
  1649. jump_values=[None, self.tupleaddr])
  1650. def test_p123_vstruct(self):
  1651. ops = """
  1652. [i1, p2, p3]
  1653. i3 = getfield_gc_i(p3, descr=adescr)
  1654. escape_n(i3)
  1655. p1 = new(descr=ssize)
  1656. setfield_gc(p1, i1, descr=adescr)
  1657. jump(i1, p1, p2)
  1658. """
  1659. preamble = """
  1660. [i1, p2, p3]
  1661. i3 = getfield_gc_i(p3, descr=adescr)
  1662. escape_n(i3)
  1663. jump(i1, p2)
  1664. """
  1665. expected = """
  1666. [i1, p2]
  1667. i3 = getfield_gc_i(p2, descr=adescr)
  1668. escape_n(i3)
  1669. p1 = new(descr=ssize)
  1670. setfield_gc(p1, i1, descr=adescr)
  1671. jump(i1, p1)
  1672. """
  1673. # We cannot track virtuals that survive for more than two iterations.
  1674. self.optimize_loop(ops, expected, preamble,
  1675. jump_values=[None, self.tupleaddr, None])
  1676. def test_virtual_raw_malloc_basic(self):
  1677. ops = """
  1678. [i1]
  1679. i2 = call_i('malloc', 10, descr=raw_malloc_descr)
  1680. guard_no_exception() []
  1681. setarrayitem_raw(i2, 0, i1, descr=rawarraydescr)
  1682. i3 = getarrayitem_raw_i(i2, 0, descr=rawarraydescr)
  1683. call_n('free', i2, descr=raw_free_descr)
  1684. jump(i3)
  1685. """
  1686. expected = """
  1687. [i1]
  1688. jump(i1)
  1689. """
  1690. self.optimize_loop(ops, expected)
  1691. def test_virtual_raw_malloc_const(self):
  1692. ops = """
  1693. [i1]
  1694. i5 = int_mul(10, 1)
  1695. i2 = call_i('malloc', i5, descr=raw_malloc_descr)
  1696. guard_no_exception() []
  1697. setarrayitem_raw(i2, 0, i1, descr=rawarraydescr)
  1698. i3 = getarrayitem_raw_i(i2, 0, descr=rawarraydescr)
  1699. call_n('free', i2, descr=raw_free_descr)
  1700. jump(i3)
  1701. """
  1702. expected = """
  1703. [i1]
  1704. jump(i1)
  1705. """
  1706. self.optimize_loop(ops, expected)
  1707. def test_virtual_raw_malloc_force(self):
  1708. ops = """
  1709. [i1]
  1710. i2 = call_i('malloc', 20, descr=raw_malloc_descr)
  1711. guard_no_exception() []
  1712. setarrayitem_

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