PageRenderTime 60ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

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

https://bitbucket.org/varialus/jyjy
Python | 5121 lines | 5093 code | 19 blank | 9 comment | 9 complexity | 53e4e24f0c9d27e43ed9071c9e55ef60 MD5 | raw file

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

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

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