PageRenderTime 107ms CodeModel.GetById 30ms RepoModel.GetById 1ms app.codeStats 0ms

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

https://bitbucket.org/evelyn559/pypy
Python | 5102 lines | 5074 code | 19 blank | 9 comment | 9 complexity | 47d891aee1f42305160966e022cd0e50 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
  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, descr=arraydescr2)
  1604. p5

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