irbuild-vectorcall.test 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. -- Test cases for calls using the vectorcall API (Python 3.8+)
  2. --
  3. -- Vectorcalls are faster than the legacy API, especially with keyword arguments,
  4. -- since there is no need to allocate a temporary dictionary for keyword args.
  5. [case testeVectorcallBasic_python3_8]
  6. from typing import Any
  7. def f(c: Any) -> None:
  8. c()
  9. c('x', 'y')
  10. [out]
  11. def f(c):
  12. c, r0 :: object
  13. r1, r2 :: str
  14. r3 :: object[2]
  15. r4 :: object_ptr
  16. r5 :: object
  17. L0:
  18. r0 = _PyObject_Vectorcall(c, 0, 0, 0)
  19. r1 = 'x'
  20. r2 = 'y'
  21. r3 = [r1, r2]
  22. r4 = load_address r3
  23. r5 = _PyObject_Vectorcall(c, r4, 2, 0)
  24. keep_alive r1, r2
  25. return 1
  26. [case testVectorcallKeywords_python3_8]
  27. from typing import Any
  28. def f(c: Any) -> None:
  29. c(x='a')
  30. c('x', a='y', b='z')
  31. [out]
  32. def f(c):
  33. c :: object
  34. r0 :: str
  35. r1 :: object[1]
  36. r2 :: object_ptr
  37. r3, r4 :: object
  38. r5, r6, r7 :: str
  39. r8 :: object[3]
  40. r9 :: object_ptr
  41. r10, r11 :: object
  42. L0:
  43. r0 = 'a'
  44. r1 = [r0]
  45. r2 = load_address r1
  46. r3 = ('x',)
  47. r4 = _PyObject_Vectorcall(c, r2, 0, r3)
  48. keep_alive r0
  49. r5 = 'x'
  50. r6 = 'y'
  51. r7 = 'z'
  52. r8 = [r5, r6, r7]
  53. r9 = load_address r8
  54. r10 = ('a', 'b')
  55. r11 = _PyObject_Vectorcall(c, r9, 1, r10)
  56. keep_alive r5, r6, r7
  57. return 1
  58. [case testVectorcallMethod_python3_8]
  59. from typing import Any
  60. def f(o: Any) -> None:
  61. # On Python 3.8 vectorcalls are only faster with keyword args
  62. o.m('x')
  63. o.m('x', a='y')
  64. [out]
  65. def f(o):
  66. o :: object
  67. r0, r1 :: str
  68. r2 :: object
  69. r3, r4, r5 :: str
  70. r6 :: object
  71. r7 :: object[2]
  72. r8 :: object_ptr
  73. r9, r10 :: object
  74. L0:
  75. r0 = 'x'
  76. r1 = 'm'
  77. r2 = CPyObject_CallMethodObjArgs(o, r1, r0, 0)
  78. r3 = 'x'
  79. r4 = 'y'
  80. r5 = 'm'
  81. r6 = CPyObject_GetAttr(o, r5)
  82. r7 = [r3, r4]
  83. r8 = load_address r7
  84. r9 = ('a',)
  85. r10 = _PyObject_Vectorcall(r6, r8, 1, r9)
  86. keep_alive r3, r4
  87. return 1
  88. [case testVectorcallMethod_python3_9_64bit]
  89. from typing import Any
  90. def f(o: Any) -> None:
  91. # Python 3.9 has a new API for calling methods
  92. o.m('x')
  93. o.m('x', 'y', a='z')
  94. [out]
  95. def f(o):
  96. o :: object
  97. r0, r1 :: str
  98. r2 :: object[2]
  99. r3 :: object_ptr
  100. r4 :: object
  101. r5, r6, r7, r8 :: str
  102. r9 :: object[4]
  103. r10 :: object_ptr
  104. r11, r12 :: object
  105. L0:
  106. r0 = 'x'
  107. r1 = 'm'
  108. r2 = [o, r0]
  109. r3 = load_address r2
  110. r4 = PyObject_VectorcallMethod(r1, r3, 9223372036854775810, 0)
  111. keep_alive o, r0
  112. r5 = 'x'
  113. r6 = 'y'
  114. r7 = 'z'
  115. r8 = 'm'
  116. r9 = [o, r5, r6, r7]
  117. r10 = load_address r9
  118. r11 = ('a',)
  119. r12 = PyObject_VectorcallMethod(r8, r10, 9223372036854775811, r11)
  120. keep_alive o, r5, r6, r7
  121. return 1
  122. [case testVectorcallMethod_python3_9_32bit]
  123. from typing import Any
  124. def f(o: Any) -> None:
  125. # The IR is slightly different on 32-bit platforms
  126. o.m('x', a='y')
  127. [out]
  128. def f(o):
  129. o :: object
  130. r0, r1, r2 :: str
  131. r3 :: object[3]
  132. r4 :: object_ptr
  133. r5, r6 :: object
  134. L0:
  135. r0 = 'x'
  136. r1 = 'y'
  137. r2 = 'm'
  138. r3 = [o, r0, r1]
  139. r4 = load_address r3
  140. r5 = ('a',)
  141. r6 = PyObject_VectorcallMethod(r2, r4, 2147483650, r5)
  142. keep_alive o, r0, r1
  143. return 1